Merge "Remove WebView MultiProcess Developer Option." into oc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b38cea7..4f94bf8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2519,7 +2519,7 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.android.settings.SHORTCUT" />
</intent-filter>
- <intent-filter android:priority="120">
+ <intent-filter android:priority="160">
<action android:name="com.android.settings.action.SETTINGS"/>
</intent-filter>
<meta-data android:name="com.android.settings.category"
@@ -2582,7 +2582,7 @@
<action android:name="com.android.settings.action.SETTINGS" />
</intent-filter>
<meta-data android:name="com.android.settings.category"
- android:value="com.android.settings.category.ia.apps" />
+ android:value="com.android.settings.category.ia.notifications" />
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.applications.NotificationApps" />
</activity>
@@ -2645,6 +2645,10 @@
android:value="true" />
</activity>
+ <!-- Confirmation dialog for enabling notification access from CompanionDeviceManager -->
+ <activity android:name=".notification.NotificationAccessConfirmationActivity"
+ android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert" />
+
<receiver android:name=".widget.SettingsAppWidgetProvider"
android:label="@string/gadget_title"
android:exported="false"
diff --git a/res/drawable/action_bar_dropshadow.xml b/res/drawable/action_bar_dropshadow.xml
new file mode 100644
index 0000000..dd85877
--- /dev/null
+++ b/res/drawable/action_bar_dropshadow.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <gradient
+ android:angle="270"
+ android:startColor="#4D000000"
+ android:endColor="@android:color/transparent"
+ android:type="linear" />
+ <size android:height="8dp" />
+</shape>
\ No newline at end of file
diff --git a/res/drawable/ic_instant_apps_badge.xml b/res/drawable/ic_instant_apps_badge.xml
deleted file mode 100644
index 115aa83..0000000
--- a/res/drawable/ic_instant_apps_badge.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2017 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
- android:viewportWidth="48"
- android:viewportHeight="48">
- <path
- android:fillColor="#FFFFFF"
- android:fillType="evenOdd"
- android:pathData="M 24.5 2.7 C 35.5456949966 2.7 44.5 11.6543050034 44.5 22.7 C 44.5 33.7456949966 35.5456949966 42.7 24.5 42.7 C 13.4543050034 42.7 4.5 33.7456949966 4.5 22.7 C 4.5 11.6543050034 13.4543050034 2.7 24.5 2.7 Z" />
- <path
- android:fillColor="#757575"
- android:fillType="evenOdd"
- android:pathData="M 33.3 19.1 L 26.4 19.1 L 26.4 5.8 L 16.6 26.4 L 23.5 26.3 L 23.5 39.6 Z" />
- <path
- android:fillType="evenOdd"
- android:pathData="M 0.5 0 H 48.5 V 48 H 0.5 V 0 Z" />
-</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_instant_apps_badge_bg.xml b/res/drawable/ic_instant_apps_badge_bg.xml
deleted file mode 100644
index bf8d3ea..0000000
--- a/res/drawable/ic_instant_apps_badge_bg.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2017 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
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval">
- <gradient android:type="radial"
- android:startColor="#4d000000"
- android:endColor="#00000000"
- android:gradientRadius="12dp"/>
-</shape>
\ No newline at end of file
diff --git a/res/drawable/ic_media_stream_on_24dp.xml b/res/drawable/ic_media_stream_on_24dp.xml
new file mode 100644
index 0000000..3db55dd
--- /dev/null
+++ b/res/drawable/ic_media_stream_on_24dp.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M18,3h-5c-0.55,0 -1,0.45 -1,1v8.3a3.88,3.88 0,0 0,-2.9 -0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26A4.483,4.483 0,0 0,10.5 21c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1z"/>
+</vector>
diff --git a/res/layout/app_details.xml b/res/layout/app_details.xml
index 5ffeec5..b05c0dc 100644
--- a/res/layout/app_details.xml
+++ b/res/layout/app_details.xml
@@ -17,49 +17,27 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/app_snippet"
- style="@style/EntityHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal|top"
- android:orientation="vertical"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:paddingTop="24dp"
- android:paddingBottom="24dp"
- android:clipChildren="false"
- android:clipToPadding="false">
+ android:orientation="vertical">
<!-- App snippet with buttons -->
<RelativeLayout
+ android:id="@+id/app_snippet"
+ style="@style/EntityHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="8dp"
- android:clipChildren="false"
- android:clipToPadding="false">
-
- <FrameLayout android:id="@+id/app_icon_frame"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:clipChildren="false"
- android:clipToPadding="false">
- <ImageView
- android:id="@+id/app_detail_icon"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="fitXY"
- android:layout_gravity="center_horizontal"
- android:antialias="true"/>
- <ImageView android:id="@+id/app_icon_instant_apps_badge"
- android:layout_width="22dp"
- android:layout_height="22dp"
- android:layout_gravity="end|bottom"
- android:layout_margin="8dp"
- android:visibility="gone"
- android:elevation="20dp"
- android:background="@drawable/ic_instant_apps_badge_bg"
- android:src="@drawable/ic_instant_apps_badge" />
- </FrameLayout>
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="0dp"
+ android:paddingTop="24dp"
+ android:paddingBottom="24dp">
+ <ImageView
+ android:id="@+id/app_detail_icon"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:scaleType="fitXY"
+ android:layout_gravity="center_horizontal"
+ android:antialias="true"/>
<LinearLayout
android:id="@+id/app_detail_links"
@@ -70,19 +48,22 @@
<ImageButton
android:id="@+id/right_button"
- style="@android:style/Widget.Material.Button.Borderless"
+ style="?android:attr/actionOverflowButtonStyle"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="0dp"
+ android:minWidth="@dimen/min_tap_target_size"
android:src="@drawable/ic_settings_24dp"
android:tint="?android:attr/colorAccent"/>
<ImageButton
android:id="@+id/left_button"
- style="@android:style/Widget.Material.Button.Borderless"
+ style="?android:attr/actionOverflowButtonStyle"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="0dp"
+ android:minWidth="@dimen/min_tap_target_size"
+ android:src="@null"
android:tint="?android:attr/colorAccent"/>
</LinearLayout>
@@ -90,7 +71,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_toEndOf="@id/app_icon_frame"
+ android:layout_toEndOf="@id/app_detail_icon"
android:layout_toStartOf="@id/app_detail_links"
android:paddingStart="24dp"
android:paddingEnd="24dp"
@@ -131,4 +112,9 @@
</RelativeLayout>
+ <!-- Drop shadow -->
+ <View android:layout_width="match_parent"
+ android:layout_height="5dp"
+ android:background="@drawable/action_bar_dropshadow"/>
+
</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/choose_lock_password.xml b/res/layout/choose_lock_password.xml
index 260db7f..0888b5e 100644
--- a/res/layout/choose_lock_password.xml
+++ b/res/layout/choose_lock_password.xml
@@ -20,6 +20,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
+ settings:suwFooter="@layout/choose_lock_password_footer"
settings:suwHeaderText="@string/lockpassword_choose_your_password_header">
<LinearLayout
@@ -65,33 +66,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:gravity="end"
- android:orientation="horizontal">
-
- <!-- left : cancel -->
- <Button android:id="@+id/cancel_button"
- style="@style/SetupWizardButton.Negative"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/lockpassword_cancel_label" />
-
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
- <!-- right : continue -->
- <Button android:id="@+id/next_button"
- style="@style/SetupWizardButton.Positive"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/lockpassword_continue_label" />
- </LinearLayout>
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/choose_lock_password_footer.xml b/res/layout/choose_lock_password_footer.xml
new file mode 100644
index 0000000..57be320
--- /dev/null
+++ b/res/layout/choose_lock_password_footer.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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.
+-->
+
+<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/SuwGlifButtonBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <!-- left : cancel -->
+ <Button android:id="@+id/cancel_button"
+ style="@style/SuwGlifButton.Secondary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/lockpassword_cancel_label" />
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <!-- right : continue -->
+ <Button android:id="@+id/next_button"
+ style="@style/SuwGlifButton.Primary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/lockpassword_continue_label" />
+
+</LinearLayout>
diff --git a/res/layout/choose_lock_pattern_common.xml b/res/layout/choose_lock_pattern_common.xml
index 050479b..a54987d 100644
--- a/res/layout/choose_lock_pattern_common.xml
+++ b/res/layout/choose_lock_pattern_common.xml
@@ -22,6 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
+ settings:suwFooter="@layout/choose_lock_pattern_common_footer"
settings:suwHeaderText="@string/lockpassword_choose_your_pattern_header">
<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
@@ -56,35 +57,6 @@
android:layout_height="0dip"
android:layout_weight="4" />
- <!-- Buttons are hidden during setup, and use the buttons in setup navigation bar instead -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="horizontal">
-
- <!-- left : cancel, or re-try -->
- <Button android:id="@+id/footerLeftButton"
- style="@style/SetupWizardButton.Negative"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/lockpattern_tutorial_cancel_label" />
-
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
- <!-- right : confirm or ok -->
- <Button android:id="@+id/footerRightButton"
- style="@style/SetupWizardButton.Positive"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/lockpattern_tutorial_continue_label" />
-
- </LinearLayout>
-
</LinearLayout>
<TextView android:id="@+id/footerText"
diff --git a/res/layout/choose_lock_pattern_common_footer.xml b/res/layout/choose_lock_pattern_common_footer.xml
new file mode 100644
index 0000000..d80702e
--- /dev/null
+++ b/res/layout/choose_lock_pattern_common_footer.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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.
+-->
+
+<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/SuwGlifButtonBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <!-- left : cancel, or re-try -->
+ <Button android:id="@+id/footerLeftButton"
+ style="@style/SuwGlifButton.Secondary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/lockpattern_tutorial_cancel_label" />
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <!-- right : confirm or ok -->
+ <Button android:id="@+id/footerRightButton"
+ style="@style/SuwGlifButton.Primary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/lockpattern_tutorial_continue_label" />
+
+</LinearLayout>
diff --git a/res/layout/confirm_lock_password_internal.xml b/res/layout/confirm_lock_password_internal.xml
index 4f22cfb..02d28b2 100644
--- a/res/layout/confirm_lock_password_internal.xml
+++ b/res/layout/confirm_lock_password_internal.xml
@@ -48,13 +48,6 @@
android:layout_marginStart="?attr/suwMarginSides"
android:layout_marginEnd="?attr/suwMarginSides" />
- <Button
- style="@style/SetupWizardButton.Negative"
- android:id="@+id/cancelButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/cancel" />
-
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
@@ -94,5 +87,12 @@
android:contentDescription="@string/confirm_fingerprint_icon_content_description"
android:visibility="gone"/>
+ <Button
+ style="@style/SetupWizardButton.Negative"
+ android:id="@+id/cancelButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
</com.android.setupwizardlib.GlifLayout>
\ No newline at end of file
diff --git a/res/layout/confirm_lock_pattern_internal_base.xml b/res/layout/confirm_lock_pattern_internal_base.xml
index 359b51b..e20d04d 100644
--- a/res/layout/confirm_lock_pattern_internal_base.xml
+++ b/res/layout/confirm_lock_pattern_internal_base.xml
@@ -58,15 +58,6 @@
android:layout_marginStart="?attr/suwMarginSides"
android:layout_marginEnd="?attr/suwMarginSides" />
- <Button
- android:id="@+id/cancelButton"
- style="@style/SetupWizardButton.Negative"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="?attr/suwMarginSides"
- android:layout_marginEnd="?attr/suwMarginSides"
- android:text="@string/cancel" />
-
</LinearLayout>
</ScrollView>
@@ -108,5 +99,15 @@
android:visibility="gone"/>
</LinearLayout>
+ <Button
+ android:id="@+id/cancelButton"
+ style="@style/SuwGlifButton.Secondary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="?attr/suwMarginSides"
+ android:layout_marginEnd="?attr/suwMarginSides"
+ android:text="@string/cancel" />
+
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
+
</com.android.setupwizardlib.GlifLayout>
diff --git a/res/layout/encryption_interstitial.xml b/res/layout/encryption_interstitial.xml
new file mode 100644
index 0000000..f827e37
--- /dev/null
+++ b/res/layout/encryption_interstitial.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<com.android.setupwizardlib.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">
+
+ <LinearLayout
+ style="@style/SuwContentFrame"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/encryption_message"
+ style="@style/SuwDescription.Glif"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+
+</com.android.setupwizardlib.GlifLayout>
diff --git a/res/layout/encryption_interstitial_footer.xml b/res/layout/encryption_interstitial_footer.xml
new file mode 100644
index 0000000..2f876f3
--- /dev/null
+++ b/res/layout/encryption_interstitial_footer.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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.
+-->
+
+<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/SuwGlifButtonBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/encrypt_dont_require_password"
+ style="@style/SuwGlifButton.Secondary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/encryption_interstitial_no" />
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+ <Button
+ android:id="@+id/encrypt_require_password"
+ style="@style/SuwGlifButton.Primary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/encryption_interstitial_yes" />
+
+</LinearLayout>
diff --git a/res/layout/encryption_interstitial_header.xml b/res/layout/encryption_interstitial_header.xml
deleted file mode 100644
index b4f6dbb..0000000
--- a/res/layout/encryption_interstitial_header.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2016 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.
--->
-
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/encryption_interstitial_header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:minHeight="56dp"
- android:paddingBottom="@dimen/suw_description_glif_margin_bottom_lists"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:paddingTop="@dimen/suw_description_glif_margin_top"
- android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
- android:textAppearance="?android:attr/textAppearanceListItem" />
diff --git a/res/layout/fingerprint_enroll_find_sensor_base.xml b/res/layout/fingerprint_enroll_find_sensor_base.xml
index 60c8bc7..fa344ab 100644
--- a/res/layout/fingerprint_enroll_find_sensor_base.xml
+++ b/res/layout/fingerprint_enroll_find_sensor_base.xml
@@ -18,9 +18,9 @@
<com.android.setupwizardlib.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/setup_wizard_layout"
+ style="?attr/fingerprint_layout_theme"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- style="?attr/fingerprint_layout_theme">
+ android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
@@ -56,7 +56,7 @@
android:layout_weight="1"/>
<Button
- style="@style/SetupWizardButton.Positive"
+ style="@style/SuwGlifButton.Primary"
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/layout/fingerprint_enroll_finish_base.xml b/res/layout/fingerprint_enroll_finish_base.xml
index db099c3..6d9cf70 100644
--- a/res/layout/fingerprint_enroll_finish_base.xml
+++ b/res/layout/fingerprint_enroll_finish_base.xml
@@ -17,10 +17,12 @@
<com.android.setupwizardlib.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"
- style="?attr/fingerprint_layout_theme">
+ app:suwFooter="@layout/fingerprint_enroll_finish_base_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -71,35 +73,6 @@
android:layout_width="match_parent"
android:layout_weight="1"/>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="horizontal">
-
- <Button
- style="@style/SetupWizardButton.Negative"
- android:id="@+id/add_another_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/fingerprint_enroll_button_add" />
-
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
- <Button
- style="@style/SetupWizardButton.Positive"
- android:id="@+id/next_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/security_settings_fingerprint_enroll_done" />
-
- </LinearLayout>
-
</LinearLayout>
</com.android.setupwizardlib.GlifLayout>
diff --git a/res/layout/fingerprint_enroll_finish_base_footer.xml b/res/layout/fingerprint_enroll_finish_base_footer.xml
new file mode 100644
index 0000000..b3b9c74
--- /dev/null
+++ b/res/layout/fingerprint_enroll_finish_base_footer.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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.
+-->
+
+<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/SuwGlifButtonBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ style="@style/SuwGlifButton.Secondary"
+ android:id="@+id/add_another_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/fingerprint_enroll_button_add" />
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button
+ style="@style/SuwGlifButton.Primary"
+ android:id="@+id/next_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/security_settings_fingerprint_enroll_done" />
+
+</LinearLayout>
diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml
index 6d20756..4f73395 100644
--- a/res/layout/fingerprint_enroll_introduction.xml
+++ b/res/layout/fingerprint_enroll_introduction.xml
@@ -17,10 +17,12 @@
<com.android.setupwizardlib.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">
+ android:layout_height="match_parent"
+ app:suwFooter="@layout/fingerprint_enroll_introduction_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -43,34 +45,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="horizontal">
-
- <Button
- android:id="@+id/fingerprint_cancel_button"
- style="@style/SetupWizardButton.Negative"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/security_settings_fingerprint_enroll_introduction_cancel" />
-
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
- <Button
- android:id="@+id/fingerprint_next_button"
- style="@style/SetupWizardButton.Positive"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/suw_next_button_label" />
-
- </LinearLayout>
-
</LinearLayout>
</com.android.setupwizardlib.GlifLayout>
diff --git a/res/layout/fingerprint_enroll_introduction_footer.xml b/res/layout/fingerprint_enroll_introduction_footer.xml
new file mode 100644
index 0000000..17420fe
--- /dev/null
+++ b/res/layout/fingerprint_enroll_introduction_footer.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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
+-->
+
+<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/SuwGlifButtonBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/fingerprint_cancel_button"
+ style="@style/SuwGlifButton.Secondary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/security_settings_fingerprint_enroll_introduction_cancel" />
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button
+ android:id="@+id/fingerprint_next_button"
+ style="@style/SuwGlifButton.Primary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/suw_next_button_label" />
+
+</LinearLayout>
diff --git a/res/layout/preference_wallpaper_type.xml b/res/layout/preference_wallpaper_type.xml
deleted file mode 100644
index a35a24e..0000000
--- a/res/layout/preference_wallpaper_type.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:gravity="center_vertical"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" >
-
- <ImageView
- android:id="@android:id/icon"
- android:layout_width="40dp"
- android:layout_height="40dp"
- android:layout_gravity="center"
- android:scaleType="fitXY"
- android:layout_marginEnd="16dip"
- android:contentDescription="@null" />
-
- <TextView android:id="@android:id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:layout_weight="1" />
-
-</LinearLayout>
diff --git a/res/layout/redaction_interstitial.xml b/res/layout/redaction_interstitial.xml
index e48f20f..ecc122f 100644
--- a/res/layout/redaction_interstitial.xml
+++ b/res/layout/redaction_interstitial.xml
@@ -22,6 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
+ settings:suwFooter="@layout/redaction_interstitial_footer"
settings:suwHeaderText="@string/lock_screen_notifications_interstitial_title">
<LinearLayout
@@ -69,14 +70,6 @@
</RadioGroup>
- <Button
- android:id="@+id/redaction_done_button"
- style="@style/SetupWizardButton.Positive"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="end"
- android:text="@string/app_notifications_dialog_done" />
-
</LinearLayout>
</com.android.setupwizardlib.GlifLayout>
diff --git a/res/layout/redaction_interstitial_footer.xml b/res/layout/redaction_interstitial_footer.xml
new file mode 100644
index 0000000..1d8758b
--- /dev/null
+++ b/res/layout/redaction_interstitial_footer.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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
+-->
+
+<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/SuwGlifButtonBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/redaction_done_button"
+ style="@style/SuwGlifButton.Primary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:text="@string/app_notifications_dialog_done" />
+
+</FrameLayout>
diff --git a/res/layout/setup_encryption_interstitial_header.xml b/res/layout/setup_encryption_interstitial_header.xml
deleted file mode 100644
index 9601fa8..0000000
--- a/res/layout/setup_encryption_interstitial_header.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2016 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.
--->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:minHeight="56dp"
- android:paddingBottom="@dimen/suw_description_glif_margin_bottom_lists"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:paddingTop="@dimen/suw_description_glif_margin_top"
- android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
- android:textAppearance="?android:attr/textAppearanceListItem" />
diff --git a/res/layout/storage_item.xml b/res/layout/storage_item.xml
index 33f4f9e..0c1f60c 100644
--- a/res/layout/storage_item.xml
+++ b/res/layout/storage_item.xml
@@ -76,6 +76,7 @@
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="8dp"
+ android:layout_marginStart="60dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:visibility="gone"
diff --git a/res/values/colors.xml b/res/values/colors.xml
index ec8fca9..4a09594 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -79,6 +79,8 @@
<!-- Accessibility SUW colors -->
<color name="material_blue_500">#4285F4</color>
<color name="material_blue_700">#3367D6</color>
+ <color name="material_grey_100">#f5f5f5</color>
+ <color name="material_grey_200">#ffffff</color>
<color name="message_text_incoming">#ffffffff</color>
<color name="message_text_outgoing">#ff323232</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 09f7cda..6495ab0 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -22,6 +22,7 @@
<dimen name="action_bar_switch_padding">16dip</dimen>
<dimen name="app_icon_size">40dip</dimen>
+ <dimen name="min_tap_target_size">48dp</dimen>
<dimen name="screen_margin_sides">64dip</dimen>
<dimen name="screen_margin_top">72dip</dimen>
<dimen name="screen_margin_bottom">48dip</dimen>
@@ -241,7 +242,6 @@
<dimen name="mdm_app_icon_width_height">56dp</dimen>
<!-- Launcher Icons -->
- <dimen name="launcher_icon_elevation">6dp</dimen>
<dimen name="shortcut_size_maskable">120dp</dimen>
<dimen name="shortcut_size">40dp</dimen>
<dimen name="shortcut_icon_size">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index dea40b6..236ec29 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1628,6 +1628,8 @@
<string name="wifi_wakeup">Turn on Wi\u2011Fi automatically</string>
<!-- Checkbox summary for option to enable Wi-Fi when high quality saved networks are nearby-->
<string name="wifi_wakeup_summary">Wi\u2011Fi will turn back on near high\u2011quality saved networks, like your home network</string>
+ <!-- Checkbox summary for Wi-Fi wakeup option to explain that Wi-Fi wakeup is disabled because Wi-Fi scanning is turned off -->
+ <string name="wifi_wakeup_summary_scanning_disabled">Unavailable because Wi\u2011Fi scanning is turned off</string>
<!-- Checkbox title for option to toggle poor network detection -->
<string name="wifi_poor_network_detection">Avoid poor connections</string>
<!-- Checkbox summary for option to toggle poor network detection -->
@@ -2376,7 +2378,7 @@
<!-- [CHAR LIMIT=40] Display settings screen, setting option name to change whether the device wakes up when a lift gesture is detected. -->
<string name="lift_to_wake_title">Lift to wake</string>
<!-- [CHAR LIMIT=30] Display settings screen, setting option name to change whether the ambient display feature is enabled. -->
- <string name="doze_title">Incoming notification screen</string>
+ <string name="doze_title">Ambient display</string>
<!-- [CHAR LIMIT=NONE] Display settings screen, setting description for the ambient display feature. -->
<string name="doze_summary">Wake screen when you receive notifications</string>
<!-- [CHAR LIMIT=30] Sound & display settings screen, setting option name to change font size -->
@@ -4686,9 +4688,9 @@
<string name="battery_last_full_charge">Last full charge</string>
<!-- Description for text in battery footer. [CHAR LIMIT=120] -->
<string name="battery_footer_summary">Remaining battery time is approximate and can change based on usage</string>
- <!-- Title for battery usage detail in foreground. [CHAR LIMIT=80] -->
+ <!-- Title for text that shows the amount of time an app has been running while in the foreground. [CHAR LIMIT=80] -->
<string name="battery_detail_foreground">While in active use</string>
- <!-- Title for battery usage detail in background. [CHAR LIMIT=80] -->
+ <!-- Title for text that shows the amount of time an app has been running while in the background. [CHAR LIMIT=80] -->
<string name="battery_detail_background">While in background</string>
<!-- Title for battery usage amount by this app. [CHAR LIMIT=80] -->
<string name="battery_detail_power_usage">Battery usage</string>
@@ -7055,42 +7057,30 @@
<!-- Encryption interstitial button to continue with the shown setting. Appears on screen that asks the user to opt in/out of encrypting device with a pin/pattern/password. [CHAR LIMIT=NONE] -->
<string name="encryption_continue_button">Continue</string>
- <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a PIN to encrypt the device. [CHAR LIMIT=NONE] -->
- <string name="encryption_interstitial_message_pin">
- You can further protect this device by requiring your PIN before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.
- \n\nThis helps protect data on lost or stolen devices.
+ <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a PIN to encrypt the device. [CHAR LIMIT=NONE] [BACKUP_MESSAGE_ID=2317181134653424679] -->
+ <string name="encryption_interstitial_message_pin">You can further protect this device by requiring your PIN before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.
+ \n\nThis helps protect data on lost or stolen devices. Require PIN to start your device?
</string>
- <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a pattern to encrypt the device. [CHAR LIMIT=NONE] -->
- <string name="encryption_interstitial_message_pattern">
- You can further protect this device by requiring your pattern before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.
- \n\nThis helps protect data on lost or stolen devices.
+ <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a pattern to encrypt the device. [CHAR LIMIT=NONE] [BACKUP_MESSAGE_ID=7081249914068568570] -->
+ <string name="encryption_interstitial_message_pattern">You can further protect this device by requiring your pattern before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.
+ \n\nThis helps protect data on lost or stolen devices. Require pattern to start your device?
</string>
- <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a password to encrypt the device. [CHAR LIMIT=NONE] -->
- <string name="encryption_interstitial_message_password">
- You can further protect this device by requiring your password before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.
- \n\nThis helps protect data on lost or stolen devices.
+ <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a password to encrypt the device. [CHAR LIMIT=NONE] [BACKUP_MESSAGE_ID=7796567133897436443] -->
+ <string name="encryption_interstitial_message_password">You can further protect this device by requiring your password before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.
+ \n\nThis helps protect data on lost or stolen devices. Require password to start your device?
</string>
- <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a PIN to encrypt the device while setting up fingerprint unlock. [CHAR LIMIT=NONE] -->
- <string name="encryption_interstitial_message_pin_for_fingerprint">In addition to using your fingerprint to unlock your device, you can further protect this device by requiring your PIN before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.\n\nThis helps protect data on lost or stolen devices.</string>
- <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a pattern to encrypt the device while setting up fingerprint unlock. [CHAR LIMIT=NONE] -->
- <string name="encryption_interstitial_message_pattern_for_fingerprint">In addition to using your fingerprint to unlock your device, you can further protect this device by requiring your pattern before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.\n\nThis helps protect data on lost or stolen devices.</string>
- <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a password to encrypt the device while setting up fingerprint unlock. [CHAR LIMIT=NONE] -->
- <string name="encryption_interstitial_message_password_for_fingerprint">In addition to using your fingerprint to unlock your device, you can further protect this device by requiring your password before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.\n\nThis helps protect data on lost or stolen devices.</string>
+ <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a PIN to encrypt the device while setting up fingerprint unlock. [CHAR LIMIT=NONE] [BACKUP_MESSAGE_ID=4550632760119547492] -->
+ <string name="encryption_interstitial_message_pin_for_fingerprint">In addition to using your fingerprint to unlock your device, you can further protect this device by requiring your PIN before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.\n\nThis helps protect data on lost or stolen devices. Require PIN to start your device?</string>
+ <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a pattern to encrypt the device while setting up fingerprint unlock. [CHAR LIMIT=NONE] [BACKUP_MESSAGE_ID=932184823193006087] -->
+ <string name="encryption_interstitial_message_pattern_for_fingerprint">In addition to using your fingerprint to unlock your device, you can further protect this device by requiring your pattern before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.\n\nThis helps protect data on lost or stolen devices. Require pattern to start your device?</string>
+ <!-- Message shown on encryption interstitial to ask the user whether or not they want to use a password to encrypt the device while setting up fingerprint unlock. [CHAR LIMIT=NONE] [BACKUP_MESSAGE_ID=5560954719370251702] -->
+ <string name="encryption_interstitial_message_password_for_fingerprint">In addition to using your fingerprint to unlock your device, you can further protect this device by requiring your password before it starts up. Until the device starts up, it can\u2019t receive calls, messages, or notifications, including alarms.\n\nThis helps protect data on lost or stolen devices. Require password to start your device></string>
- <!-- Radio button text that require a PIN to start device [CHAR LIMIT=NONE] -->
- <string name="encrypt_require_pin">Require PIN to start device</string>
- <!-- Radio button text that require a pattern to start device [CHAR LIMIT=NONE] -->
- <string name="encrypt_require_pattern">Require pattern to start device</string>
- <!-- Radio button text that require a password to start device [CHAR LIMIT=NONE] -->
- <string name="encrypt_require_password">Require password to start device</string>
-
- <!-- Radio button text that doesn't require a PIN to decrypt [CHAR LIMIT=NONE] -->
- <string name="encrypt_dont_require_pin">No thanks</string>
- <!-- Radio button text that doesn't require a pattern to decrypt [CHAR LIMIT=NONE] -->
- <string name="encrypt_dont_require_pattern">No thanks</string>
- <!-- Radio button text that doesn't require a password to decrypt [CHAR LIMIT=NONE] -->
- <string name="encrypt_dont_require_password">No thanks</string>
+ <!-- Button label to say yes to the question of whether to require PIN/password/pattern to start your device. [CHAR LIMIT=20] [BACKUP_MESSAGE_ID=4439509435889513411] -->
+ <string name="encryption_interstitial_yes">Yes</string>
+ <!-- Button label to say no to the question of whether to require PIN/password/pattern to start your device. [CHAR LIMIT=20] [BACKUP_MESSAGE_ID=8935031349097025137] -->
+ <string name="encryption_interstitial_no">No</string>
<!-- Title for encryption dialog that disables TalkBack. [CHAR_LIMIT=25] -->
<string name="encrypt_talkback_dialog_require_pin">Require PIN?</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e9d25ff..bae36b3 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -416,7 +416,7 @@
<style name="TextAppearance.EntityHeaderTitle"
parent="@android:style/TextAppearance.Material.Subhead">
<item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:textSize">24sp</item>
+ <item name="android:textSize">16sp</item>
</style>
<style name="AppActionPrimaryButton" parent="android:Widget.Material.Button.Colored"/>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 7ca109b..3dbaa8b 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -108,16 +108,17 @@
<!-- Accessibility portion of Setup Wizard -->
<style name="SetupWizardAccessibilityTheme" parent="Theme.SettingsBase">
<item name="android:windowLightStatusBar">false</item>
- <item name="android:colorPrimary">@color/material_blue_700</item>
- <item name="android:colorPrimaryDark">@color/material_blue_700</item>
- <item name="android:actionBarTheme">@android:style/ThemeOverlay.Material.Dark.ActionBar</item>
+ <item name="android:colorPrimary">@color/material_grey_100</item>
+ <item name="android:colorAccent">@color/material_blue_700</item>
+ <item name="android:titleTextColor">@color/material_blue_700</item>
<item name="preferenceTheme">@style/PreferenceTheme</item>
<item name="switchBarTheme">@style/SetupWizardAccessibilitySwitchBarTheme</item>
</style>
<style name="SetupWizardAccessibilitySwitchBarTheme" parent="ThemeOverlay.SwitchBar.Settings">
- <item name="switchBarBackgroundColor">@color/material_blue_500</item>
- <item name="android:colorControlActivated">@android:color/white</item>
+ <item name="switchBarBackgroundColor">@color/material_grey_200</item>
+ <item name="android:colorControlActivated">@color/material_blue_500</item>
+ <item name="android:textColorPrimary">@android:color/black</item>
</style>
<!-- Theme with no local references, used by AccountPreferenceBase where we have to inflate
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 795d35e..02b9949 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -57,11 +57,6 @@
android:title="@string/accessibility_screen_magnification_title"
android:icon="@mipmap/ic_accessibility_magnification" />
- <Preference
- android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
- android:key="daltonizer_preference_screen"
- android:title="@string/accessibility_display_daltonizer_preference_title" />
-
<SwitchPreference
android:key="toggle_large_pointer_icon"
android:title="@string/accessibility_toggle_large_pointer_icon_title" />
@@ -118,6 +113,11 @@
android:key="toggle_high_text_contrast_preference"
android:title="@string/accessibility_toggle_high_text_contrast_preference_title" />
+ <Preference
+ android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
+ android:key="daltonizer_preference_screen"
+ android:title="@string/accessibility_display_daltonizer_preference_title" />
+
<SwitchPreference
android:key="toggle_inversion_preference"
android:title="@string/accessibility_display_inversion_preference_title"
diff --git a/res/xml/app_memory_settings.xml b/res/xml/app_memory_settings.xml
index 53a71ff..308f189 100644
--- a/res/xml/app_memory_settings.xml
+++ b/res/xml/app_memory_settings.xml
@@ -18,26 +18,25 @@
android:title="@string/memory_usage">
<PreferenceCategory
- android:title="@string/average_memory_use"/>
+ android:title="@string/average_memory_use">
- <com.android.settings.SummaryPreference
- android:key="status_header"
- android:selectable="false" />
+ <com.android.settings.SummaryPreference
+ android:key="status_header"
+ android:selectable="false" />
- <com.android.settings.applications.SpacePreference
- android:layout_height="5dp" />
+ <Preference
+ android:key="frequency"
+ android:selectable="false"
+ android:layout="@layout/horizontal_preference"
+ android:title="@string/running_frequency" />
- <Preference
- android:key="frequency"
- android:selectable="false"
- android:layout="@layout/horizontal_preference"
- android:title="@string/running_frequency" />
+ <Preference
+ android:key="max_usage"
+ android:selectable="false"
+ android:layout="@layout/horizontal_preference"
+ android:title="@string/memory_maximum_usage" />
- <Preference
- android:key="max_usage"
- android:selectable="false"
- android:layout="@layout/horizontal_preference"
- android:title="@string/memory_maximum_usage" />
+ </PreferenceCategory>
<PreferenceCategory
android:key="processes"
diff --git a/res/xml/app_storage_settings.xml b/res/xml/app_storage_settings.xml
index 6bd8ae3..1c71bfa 100644
--- a/res/xml/app_storage_settings.xml
+++ b/res/xml/app_storage_settings.xml
@@ -15,8 +15,14 @@
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/application_info_label">
+ <com.android.settings.applications.LayoutPreference
+ android:key="header_view"
+ android:layout="@layout/app_action_buttons"
+ android:selectable="false" />
+
<com.android.settings.applications.SpacePreference
android:key="storage_space"
android:layout_height="8dp" />
@@ -36,13 +42,9 @@
<PreferenceCategory
android:key="storage_category"
android:layout="@layout/tall_preference_category"
- android:title="@string/storage_label">
-
- <Preference
- android:key="total_size"
- android:title="@string/total_size_label"
- android:selectable="false"
- android:layout="@layout/horizontal_preference" />
+ android:title="@string/app_info_storage_title"
+ settings:allowDividerAbove="false"
+ settings:allowDividerBelow="false">
<Preference
android:key="app_size"
@@ -56,32 +58,28 @@
android:selectable="false"
android:layout="@layout/horizontal_preference" />
- <com.android.settings.applications.LayoutPreference
- android:key="clear_data_button"
+ <Preference
+ android:key="cache_size"
+ android:title="@string/cache_size_label"
android:selectable="false"
- android:layout="@layout/single_button_panel" />
+ android:layout="@layout/horizontal_preference" />
+
+ <Preference
+ android:key="total_size"
+ android:title="@string/total_size_label"
+ android:selectable="false"
+ android:layout="@layout/horizontal_preference" />
+
+ <com.android.settings.applications.SpacePreference
+ android:layout_height="8dp" />
+
</PreferenceCategory>
- <com.android.settings.applications.SpacePreference
- android:layout_height="8dp" />
-
- <Preference
- android:key="cache_size"
- android:title="@string/cache_size_label"
- android:selectable="false"
- android:layout="@layout/horizontal_preference" />
-
- <com.android.settings.applications.LayoutPreference
- android:key="clear_cache_button"
- android:selectable="false"
- android:layout="@layout/single_button_panel" />
-
- <com.android.settings.applications.SpacePreference
- android:layout_height="8dp" />
-
<PreferenceCategory
android:key="uri_category"
- android:layout="@layout/headerless_preference_category" >
+ android:layout="@layout/headerless_preference_category"
+ settings:allowDividerAbove="false"
+ settings:allowDividerBelow="false">
<com.android.settings.applications.LayoutPreference
android:key="clear_uri_button"
android:layout="@layout/single_button_panel"
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index 626cd33..a6ffff4 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -18,6 +18,10 @@
android:title="@string/configure_notification_settings"
android:key="configure_notification_settings">
+ <PreferenceCategory
+ android:key="dashboard_tile_placeholder"
+ android:order="1"/>
+
<!-- Pulse notification light -->
<SwitchPreference
android:key="notification_pulse"
diff --git a/res/xml/legacy_channel_notification_settings.xml b/res/xml/legacy_channel_notification_settings.xml
new file mode 100644
index 0000000..4e341a9
--- /dev/null
+++ b/res/xml/legacy_channel_notification_settings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" >
+
+
+ <!-- Importance toggle -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="allow_sound"
+ android:title="@string/allow_sound" />
+
+ <!-- Visibility Override -->
+ <com.android.settings.notification.RestrictedDropDownPreference
+ android:key="visibility_override"
+ android:title="@string/app_notification_visibility_override_title" />
+
+ <!-- Bypass DND -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="bypass_dnd"
+ android:title="@string/app_notification_override_dnd_title"
+ android:summary="@string/app_notification_override_dnd_summary"
+ settings:useAdditionalSummary="true" />
+
+</PreferenceScreen>
diff --git a/res/xml/security_settings_encryption_interstitial.xml b/res/xml/security_settings_encryption_interstitial.xml
deleted file mode 100644
index 576cbf0..0000000
--- a/res/xml/security_settings_encryption_interstitial.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2016 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.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/lock_settings_picker_title"
- android:key="lock_settings_picker">
-
- <com.android.settings.MultiLinePreference
- android:icon="@drawable/ic_lock_list_icon"
- android:key="encrypt_require_password"
- android:persistent="false"/>
-
- <Preference
- android:icon="@drawable/ic_skip"
- android:key="encrypt_dont_require_password"
- android:persistent="false"/>
-
-</PreferenceScreen>
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
index 86e3b16..7946dd9 100644
--- a/res/xml/security_settings_misc.xml
+++ b/res/xml/security_settings_misc.xml
@@ -60,7 +60,7 @@
<Preference
android:key="encryption_and_credential"
android:title="@string/encryption_and_credential_settings_title"
- android:summary="@string/encryption_and_credential_settings_summary"/>
+ android:summary="@string/encryption_and_credential_settings_summary"
android:fragment="com.android.settings.EncryptionAndCredential"/>
<Preference android:key="manage_trust_agents"
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 3e9304d..546b11e 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -129,6 +129,7 @@
private boolean mHideDrawer = false;
private ManagedLockPasswordProvider mManagedPasswordProvider;
private boolean mIsSetNewPassword = false;
+ private UserManager mUserManager;
protected boolean mForFingerprint = false;
@@ -166,6 +167,7 @@
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT);
+ mUserManager = UserManager.get(getActivity());
if (savedInstanceState != null) {
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
@@ -751,11 +753,10 @@
if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
mFingerprintManager.setActiveUser(UserHandle.myUserId());
}
- final UserManager um = UserManager.get(getActivity());
boolean hasChildProfile = false;
- if (!um.getUserInfo(parentUserId).isManagedProfile()) {
+ if (!mUserManager.getUserInfo(parentUserId).isManagedProfile()) {
// Current user is primary profile, remove work profile fingerprints if necessary
- final List<UserInfo> profiles = um.getProfiles(parentUserId);
+ final List<UserInfo> profiles = mUserManager.getProfiles(parentUserId);
final int profilesSize = profiles.size();
for (int i = 0; i < profilesSize; i++) {
final UserInfo userInfo = profiles.get(i);
diff --git a/src/com/android/settings/EncryptionInterstitial.java b/src/com/android/settings/EncryptionInterstitial.java
index 4f24381..42ca516 100644
--- a/src/com/android/settings/EncryptionInterstitial.java
+++ b/src/com/android/settings/EncryptionInterstitial.java
@@ -23,21 +23,18 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.res.Resources;
import android.os.Bundle;
-import android.support.v7.preference.Preference;
-import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
+import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.utils.SettingsDividerItemDecoration;
-import com.android.setupwizardlib.GlifPreferenceLayout;
+import com.android.setupwizardlib.GlifLayout;
import java.util.List;
@@ -78,15 +75,12 @@
}
public static class EncryptionInterstitialFragment extends SettingsPreferenceFragment
- implements DialogInterface.OnClickListener {
+ implements View.OnClickListener, DialogInterface.OnClickListener {
private static final int ACCESSIBILITY_WARNING_DIALOG = 1;
- private static final String KEY_ENCRYPT_REQUIRE_PASSWORD = "encrypt_require_password";
- private static final String KEY_ENCRYPT_DONT_REQUIRE_PASSWORD =
- "encrypt_dont_require_password";
- private Preference mRequirePasswordToDecrypt;
- private Preference mDontRequirePasswordToDecrypt;
+ private View mRequirePasswordToDecrypt;
+ private View mDontRequirePasswordToDecrypt;
private boolean mPasswordRequired;
private Intent mUnlockMethodIntent;
private int mRequestedPasswordQuality;
@@ -97,81 +91,52 @@
}
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.encryption_interstitial, container, false);
+ }
- addPreferencesFromResource(R.xml.security_settings_encryption_interstitial);
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
- // Used for testing purposes
- findPreference(KEY_ENCRYPT_DONT_REQUIRE_PASSWORD)
- .setViewId(R.id.encrypt_dont_require_password);
-
- mRequirePasswordToDecrypt = findPreference(KEY_ENCRYPT_REQUIRE_PASSWORD);
- mDontRequirePasswordToDecrypt = findPreference(KEY_ENCRYPT_DONT_REQUIRE_PASSWORD);
+ mRequirePasswordToDecrypt = view.findViewById(R.id.encrypt_require_password);
+ mDontRequirePasswordToDecrypt = view.findViewById(R.id.encrypt_dont_require_password);
boolean forFingerprint = getActivity().getIntent().getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
Intent intent = getActivity().getIntent();
mRequestedPasswordQuality = intent.getIntExtra(EXTRA_PASSWORD_QUALITY, 0);
mUnlockMethodIntent = intent.getParcelableExtra(EXTRA_UNLOCK_METHOD_INTENT);
final int msgId;
- final int enableId;
- final int disableId;
switch (mRequestedPasswordQuality) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
msgId = forFingerprint ?
R.string.encryption_interstitial_message_pattern_for_fingerprint :
R.string.encryption_interstitial_message_pattern;
- enableId = R.string.encrypt_require_pattern;
- disableId = R.string.encrypt_dont_require_pattern;
break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
msgId = forFingerprint ?
R.string.encryption_interstitial_message_pin_for_fingerprint :
R.string.encryption_interstitial_message_pin;
- enableId = R.string.encrypt_require_pin;
- disableId = R.string.encrypt_dont_require_pin;
break;
default:
msgId = forFingerprint ?
R.string.encryption_interstitial_message_password_for_fingerprint :
R.string.encryption_interstitial_message_password;
- enableId = R.string.encrypt_require_password;
- disableId = R.string.encrypt_dont_require_password;
break;
}
- TextView message = (TextView) LayoutInflater.from(getActivity()).inflate(
- R.layout.encryption_interstitial_header, null, false);
+ TextView message = (TextView) getActivity().findViewById(R.id.encryption_message);
message.setText(msgId);
- setHeaderView(message);
- mRequirePasswordToDecrypt.setTitle(enableId);
-
- mDontRequirePasswordToDecrypt.setTitle(disableId);
+ mRequirePasswordToDecrypt.setOnClickListener(this);
+ mDontRequirePasswordToDecrypt.setOnClickListener(this);
setRequirePasswordState(getActivity().getIntent().getBooleanExtra(
EXTRA_REQUIRE_PASSWORD, true));
- }
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- GlifPreferenceLayout layout = (GlifPreferenceLayout) view;
- layout.setDividerItemDecoration(new SettingsDividerItemDecoration(getContext()));
-
- layout.setIcon(getContext().getDrawable(R.drawable.ic_lock));
+ GlifLayout layout = (GlifLayout) view;
layout.setHeaderText(getActivity().getTitle());
-
- // Use the dividers in SetupWizardRecyclerLayout. Suppress the dividers in
- // PreferenceFragment.
- setDivider(null);
- }
-
- @Override
- public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
- Bundle savedInstanceState) {
- GlifPreferenceLayout layout = (GlifPreferenceLayout) parent;
- return layout.onCreateRecyclerView(inflater, parent, savedInstanceState);
}
protected void startLockIntent() {
@@ -194,12 +159,8 @@
}
@Override
- public boolean onPreferenceTreeClick(Preference preference) {
- final String key = preference.getKey();
- if (key == null) {
- return super.onPreferenceTreeClick(preference);
- }
- if (key.equals(KEY_ENCRYPT_REQUIRE_PASSWORD)) {
+ public void onClick(View view) {
+ if (view == mRequirePasswordToDecrypt) {
final boolean accEn = AccessibilityManager.getInstance(getActivity()).isEnabled();
if (accEn && !mPasswordRequired) {
setRequirePasswordState(false); // clear the UI state
@@ -212,7 +173,6 @@
setRequirePasswordState(false);
startLockIntent();
}
- return true;
}
@Override
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 1e64b7f..bdf9644 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -1227,55 +1227,18 @@
@Override
public void setListening(boolean listening) {
- if (!listening) {
- return;
- }
- int packageVerifierState = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.PACKAGE_VERIFIER_STATE, 0);
- DashboardFeatureProvider dashboardFeatureProvider =
- FeatureFactory.getFactory(mContext).getDashboardFeatureProvider(mContext);
- if (packageVerifierState == PACKAGE_VERIFIER_STATE_ENABLED) {
- // Calling the feature provider could potentially be slow, so do this on a separate
- // thread so as to not block the loading of Settings.
- Executors.newSingleThreadExecutor().execute(new Runnable() {
- @Override
- public void run() {
- DashboardCategory dashboardCategory =
- dashboardFeatureProvider.getTilesForCategory(
- CategoryKey.CATEGORY_SECURITY);
- mSummaryLoader.setSummary(SummaryProvider.this,
- getPackageVerifierSummary(dashboardCategory));
- }
- });
- } else {
- final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(mContext);
+ if (listening) {
+ final FingerprintManager fpm =
+ Utils.getFingerprintManagerOrNull(mContext);
if (fpm != null && fpm.isHardwareDetected()) {
mSummaryLoader.setSummary(this,
- mContext.getString(R.string.security_dashboard_summary));
+ mContext.getString(R.string.security_dashboard_summary));
} else {
- mSummaryLoader.setSummary(this, null);
+ mSummaryLoader.setSummary(this, mContext.getString(
+ R.string.security_dashboard_summary_no_fingerprint));
}
}
}
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- String getPackageVerifierSummary(DashboardCategory dashboardCategory) {
- int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
- if (tilesCount == 0) {
- return null;
- }
- for (int i = 0; i < tilesCount; i++) {
- Tile tile = dashboardCategory.getTile(i);
- if (!KEY_PACKAGE_VERIFIER_STATUS.equals(tile.key)) {
- continue;
- }
- String summaryUri = tile.metaData.getString(
- TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, null);
- return TileUtils.getTextFromUri(mContext, summaryUri,
- new ArrayMap<>(), TileUtils.META_DATA_PREFERENCE_SUMMARY);
- }
- return null;
- }
}
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 70743e2..761e8cf 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -440,6 +440,7 @@
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
if (mHelpUri != null && getActivity() != null) {
HelpUtils.prepareHelpMenuItem(getActivity(), menu, mHelpUri, getClass().getName());
}
diff --git a/src/com/android/settings/SetupChooseLockGeneric.java b/src/com/android/settings/SetupChooseLockGeneric.java
index 61545a6..2c8195d 100644
--- a/src/com/android/settings/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/SetupChooseLockGeneric.java
@@ -17,10 +17,8 @@
package com.android.settings;
import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.UserHandle;
@@ -120,12 +118,6 @@
data.putExtra(EXTRA_PASSWORD_QUALITY,
lockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId()));
- PackageManager packageManager = getPackageManager();
- ComponentName componentName = new ComponentName("com.android.settings",
- "com.android.settings.SetupRedactionInterstitial");
- packageManager.setComponentEnabledSetting(componentName,
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
- PackageManager.DONT_KILL_APP);
super.onActivityResult(requestCode, resultCode, data);
}
// If the started activity was cancelled (e.g. the user presses back), then this
diff --git a/src/com/android/settings/SetupChooseLockPassword.java b/src/com/android/settings/SetupChooseLockPassword.java
index f0a9a26..f2c24d0 100644
--- a/src/com/android/settings/SetupChooseLockPassword.java
+++ b/src/com/android/settings/SetupChooseLockPassword.java
@@ -87,6 +87,9 @@
@Override
protected Intent getRedactionInterstitialIntent(Context context) {
+ // Setup wizard's redaction interstitial is deferred to optional step. Enable that
+ // optional step if the lock screen was set up.
+ SetupRedactionInterstitial.setEnabled(context, true);
return null;
}
}
diff --git a/src/com/android/settings/SetupChooseLockPattern.java b/src/com/android/settings/SetupChooseLockPattern.java
index 09b951e..30a3c7c 100644
--- a/src/com/android/settings/SetupChooseLockPattern.java
+++ b/src/com/android/settings/SetupChooseLockPattern.java
@@ -73,6 +73,9 @@
@Override
protected Intent getRedactionInterstitialIntent(Context context) {
+ // Setup wizard's redaction interstitial is deferred to optional step. Enable that
+ // optional step if the lock screen was set up.
+ SetupRedactionInterstitial.setEnabled(context, false);
return null;
}
}
diff --git a/src/com/android/settings/SetupEncryptionInterstitial.java b/src/com/android/settings/SetupEncryptionInterstitial.java
index 59e4d07..4f30cc0 100644
--- a/src/com/android/settings/SetupEncryptionInterstitial.java
+++ b/src/com/android/settings/SetupEncryptionInterstitial.java
@@ -20,15 +20,8 @@
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
import android.widget.LinearLayout;
-import com.android.settings.utils.SettingsDividerItemDecoration;
-import com.android.setupwizardlib.GlifPreferenceLayout;
-
/**
* Setup Wizard's version of EncryptionInterstitial screen. It inherits the logic and basic
* structure from EncryptionInterstitial class, and should remain similar to that behaviorally. This
@@ -75,29 +68,5 @@
}
public static class SetupEncryptionInterstitialFragment extends EncryptionInterstitialFragment {
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- final GlifPreferenceLayout layout = (GlifPreferenceLayout) view;
- layout.setDividerItemDecoration(new SettingsDividerItemDecoration(getContext()));
- layout.setDividerInset(getContext().getResources().getDimensionPixelSize(
- R.dimen.suw_items_glif_icon_divider_inset));
- layout.setIcon(getContext().getDrawable(R.drawable.ic_lock));
-
- layout.setHeaderText(R.string.encryption_interstitial_header);
-
- // Use the dividers in SetupWizardRecyclerLayout. Suppress the dividers in
- // PreferenceFragment.
- setDivider(null);
- }
-
- @Override
- public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
- Bundle savedInstanceState) {
- GlifPreferenceLayout layout = (GlifPreferenceLayout) parent;
- return layout.onCreateRecyclerView(inflater, parent, savedInstanceState);
- }
}
}
diff --git a/src/com/android/settings/SetupRedactionInterstitial.java b/src/com/android/settings/SetupRedactionInterstitial.java
index d527585..321040e 100644
--- a/src/com/android/settings/SetupRedactionInterstitial.java
+++ b/src/com/android/settings/SetupRedactionInterstitial.java
@@ -16,11 +16,11 @@
package com.android.settings;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.Button;
import com.android.settings.notification.RedactionInterstitial;
@@ -33,6 +33,20 @@
*/
public class SetupRedactionInterstitial extends RedactionInterstitial {
+ /**
+ * Set the enabled state of SetupRedactionInterstitial activity to configure whether it is shown
+ * as part of setup wizard's optional steps.
+ */
+ public static void setEnabled(Context context, boolean enabled) {
+ PackageManager packageManager = context.getPackageManager();
+ ComponentName componentName = new ComponentName(context, SetupRedactionInterstitial.class);
+ packageManager.setComponentEnabledSetting(
+ componentName,
+ enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ }
+
@Override
public Intent getIntent() {
Intent modIntent = new Intent(super.getIntent());
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index ac618d0..44dd353 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -389,6 +389,7 @@
// Display magnification.
mDisplayMagnificationPreferenceScreen = findPreference(
DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
+ configureMagnificationPreferenceIfNeeded(mDisplayMagnificationPreferenceScreen);
// Font size.
mFontSizePreferenceScreen = findPreference(FONT_SIZE_PREFERENCE_SCREEN);
@@ -549,6 +550,22 @@
}
private void updateSystemPreferences() {
+ // Move color inversion and color correction preferences to Display category if device
+ // supports HWC hardware-accelerated color transform.
+ if (isColorTransformAccelerated(getContext())) {
+ PreferenceCategory experimentalCategory =
+ mCategoryToPrefCategoryMap.get(CATEGORY_EXPERIMENTAL);
+ PreferenceCategory displayCategory =
+ mCategoryToPrefCategoryMap.get(CATEGORY_DISPLAY);
+ experimentalCategory.removePreference(mToggleInversionPreference);
+ experimentalCategory.removePreference(mDisplayDaltonizerPreferenceScreen);
+ mToggleInversionPreference.setOrder(mToggleLargePointerIconPreference.getOrder());
+ mDisplayDaltonizerPreferenceScreen.setOrder(mToggleInversionPreference.getOrder());
+ mToggleInversionPreference.setSummary(R.string.summary_empty);
+ displayCategory.addPreference(mToggleInversionPreference);
+ displayCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
+ }
+
// Text contrast.
mToggleHighTextContrastPreference.setChecked(
Settings.Secure.getInt(getContentResolver(),
@@ -600,6 +617,11 @@
updateAccessibilityShortcut(mAccessibilityShortcutPreferenceScreen);
}
+ private boolean isColorTransformAccelerated(Context context) {
+ return context.getResources()
+ .getBoolean(com.android.internal.R.bool.config_setColorTransformAccelerated);
+ }
+
private void updateMagnificationSummary(Preference pref) {
final boolean tripleTapEnabled = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1;
@@ -682,6 +704,19 @@
}
}
+ private static void configureMagnificationPreferenceIfNeeded(Preference preference) {
+ // Some devices support only a single magnification mode. In these cases, we redirect to
+ // the magnification mode's UI directly, rather than showing a PreferenceScreen with a
+ // single list item.
+ final Context context = preference.getContext();
+ if (!MagnificationPreferenceFragment.isApplicable(context.getResources())) {
+ preference.setFragment(ToggleScreenMagnificationPreferenceFragment.class.getName());
+ final Bundle extras = preference.getExtras();
+ MagnificationPreferenceFragment.populateMagnificationGesturesPreferenceExtras(extras,
+ context);
+ }
+ }
+
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
diff --git a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
index 8c76fb7..55b79ba 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
@@ -18,9 +18,9 @@
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
+import android.content.Context;
import android.content.pm.ServiceInfo;
import android.os.Bundle;
-import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityManager;
@@ -79,6 +79,7 @@
findService(SCREEN_READER_PACKAGE_NAME, SCREEN_READER_SERVICE_NAME));
updateAccessibilityServicePreference(mSelectToSpeakPreference,
findService(SELECT_TO_SPEAK_PACKAGE_NAME, SELECT_TO_SPEAK_SERVICE_NAME));
+ configureMagnificationPreferenceIfNeeded(mDisplayMagnificationPreference);
}
@Override
@@ -145,4 +146,18 @@
}
extras.putString(AccessibilitySettings.EXTRA_SUMMARY, description);
}
+
+ private static void configureMagnificationPreferenceIfNeeded(Preference preference) {
+ // Some devices support only a single magnification mode. In these cases, we redirect to
+ // the magnification mode's UI directly, rather than showing a PreferenceScreen with a
+ // single list item.
+ final Context context = preference.getContext();
+ if (!MagnificationPreferenceFragment.isApplicable(context.getResources())) {
+ preference.setFragment(
+ ToggleScreenMagnificationPreferenceFragmentForSetupWizard.class.getName());
+ final Bundle extras = preference.getExtras();
+ MagnificationPreferenceFragment.populateMagnificationGesturesPreferenceExtras(extras,
+ context);
+ }
+ }
}
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index 6ed06da..24320b3 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -42,12 +42,9 @@
public static final String SHORTCUT_SERVICE_KEY = "accessibility_shortcut_service";
public static final String ON_LOCK_SCREEN_KEY = "accessibility_shortcut_on_lock_screen";
- // ID for dialog that confirms shortcut capabilities
- private static final int DIALOG_ID_ADD_SHORTCUT_WARNING = 1;
private Preference mServicePreference;
private SwitchPreference mOnLockScreenSwitchPreference;
- private String mSelectedServiceComponentNameString;
@Override
public int getMetricsCategory() {
diff --git a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
index 22706d7..83299e8 100644
--- a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
@@ -19,6 +19,7 @@
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.content.res.Resources;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
@@ -34,6 +35,7 @@
import com.android.settings.search.Indexable;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
public final class MagnificationPreferenceFragment extends SettingsPreferenceFragment implements
@@ -123,18 +125,7 @@
private void handleMagnificationGesturesPreferenceScreenClick() {
Bundle extras = mMagnificationGesturesPreference.getExtras();
- extras.putString(AccessibilitySettings.EXTRA_PREFERENCE_KEY,
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
- extras.putString(AccessibilitySettings.EXTRA_TITLE, getString(
- R.string.accessibility_screen_magnification_gestures_title));
- extras.putCharSequence(AccessibilitySettings.EXTRA_SUMMARY,
- getActivity().getResources().getText(
- R.string.accessibility_screen_magnification_summary));
- extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED,
- Settings.Secure.getInt(getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1);
- extras.putInt(AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID,
- R.raw.accessibility_screen_magnification);
+ populateMagnificationGesturesPreferenceExtras(extras, getContext());
extras.putBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW, mLaunchedFromSuw);
}
@@ -188,14 +179,40 @@
return null;
}
+ static void populateMagnificationGesturesPreferenceExtras(Bundle extras, Context context) {
+ extras.putString(AccessibilitySettings.EXTRA_PREFERENCE_KEY,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
+ extras.putString(AccessibilitySettings.EXTRA_TITLE, context.getString(
+ R.string.accessibility_screen_magnification_gestures_title));
+ extras.putCharSequence(AccessibilitySettings.EXTRA_SUMMARY, context.getResources().getText(
+ R.string.accessibility_screen_magnification_summary));
+ extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED,
+ Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1);
+ extras.putInt(AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID,
+ R.raw.accessibility_screen_magnification);
+ }
+
+ /**
+ * @return {@code true} if this fragment should be shown, {@code false} otherwise. This
+ * fragment is shown in the case that more than one magnification mode is available.
+ */
+ static boolean isApplicable(Resources res) {
+ return res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
+ }
+
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
- final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.accessibility_magnification_settings;
- return Arrays.asList(sir);
+ if (isApplicable(context.getResources())) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.accessibility_magnification_settings;
+ return Arrays.asList(sir);
+ } else {
+ return Collections.emptyList();
+ }
}
};
}
diff --git a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
index 8b6d52a..3250521 100644
--- a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
+++ b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
@@ -15,6 +15,8 @@
*/
package com.android.settings.accessibility;
+import static android.content.DialogInterface.BUTTON_POSITIVE;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.AlertDialog;
@@ -147,7 +149,7 @@
@Override
public void onClick(DialogInterface dialog, int which) {
final Fragment fragment = getTargetFragment();
- if (fragment instanceof DefaultAppPickerFragment) {
+ if ((which == BUTTON_POSITIVE) && (fragment instanceof DefaultAppPickerFragment)) {
final Bundle bundle = getArguments();
((ShortcutServicePickerFragment) fragment).onServiceConfirmed(
bundle.getString(EXTRA_KEY));
diff --git a/src/com/android/settings/accounts/AutoSyncDataPreferenceController.java b/src/com/android/settings/accounts/AutoSyncDataPreferenceController.java
index 79776a0..f5d7b64 100644
--- a/src/com/android/settings/accounts/AutoSyncDataPreferenceController.java
+++ b/src/com/android/settings/accounts/AutoSyncDataPreferenceController.java
@@ -28,8 +28,8 @@
import android.os.UserManager;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
-
import android.util.Log;
+
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.PreferenceController;
@@ -41,9 +41,10 @@
private static final String TAG_CONFIRM_AUTO_SYNC_CHANGE = "confirmAutoSyncChange";
private static final String KEY_AUTO_SYNC_ACCOUNT = "auto_sync_account_data";
- protected UserManager mUserManager;
- private UserHandle mUserHandle;
- private Fragment mParentFragment;
+ protected final UserManager mUserManager;
+ private final Fragment mParentFragment;
+
+ protected UserHandle mUserHandle;
public AutoSyncDataPreferenceController(Context context, Fragment parent) {
super(context);
diff --git a/src/com/android/settings/accounts/AutoSyncWorkDataPreferenceController.java b/src/com/android/settings/accounts/AutoSyncWorkDataPreferenceController.java
index 899f77d..1d08968 100644
--- a/src/com/android/settings/accounts/AutoSyncWorkDataPreferenceController.java
+++ b/src/com/android/settings/accounts/AutoSyncWorkDataPreferenceController.java
@@ -18,6 +18,8 @@
import android.app.Fragment;
import android.content.Context;
+import com.android.settings.Utils;
+
public class AutoSyncWorkDataPreferenceController extends AutoSyncPersonalDataPreferenceController {
private static final String TAG = "AutoSyncWorkData";
@@ -25,11 +27,11 @@
public AutoSyncWorkDataPreferenceController(Context context, Fragment parent) {
super(context, parent);
+ mUserHandle = Utils.getManagedProfile(mUserManager);
}
@Override
public String getPreferenceKey() {
return KEY_AUTO_SYNC_WORK_ACCOUNT;
}
-
}
diff --git a/src/com/android/settings/applications/AppHeaderController.java b/src/com/android/settings/applications/AppHeaderController.java
index f3a086b..45938ae 100644
--- a/src/com/android/settings/applications/AppHeaderController.java
+++ b/src/com/android/settings/applications/AppHeaderController.java
@@ -18,25 +18,26 @@
import android.annotation.IdRes;
import android.annotation.UserIdInt;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.graphics.Outline;
-import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.support.annotation.IntDef;
+import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewOutlineProvider;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
+
import com.android.settings.AppHeader;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -63,13 +64,13 @@
}
public static final String PREF_KEY_APP_HEADER = "pref_app_header";
+
private static final String TAG = "AppDetailFeature";
private final Context mContext;
private final Fragment mFragment;
private final int mMetricsCategory;
private final View mAppHeader;
- private final int mIconElevation;
private Drawable mIcon;
private CharSequence mLabel;
@@ -96,8 +97,6 @@
mAppHeader = LayoutInflater.from(fragment.getContext())
.inflate(R.layout.app_details, null /* root */);
}
- mIconElevation = mContext.getResources()
- .getDimensionPixelSize(R.dimen.launcher_icon_elevation);
}
public AppHeaderController setIcon(Drawable icon) {
@@ -164,39 +163,10 @@
}
/**
- * Binds app header view and data from {@code PackageInfo} and {@code AppEntry}.
- */
- public void bindAppHeader(PackageInfo packageInfo, ApplicationsState.AppEntry appEntry) {
- final String versionName = packageInfo == null ? null : packageInfo.versionName;
- final Resources res = mAppHeader.getResources();
-
- // Set Icon
- final ImageView iconView = (ImageView) mAppHeader.findViewById(R.id.app_detail_icon);
- if (appEntry.icon != null) {
- iconView.setImageDrawable(appEntry.icon.getConstantState().newDrawable(res));
- }
-
- // Set application name.
- final TextView labelView = (TextView) mAppHeader.findViewById(R.id.app_detail_title);
- labelView.setText(appEntry.label);
-
- // Version number of application
- final TextView appVersion = (TextView) mAppHeader.findViewById(R.id.app_detail_summary);
-
- if (!TextUtils.isEmpty(versionName)) {
- appVersion.setSelected(true);
- appVersion.setVisibility(View.VISIBLE);
- appVersion.setText(res.getString(R.string.version_text, String.valueOf(versionName)));
- } else {
- appVersion.setVisibility(View.INVISIBLE);
- }
- }
-
- /**
* Done mutating appheader, rebinds everything and return a new {@link LayoutPreference}.
*/
- public LayoutPreference done(Context context) {
- final LayoutPreference pref = new LayoutPreference(context, done());
+ public LayoutPreference done(Activity activity, Context uiContext) {
+ final LayoutPreference pref = new LayoutPreference(uiContext, done(activity));
// Makes sure it's the first preference onscreen.
pref.setOrder(-1000);
pref.setKey(PREF_KEY_APP_HEADER);
@@ -204,23 +174,13 @@
}
/**
- * Done mutating appheader, rebinds everything.
- */
- public View done() {
- return done(true);
- }
-
- /**
* Done mutating appheader, rebinds everything (optionally skip rebinding buttons).
*/
- public View done(boolean rebindActions) {
- ImageView iconView = (ImageView) mAppHeader.findViewById(R.id.app_detail_icon);
+ public View done(Activity activity, boolean rebindActions) {
+ styleActionBar(activity);
+ ImageView iconView = mAppHeader.findViewById(R.id.app_detail_icon);
if (iconView != null) {
iconView.setImageDrawable(mIcon);
- ImageView badgeView = mAppHeader.findViewById(R.id.app_icon_instant_apps_badge);
- if (badgeView != null) {
- badgeView.setVisibility(mIsInstantApp ? View.VISIBLE : View.GONE);
- }
}
setText(R.id.app_detail_title, mLabel);
setText(R.id.app_detail_summary, mSummary);
@@ -239,12 +199,38 @@
/**
* Only binds app header with button actions.
*/
- public void bindAppHeaderButtons() {
- ImageButton leftButton = (ImageButton) mAppHeader.findViewById(R.id.left_button);
- ImageButton rightButton = (ImageButton) mAppHeader.findViewById(R.id.right_button);
+ public AppHeaderController bindAppHeaderButtons() {
+ ImageButton leftButton = mAppHeader.findViewById(R.id.left_button);
+ ImageButton rightButton = mAppHeader.findViewById(R.id.right_button);
bindButton(leftButton, mLeftAction);
bindButton(rightButton, mRightAction);
+ return this;
+ }
+
+ public AppHeaderController styleActionBar(Activity activity) {
+ if (activity == null) {
+ Log.w(TAG, "No activity, cannot style actionbar.");
+ return this;
+ }
+ final ActionBar actionBar = activity.getActionBar();
+ if (actionBar == null) {
+ Log.w(TAG, "No actionbar, cannot style actionbar.");
+ return this;
+ }
+ actionBar.setBackgroundDrawable(
+ new ColorDrawable(Utils.getColorAttr(activity, android.R.attr.colorSecondary)));
+ actionBar.setElevation(0);
+
+ return this;
+ }
+
+ /**
+ * Done mutating appheader, rebinds everything.
+ */
+ @VisibleForTesting
+ View done(Activity activity) {
+ return done(activity, true /* rebindActions */);
}
private void bindButton(ImageButton button, @ActionType int action) {
@@ -328,7 +314,7 @@
}
private void setText(@IdRes int id, CharSequence text) {
- TextView textView = (TextView) mAppHeader.findViewById(id);
+ TextView textView = mAppHeader.findViewById(id);
if (textView != null) {
textView.setText(text);
textView.setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE);
diff --git a/src/com/android/settings/applications/AppInfoWithHeader.java b/src/com/android/settings/applications/AppInfoWithHeader.java
index 768a726..6b1ef67 100644
--- a/src/com/android/settings/applications/AppInfoWithHeader.java
+++ b/src/com/android/settings/applications/AppInfoWithHeader.java
@@ -16,16 +16,17 @@
package com.android.settings.applications;
+import static com.android.settings.applications.AppHeaderController.ActionType;
+
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.preference.Preference;
+import android.util.IconDrawableFactory;
import android.util.Log;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.AppUtils;
-import static com.android.settings.applications.AppHeaderController.ActionType;
-
public abstract class AppInfoWithHeader extends AppInfoBase {
private boolean mCreated;
@@ -41,16 +42,17 @@
if (mPackageInfo == null) return;
final Activity activity = getActivity();
final Preference pref = FeatureFactory.getFactory(activity)
- .getApplicationFeatureProvider(activity)
- .newAppHeaderController(this, null /* appHeader */)
- .setIcon(mPackageInfo.applicationInfo.loadIcon(mPm))
- .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
- .setSummary(mPackageInfo)
- .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
- .setPackageName(mPackageName)
- .setUid(mPackageInfo.applicationInfo.uid)
- .setButtonActions(ActionType.ACTION_APP_INFO, ActionType.ACTION_NONE)
- .done(getPrefContext());
+ .getApplicationFeatureProvider(activity)
+ .newAppHeaderController(this, null /* appHeader */)
+ .setIcon(IconDrawableFactory.newInstance(activity)
+ .getBadgedIcon(mPackageInfo.applicationInfo))
+ .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
+ .setSummary(mPackageInfo)
+ .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
+ .setPackageName(mPackageName)
+ .setUid(mPackageInfo.applicationInfo.uid)
+ .setButtonActions(ActionType.ACTION_APP_INFO, ActionType.ACTION_NONE)
+ .done(activity, getPrefContext());
getPreferenceScreen().addPreference(pref);
}
}
diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java
index 8d41558..0676f56 100644
--- a/src/com/android/settings/applications/AppStorageSettings.java
+++ b/src/com/android/settings/applications/AppStorageSettings.java
@@ -90,13 +90,10 @@
private static final String KEY_TOTAL_SIZE = "total_size";
private static final String KEY_APP_SIZE = "app_size";
- private static final String KEY_EXTERNAL_CODE_SIZE = "external_code_size";
private static final String KEY_DATA_SIZE = "data_size";
- private static final String KEY_EXTERNAL_DATA_SIZE = "external_data_size";
private static final String KEY_CACHE_SIZE = "cache_size";
- private static final String KEY_CLEAR_DATA = "clear_data_button";
- private static final String KEY_CLEAR_CACHE = "clear_cache_button";
+ private static final String KEY_HEADER_BUTTONS = "header_view";
private static final String KEY_URI_CATEGORY = "uri_category";
private static final String KEY_CLEAR_URI = "clear_uri_button";
@@ -119,16 +116,11 @@
private boolean mCanClearData = true;
private boolean mCacheCleared;
- private AppStorageStats mLastResult;
private AppStorageSizesController mSizeController;
private ClearCacheObserver mClearCacheObserver;
private ClearUserDataObserver mClearDataObserver;
- // Resource strings
- private CharSequence mInvalidSizeStr;
- private CharSequence mComputingStr;
-
private VolumeInfo[] mCandidates;
private AlertDialog.Builder mDialogBuilder;
private ApplicationInfo mInfo;
@@ -158,9 +150,6 @@
}
private void setupViews() {
- mComputingStr = getActivity().getText(R.string.computing_size);
- mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
-
// Set default values on sizes
mSizeController = new AppStorageSizesController.Builder()
.setTotalSizePreference(findPreference(KEY_TOTAL_SIZE))
@@ -171,8 +160,8 @@
.setErrorString(R.string.invalid_size_value)
.build();
- mClearDataButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_DATA))
- .findViewById(R.id.button);
+ mClearDataButton = (Button) ((LayoutPreference) findPreference(KEY_HEADER_BUTTONS))
+ .findViewById(R.id.left_button);
mStorageUsed = findPreference(KEY_STORAGE_USED);
mChangeStorageButton = (Button) ((LayoutPreference) findPreference(KEY_CHANGE_STORAGE))
@@ -182,8 +171,8 @@
// Cache section
mCacheSize = findPreference(KEY_CACHE_SIZE);
- mClearCacheButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_CACHE))
- .findViewById(R.id.button);
+ mClearCacheButton = (Button) ((LayoutPreference) findPreference(KEY_HEADER_BUTTONS))
+ .findViewById(R.id.right_button);
mClearCacheButton.setText(R.string.clear_cache_btn_text);
// URI permissions section
@@ -267,7 +256,7 @@
if (mAppEntry == null) {
return false;
}
- updateUiWithSize(mLastResult);
+ updateUiWithSize(mSizeController.getLastResult());
refreshGrantedUriPermissions();
final VolumeInfo currentVol = getActivity().getPackageManager()
diff --git a/src/com/android/settings/applications/AppStorageSizesController.java b/src/com/android/settings/applications/AppStorageSizesController.java
index 94935bd..23a3eb2 100644
--- a/src/com/android/settings/applications/AppStorageSizesController.java
+++ b/src/com/android/settings/applications/AppStorageSizesController.java
@@ -110,6 +110,13 @@
mCachedCleared = isCleared;
}
+ /**
+ * Returns the last result calculated, if it exists. If it does not, returns null.
+ */
+ public StorageStatsSource.AppStorageStats getLastResult() {
+ return mLastResult;
+ }
+
private String getSizeStr(Context context, long size) {
return Formatter.formatFileSize(context, size);
}
diff --git a/src/com/android/settings/applications/FetchPackageStorageAsyncLoader.java b/src/com/android/settings/applications/FetchPackageStorageAsyncLoader.java
index 97e5b7b..b39ec3b 100644
--- a/src/com/android/settings/applications/FetchPackageStorageAsyncLoader.java
+++ b/src/com/android/settings/applications/FetchPackageStorageAsyncLoader.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.os.UserHandle;
import android.util.Log;
@@ -27,6 +28,8 @@
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
+import java.io.IOException;
+
/**
* Fetches the storage stats using the StorageStatsManager for a given package and user tuple.
*/
@@ -49,7 +52,7 @@
AppStorageStats result = null;
try {
result = mSource.getStatsForPackage(mInfo.volumeUuid, mInfo.packageName, mUser);
- } catch (IllegalStateException e) {
+ } catch (NameNotFoundException | IOException e) {
Log.w(TAG, "Package may have been removed during query, failing gracefully", e);
}
return result;
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 7510146..09771f2 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -16,8 +16,9 @@
package com.android.settings.applications;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
import android.Manifest.permission;
-import android.annotation.IdRes;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
@@ -115,8 +116,6 @@
import java.util.List;
import java.util.Set;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
/**
* Activity to display application information from Settings. This activity presents
* extended information associated with a package like code, data, total size, permissions
@@ -413,12 +412,13 @@
mHeader = (LayoutPreference) findPreference(KEY_HEADER);
mActionButtons = (LayoutPreference) findPreference(KEY_ACTION_BUTTONS);
FeatureFactory.getFactory(activity)
- .getApplicationFeatureProvider(activity)
- .newAppHeaderController(this, mHeader.findViewById(R.id.app_snippet))
- .setPackageName(mPackageName)
- .setButtonActions(AppHeaderController.ActionType.ACTION_STORE_DEEP_LINK,
- AppHeaderController.ActionType.ACTION_APP_PREFERENCE)
- .bindAppHeaderButtons();
+ .getApplicationFeatureProvider(activity)
+ .newAppHeaderController(this, mHeader.findViewById(R.id.app_snippet))
+ .setPackageName(mPackageName)
+ .setButtonActions(AppHeaderController.ActionType.ACTION_STORE_DEEP_LINK,
+ AppHeaderController.ActionType.ACTION_APP_PREFERENCE)
+ .styleActionBar(activity)
+ .bindAppHeaderButtons();
prepareUninstallAndStop();
mNotificationPreference = findPreference(KEY_NOTIFICATION);
@@ -590,7 +590,7 @@
.setIcon(mAppEntry)
.setSummary(summary)
.setIsInstantApp(isInstantApp)
- .done(false /* rebindActions */);
+ .done(activity, false /* rebindActions */);
mVersionPreference.setSummary(getString(R.string.version_text, pkgInfo.versionName));
}
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 3cc40151..f24c3f7 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -23,7 +23,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
-import android.graphics.drawable.AdaptiveIconDrawable;
import android.icu.text.AlphabeticIndex;
import android.os.Bundle;
import android.os.Environment;
@@ -35,7 +34,6 @@
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.ArraySet;
-import android.util.LauncherIcons;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -55,8 +53,8 @@
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.Spinner;
-
import android.widget.TextView;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Settings.AllApplicationsActivity;
@@ -826,7 +824,6 @@
private final AppStateBaseBridge mExtraInfoBridge;
private final Handler mBgHandler;
private final Handler mFgHandler;
- private final LauncherIcons mLauncherIcons;
private int mFilterMode;
private ArrayList<ApplicationsState.AppEntry> mBaseEntries;
@@ -882,7 +879,6 @@
mContext = manageApplications.getActivity();
mPm = mContext.getPackageManager();
mFilterMode = filterMode;
- mLauncherIcons = new LauncherIcons(mContext);
if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
mExtraInfoBridge = new AppStateNotificationBridge(mContext, mState, this,
manageApplications.mNotifBackend);
@@ -1317,9 +1313,6 @@
}
mState.ensureIcon(entry);
if (entry.icon != null) {
- if (entry.icon instanceof AdaptiveIconDrawable) {
- entry.icon = mLauncherIcons.wrapIconDrawableWithShadow(entry.icon);
- }
holder.appIcon.setImageDrawable(entry.icon);
}
updateSummary(holder);
diff --git a/src/com/android/settings/applications/MusicViewHolderController.java b/src/com/android/settings/applications/MusicViewHolderController.java
index 4599fcc..1bca26a 100644
--- a/src/com/android/settings/applications/MusicViewHolderController.java
+++ b/src/com/android/settings/applications/MusicViewHolderController.java
@@ -23,15 +23,20 @@
import android.provider.DocumentsContract;
import android.support.annotation.WorkerThread;
import android.text.format.Formatter;
+import android.util.Log;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settingslib.applications.StorageStatsSource;
+import java.io.IOException;
+
/**
* MusicViewHolderController controls an Audio/Music file view in the ManageApplications view.
*/
public class MusicViewHolderController implements FileViewHolderController {
+ private static final String TAG = "MusicViewHolderController";
+
private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
private Context mContext;
@@ -51,7 +56,12 @@
@Override
@WorkerThread
public void queryStats() {
- mMusicSize = mSource.getExternalStorageStats(mVolumeUuid, mUser).audioBytes;
+ try {
+ mMusicSize = mSource.getExternalStorageStats(mVolumeUuid, mUser).audioBytes;
+ } catch (IOException e) {
+ mMusicSize = 0;
+ Log.w(TAG, e);
+ }
}
@Override
@@ -61,7 +71,7 @@
@Override
public void setupView(AppViewHolder holder) {
- holder.appIcon.setImageDrawable(mContext.getDrawable(R.drawable.empty_icon));
+ holder.appIcon.setImageDrawable(mContext.getDrawable(R.drawable.ic_media_stream_on_24dp));
holder.appName.setText(mContext.getText(R.string.audio_files_title));
holder.summary.setText(Formatter.formatFileSize(mContext, mMusicSize));
}
diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java
index 9b6f41e..6c0928c 100644
--- a/src/com/android/settings/applications/ProcessStatsDetail.java
+++ b/src/com/android/settings/applications/ProcessStatsDetail.java
@@ -16,6 +16,8 @@
package com.android.settings.applications;
+import static com.android.settings.applications.AppHeaderController.ActionType;
+
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
@@ -37,6 +39,7 @@
import android.support.v7.preference.PreferenceCategory;
import android.text.format.Formatter;
import android.util.ArrayMap;
+import android.util.IconDrawableFactory;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@@ -58,8 +61,6 @@
import java.util.HashMap;
import java.util.List;
-import static com.android.settings.applications.AppHeaderController.ActionType;
-
public class ProcessStatsDetail extends SettingsPreferenceFragment {
private static final String TAG = "ProcessStatsDetail";
@@ -129,7 +130,7 @@
.getApplicationFeatureProvider(activity)
.newAppHeaderController(this, null /* appHeader */)
.setIcon(mApp.mUiTargetApp != null
- ? mApp.mUiTargetApp.loadIcon(mPm)
+ ? IconDrawableFactory.newInstance(activity).getBadgedIcon(mApp.mUiTargetApp)
: new ColorDrawable(0))
.setLabel(mApp.mUiLabel)
.setPackageName(mApp.mPackage)
@@ -137,7 +138,7 @@
? mApp.mUiTargetApp.uid
: UserHandle.USER_NULL)
.setButtonActions(ActionType.ACTION_APP_INFO, ActionType.ACTION_NONE)
- .done(getPrefContext());
+ .done(activity, getPrefContext());
getPreferenceScreen().addPreference(pref);
}
diff --git a/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java b/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java
index 747ce4d..b8d6a87 100644
--- a/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java
+++ b/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java
@@ -24,6 +24,7 @@
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionServiceInfo;
+import android.support.annotation.VisibleForTesting;
import com.android.internal.app.AssistUtils;
import com.android.settings.applications.defaultapps.DefaultAppInfo;
import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
@@ -56,13 +57,10 @@
if (services == null || services.isEmpty()) {
return null;
}
- final ResolveInfo resolveInfo = services.get(0);
- final VoiceInteractionServiceInfo voiceInfo =
- new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
- if (!voiceInfo.getSupportsAssist()) {
+ final String activity = getAssistSettingsActivity(cn, services.get(0), pm);
+ if (activity == null) {
return null;
}
- final String activity = voiceInfo.getSettingsActivity();
return new Intent(Intent.ACTION_MAIN)
.setComponent(new ComponentName(cn.getPackageName(), activity));
}
@@ -85,4 +83,14 @@
}
return new DefaultAppInfo(mPackageManager, mUserId, cn);
}
+
+ @VisibleForTesting
+ String getAssistSettingsActivity(ComponentName cn, ResolveInfo resolveInfo, PackageManager pm) {
+ final VoiceInteractionServiceInfo voiceInfo =
+ new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
+ if (!voiceInfo.getSupportsAssist()) {
+ return null;
+ }
+ return voiceInfo.getSettingsActivity();
+ }
}
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index 22b21e4..6c41f83 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -21,13 +21,16 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.UserManager;
import android.provider.Settings;
import android.widget.Switch;
import android.widget.Toast;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.widget.SwitchWidgetController;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.WirelessUtils;
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -45,6 +48,7 @@
private boolean mValidListener;
private final LocalBluetoothAdapter mLocalAdapter;
private final IntentFilter mIntentFilter;
+ private final RestrictionUtils mRestrictionUtils;
private static final String EVENT_DATA_IS_BT_ON = "is_bluetooth_on";
private static final int EVENT_UPDATE_INDEX = 0;
@@ -63,6 +67,13 @@
public BluetoothEnabler(Context context, SwitchWidgetController switchWidget,
MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager,
int metricsEvent) {
+ this(context, switchWidget, metricsFeatureProvider, manager, metricsEvent,
+ new RestrictionUtils());
+ }
+
+ public BluetoothEnabler(Context context, SwitchWidgetController switchWidget,
+ MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager,
+ int metricsEvent, RestrictionUtils restrictionUtils) {
mContext = context;
mMetricsFeatureProvider = metricsFeatureProvider;
mSwitchWidget = switchWidget;
@@ -79,6 +90,7 @@
mLocalAdapter = manager.getBluetoothAdapter();
}
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
+ mRestrictionUtils = restrictionUtils;
}
public void setupSwitchController() {
@@ -90,15 +102,17 @@
}
public void resume(Context context) {
+ if (mContext != context) {
+ mContext = context;
+ }
+
+ maybeEnforceRestrictions();
+
if (mLocalAdapter == null) {
mSwitchWidget.setEnabled(false);
return;
}
- if (mContext != context) {
- mContext = context;
- }
-
// Bluetooth state is not sticky, so set it manually
handleStateChanged(mLocalAdapter.getBluetoothState());
@@ -156,6 +170,10 @@
@Override
public boolean onSwitchToggled(boolean isChecked) {
+ if (maybeEnforceRestrictions()) {
+ return true;
+ }
+
// Show toast message if Bluetooth is not allowed in airplane mode
if (isChecked &&
!WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
@@ -182,4 +200,29 @@
mSwitchWidget.setEnabled(false);
return true;
}
+
+ /**
+ * Enforces user restrictions disallowing Bluetooth (or its configuration) if there are any.
+ *
+ * @return if there was any user restriction to enforce.
+ */
+ @VisibleForTesting
+ boolean maybeEnforceRestrictions() {
+ EnforcedAdmin admin = mRestrictionUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_BLUETOOTH);
+ if (admin == null) {
+ admin = mRestrictionUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_CONFIG_BLUETOOTH);
+ }
+ mSwitchWidget.setDisabledByAdmin(admin);
+ if (admin != null) {
+ mSwitchWidget.setChecked(false);
+ if (mSwitch != null) {
+ mSwitch.setEnabled(false);
+ mSwitch.setChecked(false);
+ }
+ }
+ return admin != null;
+ }
+
}
diff --git a/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java
index f98a209..c071570 100644
--- a/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.support.v7.preference.PreferenceScreen;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.core.PreferenceController;
import com.android.settings.core.lifecycle.LifecycleObserver;
@@ -26,9 +27,9 @@
import com.android.settings.core.lifecycle.events.OnStart;
import com.android.settings.core.lifecycle.events.OnStop;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
-import com.android.settings.widget.MasterSwitchPreference;
import com.android.settings.widget.MasterSwitchController;
+import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
public class BluetoothMasterSwitchPreferenceController extends PreferenceController
@@ -41,12 +42,20 @@
private MasterSwitchPreference mBtPreference;
private BluetoothEnabler mBluetoothEnabler;
private BluetoothSummaryUpdater mSummaryUpdater;
+ private RestrictionUtils mRestrictionUtils;
public BluetoothMasterSwitchPreferenceController(Context context,
LocalBluetoothManager bluetoothManager) {
+ this(context, bluetoothManager, new RestrictionUtils());
+ }
+
+ @VisibleForTesting
+ public BluetoothMasterSwitchPreferenceController(Context context,
+ LocalBluetoothManager bluetoothManager, RestrictionUtils restrictionUtils) {
super(context);
mBluetoothManager = bluetoothManager;
mSummaryUpdater = new BluetoothSummaryUpdater(mContext, this, mBluetoothManager);
+ mRestrictionUtils = restrictionUtils;
}
@Override
@@ -56,7 +65,8 @@
mBluetoothEnabler = new BluetoothEnabler(mContext,
new MasterSwitchController(mBtPreference),
FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(), mBluetoothManager,
- MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE);
+ MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE,
+ mRestrictionUtils);
}
@Override
diff --git a/src/com/android/settings/bluetooth/RestrictionUtils.java b/src/com/android/settings/bluetooth/RestrictionUtils.java
new file mode 100644
index 0000000..9c0c481
--- /dev/null
+++ b/src/com/android/settings/bluetooth/RestrictionUtils.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 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.bluetooth;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+/**
+ * A utility class to aid testing.
+ */
+public class RestrictionUtils {
+
+ public RestrictionUtils() {}
+
+ /**
+ * Utility method to check if user restriction is enforced on the current user.
+ *
+ * <p> It helps with testing - override it to avoid calling static method which calls system
+ * API.
+ */
+ public EnforcedAdmin checkIfRestrictionEnforced(Context context, String restriction) {
+ return RestrictedLockUtils.checkIfRestrictionEnforced(
+ context, restriction, UserHandle.myUserId());
+ }
+
+}
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index c65c316..dddfb1b 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -30,6 +30,7 @@
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.language.LanguageAndInputSettings;
import com.android.settings.network.NetworkDashboardFragment;
+import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.SoundSettings;
import com.android.settings.system.SystemDashboardFragment;
import com.android.settingslib.drawer.CategoryKey;
@@ -83,6 +84,8 @@
CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettings.class.getName(),
CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
+ PARENT_TO_CATEGORY_KEY_MAP.put(ConfigureNotificationSettings.class.getName(),
+ CategoryKey.CATEGORY_NOTIFICATIONS);
CATEGORY_KEY_TO_PARENT_MAP = new ArrayMap<>(PARENT_TO_CATEGORY_KEY_MAP.size());
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
index 0431ce5..a448b5c 100644
--- a/src/com/android/settings/datausage/AppDataUsage.java
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -14,6 +14,8 @@
package com.android.settings.datausage;
+import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+
import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
@@ -38,6 +40,7 @@
import android.support.v7.preference.PreferenceCategory;
import android.text.format.Formatter;
import android.util.ArraySet;
+import android.util.IconDrawableFactory;
import android.view.View;
import android.widget.AdapterView;
@@ -57,8 +60,6 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
-
public class AppDataUsage extends DataUsageBase implements Preference.OnPreferenceChangeListener,
DataSaverBackend.Listener {
@@ -158,7 +159,7 @@
PackageManager pm = getPackageManager();
try {
ApplicationInfo info = pm.getApplicationInfo(mPackages.valueAt(0), 0);
- mIcon = info.loadIcon(pm);
+ mIcon = IconDrawableFactory.newInstance(getActivity()).getBadgedIcon(info);
mLabel = info.loadLabel(pm);
mPackageName = info.packageName;
} catch (PackageManager.NameNotFoundException e) {
@@ -362,7 +363,7 @@
.setUid(uid)
.setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO,
AppHeaderController.ActionType.ACTION_NONE)
- .done(getPrefContext());
+ .done(activity, getPrefContext());
getPreferenceScreen().addPreference(pref);
}
diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java
index dda984b..aca4809 100644
--- a/src/com/android/settings/datausage/BillingCycleSettings.java
+++ b/src/com/android/settings/datausage/BillingCycleSettings.java
@@ -14,13 +14,16 @@
package com.android.settings.datausage;
+import static android.net.NetworkPolicy.LIMIT_DISABLED;
+import static android.net.NetworkPolicy.WARNING_DISABLED;
+
import android.app.AlertDialog;
import android.app.Dialog;
-import android.app.DialogFragment;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
+import android.icu.text.NumberFormat;
import android.net.NetworkPolicy;
import android.net.NetworkTemplate;
import android.os.Bundle;
@@ -42,8 +45,7 @@
import com.android.settingslib.NetworkPolicyEditor;
import com.android.settingslib.net.DataUsageController;
-import static android.net.NetworkPolicy.LIMIT_DISABLED;
-import static android.net.NetworkPolicy.WARNING_DISABLED;
+import java.text.ParseException;
public class BillingCycleSettings extends DataUsageBase implements
Preference.OnPreferenceChangeListener, DataUsageEditController {
@@ -246,7 +248,6 @@
final boolean isLimit = getArguments().getBoolean(EXTRA_LIMIT);
final long bytes = isLimit ? editor.getPolicyLimitBytes(template)
: editor.getPolicyWarningBytes(template);
- final long limitDisabled = isLimit ? LIMIT_DISABLED : WARNING_DISABLED;
if (bytes > 1.5f * GB_IN_BYTES) {
final String bytesText = formatText(bytes / (float) GB_IN_BYTES);
@@ -265,7 +266,7 @@
private String formatText(float v) {
v = Math.round(v * 100) / 100f;
- return String.valueOf(v);
+ return NumberFormat.getInstance().format(v);
}
@Override
@@ -278,15 +279,20 @@
final NetworkTemplate template = getArguments().getParcelable(EXTRA_TEMPLATE);
final boolean isLimit = getArguments().getBoolean(EXTRA_LIMIT);
- EditText bytesField = (EditText) mView.findViewById(R.id.bytes);
- Spinner spinner = (Spinner) mView.findViewById(R.id.size_spinner);
+ EditText bytesField = mView.findViewById(R.id.bytes);
+ Spinner spinner = mView.findViewById(R.id.size_spinner);
String bytesString = bytesField.getText().toString();
- if (bytesString.isEmpty()) {
- bytesString = "0";
+
+ double input = 0;
+ try {
+ input = NumberFormat.getInstance().parse(bytesString).doubleValue();
+ } catch (ParseException e) {
+ Log.w(TAG, "Failed to parse byte value " + bytesString);
}
- final long bytes = (long) (Float.valueOf(bytesString)
- * (spinner.getSelectedItemPosition() == 0 ? MB_IN_BYTES : GB_IN_BYTES));
+
+ final long bytes = (long) (input
+ * (spinner.getSelectedItemPosition() == 0 ? MB_IN_BYTES : GB_IN_BYTES));
// to fix the overflow problem
final long correctedBytes = Math.min(MAX_DATA_LIMIT_BYTES, bytes);
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
index b5d7ddf..10df004 100644
--- a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
+++ b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
@@ -59,7 +59,6 @@
import com.android.settings.Utils;
import com.android.settings.applications.ManageApplications;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
import com.android.settings.deviceinfo.StorageSettings.MountTask;
import com.android.settingslib.deviceinfo.StorageMeasurement;
import com.android.settingslib.deviceinfo.StorageMeasurement.MeasurementDetails;
@@ -126,7 +125,6 @@
private int mItemPoolIndex;
private Preference mExplore;
- private Preference mAutomaticStorageManagement;
private boolean mNeedsUpdate;
@@ -185,7 +183,6 @@
mCurrentUser = mUserManager.getUserInfo(UserHandle.myUserId());
mExplore = buildAction(R.string.storage_menu_explore);
- mAutomaticStorageManagement = buildAction(R.string.storage_menu_manage);
mNeedsUpdate = true;
@@ -212,9 +209,6 @@
screen.removeAll();
- if (getResources().getBoolean(R.bool.config_storage_manager_settings_enabled)) {
- addPreference(screen, mAutomaticStorageManagement);
- }
addPreference(screen, mSummary);
List<UserInfo> allUsers = mUserManager.getUsers();
@@ -331,6 +325,7 @@
private StorageItemPreference buildItem() {
final StorageItemPreference item = new StorageItemPreference(getPrefContext());
+ item.setIcon(R.drawable.empty_icon);
return item;
}
@@ -511,11 +506,6 @@
case R.string.storage_menu_explore: {
intent = mSharedVolume.buildBrowseIntent();
} break;
- case R.string.storage_menu_manage: {
- startFragment(this, AutomaticStorageManagerSettings.class.getCanonicalName(),
- R.string.automatic_storage_manager_settings, 0, null);
- return true;
- }
case 0: {
UserInfoFragment.show(this, pref.getTitle(), pref.getSummary());
return true;
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 602e65f..2a5ac17 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -16,9 +16,9 @@
package com.android.settings.deviceinfo;
+import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
-import android.content.Intent;
import android.content.Loader;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -28,16 +28,11 @@
import android.os.storage.VolumeInfo;
import android.provider.SearchIndexableResource;
import android.support.annotation.VisibleForTesting;
-import android.util.Log;
import android.util.SparseArray;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.applications.PackageManagerWrapper;
import com.android.settings.applications.PackageManagerWrapperImpl;
import com.android.settings.applications.UserManagerWrapper;
import com.android.settings.applications.UserManagerWrapperImpl;
@@ -57,7 +52,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Objects;
public class StorageDashboardFragment extends DashboardFragment
implements LoaderManager.LoaderCallbacks<SparseArray<StorageAsyncLoader.AppsStorageResult>> {
@@ -78,16 +72,15 @@
super.onCreate(icicle);
// Initialize the storage sizes that we can quickly calc.
- final Context context = getActivity();
- StorageManager sm = context.getSystemService(StorageManager.class);
+ final Activity activity = getActivity();
+ StorageManager sm = activity.getSystemService(StorageManager.class);
mVolume = Utils.maybeInitializeVolume(sm, getArguments());
if (mVolume == null) {
- getActivity().finish();
+ activity.finish();
return;
}
- mOptionMenuController = new PrivateVolumeOptionMenuController(
- context, mVolume, new PackageManagerWrapperImpl(context.getPackageManager()));
+ initializeOptionsMenu(activity);
final long sharedDataSize = mVolume.getPath().getTotalSpace();
long totalSize = sm.getPrimaryStorageSize();
@@ -101,8 +94,7 @@
final long usedBytes = totalSize - mVolume.getPath().getFreeSpace();
mSummaryController.updateBytes(usedBytes, totalSize);
mPreferenceController.setVolume(mVolume);
- mPreferenceController.setSystemSize(systemSize);
-
+ mPreferenceController.setUsedSize(usedBytes);
mPreferenceController.setTotalSize(totalSize);
for (int i = 0, size = mSecondaryUsers.size(); i < size; i++) {
PreferenceController controller = mSecondaryUsers.get(i);
@@ -114,10 +106,19 @@
}
}
+ @VisibleForTesting
+ void initializeOptionsMenu(Activity activity) {
+ mOptionMenuController = new PrivateVolumeOptionMenuController(
+ activity, mVolume, new PackageManagerWrapperImpl(activity.getPackageManager()));
+ getLifecycle().addObserver(mOptionMenuController);
+ setHasOptionsMenu(true);
+ activity.invalidateOptionsMenu();
+ }
+
@Override
public void onResume() {
super.onResume();
- getLoaderManager().initLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
+ getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
getLoaderManager().initLoader(ICON_JOB_ID, Bundle.EMPTY, new IconLoaderCallbacks());
}
@@ -156,7 +157,6 @@
new AutomaticStorageManagementSwitchPreferenceController(
context, mMetricsFeatureProvider, getFragmentManager());
getLifecycle().addObserver(asmController);
- getLifecycle().addObserver(mOptionMenuController);
controllers.add(asmController);
return controllers;
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
index e83c5d2..8652804 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.UserInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
@@ -32,6 +33,7 @@
import com.android.settings.utils.AsyncLoader;
import com.android.settingslib.applications.StorageStatsSource;
+import java.io.IOException;
import java.util.List;
/**
@@ -79,8 +81,15 @@
UserHandle myUser = UserHandle.of(userId);
for (int i = 0, size = applicationInfos.size(); i < size; i++) {
ApplicationInfo app = applicationInfos.get(i);
- StorageStatsSource.AppStorageStats stats =
- mStatsManager.getStatsForPackage(mUuid, app.packageName, myUser);
+
+ StorageStatsSource.AppStorageStats stats;
+ try {
+ stats = mStatsManager.getStatsForPackage(mUuid, app.packageName, myUser);
+ } catch (NameNotFoundException | IOException e) {
+ // This may happen if the package was removed during our calculation.
+ Log.w("App unexpectedly not found", e);
+ continue;
+ }
long attributedAppSizeInBytes = stats.getDataBytes();
// This matches how the package manager calculates sizes -- by zeroing out code sizes of
@@ -115,7 +124,11 @@
}
Log.d(TAG, "Loading external stats");
- result.externalStats = mStatsManager.getExternalStorageStats(mUuid, UserHandle.of(userId));
+ try {
+ result.externalStats = mStatsManager.getExternalStorageStats(mUuid, UserHandle.of(userId));
+ } catch (IOException e) {
+ Log.w(TAG, e);
+ }
Log.d(TAG, "Obtaining result completed");
return result;
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index 36694f0..5c4e354 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -78,7 +78,7 @@
private final StorageVolumeProvider mSvp;
private VolumeInfo mVolume;
private int mUserId;
- private long mSystemSize;
+ private long mUsedBytes;
private long mTotalSize;
private StorageItemPreference mPhotoPreference;
@@ -226,17 +226,29 @@
mGamePreference.setStorageSize(data.gamesSize, mTotalSize);
mMoviesPreference.setStorageSize(data.videoAppsSize, mTotalSize);
mAppPreference.setStorageSize(data.otherAppsSize, mTotalSize);
- if (mSystemPreference != null) {
- mSystemPreference.setStorageSize(mSystemSize + data.systemSize, mTotalSize);
- }
- long unattributedBytes = data.externalStats.totalBytes - data.externalStats.audioBytes
- - data.externalStats.videoBytes - data.externalStats.imageBytes;
- mFilePreference.setStorageSize(unattributedBytes, mTotalSize);
+ long unattributedExternalBytes =
+ data.externalStats.totalBytes
+ - data.externalStats.audioBytes
+ - data.externalStats.videoBytes
+ - data.externalStats.imageBytes;
+ mFilePreference.setStorageSize(unattributedExternalBytes, mTotalSize);
+
+ // We define the system size as everything we can't classify.
+ if (mSystemPreference != null) {
+ mSystemPreference.setStorageSize(
+ mUsedBytes
+ - data.externalStats.totalBytes
+ - data.musicAppsSize
+ - data.gamesSize
+ - data.videoAppsSize
+ - data.otherAppsSize,
+ mTotalSize);
+ }
}
- public void setSystemSize(long systemSizeBytes) {
- mSystemSize = systemSizeBytes;
+ public void setUsedSize(long usedSizeBytes) {
+ mUsedBytes = usedSizeBytes;
}
public void setTotalSize(long totalSizeBytes) {
diff --git a/src/com/android/settings/fingerprint/FingerprintSettings.java b/src/com/android/settings/fingerprint/FingerprintSettings.java
index 01670fe..fb59c59 100644
--- a/src/com/android/settings/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/fingerprint/FingerprintSettings.java
@@ -47,6 +47,7 @@
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.style.URLSpan;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
@@ -604,7 +605,9 @@
private void renameFingerPrint(int fingerId, String newName) {
mFingerprintManager.rename(fingerId, mUserId, newName);
- mFingerprintsRenaming.put(fingerId, newName);
+ if (!TextUtils.isEmpty(newName)) {
+ mFingerprintsRenaming.put(fingerId, newName);
+ }
updatePreferences();
}
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 2f8e28e..0c798a6 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -17,16 +17,12 @@
package com.android.settings.fuelgauge;
import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.BatteryStats;
import android.os.Bundle;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
@@ -179,7 +175,7 @@
@VisibleForTesting
void initHeader() {
final View appSnippet = mHeaderPreference.findViewById(R.id.app_snippet);
- final Context context = getContext();
+ final Activity context = getActivity();
final Bundle bundle = getArguments();
AppHeaderController controller = FeatureFactory.getFactory(context)
.getApplicationFeatureProvider(context)
@@ -203,7 +199,7 @@
controller.setSummary(getString(Utils.getInstallationStatus(mAppEntry.info)));
}
- controller.done(true /* rebindActions */);
+ controller.done(context, true /* rebindActions */);
}
@Override
diff --git a/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java b/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java
new file mode 100644
index 0000000..9d37333
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.Utils;
+
+/**
+ * Use this broadcastReceiver to listen to the battery change, and it will invoke
+ * {@link OnBatteryChangedListener} if any of the following happens:
+ *
+ * 1. Battery level has been changed
+ * 2. Battery status has been changed
+ */
+public class BatteryBroadcastReceiver extends BroadcastReceiver {
+
+ interface OnBatteryChangedListener {
+ void onBatteryChanged();
+ }
+
+ @VisibleForTesting
+ String mBatteryLevel;
+ @VisibleForTesting
+ String mBatteryStatus;
+ private OnBatteryChangedListener mBatteryListener;
+ private Context mContext;
+
+ public BatteryBroadcastReceiver(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (mBatteryListener != null && Intent.ACTION_BATTERY_CHANGED.equals(action)
+ && updateBatteryStatus(intent)) {
+ mBatteryListener.onBatteryChanged();
+ }
+ }
+
+ public void setBatteryChangedListener(OnBatteryChangedListener lsn) {
+ mBatteryListener = lsn;
+ }
+
+ public void register() {
+ mContext.registerReceiver(this,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ }
+
+ public void unRegister() {
+ mContext.unregisterReceiver(this);
+ }
+
+ private boolean updateBatteryStatus(Intent intent) {
+ if (intent != null) {
+ String batteryLevel = Utils.getBatteryPercentage(intent);
+ String batteryStatus = Utils.getBatteryStatus(
+ mContext.getResources(), intent);
+ if (!batteryLevel.equals(mBatteryLevel) || !batteryStatus.equals(mBatteryStatus)) {
+ mBatteryLevel = batteryLevel;
+ mBatteryStatus = batteryStatus;
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
index 3509834..722f4ad 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
@@ -172,7 +172,7 @@
mUsageListGroup.removeAll();
for (int i = 0, size = dataList.size(); i < size; i++) {
final PowerUsageData batteryData = dataList.get(i);
- if (shouldHide(batteryData)) {
+ if (shouldHideCategory(batteryData)) {
continue;
}
final PowerGaugePreference pref = new PowerGaugePreference(getPrefContext());
@@ -217,13 +217,15 @@
}
@VisibleForTesting
- boolean shouldHide(PowerUsageData powerUsageData) {
- if (powerUsageData.usageType == UsageType.UNACCOUNTED
- || powerUsageData.usageType == UsageType.OVERCOUNTED) {
- return true;
- }
+ boolean shouldHideCategory(PowerUsageData powerUsageData) {
+ return powerUsageData.usageType == UsageType.UNACCOUNTED
+ || powerUsageData.usageType == UsageType.OVERCOUNTED
+ || (powerUsageData.usageType == UsageType.USER && mUserManager.getUserCount() == 1);
+ }
- return false;
+ @VisibleForTesting
+ boolean shouldShowBatterySipper(BatterySipper batterySipper) {
+ return batterySipper.drainType != DrainType.SCREEN;
}
@VisibleForTesting
@@ -245,7 +247,9 @@
BatteryUtils.StatusType.FOREGROUND, sipper.uidObj, STATUS_TYPE);
}
usageData.totalUsageTimeMs += sipper.usageTimeMs;
- usageData.usageList.add(sipper);
+ if (shouldShowBatterySipper(sipper)) {
+ usageData.usageList.add(sipper);
+ }
}
final List<PowerUsageData> batteryDataList = new ArrayList<>(batteryDataMap.values());
@@ -264,6 +268,9 @@
@VisibleForTesting
void updateUsageDataSummary(PowerUsageData usageData, double totalPower, int dischargeAmount) {
+ if (shouldHideSummary(usageData)) {
+ return;
+ }
if (usageData.usageList.size() <= 1) {
usageData.summary = getString(R.string.battery_used_for,
Utils.formatElapsedTime(getContext(), usageData.totalUsageTimeMs, false));
@@ -278,6 +285,13 @@
}
@VisibleForTesting
+ boolean shouldHideSummary(PowerUsageData powerUsageData) {
+ @UsageType final int usageType = powerUsageData.usageType;
+
+ return usageType == UsageType.CELL;
+ }
+
+ @VisibleForTesting
BatterySipper findBatterySipperWithMaxBatteryUsage(List<BatterySipper> usageList) {
BatterySipper sipper = usageList.get(0);
for (int i = 1, size = usageList.size(); i < size; i++) {
@@ -299,6 +313,10 @@
void setPowerUsageFeatureProvider(PowerUsageFeatureProvider provider) {
mPowerUsageFeatureProvider = provider;
}
+ @VisibleForTesting
+ void setUserManager(UserManager userManager) {
+ mUserManager = userManager;
+ }
/**
* Class that contains data used in {@link PowerGaugePreference}.
diff --git a/src/com/android/settings/fuelgauge/PowerUsageBase.java b/src/com/android/settings/fuelgauge/PowerUsageBase.java
index 0236a30..1d9a228 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageBase.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageBase.java
@@ -45,9 +45,7 @@
protected BatteryStatsHelper mStatsHelper;
protected UserManager mUm;
-
- private String mBatteryLevel;
- private String mBatteryStatus;
+ private BatteryBroadcastReceiver mBatteryBroadcastReceiver;
@Override
public void onAttach(Activity activity) {
@@ -61,6 +59,13 @@
super.onCreate(icicle);
mStatsHelper.create(icicle);
setHasOptionsMenu(true);
+
+ mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(getContext());
+ mBatteryBroadcastReceiver.setBatteryChangedListener(() -> {
+ if (!mHandler.hasMessages(MSG_REFRESH_STATS)) {
+ mHandler.sendEmptyMessageDelayed(MSG_REFRESH_STATS, 500);
+ }
+ });
}
@Override
@@ -73,8 +78,7 @@
public void onResume() {
super.onResume();
BatteryStatsHelper.dropFile(getActivity(), BatteryHistoryDetail.BATTERY_HISTORY_FILE);
- updateBatteryStatus(getActivity().registerReceiver(mBatteryInfoReceiver,
- new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
+ mBatteryBroadcastReceiver.register();
if (mHandler.hasMessages(MSG_REFRESH_STATS)) {
mHandler.removeMessages(MSG_REFRESH_STATS);
mStatsHelper.clearStats();
@@ -84,7 +88,7 @@
@Override
public void onPause() {
super.onPause();
- getActivity().unregisterReceiver(mBatteryInfoReceiver);
+ mBatteryBroadcastReceiver.unRegister();
}
@Override
@@ -109,20 +113,6 @@
historyPref.setStats(mStatsHelper);
}
- private boolean updateBatteryStatus(Intent intent) {
- if (intent != null) {
- String batteryLevel = com.android.settings.Utils.getBatteryPercentage(intent);
- String batteryStatus = com.android.settings.Utils.getBatteryStatus(getResources(),
- intent);
- if (!batteryLevel.equals(mBatteryLevel) || !batteryStatus.equals(mBatteryStatus)) {
- mBatteryLevel = batteryLevel;
- mBatteryStatus = batteryStatus;
- return true;
- }
- }
- return false;
- }
-
static final int MSG_REFRESH_STATS = 100;
private final Handler mHandler = new Handler() {
@@ -137,17 +127,4 @@
}
};
- private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (Intent.ACTION_BATTERY_CHANGED.equals(action)
- && updateBatteryStatus(intent)) {
- if (!mHandler.hasMessages(MSG_REFRESH_STATS)) {
- mHandler.sendEmptyMessageDelayed(MSG_REFRESH_STATS, 500);
- }
- }
- }
- };
-
}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index ac041b8..5f12d7c 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -683,22 +683,28 @@
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
private final Context mContext;
private final SummaryLoader mLoader;
+ private final BatteryBroadcastReceiver mBatteryBroadcastReceiver;
private SummaryProvider(Context context, SummaryLoader loader) {
mContext = context;
mLoader = loader;
- }
-
- @Override
- public void setListening(boolean listening) {
- if (listening) {
- // TODO: Listen.
+ mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(mContext);
+ mBatteryBroadcastReceiver.setBatteryChangedListener(() -> {
BatteryInfo.getBatteryInfo(mContext, new BatteryInfo.Callback() {
@Override
public void onBatteryInfoLoaded(BatteryInfo info) {
mLoader.setSummary(SummaryProvider.this, info.chargeLabelString);
}
});
+ });
+ }
+
+ @Override
+ public void setListening(boolean listening) {
+ if (listening) {
+ mBatteryBroadcastReceiver.register();
+ } else {
+ mBatteryBroadcastReceiver.unRegister();
}
}
}
diff --git a/src/com/android/settings/network/NetworkResetActionMenuController.java b/src/com/android/settings/network/NetworkResetActionMenuController.java
index 028ac7b..254834b 100644
--- a/src/com/android/settings/network/NetworkResetActionMenuController.java
+++ b/src/com/android/settings/network/NetworkResetActionMenuController.java
@@ -17,9 +17,6 @@
package com.android.settings.network;
import android.content.Context;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.annotation.VisibleForTesting;
import android.view.Menu;
import android.view.MenuItem;
@@ -27,15 +24,16 @@
import com.android.settings.R;
import com.android.settings.ResetNetwork;
import com.android.settings.Utils;
-import com.android.settingslib.RestrictedLockUtils;
public class NetworkResetActionMenuController {
private static final int MENU_NETWORK_RESET = Menu.FIRST + 200;
private final Context mContext;
+ private final NetworkResetRestrictionChecker mRestrictionChecker;
public NetworkResetActionMenuController(Context context) {
mContext = context;
+ mRestrictionChecker = new NetworkResetRestrictionChecker(context);
}
public void buildMenuItem(Menu menu) {
@@ -53,14 +51,8 @@
}
}
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+
boolean isAvailable() {
- return isAvailable(mContext);
+ return !mRestrictionChecker.hasRestriction();
}
-
- static boolean isAvailable(Context context) {
- return !RestrictedLockUtils.hasBaseUserRestriction(context,
- UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
- }
-
}
diff --git a/src/com/android/settings/network/NetworkResetPreferenceController.java b/src/com/android/settings/network/NetworkResetPreferenceController.java
index 04573c9..ce36a7f 100644
--- a/src/com/android/settings/network/NetworkResetPreferenceController.java
+++ b/src/com/android/settings/network/NetworkResetPreferenceController.java
@@ -22,13 +22,16 @@
public class NetworkResetPreferenceController extends PreferenceController {
+ private final NetworkResetRestrictionChecker mRestrictionChecker;
+
public NetworkResetPreferenceController(Context context) {
super(context);
+ mRestrictionChecker = new NetworkResetRestrictionChecker(context);
}
@Override
public boolean isAvailable() {
- return NetworkResetActionMenuController.isAvailable(mContext);
+ return !mRestrictionChecker.hasRestriction();
}
@Override
diff --git a/src/com/android/settings/network/NetworkResetRestrictionChecker.java b/src/com/android/settings/network/NetworkResetRestrictionChecker.java
new file mode 100644
index 0000000..4fe9f59
--- /dev/null
+++ b/src/com/android/settings/network/NetworkResetRestrictionChecker.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settingslib.RestrictedLockUtils;
+
+public class NetworkResetRestrictionChecker {
+
+ private final Context mContext;
+ private final UserManager mUserManager;
+
+ public NetworkResetRestrictionChecker(Context context) {
+ mContext = context;
+ mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ boolean hasUserBaseRestriction() {
+ return RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ boolean isRestrictionEnforcedByAdmin() {
+ return RestrictedLockUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId()) != null;
+ }
+
+ boolean hasRestriction() {
+ return !mUserManager.isAdminUser()
+ || hasUserBaseRestriction()
+ || isRestrictionEnforcedByAdmin();
+ }
+}
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index e359da6..bcf9c3f 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -16,6 +16,7 @@
package com.android.settings.notification;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
@@ -49,7 +50,6 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import java.util.Objects;
/** These settings are per app, so should not be returned in global search results. */
public class AppNotificationSettings extends NotificationSettingsBase {
@@ -57,9 +57,13 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String KEY_BLOCK = "block";
+ private static final String KEY_IMPORTANCE = "allow_sound";
private List<NotificationChannelGroup> mChannelGroupList;
private List<PreferenceCategory> mChannelGroups = new ArrayList();
+ private RestrictedSwitchPreference mImportanceToggle;
+
+ private boolean mShowLegacyChannelConfig = false;
@Override
public int getMetricsCategory() {
@@ -109,8 +113,9 @@
}
}.execute();
- final Preference pref = FeatureFactory.getFactory(getActivity())
- .getApplicationFeatureProvider(getActivity())
+ final Activity activity = getActivity();
+ final Preference pref = FeatureFactory.getFactory(activity)
+ .getApplicationFeatureProvider(activity)
.newAppHeaderController(this /* fragment */, null /* appHeader */)
.setIcon(mAppRow.icon)
.setLabel(mAppRow.label)
@@ -118,7 +123,7 @@
.setUid(mAppRow.uid)
.setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO,
AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE)
- .done(getPrefContext());
+ .done(activity, getPrefContext());
getPreferenceScreen().addPreference(pref);
if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
@@ -139,6 +144,15 @@
empty.setTitle(R.string.no_channels);
empty.setEnabled(false);
groupCategory.addPreference(empty);
+
+ } else if (mChannelGroupList.size() == 1 &&
+ mChannelGroupList.get(0).getChannels().get(0).getId()
+ .equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
+ // Legacy app using only default channel. Hoist default channel settings to main panel.
+ mShowLegacyChannelConfig = true;
+ mChannel = mChannelGroupList.get(0).getChannels().get(0);
+ populateDefaultChannelPrefs();
+
} else {
for (NotificationChannelGroup group : mChannelGroupList) {
PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
@@ -159,39 +173,7 @@
int N = channels.size();
for (int i = 0; i < N; i++) {
final NotificationChannel channel = channels.get(i);
- MasterSwitchPreference channelPref = new MasterSwitchPreference(
- getPrefContext());
- channelPref.setDisabledByAdmin(mSuspendedAppsAdmin);
- channelPref.setKey(channel.getId());
- channelPref.setTitle(channel.getName());
- channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE);
- channelPref.setSummary(getImportanceSummary(channel.getImportance()));
- Bundle channelArgs = new Bundle();
- channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
- channelArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true);
- channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
- channelArgs.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
- Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
- ChannelNotificationSettings.class.getName(),
- channelArgs, null, 0, null, false, getMetricsCategory());
- channelPref.setIntent(channelIntent);
-
- channelPref.setOnPreferenceChangeListener(
- new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference,
- Object o) {
- boolean value = (Boolean) o;
- int importance = value ? IMPORTANCE_LOW : IMPORTANCE_NONE;
- channel.setImportance(importance);
- channel.lockFields(
- NotificationChannel.USER_LOCKED_IMPORTANCE);
- mBackend.updateChannel(mPkg, mUid, channel);
-
- return true;
- }
- });
- groupCategory.addPreference(channelPref);
+ populateSingleChannelPrefs(groupCategory, channel);
}
}
@@ -215,6 +197,74 @@
updateDependents(mAppRow.banned);
}
+ private void populateSingleChannelPrefs(PreferenceCategory groupCategory,
+ final NotificationChannel channel) {
+ MasterSwitchPreference channelPref = new MasterSwitchPreference(
+ getPrefContext());
+ channelPref.setSwitchEnabled(mSuspendedAppsAdmin == null && !mAppRow.systemApp);
+ channelPref.setKey(channel.getId());
+ channelPref.setTitle(channel.getName());
+ channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE);
+ channelPref.setSummary(getImportanceSummary(channel.getImportance()));
+ Bundle channelArgs = new Bundle();
+ channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
+ channelArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true);
+ channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
+ channelArgs.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
+ Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
+ ChannelNotificationSettings.class.getName(),
+ channelArgs, null, 0, null, false, getMetricsCategory());
+ channelPref.setIntent(channelIntent);
+
+ channelPref.setOnPreferenceChangeListener(
+ new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference,
+ Object o) {
+ boolean value = (Boolean) o;
+ int importance = value ? IMPORTANCE_LOW : IMPORTANCE_NONE;
+ channel.setImportance(importance);
+ channel.lockFields(
+ NotificationChannel.USER_LOCKED_IMPORTANCE);
+ mBackend.updateChannel(mPkg, mUid, channel);
+
+ return true;
+ }
+ });
+ groupCategory.addPreference(channelPref);
+ }
+
+ private void populateDefaultChannelPrefs() {
+ addPreferencesFromResource(R.xml.legacy_channel_notification_settings);
+ mPriority =
+ (RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND);
+ mVisibilityOverride =
+ (RestrictedDropDownPreference) findPreference(KEY_VISIBILITY_OVERRIDE);
+ mImportanceToggle = (RestrictedSwitchPreference) findPreference(KEY_IMPORTANCE);
+
+ if (mPkgInfo != null && mChannel != null) {
+ setupPriorityPref(mChannel.canBypassDnd());
+ setupVisOverridePref(mChannel.getLockscreenVisibility());
+ setupImportanceToggle();
+ }
+ }
+
+ private void setupImportanceToggle() {
+ mImportanceToggle.setDisabledByAdmin(mSuspendedAppsAdmin);
+ mImportanceToggle.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT);
+ mImportanceToggle.setOnPreferenceChangeListener(
+ new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final int importance = ((Boolean) newValue ? IMPORTANCE_DEFAULT : IMPORTANCE_LOW);
+ mChannel.setImportance(importance);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+ mBackend.updateChannel(mPkg, mUid, mChannel);
+ return true;
+ }
+ });
+ }
+
private void setupBadge() {
mBadge.setDisabledByAdmin(mSuspendedAppsAdmin);
mBadge.setChecked(mAppRow.showBadge);
@@ -254,6 +304,11 @@
setVisible(category, !banned);
}
setVisible(mBadge, !banned);
+ if (mShowLegacyChannelConfig) {
+ setVisible(mImportanceToggle, !banned);
+ setVisible(mPriority, !banned);
+ setVisible(mVisibilityOverride, !banned);
+ }
if (mAppRow.systemApp && !mAppRow.banned) {
setVisible(mBlock, false);
}
diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java
index bec4845..f6a7b42 100644
--- a/src/com/android/settings/notification/ChannelNotificationSettings.java
+++ b/src/com/android/settings/notification/ChannelNotificationSettings.java
@@ -21,16 +21,14 @@
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_NONE;
-import android.app.Notification;
+import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.provider.Settings;
-import android.service.notification.NotificationListenerService.Ranking;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -43,7 +41,6 @@
import com.android.settings.RingtonePreference;
import com.android.settings.applications.AppHeaderController;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import java.util.ArrayList;
@@ -52,9 +49,6 @@
public class ChannelNotificationSettings extends NotificationSettingsBase {
private static final String TAG = "ChannelSettings";
- protected static final String KEY_BYPASS_DND = "bypass_dnd";
- protected static final String KEY_VISIBILITY_OVERRIDE = "visibility_override";
- protected static final String KEY_IMPORTANCE = "importance";
protected static final String KEY_LIGHTS = "lights";
protected static final String KEY_VIBRATE = "vibrate";
protected static final String KEY_RINGTONE = "ringtone";
@@ -62,9 +56,6 @@
protected RestrictedSwitchPreference mLights;
protected RestrictedSwitchPreference mVibrate;
protected NotificationSoundPreference mRingtone;
- protected RestrictedDropDownPreference mImportance;
- protected RestrictedSwitchPreference mPriority;
- protected RestrictedDropDownPreference mVisibilityOverride;
@Override
public int getMetricsCategory() {
@@ -111,8 +102,9 @@
setupBlockAndImportance();
updateDependents();
}
- final Preference pref = FeatureFactory.getFactory(getActivity())
- .getApplicationFeatureProvider(getActivity())
+ final Activity activity = getActivity();
+ final Preference pref = FeatureFactory.getFactory(activity)
+ .getApplicationFeatureProvider(activity)
.newAppHeaderController(this /* fragment */, null /* appHeader */)
.setIcon(mAppRow.icon)
.setLabel(mChannel.getName())
@@ -121,7 +113,7 @@
.setUid(mAppRow.uid)
.setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO,
AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE)
- .done(getPrefContext());
+ .done(activity, getPrefContext());
getPreferenceScreen().addPreference(pref);
if (mAppRow.settingsIntent != null) {
@@ -175,9 +167,7 @@
mRingtone.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- Uri ringtone = Uri.parse((String) newValue);
- mRingtone.setRingtone(ringtone);
- mChannel.setSound(ringtone, mChannel.getAudioAttributes());
+ mChannel.setSound((Uri) newValue, mChannel.getAudioAttributes());
mChannel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
mBackend.updateChannel(mPkg, mUid, mChannel);
return false;
@@ -224,7 +214,7 @@
final int numImportances = IMPORTANCE_HIGH - IMPORTANCE_MIN + 1;
List<String> summaries = new ArrayList<>();
List<String> values = new ArrayList<>();
- ;
+
for (int i = 0; i < numImportances; i++) {
int importance = i + 1;
summaries.add(getImportanceSummary(importance));
@@ -238,7 +228,7 @@
mImportance.setEntryValues(values.toArray(new String[0]));
mImportance.setEntries(summaries.toArray(new String[0]));
mImportance.setValue(String.valueOf(mChannel.getImportance()));
- mImportance.setSummary("%s");
+ mImportance.setSummary(getImportanceSummary(mChannel.getImportance()));
if (mAppRow.lockedImportance) {
mImportance.setEnabled(false);
} else {
@@ -256,105 +246,6 @@
}
}
- protected void setupPriorityPref(boolean priority) {
- mPriority.setDisabledByAdmin(mSuspendedAppsAdmin);
- mPriority.setChecked(priority);
- mPriority.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final boolean bypassZenMode = (Boolean) newValue;
- mChannel.setBypassDnd(bypassZenMode);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- return true;
- }
- });
- }
-
- protected void setupVisOverridePref(int sensitive) {
- ArrayList<CharSequence> entries = new ArrayList<>();
- ArrayList<CharSequence> values = new ArrayList<>();
-
- mVisibilityOverride.clearRestrictedItems();
- if (getLockscreenNotificationsEnabled() && getLockscreenAllowPrivateNotifications()) {
- final String summaryShowEntry =
- getString(R.string.lock_screen_notifications_summary_show);
- final String summaryShowEntryValue =
- Integer.toString(NotificationManager.VISIBILITY_NO_OVERRIDE);
- entries.add(summaryShowEntry);
- values.add(summaryShowEntryValue);
- setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
- DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS
- | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
- }
-
- final String summaryHideEntry = getString(R.string.lock_screen_notifications_summary_hide);
- final String summaryHideEntryValue = Integer.toString(Notification.VISIBILITY_PRIVATE);
- entries.add(summaryHideEntry);
- values.add(summaryHideEntryValue);
- setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
- DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
- entries.add(getString(R.string.lock_screen_notifications_summary_disable));
- values.add(Integer.toString(Notification.VISIBILITY_SECRET));
- mVisibilityOverride.setEntries(entries.toArray(new CharSequence[entries.size()]));
- mVisibilityOverride.setEntryValues(values.toArray(new CharSequence[values.size()]));
-
- if (sensitive == Ranking.VISIBILITY_NO_OVERRIDE) {
- mVisibilityOverride.setValue(Integer.toString(getGlobalVisibility()));
- } else {
- mVisibilityOverride.setValue(Integer.toString(sensitive));
- }
- mVisibilityOverride.setSummary("%s");
-
- mVisibilityOverride.setOnPreferenceChangeListener(
- new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- int sensitive = Integer.parseInt((String) newValue);
- if (sensitive == getGlobalVisibility()) {
- sensitive = Ranking.VISIBILITY_NO_OVERRIDE;
- }
- mChannel.setLockscreenVisibility(sensitive);
- mChannel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
- mBackend.updateChannel(mPkg, mUid, mChannel);
- return true;
- }
- });
- mVisibilityOverride.setDisabledByAdmin(mSuspendedAppsAdmin);
- }
-
- private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
- CharSequence entryValue, int keyguardNotificationFeatures) {
- RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
- mContext, keyguardNotificationFeatures, mUserId);
- if (admin != null) {
- RestrictedDropDownPreference.RestrictedItem item =
- new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin);
- mVisibilityOverride.addRestrictedItem(item);
- }
- }
-
- private int getGlobalVisibility() {
- int globalVis = Ranking.VISIBILITY_NO_OVERRIDE;
- if (!getLockscreenNotificationsEnabled()) {
- globalVis = Notification.VISIBILITY_SECRET;
- } else if (!getLockscreenAllowPrivateNotifications()) {
- globalVis = Notification.VISIBILITY_PRIVATE;
- }
- return globalVis;
- }
-
- private boolean getLockscreenNotificationsEnabled() {
- return Settings.Secure.getInt(getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0;
- }
-
- private boolean getLockscreenAllowPrivateNotifications() {
- return Settings.Secure.getInt(getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 0;
- }
-
private boolean isLockScreenSecure() {
LockPatternUtils utils = new LockPatternUtils(getActivity());
boolean lockscreenSecure = utils.isSecure(UserHandle.myUserId());
diff --git a/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java b/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
new file mode 100644
index 0000000..a78fed7
--- /dev/null
+++ b/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2017 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 static com.android.internal.notification.NotificationAccessConfirmationActivityContract
+ .EXTRA_COMPONENT_NAME;
+import static com.android.internal.notification.NotificationAccessConfirmationActivityContract
+ .EXTRA_PACKAGE_TITLE;
+import static com.android.internal.notification.NotificationAccessConfirmationActivityContract
+ .EXTRA_USER_ID;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.SettingsStringUtil;
+import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+import com.android.settings.R;
+import com.android.settings.core.TouchOverlayManager;
+
+/** @hide */
+public class NotificationAccessConfirmationActivity extends Activity
+ implements DialogInterface {
+
+ private static final boolean DEBUG = false;
+ private static final String LOG_TAG = "NotificationAccessConfirmationActivity";
+
+ private int mUserId;
+ private ComponentName mComponentName;
+ private TouchOverlayManager mTouchOverlayManager;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mTouchOverlayManager = new TouchOverlayManager(this);
+
+ mComponentName = getIntent().getParcelableExtra(EXTRA_COMPONENT_NAME);
+ mUserId = getIntent().getIntExtra(EXTRA_USER_ID, UserHandle.USER_NULL);
+ String pkgTitle = getIntent().getStringExtra(EXTRA_PACKAGE_TITLE);
+
+ AlertController.AlertParams p = new AlertController.AlertParams(this);
+ p.mTitle = getString(
+ R.string.notification_listener_security_warning_title,
+ pkgTitle);
+ p.mMessage = getString(
+ R.string.notification_listener_security_warning_summary,
+ pkgTitle);
+ p.mPositiveButtonText = getString(R.string.allow);
+ p.mPositiveButtonListener = (a, b) -> onAllow();
+ p.mNegativeButtonText = getString(R.string.deny);
+ p.mNegativeButtonListener = (a, b) -> cancel();
+ AlertController
+ .create(this, this, getWindow())
+ .installContent(p);
+ }
+
+ private void onAllow() {
+ String requiredPermission = Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE;
+ try {
+ ServiceInfo serviceInfo = getPackageManager().getServiceInfo(mComponentName, 0);
+ if (!requiredPermission.equals(serviceInfo.permission)) {
+ Slog.e(LOG_TAG,
+ "Service " + mComponentName + " lacks permission " + requiredPermission);
+ return;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(LOG_TAG, "Failed to get service info for " + mComponentName, e);
+ return;
+ }
+
+ final SettingsStringUtil.SettingStringHelper setting =
+ new SettingsStringUtil.SettingStringHelper(
+ getContentResolver(),
+ Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
+ mUserId);
+ setting.write(SettingsStringUtil.ComponentNameSet.add(setting.read(), mComponentName));
+
+ finish();
+ }
+
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ return AlertActivity.dispatchPopulateAccessibilityEvent(this, event);
+ }
+
+ @Override
+ public void cancel() {
+ finish();
+ }
+
+ @Override
+ public void dismiss() {
+ // This is called after the click, since we finish when handling the
+ // click, don't do that again here.
+ if (!isFinishing()) {
+ finish();
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mTouchOverlayManager.setOverlayAllowed(false);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mTouchOverlayManager.setOverlayAllowed(true);
+ }
+}
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index c1ef018..6226eac 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -18,7 +18,6 @@
import android.app.INotificationManager;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -28,6 +27,7 @@
import android.graphics.drawable.Drawable;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.util.IconDrawableFactory;
import android.util.Log;
import com.android.settingslib.Utils;
@@ -48,7 +48,7 @@
Log.e(TAG, "Error loading application label for " + row.pkg, t);
row.label = row.pkg;
}
- row.icon = app.loadIcon(pm);
+ row.icon = IconDrawableFactory.newInstance(context).getBadgedIcon(app);
row.banned = getNotificationsBanned(row.pkg, row.uid);
row.showBadge = canShowBadge(row.pkg, row.uid);
row.userId = UserHandle.getUserId(row.uid);
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index 960c3b8..ff0a512 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -18,15 +18,14 @@
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
import com.android.settings.applications.AppInfoBase;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import android.app.Notification;
import android.app.NotificationChannel;
-import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -39,6 +38,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.service.notification.NotificationListenerService;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -47,6 +47,7 @@
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import java.util.ArrayList;
import java.util.List;
abstract public class NotificationSettingsBase extends SettingsPreferenceFragment {
@@ -59,6 +60,9 @@
protected static final String KEY_BLOCK = "block";
protected static final String KEY_BADGE = "badge";
+ protected static final String KEY_BYPASS_DND = "bypass_dnd";
+ protected static final String KEY_VISIBILITY_OVERRIDE = "visibility_override";
+ protected static final String KEY_IMPORTANCE = "importance";
protected PackageManager mPm;
protected UserManager mUm;
@@ -71,6 +75,10 @@
protected PackageInfo mPkgInfo;
protected RestrictedSwitchPreference mBlock;
protected RestrictedSwitchPreference mBadge;
+ protected RestrictedDropDownPreference mImportance;
+ protected RestrictedSwitchPreference mPriority;
+ protected RestrictedDropDownPreference mVisibilityOverride;
+
protected EnforcedAdmin mSuspendedAppsAdmin;
protected boolean mDndVisualEffectsSuppressed;
@@ -249,4 +257,105 @@
return getContext().getString(R.string.notification_importance_high);
}
}
+
+ protected void setupPriorityPref(boolean priority) {
+ mPriority.setDisabledByAdmin(mSuspendedAppsAdmin);
+ mPriority.setChecked(priority);
+ mPriority.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean bypassZenMode = (Boolean) newValue;
+ mChannel.setBypassDnd(bypassZenMode);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
+ mBackend.updateChannel(mPkg, mUid, mChannel);
+ return true;
+ }
+ });
+ }
+
+ protected void setupVisOverridePref(int sensitive) {
+ ArrayList<CharSequence> entries = new ArrayList<>();
+ ArrayList<CharSequence> values = new ArrayList<>();
+
+ mVisibilityOverride.clearRestrictedItems();
+ if (getLockscreenNotificationsEnabled() && getLockscreenAllowPrivateNotifications()) {
+ final String summaryShowEntry =
+ getString(R.string.lock_screen_notifications_summary_show);
+ final String summaryShowEntryValue =
+ Integer.toString(NotificationManager.VISIBILITY_NO_OVERRIDE);
+ entries.add(summaryShowEntry);
+ values.add(summaryShowEntryValue);
+ setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
+ DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS
+ | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+ }
+
+ final String summaryHideEntry = getString(R.string.lock_screen_notifications_summary_hide);
+ final String summaryHideEntryValue = Integer.toString(Notification.VISIBILITY_PRIVATE);
+ entries.add(summaryHideEntry);
+ values.add(summaryHideEntryValue);
+ setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
+ DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+ entries.add(getString(R.string.lock_screen_notifications_summary_disable));
+ values.add(Integer.toString(Notification.VISIBILITY_SECRET));
+ mVisibilityOverride.setEntries(entries.toArray(new CharSequence[entries.size()]));
+ mVisibilityOverride.setEntryValues(values.toArray(new CharSequence[values.size()]));
+
+ if (sensitive == NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
+ mVisibilityOverride.setValue(Integer.toString(getGlobalVisibility()));
+ } else {
+ mVisibilityOverride.setValue(Integer.toString(sensitive));
+ }
+ mVisibilityOverride.setSummary("%s");
+
+ mVisibilityOverride.setOnPreferenceChangeListener(
+ new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ int sensitive = Integer.parseInt((String) newValue);
+ if (sensitive == getGlobalVisibility()) {
+ sensitive = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
+ }
+ mChannel.setLockscreenVisibility(sensitive);
+ mChannel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
+ mBackend.updateChannel(mPkg, mUid, mChannel);
+ return true;
+ }
+ });
+ mVisibilityOverride.setDisabledByAdmin(mSuspendedAppsAdmin);
+ }
+
+
+ private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
+ CharSequence entryValue, int keyguardNotificationFeatures) {
+ RestrictedLockUtils.EnforcedAdmin admin =
+ RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ mContext, keyguardNotificationFeatures, mUserId);
+ if (admin != null) {
+ RestrictedDropDownPreference.RestrictedItem item =
+ new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin);
+ mVisibilityOverride.addRestrictedItem(item);
+ }
+ }
+
+ private int getGlobalVisibility() {
+ int globalVis = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
+ if (!getLockscreenNotificationsEnabled()) {
+ globalVis = Notification.VISIBILITY_SECRET;
+ } else if (!getLockscreenAllowPrivateNotifications()) {
+ globalVis = Notification.VISIBILITY_PRIVATE;
+ }
+ return globalVis;
+ }
+
+
+ private boolean getLockscreenNotificationsEnabled() {
+ return Settings.Secure.getInt(getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0;
+ }
+
+ private boolean getLockscreenAllowPrivateNotifications() {
+ return Settings.Secure.getInt(getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 0;
+ }
}
diff --git a/src/com/android/settings/notification/NotificationSoundPreference.java b/src/com/android/settings/notification/NotificationSoundPreference.java
index 51b235d..c007485 100644
--- a/src/com/android/settings/notification/NotificationSoundPreference.java
+++ b/src/com/android/settings/notification/NotificationSoundPreference.java
@@ -2,6 +2,7 @@
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
@@ -25,9 +26,21 @@
public void setRingtone(Uri ringtone) {
mRingtone = ringtone;
+ setSummary("\u00A0");
updateRingtoneName(mRingtone);
}
+ @Override
+ public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (data != null) {
+ Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
+ setRingtone(uri);
+ callChangeListener(uri);
+ }
+
+ return true;
+ }
+
private void updateRingtoneName(final Uri uri) {
AsyncTask ringtoneNameTask = new AsyncTask<Object, Void, CharSequence>() {
@Override
diff --git a/src/com/android/settings/notification/RedactionInterstitial.java b/src/com/android/settings/notification/RedactionInterstitial.java
index 08474a0..b269062 100644
--- a/src/com/android/settings/notification/RedactionInterstitial.java
+++ b/src/com/android/settings/notification/RedactionInterstitial.java
@@ -16,7 +16,11 @@
package com.android.settings.notification;
-import android.app.admin.DevicePolicyManager;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -26,7 +30,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
-import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
@@ -34,18 +37,13 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.RestrictedCheckBox;
import com.android.settings.RestrictedRadioButton;
import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.SetupRedactionInterstitial;
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils;
-import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
-import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
-
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
public class RedactionInterstitial extends SettingsActivity {
@Override
@@ -128,6 +126,7 @@
@Override
public void onClick(View v) {
if (v.getId() == R.id.redaction_done_button) {
+ SetupRedactionInterstitial.setEnabled(getContext(), false);
final RedactionInterstitial activity = (RedactionInterstitial) getActivity();
if (activity != null) {
activity.setResult(RESULT_OK, null);
diff --git a/src/com/android/settings/wallpaper/WallpaperTypeSettings.java b/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
index 6efdcf72..bef4777 100644
--- a/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
+++ b/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
@@ -67,7 +67,6 @@
// Add Preference items for each of the matching activities
for (ResolveInfo info : rList) {
Preference pref = new Preference(getPrefContext());
- pref.setLayoutResource(R.layout.preference_wallpaper_type);
Intent prefIntent = new Intent(intent);
prefIntent.setComponent(new ComponentName(
info.activityInfo.packageName, info.activityInfo.name));
diff --git a/src/com/android/settings/widget/MasterSwitchPreference.java b/src/com/android/settings/widget/MasterSwitchPreference.java
index cf22207..002cb77 100644
--- a/src/com/android/settings/widget/MasterSwitchPreference.java
+++ b/src/com/android/settings/widget/MasterSwitchPreference.java
@@ -36,6 +36,7 @@
private Switch mSwitch;
private boolean mChecked;
+ private boolean mEnableSwitch = true;
public MasterSwitchPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
@@ -67,6 +68,9 @@
widgetView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
+ if (mSwitch != null && !mSwitch.isEnabled()) {
+ return;
+ }
setChecked(!mChecked);
if (!callChangeListener(mChecked)) {
setChecked(!mChecked);
@@ -76,9 +80,11 @@
}
});
}
+
mSwitch = (Switch) holder.findViewById(R.id.switchWidget);
if (mSwitch != null) {
mSwitch.setChecked(mChecked);
+ mSwitch.setEnabled(mEnableSwitch);
}
}
@@ -94,6 +100,7 @@
}
public void setSwitchEnabled(boolean enabled) {
+ mEnableSwitch = enabled;
if (mSwitch != null) {
mSwitch.setEnabled(enabled);
}
diff --git a/src/com/android/settings/wifi/LinkablePreference.java b/src/com/android/settings/wifi/LinkablePreference.java
index 5bf51ed..9a6b11a 100644
--- a/src/com/android/settings/wifi/LinkablePreference.java
+++ b/src/com/android/settings/wifi/LinkablePreference.java
@@ -21,6 +21,7 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.Spannable;
+import android.text.method.LinkMovementMethod;
import android.text.style.TextAppearanceSpan;
import android.util.AttributeSet;
import android.widget.TextView;
@@ -81,6 +82,7 @@
mContentTitle.length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(boldSpan);
+ textView.setMovementMethod(new LinkMovementMethod());
}
}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 38f5a43..a87bd19 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -90,6 +90,7 @@
WifiDialog.WifiDialogListener {
private static final String TAG = "WifiSettings";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/* package */ static final int MENU_ID_WPS_PBC = Menu.FIRST;
private static final int MENU_ID_WPS_PIN = Menu.FIRST + 1;
@@ -190,8 +191,10 @@
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- getPreferenceManager().setPreferenceComparisonCallback(
- new PreferenceManager.SimplePreferenceComparisonCallback());
+ // TODO(b/37429702): Add animations and preference comparator back after initial screen is
+ // loaded (ODR).
+ setAnimationAllowed(false);
+
addPreferencesFromResource(R.xml.wifi_settings);
mConnectedAccessPointPreferenceCategory =
@@ -335,6 +338,21 @@
mWifiEnabler = createWifiEnabler();
mWifiTracker.startTracking();
+
+ if (!isUiRestricted() && mWifiManager.isWifiEnabled()) {
+ forceUpdateAPs();
+ }
+ }
+
+ private void forceUpdateAPs() {
+ setProgressBarVisible(true);
+ mWifiTracker.forceUpdate();
+ if (DEBUG) {
+ Log.d(TAG, "WifiSettings force update APs: " + mWifiTracker.getAccessPoints());
+ }
+
+ getView().removeCallbacks(mUpdateAccessPointsRunnable);
+ updateAccessPointPreferences();
}
/**
@@ -353,8 +371,6 @@
if (mWifiEnabler != null) {
mWifiEnabler.resume(activity);
}
-
- activity.invalidateOptionsMenu();
}
@Override
@@ -651,7 +667,7 @@
final int wifiState = mWifiManager.getWifiState();
switch (wifiState) {
case WifiManager.WIFI_STATE_ENABLED:
- updateAccessPointsDelayed();
+ forceUpdateAPs();
break;
case WifiManager.WIFI_STATE_ENABLING:
@@ -733,7 +749,7 @@
removeCachedPrefs(mAccessPointsPreferenceCategory);
mAddPreference.setOrder(index);
mAccessPointsPreferenceCategory.addPreference(mAddPreference);
- setConfigureWifiSettingsVisibility();
+ setAdditionalSettingsSummaries();
if (!hasAvailableAccessPoints) {
setProgressBarVisible(true);
@@ -812,8 +828,8 @@
// in the Wifi Network Details Fragment
pref.getAccessPoint().saveWifiState(pref.getExtras());
pref.setFragment(WifiNetworkDetailsFragment.class.getName());
-
pref.refresh();
+
mConnectedAccessPointPreferenceCategory.addPreference(pref);
mConnectedAccessPointPreferenceCategory.setVisible(true);
}
@@ -824,7 +840,7 @@
mConnectedAccessPointPreferenceCategory.setVisible(false);
}
- private void setConfigureWifiSettingsVisibility() {
+ private void setAdditionalSettingsSummaries() {
mAdditionalSettingsPreferenceCategory.addPreference(mConfigureWifiSettingsPreference);
boolean wifiWakeupEnabled = Settings.Global.getInt(
getContentResolver(), Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
diff --git a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
index 122e524..2c33fc5 100644
--- a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
@@ -26,6 +26,7 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
+import com.android.settings.R;
import com.android.settings.core.PreferenceController;
import com.android.settings.core.lifecycle.Lifecycle;
@@ -97,10 +98,20 @@
return;
}
final SwitchPreference enableWifiWakeup = (SwitchPreference) preference;
+
enableWifiWakeup.setChecked(Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1);
- enableWifiWakeup.setEnabled(Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1);
+
+ boolean wifiScanningEnabled = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1;
+ boolean networkRecommendationsEnabled = Settings.Global.getInt(
+ mContext.getContentResolver(),
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1;
+ enableWifiWakeup.setEnabled(networkRecommendationsEnabled && wifiScanningEnabled);
+
+ enableWifiWakeup.setSummary(wifiScanningEnabled ?
+ R.string.wifi_wakeup_summary :
+ R.string.wifi_wakeup_summary_scanning_disabled);
}
class SettingObserver extends ContentObserver {
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index e8bca37..21fda30 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -301,6 +301,7 @@
Preference pref = new Preference(mPrefContext);
pref.setKey(ip);
pref.setTitle(ip);
+ pref.setSelectable(false);
mIpv6AddressCategory.addPreference(pref);
mIpv6AddressCategory.setVisible(true);
}
diff --git a/tests/app/src/com/android/settings/EncryptionInterstitialTest.java b/tests/app/src/com/android/settings/EncryptionInterstitialTest.java
index 6487818..f30d511 100644
--- a/tests/app/src/com/android/settings/EncryptionInterstitialTest.java
+++ b/tests/app/src/com/android/settings/EncryptionInterstitialTest.java
@@ -16,38 +16,89 @@
package com.android.settings;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
import android.app.Instrumentation;
+import android.app.Instrumentation.ActivityMonitor;
+import android.app.Instrumentation.ActivityResult;
import android.content.Context;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
+import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
@RunWith(AndroidJUnit4.class)
-@SmallTest
+@MediumTest
public class EncryptionInterstitialTest {
private Instrumentation mInstrumentation;
private Context mContext;
+ private TestActivityMonitor mActivityMonitor;
@Before
public void setUp() {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mContext = mInstrumentation.getTargetContext();
+ mActivityMonitor = new TestActivityMonitor();
+ mInstrumentation.addMonitor(mActivityMonitor);
+ }
+
+ @After
+ public void tearDown() {
+ mInstrumentation.removeMonitor(mActivityMonitor);
}
@Test
- public void clickHeader_shouldNotCrash() {
+ public void clickYes_shouldRequirePassword() {
mInstrumentation.startActivitySync(
- new Intent().setClassName(mContext, EncryptionInterstitial.class.getName()));
- onView(withId(R.id.encryption_interstitial_header));
- // Nothing should happen
+ new Intent(mContext, EncryptionInterstitial.class)
+ .putExtra("extra_unlock_method_intent", new Intent("test.unlock.intent")));
+ onView(withId(R.id.encrypt_require_password)).perform(click());
+
+ mActivityMonitor.waitForActivityWithTimeout(1000);
+ assertEquals(1, mActivityMonitor.getHits());
+
+ assertTrue(mActivityMonitor.mMatchedIntent.getBooleanExtra(
+ EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false));
+ }
+
+ @Test
+ public void clickNo_shouldNotRequirePassword() {
+ mInstrumentation.startActivitySync(
+ new Intent(mContext, EncryptionInterstitial.class)
+ .putExtra("extra_unlock_method_intent", new Intent("test.unlock.intent")));
+ onView(withId(R.id.encrypt_dont_require_password)).perform(click());
+
+ mActivityMonitor.waitForActivityWithTimeout(1000);
+ assertEquals(1, mActivityMonitor.getHits());
+
+ assertFalse(mActivityMonitor.mMatchedIntent.getBooleanExtra(
+ EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true));
+ }
+
+ private static class TestActivityMonitor extends ActivityMonitor {
+
+ Intent mMatchedIntent = null;
+
+ @Override
+ public ActivityResult onMatchIntent(Intent intent) {
+ if ("test.unlock.intent".equals(intent.getAction())) {
+ mMatchedIntent = intent;
+ return new ActivityResult(Activity.RESULT_OK, null);
+ }
+ return null;
+ }
}
}
diff --git a/tests/robotests/src/android/util/IconDrawableFactory.java b/tests/robotests/src/android/util/IconDrawableFactory.java
new file mode 100644
index 0000000..9d0d7df
--- /dev/null
+++ b/tests/robotests/src/android/util/IconDrawableFactory.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 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 android.util;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+
+/**
+ * This class is only needed to get around Robolectric issue.
+ */
+public class IconDrawableFactory {
+
+ public static IconDrawableFactory newInstance(Context context) {
+ return new IconDrawableFactory();
+ }
+
+ public Drawable getBadgedIcon(ApplicationInfo appInfo) {
+ return getBadgedIcon(appInfo, 0);
+ }
+
+ public Drawable getBadgedIcon(ApplicationInfo appInfo, int userId) {
+ return getBadgedIcon(appInfo, appInfo, userId);
+ }
+
+ public Drawable getBadgedIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo, int userId) {
+ return new ColorDrawable(0);
+ }
+}
diff --git a/tests/robotests/src/android/util/LauncherIcons.java b/tests/robotests/src/android/util/LauncherIcons.java
deleted file mode 100644
index a18cfae..0000000
--- a/tests/robotests/src/android/util/LauncherIcons.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.util;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-/**
- * This class is only needed to get around RoboElectric issue.
- */
-public final class LauncherIcons {
-
- public LauncherIcons(Context context) {
- }
-
- public Drawable wrapIconDrawableWithShadow(Drawable drawable) {
- return drawable;
- }
-}
diff --git a/tests/robotests/src/com/android/settings/SecuritySettingsTest.java b/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
index 9bdf502..c636748 100644
--- a/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
@@ -101,24 +101,7 @@
}
@Test
- @Config(shadows = {
- ShadowSecureSettings.class,
- })
- public void testSummaryProvider_packageVerifierDisabled() {
- // Package verifier state is set to disabled.
- ShadowSecureSettings.putInt(null, Settings.Secure.PACKAGE_VERIFIER_STATE, -1);
- mSummaryProvider.setListening(true);
-
- verify(mSummaryLoader, times(1)).setSummary(any(), isNull(String.class));
- }
-
- @Test
- @Config(shadows = {
- ShadowSecureSettings.class,
- })
public void testSummaryProvider_hasFingerPrint_hasStaticSummary() {
- // Package verifier state is set to disabled.
- ShadowSecureSettings.putInt(null, Settings.Secure.PACKAGE_VERIFIER_STATE, -1);
final FingerprintManager fpm = mock(FingerprintManager.class);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(true);
@@ -133,37 +116,29 @@
}
@Test
- public void testGetPackageVerifierSummary_nullInput() {
- assertThat(mSummaryProvider.getPackageVerifierSummary(null)).isNull();
+ public void testSummaryProvider_noFpFeature_shouldSetSummaryWithNoFingerprint() {
+ final FingerprintManager fpm = mock(FingerprintManager.class);
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(false);
- when(mDashboardCategory.getTilesCount()).thenReturn(0);
+ mSummaryProvider.setListening(true);
- assertThat(mSummaryProvider.getPackageVerifierSummary(mDashboardCategory)).isNull();
+ verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
}
@Test
- public void testGetPackageVerifierSummary_noMatchingTile() {
- when(mDashboardCategory.getTilesCount()).thenReturn(1);
- when(mDashboardCategory.getTile(0)).thenReturn(new Tile());
+ public void testSummaryProvider_noFpHardware_shouldSetSummaryWithNoFingerprint() {
+ final FingerprintManager fpm = mock(FingerprintManager.class);
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(true);
- assertThat(mSummaryProvider.getPackageVerifierSummary(mDashboardCategory)).isNull();
- }
+ // Cast to Object to workaround a robolectric casting bug
+ when((Object) mContext.getSystemService(FingerprintManager.class)).thenReturn(fpm);
+ when(fpm.isHardwareDetected()).thenReturn(false);
- @Test
- @Config(shadows = {
- ShadowTileUtils.class,
- })
- public void testGetPackageVerifierSummary_matchingTile() {
- when(mDashboardCategory.getTilesCount()).thenReturn(1);
- Tile tile = new Tile();
- tile.key = SecuritySettings.KEY_PACKAGE_VERIFIER_STATUS;
- Bundle bundle = new Bundle();
- bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, "content://host/path");
- tile.metaData = bundle;
- when(mDashboardCategory.getTile(0)).thenReturn(tile);
+ mSummaryProvider.setListening(true);
- assertThat(mSummaryProvider.getPackageVerifierSummary(mDashboardCategory))
- .isEqualTo(MOCK_SUMMARY);
+ verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accounts/AutoSyncWorkDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AutoSyncWorkDataPreferenceControllerTest.java
new file mode 100644
index 0000000..d93d3a7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accounts/AutoSyncWorkDataPreferenceControllerTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 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.accounts;
+
+
+import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AutoSyncWorkDataPreferenceControllerTest {
+
+ @Mock(answer = RETURNS_DEEP_STUBS)
+ private UserManager mUserManager;
+ @Mock(answer = RETURNS_DEEP_STUBS)
+ private Fragment mFragment;
+ @Mock
+ private Context mContext;
+
+ private AutoSyncWorkDataPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+
+ mController = new AutoSyncWorkDataPreferenceController(mContext, mFragment);
+ }
+
+ @Test
+ public void checkIsAvailable_managedProfile_shouldNotDisplay() {
+ when(mUserManager.isManagedProfile()).thenReturn(true);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void checkIsAvailable_linkedUser_shouldNotDisplay() {
+ when(mUserManager.isManagedProfile()).thenReturn(false);
+ when(mUserManager.isLinkedUser()).thenReturn(true);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void checkIsAvailable_singleUserProfile_shouldNotDisplay() {
+ final List<UserInfo> infos = new ArrayList<>();
+ infos.add(new UserInfo(1, "user 1", 0));
+ when(mUserManager.isManagedProfile()).thenReturn(false);
+ when(mUserManager.isLinkedUser()).thenReturn(false);
+ when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void multipleProfile_shouldInitWithWorkProfileUserHandle() {
+ final int id1 = 1;
+ final int id2 = 2;
+ final UserInfo managedUser = new UserInfo(id2, "user 2", FLAG_MANAGED_PROFILE);
+ final List<UserHandle> infos = new ArrayList<>();
+ infos.add(new UserHandle(id1));
+ infos.add(new UserHandle(id2));
+ when(mUserManager.getUserProfiles()).thenReturn(infos);
+ when(mUserManager.getUserHandle()).thenReturn(id1);
+ when(mUserManager.getUserInfo(id2)).thenReturn(managedUser);
+
+ mController = new AutoSyncWorkDataPreferenceController(mContext, mFragment);
+
+ assertThat(mController.mUserHandle.getIdentifier()).isEqualTo(id2);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java b/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java
index 0d878ed..37a7521 100644
--- a/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java
@@ -17,6 +17,16 @@
package com.android.settings.applications;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
@@ -24,17 +34,16 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.ResolveInfo;
+import android.graphics.drawable.ColorDrawable;
import android.os.UserHandle;
import android.support.v7.preference.Preference;
import android.view.LayoutInflater;
import android.view.View;
-import android.widget.ImageView;
import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
-import com.android.settingslib.applications.ApplicationsState;
import org.junit.Before;
import org.junit.Test;
@@ -45,14 +54,6 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AppHeaderControllerTest {
@@ -60,11 +61,9 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private ApplicationsState.AppEntry mAppEntry;
+ private Activity mActivity;
@Mock
private Fragment mFragment;
- @Mock
- private View mAppHeader;
private Context mShadowContext;
private LayoutInflater mLayoutInflater;
@@ -85,7 +84,7 @@
@Test
public void testBuildView_constructedWithoutView_shouldCreateNewView() {
mController = new AppHeaderController(mShadowContext, mFragment, null);
- View view = mController.done();
+ View view = mController.done(mActivity);
assertThat(view).isNotNull();
}
@@ -93,7 +92,7 @@
@Test
public void testBuildView_withContext_shouldBuildPreference() {
mController = new AppHeaderController(mShadowContext, mFragment, null);
- Preference preference = mController.done(mShadowContext);
+ Preference preference = mController.done(mActivity, mShadowContext);
assertThat(preference instanceof LayoutPreference).isTrue();
}
@@ -102,7 +101,7 @@
public void testBuildView_constructedWithView_shouldReturnSameView() {
View inputView = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
mController = new AppHeaderController(mShadowContext, mFragment, inputView);
- View view = mController.done();
+ View view = mController.done(mActivity);
assertThat(view).isSameAs(inputView);
}
@@ -111,14 +110,14 @@
public void bindViews_shouldBindAllData() {
final String testString = "test";
final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
- final TextView label = (TextView) appHeader.findViewById(R.id.app_detail_title);
- final TextView version = (TextView) appHeader.findViewById(R.id.app_detail_summary);
+ final TextView label = appHeader.findViewById(R.id.app_detail_title);
+ final TextView version = appHeader.findViewById(R.id.app_detail_summary);
mController = new AppHeaderController(mShadowContext, mFragment, appHeader);
mController.setLabel(testString);
mController.setSummary(testString);
mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add));
- mController.done();
+ mController.done(mActivity);
assertThat(label.getText()).isEqualTo(testString);
assertThat(version.getText()).isEqualTo(testString);
@@ -139,7 +138,7 @@
mController.setButtonActions(
AppHeaderController.ActionType.ACTION_APP_PREFERENCE,
AppHeaderController.ActionType.ACTION_NONE);
- mController.done();
+ mController.done(mActivity);
assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
.isEqualTo(View.VISIBLE);
@@ -164,7 +163,7 @@
mController.setButtonActions(
AppHeaderController.ActionType.ACTION_APP_PREFERENCE,
AppHeaderController.ActionType.ACTION_NONE);
- mController.done();
+ mController.done(mActivity);
assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
.isEqualTo(View.GONE);
@@ -183,7 +182,7 @@
mController.setButtonActions(
AppHeaderController.ActionType.ACTION_STORE_DEEP_LINK,
AppHeaderController.ActionType.ACTION_NONE);
- mController.done();
+ mController.done(mActivity);
assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
.isEqualTo(View.GONE);
@@ -201,7 +200,7 @@
.setButtonActions(
AppHeaderController.ActionType.ACTION_APP_INFO,
AppHeaderController.ActionType.ACTION_NONE);
- mController.done();
+ mController.done(mActivity);
assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
.isEqualTo(View.GONE);
@@ -221,7 +220,7 @@
.setButtonActions(
AppHeaderController.ActionType.ACTION_APP_INFO,
AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE);
- mController.done();
+ mController.done(mActivity);
assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
.isEqualTo(View.VISIBLE);
@@ -242,7 +241,7 @@
.setButtonActions(
AppHeaderController.ActionType.ACTION_APP_INFO,
AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE);
- mController.done();
+ mController.done(mActivity);
assertThat(appLinks.findViewById(R.id.left_button).getContentDescription())
.isEqualTo("App Info");
@@ -258,7 +257,7 @@
.setButtonActions(
AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
AppHeaderController.ActionType.ACTION_NONE);
- mController.done();
+ mController.done(mActivity);
assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
.isEqualTo(View.VISIBLE);
@@ -272,32 +271,19 @@
public void instantApps_normalAppsDontGetLabel() {
final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
mController = new AppHeaderController(mContext, mFragment, appHeader);
- mController.done();
+ mController.done(mActivity);
assertThat(appHeader.findViewById(R.id.install_type).getVisibility())
.isEqualTo(View.GONE);
}
- // Ensure that the instant app label does not show up when we haven't told the controller the
- // app is instant.
- @Test
- public void instantApps_normalAppsDontGetInstantAppsBadge() {
- final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
- mController = new AppHeaderController(mContext, mFragment, appHeader);
- mController.done();
- assertThat(appHeader.findViewById(R.id.app_icon_instant_apps_badge).getVisibility())
- .isEqualTo(View.GONE);
- }
-
// Test that the "instant apps" label is present in the header when we have an instant app.
@Test
public void instantApps_expectedHeaderItem() {
final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
mController = new AppHeaderController(mContext, mFragment, appHeader);
mController.setIsInstantApp(true);
- mController.done();
- TextView label = (TextView)appHeader.findViewById(R.id.install_type);
- ImageView badgeView = appHeader.findViewById(R.id.app_icon_instant_apps_badge);
- assertThat(badgeView.getVisibility()).isEqualTo(View.VISIBLE);
+ mController.done(mActivity);
+ TextView label = appHeader.findViewById(R.id.install_type);
assertThat(label.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(label.getText()).isEqualTo(
appHeader.getResources().getString(R.string.install_type_instant));
@@ -306,6 +292,30 @@
}
@Test
+ public void styleActionBar_invalidObjects_shouldNotCrash() {
+ mController = new AppHeaderController(mShadowContext, mFragment, null);
+ mController.styleActionBar(null);
+
+ when(mActivity.getActionBar()).thenReturn(null);
+ mController.styleActionBar(mActivity);
+
+ verify(mActivity).getActionBar();
+ }
+
+ @Test
+ public void styleActionBar_setElevationAndBackground() {
+ final ActionBar actionBar = mActivity.getActionBar();
+
+ mController = new AppHeaderController(mShadowContext, mFragment, null);
+ mController.styleActionBar(mActivity);
+
+ verify(actionBar).setElevation(0);
+ // Enforce a color drawable as background here, as image based drawables might not be
+ // wide enough to cover entire action bar.
+ verify(actionBar).setBackgroundDrawable(any(ColorDrawable.class));
+ }
+
+ @Test
public void initAppHeaderController_appHeaderNull_useFragmentContext() {
mController = new AppHeaderController(mContext, mFragment, null);
diff --git a/tests/robotests/src/com/android/settings/applications/FetchPackageStorageAsyncLoaderTest.java b/tests/robotests/src/com/android/settings/applications/FetchPackageStorageAsyncLoaderTest.java
index 04eeb02..36116c0 100644
--- a/tests/robotests/src/com/android/settings/applications/FetchPackageStorageAsyncLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/applications/FetchPackageStorageAsyncLoaderTest.java
@@ -40,6 +40,8 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
+import java.io.IOException;
+
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class FetchPackageStorageAsyncLoaderTest {
@@ -56,7 +58,7 @@
}
@Test
- public void worksForValidPackageNameAndUid() {
+ public void worksForValidPackageNameAndUid() throws Exception {
AppStorageStats stats = mock(AppStorageStats.class);
when(stats.getCodeBytes()).thenReturn(1L);
when(stats.getDataBytes()).thenReturn(2L);
@@ -72,9 +74,9 @@
}
@Test
- public void installerExceptionHandledCleanly() {
+ public void installerExceptionHandledCleanly() throws Exception {
when(mSource.getStatsForPackage(anyString(), anyString(), any(UserHandle.class))).
- thenThrow(new IllegalStateException("intentional failure"));
+ thenThrow(new IOException("intentional failure"));
ApplicationInfo info = new ApplicationInfo();
info.packageName = PACKAGE_NAME;
FetchPackageStorageAsyncLoader task = new FetchPackageStorageAsyncLoader(
diff --git a/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
index 9bc7482..6440141 100644
--- a/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
@@ -81,7 +81,7 @@
}
@Test
- public void storageShouldRepresentStorageStatsQuery() {
+ public void storageShouldRepresentStorageStatsQuery() throws Exception {
when(mSource.getExternalStorageStats(any(String.class), any(UserHandle.class))).thenReturn(
new StorageStatsSource.ExternalStorageStats(1, 1, 0, 0));
diff --git a/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java
index 1182762..728a8a5 100644
--- a/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java
@@ -16,7 +16,16 @@
package com.android.settings.applications.assist;
+import android.Manifest;
+import android.app.SearchManager;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.provider.Settings;
import com.android.settings.SettingsRobolectricTestRunner;
@@ -24,6 +33,8 @@
import com.android.settings.applications.defaultapps.DefaultAppInfo;
import com.android.settings.testutils.shadow.ShadowSecureSettings;
+import java.util.ArrayList;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,6 +43,13 @@
import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -39,6 +57,10 @@
@Mock
private Context mContext;
+ @Mock
+ private SearchManager mSearchManager;
+ @Mock
+ private PackageManager mPackageManager;
private DefaultAssistPreferenceController mController;
@Before
@@ -61,4 +83,33 @@
assertThat(appInfo.getKey()).isEqualTo(flattenKey);
}
+
+ @Test
+ public void getSettingIntent_noSettingsActivity_shouldNotCrash() {
+ final String flattenKey = "com.android.settings/assist";
+ ShadowSecureSettings.putString(null, Settings.Secure.ASSISTANT, flattenKey);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ DefaultAssistPreferenceController controller =
+ spy(new DefaultAssistPreferenceController(mContext));
+ final ResolveInfo resolveInfo = new ResolveInfo();
+ resolveInfo.activityInfo = new ActivityInfo();
+ resolveInfo.activityInfo.name = "assist";
+ resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
+ resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
+ when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
+ .thenReturn(resolveInfo);
+ when(mContext.getSystemService(Context.SEARCH_SERVICE)).thenReturn(mSearchManager);
+ when(mSearchManager.getAssistIntent(anyBoolean())).thenReturn(mock(Intent.class));
+ final ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.permission = Manifest.permission.BIND_VOICE_INTERACTION;
+ resolveInfo.serviceInfo = serviceInfo;
+ final List<ResolveInfo> services = new ArrayList<>();
+ services.add(resolveInfo);
+ when(mPackageManager.queryIntentServices(any(Intent.class), anyInt())).thenReturn(services);
+ doReturn(null).when(controller).getAssistSettingsActivity(
+ ComponentName.unflattenFromString(flattenKey), resolveInfo, mPackageManager);
+
+ controller.getSettingIntent(null);
+ // should not crash
+ }
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
index 7761afc..074bef2 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
@@ -15,12 +15,15 @@
*/
package com.android.settings.bluetooth;
+import android.content.ComponentName;
import android.content.Context;
+import android.os.UserManager;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.widget.MasterSwitchController;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import org.junit.Before;
@@ -30,30 +33,108 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
+import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertEquals;
import static org.mockito.Mockito.mock;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class BluetoothEnablerTest {
+ private static final EnforcedAdmin FAKE_ENFORCED_ADMIN =
+ new EnforcedAdmin(new ComponentName("test.package", "test.Class"), 10);
+
@Mock
private MetricsFeatureProvider mMetricsFeatureProvider;
@Mock
private Context mContext;
+ @Mock
+ private MasterSwitchController mMasterSwitchController;
+ @Mock
+ private RestrictionUtils mRestrictionUtils;
+
+ private BluetoothEnabler mBluetoothEnabler;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mBluetoothEnabler = new BluetoothEnabler(
+ mContext,
+ mMasterSwitchController,
+ mMetricsFeatureProvider,
+ mock(LocalBluetoothManager.class),
+ 123,
+ mRestrictionUtils);
}
@Test
public void onSwitchToggled_shouldLogActionWithSuppliedEvent() {
- BluetoothEnabler bluetoothEnabler = new BluetoothEnabler(mContext,
- mock(MasterSwitchController.class), mMetricsFeatureProvider,
- mock(LocalBluetoothManager.class), 123);
- bluetoothEnabler.onSwitchToggled(false);
+ // WHEN the switch is toggled...
+ mBluetoothEnabler.onSwitchToggled(false);
+ // THEN the corresponding metrics action is logged.
verify(mMetricsFeatureProvider).action(mContext, 123, false);
}
+
+ @Test
+ public void maybeEnforceRestrictions_noRestrictions() {
+ // GIVEN there are no restrictions set...
+ when(mRestrictionUtils.checkIfRestrictionEnforced(any(Context.class), any(String.class)))
+ .thenReturn(null);
+
+ // WHEN the maybeEnforceRestrictions is called...
+ // THEN false is returned to indicate there was no restriction to enforce
+ assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isFalse();
+
+ // THEN a null EnfoceAdmin is set.
+ verify(mMasterSwitchController).setDisabledByAdmin(null);
+ // THEN the state of the switch isn't changed.
+ verify(mMasterSwitchController, never()).setChecked(anyBoolean());
+ }
+
+ @Test
+ public void maybeEnforceRestrictions_disallowBluetoothRestrictionSet() {
+ // GIVEN Bluetooth has been disallowed...
+ when(mRestrictionUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_BLUETOOTH)).thenReturn(FAKE_ENFORCED_ADMIN);
+ when(mRestrictionUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_CONFIG_BLUETOOTH)).thenReturn(null);
+
+ // WHEN the maybeEnforceRestrictions is called...
+ // THEN true is returned to indicate there was a restriction to enforce.
+ assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isTrue();
+
+ // THEN the expected EnfoceAdmin is set.
+ verify(mMasterSwitchController).setDisabledByAdmin(FAKE_ENFORCED_ADMIN);
+
+ // THEN the switch is unchecked.
+ verify(mMasterSwitchController).setChecked(false);
+ }
+
+ @Test
+ public void maybeEnforceRestrictions_disallowConfigBluetoothRestrictionSet() {
+ // GIVEN configuring Bluetooth has been disallowed...
+ when(mRestrictionUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_BLUETOOTH)).thenReturn(null);
+ when(mRestrictionUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_CONFIG_BLUETOOTH)).thenReturn(FAKE_ENFORCED_ADMIN);
+
+ // WHEN the maybeEnforceRestrictions is called...
+ // THEN true is returned to indicate there was a restriction to enforce.
+ assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isTrue();
+
+ // THEN the expected EnfoceAdmin is set.
+ verify(mMasterSwitchController).setDisabledByAdmin(FAKE_ENFORCED_ADMIN);
+
+ // THEN the switch is unchecked.
+ verify(mMasterSwitchController).setChecked(false);
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceControllerTest.java
index 0e39c5d..177130e 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceControllerTest.java
@@ -52,6 +52,8 @@
private PreferenceScreen mScreen;
@Mock
private MasterSwitchPreference mPreference;
+ @Mock
+ private RestrictionUtils mRestrictionUtils;
private Context mContext;
private BluetoothMasterSwitchPreferenceController mController;
@@ -60,7 +62,8 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application.getApplicationContext();
- mController = new BluetoothMasterSwitchPreferenceController(mContext, mBluetoothManager);
+ mController = new BluetoothMasterSwitchPreferenceController(
+ mContext, mBluetoothManager, mRestrictionUtils);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java
index b3253f9..0c9988b 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java
@@ -18,6 +18,10 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
import android.os.storage.StorageManager;
import android.provider.SearchIndexableResource;
@@ -56,6 +60,15 @@
}
@Test
+ public void test_initializeOptionsMenuInvalidatesExistingMenu() {
+ Activity activity = mock(Activity.class);
+
+ mFragment.initializeOptionsMenu(activity);
+
+ verify(activity).invalidateOptionsMenu();
+ }
+
+ @Test
public void testSearchIndexProvider_shouldIndexResource() {
final List<SearchIndexableResource> indexRes =
StorageDashboardFragment.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageSettingsTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageSettingsTest.java
index 95f9fbe..17abab1 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/StorageSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageSettingsTest.java
@@ -70,7 +70,7 @@
}
@Test
- public void updateSummary_shouldDisplayUsedPercentAndFreeSpace() {
+ public void updateSummary_shouldDisplayUsedPercentAndFreeSpace() throws Exception {
final SummaryLoader loader = mock(SummaryLoader.class);
final SummaryLoader.SummaryProvider provider =
StorageSettings.SUMMARY_PROVIDER_FACTORY.createSummaryProvider(mActivity, loader);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index 47faf92..2231c22 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -242,21 +242,19 @@
eq(StorageItemPreferenceController.FILES_KEY))).thenReturn(files);
mController.displayPreference(screen);
- mController.setSystemSize(KILOBYTE * 6);
+ mController.setUsedSize(KILOBYTE * 200); // There should 87kB attributed.
StorageAsyncLoader.AppsStorageResult result = new StorageAsyncLoader.AppsStorageResult();
result.gamesSize = KILOBYTE * 8;
result.videoAppsSize = KILOBYTE * 16;
result.musicAppsSize = KILOBYTE * 4;
result.otherAppsSize = KILOBYTE * 9;
- result.systemSize = KILOBYTE * 10;
+ result.systemSize = KILOBYTE * 10; // This value is ignored and overriden now.
result.externalStats = new StorageStatsSource.ExternalStorageStats(
KILOBYTE * 50, // total
KILOBYTE * 10, // audio
KILOBYTE * 15, // video
KILOBYTE * 20); // image
- result.gamesSize = KILOBYTE * 8;
- result.otherAppsSize = KILOBYTE * 9;
mController.onLoadFinished(result);
assertThat(audio.getSummary().toString()).isEqualTo("14.00KB"); // 4KB apps + 10KB files
@@ -264,7 +262,7 @@
assertThat(games.getSummary().toString()).isEqualTo("8.00KB");
assertThat(movies.getSummary().toString()).isEqualTo("16.00KB");
assertThat(apps.getSummary().toString()).isEqualTo("9.00KB");
- assertThat(system.getSummary().toString()).isEqualTo("16.00KB");
+ assertThat(system.getSummary().toString()).isEqualTo("113KB");
assertThat(files.getSummary().toString()).isEqualTo("5.00KB");
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index 03892a3..801034c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -17,7 +17,18 @@
package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -25,12 +36,12 @@
import android.graphics.drawable.Drawable;
import android.os.BatteryStats;
import android.os.Bundle;
-import android.os.UserHandle;
import android.view.View;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.SettingsActivity;
+import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.applications.AppHeaderController;
import com.android.settings.applications.LayoutPreference;
@@ -46,22 +57,10 @@
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AdvancedPowerUsageDetailTest {
private static final String APP_LABEL = "app label";
@@ -77,6 +76,8 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Activity mActivity;
@Mock
private AppHeaderController mAppHeaderController;
@Mock
@@ -86,8 +87,6 @@
@Mock
private ApplicationsState.AppEntry mAppEntry;
@Mock
- private Drawable mIconDrawable;
- @Mock
private Bundle mBundle;
@Mock
private BatteryEntry mBatteryEntry;
@@ -111,6 +110,7 @@
mFragment = spy(new AdvancedPowerUsageDetail());
doReturn(mContext).when(mFragment).getContext();
+ doReturn(mActivity).when(mFragment).getActivity();
doReturn(SUMMARY).when(mFragment).getString(anyInt());
doReturn(APP_LABEL).when(mBundle).getString(anyString());
doReturn(mBundle).when(mFragment).getArguments();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java
new file mode 100644
index 0000000..799dab9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.BatteryManager;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.Utils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BatteryBroadcastReceiverTest {
+ private static final String BATTERY_INIT_LEVEL = "100%";
+ private static final String BATTERY_INIT_STATUS = "Not charging";
+ private static final int BATTERY_INTENT_LEVEL = 80;
+ private static final int BATTERY_INTENT_SCALE = 100;
+
+ @Mock
+ private BatteryBroadcastReceiver.OnBatteryChangedListener mBatteryListener;
+ private BatteryBroadcastReceiver mBatteryBroadcastReceiver;
+ private Context mContext;
+ private Intent mChargingIntent;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+
+ mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(mContext);
+ mBatteryBroadcastReceiver.mBatteryLevel = BATTERY_INIT_LEVEL;
+ mBatteryBroadcastReceiver.mBatteryStatus = BATTERY_INIT_STATUS;
+ mBatteryBroadcastReceiver.setBatteryChangedListener(mBatteryListener);
+
+ mChargingIntent = new Intent(Intent.ACTION_BATTERY_CHANGED);
+ mChargingIntent.putExtra(BatteryManager.EXTRA_LEVEL, BATTERY_INTENT_LEVEL);
+ mChargingIntent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_INTENT_SCALE);
+ mChargingIntent.putExtra(BatteryManager.EXTRA_STATUS,
+ BatteryManager.BATTERY_STATUS_CHARGING);
+ }
+
+ @Test
+ public void testOnReceive_batteryDataChanged_dataUpdated() {
+ mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
+
+ assertThat(mBatteryBroadcastReceiver.mBatteryLevel).isEqualTo(
+ Utils.getBatteryPercentage(mChargingIntent));
+ assertThat(mBatteryBroadcastReceiver.mBatteryStatus).isEqualTo(
+ Utils.getBatteryStatus(mContext.getResources(), mChargingIntent));
+ verify(mBatteryListener).onBatteryChanged();
+ }
+
+ @Test
+ public void testOnReceive_batteryDataNotChanged_listenerNotInvoked() {
+ final String batteryLevel = Utils.getBatteryPercentage(mChargingIntent);
+ final String batteryStatus = Utils.getBatteryStatus(mContext.getResources(),
+ mChargingIntent);
+ mBatteryBroadcastReceiver.mBatteryLevel = batteryLevel;
+ mBatteryBroadcastReceiver.mBatteryStatus = batteryStatus;
+
+ mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
+
+ assertThat(mBatteryBroadcastReceiver.mBatteryLevel).isEqualTo(batteryLevel);
+ assertThat(mBatteryBroadcastReceiver.mBatteryStatus).isEqualTo(batteryStatus);
+ verify(mBatteryListener, never()).onBatteryChanged();
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java
index 4216d57..66d2c1a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java
@@ -17,6 +17,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.UserManager;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatterySipper.DrainType;
@@ -75,6 +76,8 @@
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
@Mock
private PackageManager mPackageManager;
+ @Mock
+ private UserManager mUserManager;
private PowerUsageAdvanced mPowerUsageAdvanced;
private PowerUsageData mPowerUsageData;
private Context mShadowContext;
@@ -104,6 +107,7 @@
doReturn(STUB_STRING).when(mPowerUsageAdvanced).getString(anyInt(), any());
mPowerUsageAdvanced.setPackageManager(mPackageManager);
mPowerUsageAdvanced.setPowerUsageFeatureProvider(mPowerUsageFeatureProvider);
+ mPowerUsageAdvanced.setUserManager(mUserManager);
mPowerUsageData = new PowerUsageData(UsageType.APP);
mMaxBatterySipper.totalPowerMah = TYPE_BLUETOOTH_USAGE;
@@ -225,25 +229,68 @@
}
@Test
- public void testShouldHide_typeUnAccounted_returnTrue() {
+ public void testShouldHideCategory_typeUnAccounted_returnTrue() {
mPowerUsageData.usageType = UsageType.UNACCOUNTED;
- assertThat(mPowerUsageAdvanced.shouldHide(mPowerUsageData)).isTrue();
+ assertThat(mPowerUsageAdvanced.shouldHideCategory(mPowerUsageData)).isTrue();
}
-
@Test
- public void testShouldHide_typeOverCounted_returnTrue() {
+ public void testShouldHideCategory_typeOverCounted_returnTrue() {
mPowerUsageData.usageType = UsageType.OVERCOUNTED;
- assertThat(mPowerUsageAdvanced.shouldHide(mPowerUsageData)).isTrue();
+ assertThat(mPowerUsageAdvanced.shouldHideCategory(mPowerUsageData)).isTrue();
}
-
@Test
- public void testShouldHide_typeNormal_returnFalse() {
+ public void testShouldHideCategory_typeUserAndOnlyOne_returnTrue() {
+ mPowerUsageData.usageType = UsageType.USER;
+ doReturn(1).when(mUserManager).getUserCount();
+
+ assertThat(mPowerUsageAdvanced.shouldHideCategory(mPowerUsageData)).isTrue();
+ }
+
+ @Test
+ public void testShouldHideCategory_typeUserAndMoreThanOne_returnFalse() {
+ mPowerUsageData.usageType = UsageType.USER;
+ doReturn(2).when(mUserManager).getUserCount();
+
+ assertThat(mPowerUsageAdvanced.shouldHideCategory(mPowerUsageData)).isFalse();
+ }
+
+ @Test
+ public void testShouldHideCategory_typeNormal_returnFalse() {
mPowerUsageData.usageType = UsageType.APP;
- assertThat(mPowerUsageAdvanced.shouldHide(mPowerUsageData)).isFalse();
+ assertThat(mPowerUsageAdvanced.shouldHideCategory(mPowerUsageData)).isFalse();
}
+
+ @Test
+ public void testShouldHideSummary_typeCell_returnTrue() {
+ mPowerUsageData.usageType = UsageType.CELL;
+
+ assertThat(mPowerUsageAdvanced.shouldHideSummary(mPowerUsageData)).isTrue();
+ }
+
+ @Test
+ public void testShouldHideSummary_typeNormal_returnFalse() {
+ mPowerUsageData.usageType = UsageType.APP;
+
+ assertThat(mPowerUsageAdvanced.shouldHideSummary(mPowerUsageData)).isFalse();
+ }
+
+ @Test
+ public void testShouldShowBatterySipper_typeScreen_returnFalse() {
+ mNormalBatterySipper.drainType = DrainType.SCREEN;
+
+ assertThat(mPowerUsageAdvanced.shouldShowBatterySipper(mNormalBatterySipper)).isFalse();
+ }
+
+ @Test
+ public void testShouldShowBatterySipper_typeNormal_returnTrue() {
+ mNormalBatterySipper.drainType = DrainType.APP;
+
+ assertThat(mPowerUsageAdvanced.shouldShowBatterySipper(mNormalBatterySipper)).isTrue();
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java b/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
index 7cd76d3..ee6ef69 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
@@ -19,9 +19,7 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -39,6 +37,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -50,19 +49,21 @@
private Menu mMenu;
@Mock
private MenuItem mMenuItem;
+ @Mock
+ private NetworkResetRestrictionChecker mRestrictionChecker;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mController = spy(new NetworkResetActionMenuController(mContext));
+ mController = new NetworkResetActionMenuController(mContext);
+ ReflectionHelpers.setField(mController, "mRestrictionChecker", mRestrictionChecker);
when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem);
}
@Test
public void buildMenuItem_available_shouldAddToMenu() {
- doReturn(true).when(mController).isAvailable();
-
+ when(mRestrictionChecker.hasRestriction()).thenReturn(false);
mController.buildMenuItem(mMenu);
verify(mMenu).add(anyInt(), anyInt(), anyInt(), anyInt());
@@ -71,7 +72,7 @@
@Test
public void buildMenuItem_notAvailable_shouldNotAddToMenu() {
- doReturn(false).when(mController).isAvailable();
+ when(mRestrictionChecker.hasRestriction()).thenReturn(true);
mController.buildMenuItem(mMenu);
diff --git a/tests/robotests/src/com/android/settings/network/NetworkResetRestrictionCheckerTest.java b/tests/robotests/src/com/android/settings/network/NetworkResetRestrictionCheckerTest.java
new file mode 100644
index 0000000..b1c88d5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/NetworkResetRestrictionCheckerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class NetworkResetRestrictionCheckerTest {
+
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private Context mContext;
+ private NetworkResetRestrictionChecker mRestrictionChecker;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ mRestrictionChecker = spy(new NetworkResetRestrictionChecker(mContext));
+ }
+
+ @Test
+ public void testHasRestriction_notAdmin_shouldReturnTrue() {
+ final Context context = mock(Context.class);
+ when(context.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mUserManager.isAdminUser()).thenReturn(false);
+
+ assertThat(mRestrictionChecker.hasRestriction()).isTrue();
+ }
+
+ @Test
+ public void testHasRestriction_hasUserRestriction_shouldReturnTrue() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ doReturn(true).when(mRestrictionChecker).hasUserBaseRestriction();
+ doReturn(false).when(mRestrictionChecker).isRestrictionEnforcedByAdmin();
+
+ assertThat(mRestrictionChecker.hasRestriction()).isTrue();
+ }
+
+ @Test
+ public void testHasRestriction_hasAdminRestriction_shouldReturnTrue() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ doReturn(false).when(mRestrictionChecker).hasUserBaseRestriction();
+ doReturn(true).when(mRestrictionChecker).isRestrictionEnforcedByAdmin();
+
+ assertThat(mRestrictionChecker.hasRestriction()).isTrue();
+ }
+
+ @Test
+ public void testHasRestriction_noRestriction_shouldReturnFalse() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ doReturn(false).when(mRestrictionChecker).hasUserBaseRestriction();
+ doReturn(false).when(mRestrictionChecker).isRestrictionEnforcedByAdmin();
+
+ assertThat(mRestrictionChecker.hasRestriction()).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/utils/ThreadUtilsTest.java b/tests/robotests/src/com/android/settings/utils/ThreadUtilsTest.java
index 4267ed1..4ee42e0 100644
--- a/tests/robotests/src/com/android/settings/utils/ThreadUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/utils/ThreadUtilsTest.java
@@ -16,16 +16,17 @@
package com.android.settings.utils;
-import com.android.settings.TestConfig;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
-@RunWith(RobolectricTestRunner.class)
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ThreadUtilsTest {
diff --git a/tests/robotests/src/com/android/settings/widget/MasterSwitchPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/MasterSwitchPreferenceTest.java
index e4d303c..3747dda 100644
--- a/tests/robotests/src/com/android/settings/widget/MasterSwitchPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/MasterSwitchPreferenceTest.java
@@ -91,6 +91,19 @@
}
@Test
+ public void setSwitchEnabled_shouldUpdateButtonEnabledState_beforeViewBound() {
+ final MasterSwitchPreference preference = new MasterSwitchPreference(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ LayoutInflater.from(mContext).inflate(
+ R.layout.preference_widget_master_switch, null));
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+
+ preference.setSwitchEnabled(false);
+ preference.onBindViewHolder(holder);
+ assertThat(toggle.isEnabled()).isFalse();
+ }
+
+ @Test
public void clickWidgetView_shouldToggleButton() {
final MasterSwitchPreference preference = new MasterSwitchPreference(mContext);
final LayoutInflater inflater = LayoutInflater.from(mContext);
@@ -109,6 +122,22 @@
}
@Test
+ public void clickWidgetView_shouldNotToggleButtonIfDisabled() {
+ final MasterSwitchPreference preference = new MasterSwitchPreference(mContext);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+ inflater.inflate(R.layout.preference_two_target, null));
+ final LinearLayout widgetView = holder.itemView.findViewById(android.R.id.widget_frame);
+ inflater.inflate(R.layout.preference_widget_master_switch, widgetView, true);
+ final Switch toggle = (Switch) holder.findViewById(R.id.switchWidget);
+ preference.onBindViewHolder(holder);
+ toggle.setEnabled(false);
+
+ widgetView.performClick();
+ assertThat(toggle.isChecked()).isFalse();
+ }
+
+ @Test
public void clickWidgetView_shouldNotifyPreferenceChanged() {
final MasterSwitchPreference preference = new MasterSwitchPreference(mContext);
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
diff --git a/tests/robotests/src/com/android/settings/wifi/LinkablePreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/LinkablePreferenceTest.java
new file mode 100644
index 0000000..96cb217
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/LinkablePreferenceTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 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.support.v7.preference.PreferenceViewHolder;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.settings.LinkifyUtils;
+import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+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(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class LinkablePreferenceTest {
+
+ private static final String TITLE = "Title";
+
+ private Context mContext = RuntimeEnvironment.application;
+
+ private LinkablePreference mPreference;
+ private PreferenceViewHolder mHolder;
+ private View mView;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mPreference = new LinkablePreference(mContext);
+ final CharSequence linkableDescription =
+ mContext.getResources().getText(R.string.wifi_scan_notify_text);
+ final LinkifyUtils.OnClickListener clickListener = () -> {/* Do nothing */ };
+ mPreference.setText(TITLE, linkableDescription, clickListener);
+
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ mView = inflater.inflate(
+ mPreference.getLayoutResource(), new LinearLayout(mContext), false);
+ mHolder = PreferenceViewHolder.createInstanceForTests(mView);
+
+ mPreference.onBindViewHolder(mHolder);
+ }
+
+ @Test
+ public void prefWithLinkShouldHaveAccessibilityMovementMethodSet() {
+ TextView textView = mView.findViewById(android.R.id.title);
+ assertThat(textView.getMovementMethod()).isNotNull();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
index d6243ac..7df5c9a 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
@@ -17,6 +17,7 @@
package com.android.settings.wifi;
import static android.provider.Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED;
+import static android.provider.Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE;
import static android.provider.Settings.Global.WIFI_WAKEUP_ENABLED;
import static com.google.common.truth.Truth.assertThat;
@@ -29,6 +30,7 @@
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
+import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.core.lifecycle.Lifecycle;
@@ -52,6 +54,7 @@
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new WifiWakeupPreferenceController(mContext, mock(Lifecycle.class));
+ Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 1);
}
@Test
@@ -95,6 +98,7 @@
verify(preference).setChecked(true);
verify(preference).setEnabled(true);
+ verify(preference).setSummary(R.string.wifi_wakeup_summary);
}
@Test
@@ -107,5 +111,20 @@
verify(preference).setChecked(false);
verify(preference).setEnabled(false);
+ verify(preference).setSummary(R.string.wifi_wakeup_summary);
+ }
+
+ @Test
+ public void updateState_preferenceSetUncheckedAndSetDisabledWhenWifiScanningDisabled() {
+ final SwitchPreference preference = mock(SwitchPreference.class);
+ Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 1);
+ Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
+ Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+
+ mController.updateState(preference);
+
+ verify(preference).setChecked(true);
+ verify(preference).setEnabled(false);
+ verify(preference).setSummary(R.string.wifi_wakeup_summary_scanning_disabled);
}
}
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index efe0c1c..8d28dee 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -54,11 +54,13 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -73,6 +75,7 @@
private static final String SECURITY = "None";
private InetAddress mIpv4Address;
+ private Inet6Address mIpv6Address;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mockScreen;
@@ -113,6 +116,12 @@
try {
mIpv4Address = InetAddress.getByAddress(
new byte[] { (byte) 255, (byte) 255, (byte) 255, (byte) 255 });
+ mIpv6Address = Inet6Address.getByAddress(
+ "123", /* host */
+ new byte[] {
+ (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x11, 0x25,
+ (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte) 0x7C, (byte) 0xB2},
+ 1 /*scope id */);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
@@ -153,6 +162,8 @@
}
private void setupMockedPreferenceScreen() {
+ when(mockScreen.getPreferenceManager().getContext()).thenReturn(mContext);
+
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_CONNECTION_DETAIL_PREF))
.thenReturn(mockConnectionDetailPref);
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF))
@@ -420,4 +431,30 @@
verify(mockActivity).finish();
}
+
+ @Test
+ public void ipv6AddressPref_shouldHaveHostAddressTextSet() {
+ LinkAddress ipv6Address = new LinkAddress(mIpv6Address, 128);
+
+ mLinkProperties.addLinkAddress(ipv6Address);
+
+ mController.onResume();
+
+ ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(Preference.class);
+ verify(mockIpv6AddressCategory).addPreference(preferenceCaptor.capture());
+ assertThat(preferenceCaptor.getValue().getTitle()).isEqualTo(mIpv6Address.getHostAddress());
+ }
+
+ @Test
+ public void ipv6AddressPref_shouldNotBeSelectable() {
+ LinkAddress ipv6Address = new LinkAddress(mIpv6Address, 128);
+
+ mLinkProperties.addLinkAddress(ipv6Address);
+
+ mController.onResume();
+
+ ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(Preference.class);
+ verify(mockIpv6AddressCategory).addPreference(preferenceCaptor.capture());
+ assertThat(preferenceCaptor.getValue().isSelectable()).isFalse();
+ }
}
diff --git a/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java b/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java
new file mode 100644
index 0000000..70087ae
--- /dev/null
+++ b/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 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;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.RootMatchers.isDialog;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static junit.framework.Assert.fail;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RegulatoryInfoDisplayActivityTest {
+
+ private Instrumentation mInstrumentation;
+ private Intent mRegulatoryInfoIntent;
+
+ @Before
+ public void setUp() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mRegulatoryInfoIntent = new Intent("android.settings.SHOW_REGULATORY_INFO")
+ .addCategory(Intent.CATEGORY_DEFAULT)
+ .setPackage(mInstrumentation.getTargetContext().getPackageName());
+ }
+
+ @Test
+ public void resolveRegulatoryInfoIntent_intentShouldMatchConfig() {
+ // Load intent from PackageManager and load config from Settings app
+ final Context context = mInstrumentation.getTargetContext();
+
+ final boolean hasRegulatoryInfo = context.getResources()
+ .getBoolean(R.bool.config_show_regulatory_info);
+ final ResolveInfo resolveInfo = mInstrumentation.getTargetContext().getPackageManager()
+ .resolveActivity(mRegulatoryInfoIntent, 0 /* flags */);
+
+ // Check config and intent both enable or both disabled.
+ if (hasRegulatoryInfo && resolveInfo == null) {
+ fail("Config enables regulatory info but there is no handling intent");
+ return;
+ }
+ if (!hasRegulatoryInfo && resolveInfo != null) {
+ fail("Config disables regulatory info but there is at least one handling intent");
+ return;
+ }
+ }
+
+ @Test
+ public void launchRegulatoryInfo_shouldNotCrash() {
+ final Context context = mInstrumentation.getTargetContext();
+ final boolean hasRegulatoryInfo = context.getResources()
+ .getBoolean(R.bool.config_show_regulatory_info);
+
+ if (!hasRegulatoryInfo) {
+ return;
+ }
+ // Launch intent
+ mInstrumentation.startActivitySync(mRegulatoryInfoIntent);
+
+ onView(withId(R.id.regulatoryInfo))
+ .inRoot(isDialog())
+ .check(matches(isDisplayed()));
+ }
+
+}
diff --git a/tests/unit/src/com/android/settings/WallpaperPreferenceLayoutTest.java b/tests/unit/src/com/android/settings/WallpaperPreferenceLayoutTest.java
deleted file mode 100644
index 4448307..0000000
--- a/tests/unit/src/com/android/settings/WallpaperPreferenceLayoutTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.LayoutInflater;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class WallpaperPreferenceLayoutTest {
- @Test
- public void testInflateWallpaperPreferenceLayout_doesNotCrash() {
- LayoutInflater.from(InstrumentationRegistry.getTargetContext())
- .inflate(R.layout.preference_wallpaper_type, null, false);
- }
-}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
index e82482e..546ea4b 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
@@ -180,8 +180,22 @@
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(0);
}
- private ApplicationInfo addPackage(
- String packageName, long cacheSize, long codeSize, long dataSize, int category) {
+ @Test
+ public void testRemovedPackageDoesNotCrash() throws Exception {
+ ApplicationInfo info = new ApplicationInfo();
+ info.packageName = PACKAGE_NAME_1;
+ info.category = ApplicationInfo.CATEGORY_UNDEFINED;
+ mInfo.add(info);
+ when(mSource.getStatsForPackage(anyString(), anyString(), any(UserHandle.class)))
+ .thenThrow(new IllegalStateException());
+
+ SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
+
+ // Should not crash.
+ }
+
+ private ApplicationInfo addPackage(String packageName, long cacheSize, long codeSize,
+ long dataSize, int category) throws Exception {
StorageStatsSource.AppStorageStats storageStats =
mock(StorageStatsSource.AppStorageStats.class);
when(storageStats.getCodeBytes()).thenReturn(codeSize);
diff --git a/tests/unit/src/com/android/settings/display/NightDisplaySettingsActivityTest.java b/tests/unit/src/com/android/settings/display/NightDisplaySettingsActivityTest.java
new file mode 100644
index 0000000..4011d9a
--- /dev/null
+++ b/tests/unit/src/com/android/settings/display/NightDisplaySettingsActivityTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 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.display;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.settings.Settings.NightDisplaySettingsActivity;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NightDisplaySettingsActivityTest {
+
+ private Context mTargetContext;
+
+ @Before
+ public void setUp() throws Exception {
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ mTargetContext = instrumentation.getTargetContext();
+ }
+
+ @Test
+ public void nightDisplaySettingsIntent_resolvesCorrectly() {
+ final boolean nightDisplayAvailable = mTargetContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_nightDisplayAvailable);
+ final PackageManager pm = mTargetContext.getPackageManager();
+ final Intent intent = new Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS);
+ final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+
+ if (nightDisplayAvailable) {
+ Assert.assertNotNull("No activity for " + Settings.ACTION_NIGHT_DISPLAY_SETTINGS, ri);
+ Assert.assertEquals(mTargetContext.getPackageName(), ri.activityInfo.packageName);
+ Assert.assertEquals(NightDisplaySettingsActivity.class.getName(),
+ ri.activityInfo.name);
+ } else {
+ Assert.assertNull("Should have no activity for "
+ + Settings.ACTION_NIGHT_DISPLAY_SETTINGS, ri);
+ }
+ }
+
+}