Snap for 5124112 from 3c7841c94a to qt-release
Change-Id: I226eea6f2a8d9f3d2caeb69ebeeaef6496dce78f
This commit is contained in:
@@ -911,7 +911,7 @@
|
||||
|
||||
<activity android:name=".Settings$MyDeviceInfoActivity"
|
||||
android:label="@string/about_settings"
|
||||
android:icon="@drawable/ic_settings_about"
|
||||
android:icon="@drawable/ic_homepage_about"
|
||||
android:parentActivityName="Settings">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.DEVICE_INFO_SETTINGS" />
|
||||
@@ -922,14 +922,6 @@
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="com.android.settings.SHORTCUT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.android.settings.action.SETTINGS" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.order" android:value="-270"/>
|
||||
<meta-data android:name="com.android.settings.category"
|
||||
android:value="com.android.settings.category.ia.system" />
|
||||
<meta-data android:name="com.android.settings.title"
|
||||
android:resource="@string/about_settings" />
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment" />
|
||||
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
|
||||
@@ -2962,16 +2954,6 @@
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<activity android:name="Settings$DirectoryAccessSettingsActivity"
|
||||
android:label="@string/directory_access">
|
||||
<intent-filter>
|
||||
<action android:name="android.settings.STORAGE_VOLUME_ACCESS_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.applications.manageapplications.ManageApplications" />
|
||||
</activity>
|
||||
|
||||
<provider android:name=".slices.SettingsSliceProvider"
|
||||
android:authorities="com.android.settings.slices;android.settings.slices"
|
||||
android:exported="true"
|
||||
|
||||
@@ -1029,7 +1029,7 @@
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="homepage_connected_device_background">#71A234</color>"
|
||||
errorLine1=" <color name="homepage_connected_device_background">#72B70F</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
@@ -1077,7 +1077,7 @@
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="homepage_display_background">#FFB600</color>"
|
||||
errorLine1=" <color name="homepage_display_background">#FFA727</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
@@ -1173,7 +1173,7 @@
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="homepage_system_background">#757575</color>"
|
||||
errorLine1=" <color name="homepage_system_background">#9E9E9E</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
@@ -1229,6 +1229,22 @@
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="homepage_about_background">#9FA8DA</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="129"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -1241,7 +1257,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="133"
|
||||
line="134"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1257,7 +1273,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="134"
|
||||
line="135"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1273,7 +1289,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="135"
|
||||
line="136"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1289,7 +1305,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="136"
|
||||
line="137"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1305,7 +1321,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="137"
|
||||
line="138"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1321,7 +1337,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="138"
|
||||
line="139"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1337,7 +1353,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="141"
|
||||
line="142"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1353,7 +1369,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="142"
|
||||
line="143"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1369,7 +1385,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="143"
|
||||
line="144"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1385,7 +1401,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="144"
|
||||
line="145"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1401,7 +1417,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="145"
|
||||
line="146"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1693,6 +1709,22 @@
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" android:color="@color/homepage_about_background" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/ic_homepage_about.xml"
|
||||
line="23"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
|
||||
36
res/drawable/ic_homepage_about.xml
Normal file
36
res/drawable/ic_homepage_about.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid
|
||||
android:color="@color/homepage_about_background" />
|
||||
<size
|
||||
android:width="@dimen/dashboard_tile_image_size"
|
||||
android:height="@dimen/dashboard_tile_image_size" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:width="@dimen/dashboard_tile_foreground_image_size"
|
||||
android:height="@dimen/dashboard_tile_foreground_image_size"
|
||||
android:start="@dimen/dashboard_tile_foreground_image_inset"
|
||||
android:top="@dimen/dashboard_tile_foreground_image_inset"
|
||||
android:drawable="@drawable/ic_phone_info" />
|
||||
</layer-list>
|
||||
9
res/drawable/ic_phone_info.xml
Normal file
9
res/drawable/ic_phone_info.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<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="#FFFFFFFF"
|
||||
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7v-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM11,7h2v2h-2V7zM11,11h2v6h-2V11z"/>
|
||||
</vector>
|
||||
@@ -1,113 +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.
|
||||
-->
|
||||
|
||||
<!-- Entity header -->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/entity_header"
|
||||
style="@style/EntityHeader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingBottom="24dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/entity_header_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="56dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/entity_header_icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:antialias="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/entity_header_title"
|
||||
style="@style/TextAppearance.EntityHeaderTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="false"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="start"
|
||||
android:textDirection="locale" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_type"
|
||||
style="@style/TextAppearance.EntityHeaderSummary"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/entity_header_summary"
|
||||
style="@style/TextAppearance.EntityHeaderSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/entity_header_second_summary"
|
||||
style="@style/TextAppearance.EntityHeaderSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/entity_header_links"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageButton
|
||||
android:id="@android:id/button1"
|
||||
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" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@android:id/button2"
|
||||
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>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -27,8 +27,6 @@
|
||||
<ImageView android:id="@+id/admin_support_icon"
|
||||
android:layout_width="@dimen/admin_details_dialog_icon_size"
|
||||
android:layout_height="@dimen/admin_details_dialog_icon_size"
|
||||
android:tint="?android:attr/colorAccent"
|
||||
android:src="@*android:drawable/ic_info"
|
||||
android:scaleType="fitCenter"
|
||||
android:contentDescription="@null" />
|
||||
<TextView android:id="@+id/admin_support_dialog_title"
|
||||
|
||||
@@ -24,16 +24,18 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/homepage_condition_full_card_height"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/homepage_card_padding_start"
|
||||
android:paddingEnd="@dimen/homepage_card_padding_end"
|
||||
android:paddingTop="@dimen/homepage_condition_full_card_padding_top"
|
||||
android:paddingBottom="@dimen/homepage_condition_full_card_padding_bottom"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@dimen/suggestion_card_icon_size"
|
||||
android:layout_height="@dimen/suggestion_card_icon_size"
|
||||
android:layout_width="@dimen/homepage_card_icon_size"
|
||||
android:layout_height="@dimen/homepage_card_icon_size"
|
||||
android:tint="?android:attr/colorAccent"/>
|
||||
|
||||
<LinearLayout
|
||||
@@ -59,13 +61,7 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="@dimen/homepage_condition_full_card_divider_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/homepage_condition_full_card_divider_padding_top"
|
||||
android:layout_marginBottom="@dimen/homepage_condition_full_card_divider_padding_bottom"
|
||||
android:background="?android:attr/dividerVertical" />
|
||||
<include layout="@layout/vertical_divider"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/first_action"
|
||||
|
||||
@@ -32,14 +32,16 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@dimen/suggestion_card_icon_size"
|
||||
android:layout_height="@dimen/suggestion_card_icon_size"
|
||||
android:layout_width="@dimen/homepage_card_icon_size"
|
||||
android:layout_height="@dimen/homepage_card_icon_size"
|
||||
android:tint="?android:attr/colorAccent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_marginTop="@dimen/homepage_condition_half_card_title_margin_top"
|
||||
android:layout_marginBottom="@dimen/homepage_condition_card_title_margin_bottom"
|
||||
style="@style/TextAppearance.ConditionCardTitle"/>
|
||||
@@ -48,6 +50,9 @@
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_marginBottom="@dimen/homepage_condition_half_card_summary_margin_bottom"
|
||||
style="@style/TextAppearance.ConditionCardSummary"/>
|
||||
|
||||
<include layout="@layout/horizontal_divider"/>
|
||||
|
||||
70
res/layout/homepage_suggestion_tile.xml
Normal file
70
res/layout/homepage_suggestion_tile.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/suggestion_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/ContextualCardStyle">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="112dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@dimen/homepage_card_icon_size"
|
||||
android:layout_height="@dimen/homepage_card_icon_size"
|
||||
style="@style/SuggestionCardIcon"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="6dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/SuggestionCardText"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.SuggestionTitle"
|
||||
android:fadingEdge="horizontal"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/SuggestionCardText"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.SuggestionSummary"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -16,60 +16,58 @@
|
||||
-->
|
||||
|
||||
<!-- Entity header -->
|
||||
<LinearLayout
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/entity_header"
|
||||
style="@style/EntityHeader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/preference_no_icon_padding_start"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingBottom="32dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/entity_header_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/entity_header_icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleType="fitXY"
|
||||
android:antialias="true" />
|
||||
android:antialias="true"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/entity_header_title"
|
||||
style="@style/TextAppearance.EntityHeaderTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="false"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="start"
|
||||
android:textDirection="locale" />
|
||||
android:textDirection="locale"
|
||||
android:layout_marginTop="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_type"
|
||||
style="@style/TextAppearance.EntityHeaderSummary"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/entity_header_summary"
|
||||
style="@style/TextAppearance.EntityHeaderSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/entity_header_second_summary"
|
||||
style="@style/TextAppearance.EntityHeaderSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -78,6 +76,8 @@
|
||||
android:id="@+id/entity_header_links"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageButton
|
||||
@@ -102,4 +102,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2018 The Android Open Source Project
|
||||
<!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -14,7 +15,9 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="directory_access_details"
|
||||
android:title="@string/directory_access"/>
|
||||
<View
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="@dimen/vertical_divider_width"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/dividerVertical"/>
|
||||
@@ -215,10 +215,12 @@
|
||||
<string-array name="wifi_security">
|
||||
<!-- The Wi-Fi network does not have any security. -->
|
||||
<item>@string/wifi_security_none</item>
|
||||
<item translatable="false">@string/wifi_security_owe</item>
|
||||
<item translatable="false">@string/wifi_security_wep</item>
|
||||
<item translatable="false">@string/wifi_security_psk_generic</item>
|
||||
<item translatable="false">@string/wifi_security_sae</item>
|
||||
<item translatable="false">@string/wifi_security_eap</item>
|
||||
|
||||
<item translatable="false">@string/wifi_security_eap_suiteb</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Match this with the constants in AccessPoint. --> <skip />
|
||||
@@ -228,6 +230,7 @@
|
||||
<item>@string/wifi_security_none</item>
|
||||
<item translatable="false">@string/wifi_security_wep</item>
|
||||
<item translatable="false">@string/wifi_security_psk_generic</item>
|
||||
<item translatable="false">@string/wifi_security_sae</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Security types for wireless tether -->
|
||||
|
||||
@@ -113,19 +113,20 @@
|
||||
|
||||
<!-- Dashboard/homepage icon background colors -->
|
||||
<color name="homepage_network_background">#2196F3</color>
|
||||
<color name="homepage_connected_device_background">#71A234</color>
|
||||
<color name="homepage_connected_device_background">#72B70F</color>
|
||||
<color name="homepage_app_and_notification_background">#FF7E0F</color>
|
||||
<color name="homepage_battery_background">#258982</color>
|
||||
<color name="homepage_display_background">#FFB600</color>
|
||||
<color name="homepage_display_background">#FFA727</color>
|
||||
<color name="homepage_sound_background">#01B1AF</color>
|
||||
<color name="homepage_storage_background">#C14CE6</color>
|
||||
<color name="homepage_security_background">#0F9D58</color>
|
||||
<color name="homepage_accounts_background">#F15B8D</color>
|
||||
<color name="homepage_accessibility_background">#5011C1</color>
|
||||
<color name="homepage_system_background">#757575</color>
|
||||
<color name="homepage_system_background">#9E9E9E</color>
|
||||
<color name="homepage_support_background">#26459C</color>
|
||||
<color name="homepage_generic_icon_background">#1A73E8</color>
|
||||
<color name="homepage_location_background">#2EC7DC</color>
|
||||
<color name="homepage_about_background">#9FA8DA</color>
|
||||
<!-- End of dashboard/homepage icon background colors -->
|
||||
|
||||
<color name="glif_error_color">@*android:color/material_red_A700</color>
|
||||
|
||||
@@ -134,14 +134,15 @@
|
||||
have distinct intensity levels -->
|
||||
<bool name="config_vibration_supports_multiple_intensities">false</bool>
|
||||
|
||||
<!--
|
||||
Whether or not the homepage should be powered by legacy suggestion (versus contextual cards)
|
||||
Default to true as not all devices support contextual cards.
|
||||
-->
|
||||
<bool name="config_use_legacy_suggestion">true</bool>
|
||||
|
||||
<!-- Whether or not homepage should display user's account avatar -->
|
||||
<bool name="config_show_avatar_in_homepage">false</bool>
|
||||
|
||||
<!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
|
||||
<bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
|
||||
|
||||
<!-- TODO(b/115429501): move those 3 configs to framework-->
|
||||
<!-- Show enabled lte option for lte device -->
|
||||
<bool name="config_enabled_lte" translatable="false">false</bool>
|
||||
<!-- Show enabled tdscdma option for device -->
|
||||
<bool name="config_support_tdscdma" translatable="false">false</bool>
|
||||
<!-- Show enabled tdscdma option for device when connect roaming network -->
|
||||
<string-array name="config_support_tdscdma_roaming_on_networks" translatable="false"></string-array>
|
||||
</resources>
|
||||
|
||||
@@ -303,17 +303,6 @@
|
||||
<dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
|
||||
<dimen name="condition_header_height">36dp</dimen>
|
||||
|
||||
<!-- Suggestion cards size and padding -->
|
||||
<dimen name="suggestion_card_icon_size">24dp</dimen>
|
||||
<dimen name="suggestion_card_outer_margin">14dp</dimen>
|
||||
<dimen name="suggestion_card_inner_margin">12dp</dimen>
|
||||
<dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
|
||||
<dimen name="suggestion_card_corner_radius">2dp</dimen>
|
||||
<dimen name="suggestion_card_icon_side_margin">12dp</dimen>
|
||||
<dimen name="suggestion_card_button_side_margin">8dp</dimen>
|
||||
<dimen name="suggestion_card_button_top_margin">16dp</dimen>
|
||||
<dimen name="suggestion_card_button_bottom_margin">18dp</dimen>
|
||||
|
||||
<!-- Condition cards size and padding -->
|
||||
<dimen name="condition_card_elevation">2dp</dimen>
|
||||
|
||||
@@ -331,6 +320,7 @@
|
||||
<dimen name="homepage_bottombar_fab_cradle">68dp</dimen>
|
||||
|
||||
<!-- Homepage cards size and padding -->
|
||||
<dimen name="homepage_card_icon_size">24dp</dimen>
|
||||
<dimen name="homepage_card_corner_radius">8dp</dimen>
|
||||
<dimen name="homepage_card_elevation">2dp</dimen>
|
||||
<dimen name="homepage_card_vertical_margin">4dp</dimen>
|
||||
@@ -343,6 +333,9 @@
|
||||
<dimen name="horizontal_divider_margin_bottom">8dp</dimen>
|
||||
<dimen name="horizontal_divider_height">.75dp</dimen>
|
||||
|
||||
<!-- Vertical divider size -->
|
||||
<dimen name="vertical_divider_width">.75dp</dimen>
|
||||
|
||||
<!-- Signal icon in NetworkSelectSetting -->
|
||||
<dimen name="signal_strength_icon_size">24dp</dimen>
|
||||
|
||||
@@ -351,11 +344,10 @@
|
||||
<dimen name="homepage_condition_half_card_height">150dp</dimen>
|
||||
<dimen name="homepage_condition_half_card_padding_top">12dp</dimen>
|
||||
<dimen name="homepage_condition_half_card_title_margin_top">12dp</dimen>
|
||||
<dimen name="homepage_condition_full_card_height">72dp</dimen>
|
||||
<dimen name="homepage_condition_half_card_summary_margin_bottom">12dp</dimen>
|
||||
<dimen name="homepage_condition_full_card_padding_start">24dp</dimen>
|
||||
<dimen name="homepage_condition_full_card_padding_end">24dp</dimen>
|
||||
<dimen name="homepage_condition_full_card_divider_width">.75dp</dimen>
|
||||
<dimen name="homepage_condition_full_card_divider_padding_top">12dp</dimen>
|
||||
<dimen name="homepage_condition_full_card_divider_padding_bottom">12dp</dimen>
|
||||
<dimen name="homepage_condition_full_card_padding_top">12dp</dimen>
|
||||
<dimen name="homepage_condition_full_card_padding_bottom">12dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -678,7 +678,7 @@
|
||||
<!-- check box to allow data usage when roaming [CHAR LIMIT=41] -->
|
||||
<string name="allow_data_usage_title">Allow data usage when roaming</string>
|
||||
<!-- mobile network settings screen, setting check box title -->
|
||||
<string name="roaming">Data roaming</string>
|
||||
<string name="roaming">Roaming</string>
|
||||
<!-- mobile network settings screen, setting option summary text when check box is selected -->
|
||||
<string name="roaming_enable">Connect to data services when roaming</string>
|
||||
<!-- mobile network settings screen, setting option summary text when check box is clear -->
|
||||
@@ -9964,14 +9964,12 @@
|
||||
<!-- UI debug setting: ANGLE enabled app has been set [CHAR LIMIT=NONE] -->
|
||||
<string name="angle_enabled_app_set">ANGLE enabled application: <xliff:g id="app_name" example="com.company.app">%1$s</xliff:g></string>
|
||||
|
||||
<!-- Title for Directory Access settings -->
|
||||
<string name="directory_access">Directory access</string>
|
||||
<!-- Keywords for Directory Access settings -->
|
||||
<string name="keywords_directory_access">directory access</string>
|
||||
|
||||
<!-- String used to describe the name of a directory in a volume; it must
|
||||
show both names, with the directory name wrapped in parenthesis -->
|
||||
<string name="directory_on_volume"><xliff:g id="volume" example="SD Card">%1$s</xliff:g> (<xliff:g id="directory" example="Movies">%2$s</xliff:g>)</string>
|
||||
<!-- UI debug setting: select an app to use updated graphics driver [CHAR LIMIT=100] -->
|
||||
<string name="updated_gfx_driver_dev_opt_in_app">Select app to use updated graphics driver</string>
|
||||
<!-- UI debug setting: no app selected to use updated GPU driver [CHAR LIMIT=100] -->
|
||||
<string name="updated_gfx_driver_dev_opt_in_app_not_set">No selected app to use updated graphics driver</string>
|
||||
<!-- UI debug setting: app selected to use updated graphics driver [CHAR LIMIT=NONE] -->
|
||||
<string name="updated_gfx_driver_dev_opt_in_app_set">Opt in application: <xliff:g id="app_name" example="com.company.app">%1$s</xliff:g></string>
|
||||
|
||||
<!-- Slices Strings -->
|
||||
|
||||
@@ -10010,11 +10008,6 @@
|
||||
<!-- Title for preference showing the name of the device. [CHAR LIMIT=60]-->
|
||||
<string name="my_device_info_device_name_preference_title">Device name</string>
|
||||
|
||||
<!-- Settings item title for automatic Bluetooth on while driving preference [CHAR LIMIT=35] -->
|
||||
<string name="bluetooth_on_while_driving_pref">Use Bluetooth when driving</string>
|
||||
<!-- Settings item summary for automatic Bluetooth on while driving preference [CHAR LIMIT=100] -->
|
||||
<string name="bluetooth_on_while_driving_summary">Turn on Bluetooth automatically when driving</string>
|
||||
|
||||
<!-- Title for Wifi Access settings [CHAR LIMIT=35] -->
|
||||
<string name="change_wifi_state_title">Wi-Fi control</string>
|
||||
|
||||
@@ -10187,9 +10180,6 @@
|
||||
<!-- Text for Network global [CHAR LIMIT=NONE] -->
|
||||
<string name="network_global">Global</string>
|
||||
|
||||
<!-- Configuration setting for world mode Format is <true;GID if any to be checked> [CHAR LIMIT=NONE] -->
|
||||
<string translatable="false" name="config_world_mode"/>
|
||||
|
||||
<!-- Available networks screen title/heading [CHAR LIMIT=NONE] -->
|
||||
<string name="label_available">Available networks</string>
|
||||
<!-- Mobile network settings screen, toast when searching for available networks [CHAR LIMIT=NONE] -->
|
||||
@@ -10260,6 +10250,8 @@
|
||||
<string name="mobile_data_usage_title">App data usage</string>
|
||||
<!-- Summary to show the current network mode is invalid. [CHAR LIMIT=NONE]-->
|
||||
<string name="mobile_network_mode_error">Invalid Network Mode <xliff:g id="networkModeId" example="0">%1$d</xliff:g>. Ignore.</string>
|
||||
<!-- Title for Apn settings in mobile network settings [CHAR LIMIT=60] -->
|
||||
<string name="mobile_network_apn_title">Access Point Names</string>
|
||||
|
||||
<!-- Available networks screen, summary when button disallowed due to permanent automatic mode [CHAR LIMIT=NONE] -->
|
||||
<string name="manual_mode_disallowed_summary">Unavailable when connected to <xliff:g id="carrier" example="verizon">%1$s</xliff:g></string>
|
||||
@@ -10281,4 +10273,9 @@
|
||||
</plurals>
|
||||
<!-- Title for no connected devices in connected device slice. [CHAR LIMIT=NONE] -->
|
||||
<string name="no_connected_devices">No connected devices</string>
|
||||
|
||||
<!-- UI debug setting: force desktop mode [CHAR LIMIT=50] -->
|
||||
<string name="force_desktop_mode">Force desktop mode</string>
|
||||
<!-- UI debug setting: force desktop mode summary [CHAR LIMIT=150] -->
|
||||
<string name="force_desktop_mode_summary">Force experimental desktop mode on secondary displays</string>
|
||||
</resources>
|
||||
|
||||
@@ -320,8 +320,9 @@
|
||||
|
||||
<style name="TextAppearance.EntityHeaderTitle"
|
||||
parent="@android:style/TextAppearance.Material.Subhead">
|
||||
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:textSize">20sp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.EntityHeaderSummary"
|
||||
@@ -331,6 +332,7 @@
|
||||
<item name="android:gravity">start</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:ellipsize">marquee</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.ZenOnboardingButton">
|
||||
@@ -350,16 +352,8 @@
|
||||
<style name="SuggestionCardIcon">
|
||||
<item name="android:layout_centerHorizontal">false</item>
|
||||
<item name="android:layout_alignParentStart">true</item>
|
||||
<item name="android:layout_marginStart">@dimen/suggestion_card_icon_side_margin</item>
|
||||
<item name="android:layout_marginEnd">@dimen/suggestion_card_icon_side_margin</item>
|
||||
</style>
|
||||
|
||||
<style name="SuggestionCardButton">
|
||||
<item name="android:layout_gravity">start</item>
|
||||
<item name="android:layout_marginStart">@dimen/suggestion_card_button_side_margin</item>
|
||||
<item name="android:layout_marginEnd">@dimen/suggestion_card_button_side_margin</item>
|
||||
<item name="android:layout_marginTop">@dimen/suggestion_card_button_top_margin</item>
|
||||
<item name="android:layout_marginBottom">@dimen/suggestion_card_button_bottom_margin</item>
|
||||
<item name="android:layout_marginStart">12dp</item>
|
||||
<item name="android:layout_marginEnd">12dp</item>
|
||||
</style>
|
||||
|
||||
<style name="FingerprintLayoutTheme">
|
||||
@@ -405,12 +399,10 @@
|
||||
</style>
|
||||
|
||||
<style name="EntityHeader">
|
||||
<item name="android:background">?android:attr/colorPrimary</item>
|
||||
<item name="android:gravity">center_horizontal</item>
|
||||
<item name="android:paddingTop">16dp</item>
|
||||
<item name="android:paddingStart">16dp</item>
|
||||
<item name="android:background">?android:attr/colorPrimaryDark</item>
|
||||
<item name="android:paddingTop">24dp</item>
|
||||
<item name="android:paddingBottom">16dp</item>
|
||||
<item name="android:paddingEnd">16dp</item>
|
||||
<item name="android:paddingBottom">8dp</item>
|
||||
</style>
|
||||
|
||||
<style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored"/>
|
||||
|
||||
@@ -44,14 +44,6 @@
|
||||
android:icon="@drawable/ic_android"
|
||||
android:order="-6"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="bluetooth_on_while_driving"
|
||||
android:title="@string/bluetooth_on_while_driving_pref"
|
||||
android:icon="@drawable/ic_settings_bluetooth"
|
||||
android:summary="@string/bluetooth_on_while_driving_summary"
|
||||
settings:controller="com.android.settings.connecteddevice.BluetoothOnWhileDrivingPreferenceController"
|
||||
android:order="-4"/>
|
||||
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="connected_device_printing"
|
||||
android:title="@string/print_settings"
|
||||
|
||||
@@ -422,6 +422,10 @@
|
||||
<Preference android:key="angle_enabled_app"
|
||||
android:title="@string/angle_enabled_app" />
|
||||
|
||||
<Preference android:key="updated_gfx_driver_dev_opt_in_app"
|
||||
android:summary="@string/updated_gfx_driver_dev_opt_in_app_summary"
|
||||
android:title="@string/updated_gfx_driver_dev_opt_in_app" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
@@ -510,6 +514,11 @@
|
||||
android:title="@string/enable_freeform_support"
|
||||
android:summary="@string/enable_freeform_support_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="force_desktop_mode_on_external_displays"
|
||||
android:title="@string/force_desktop_mode"
|
||||
android:summary="@string/force_desktop_mode_summary" />
|
||||
|
||||
<Preference
|
||||
android:key="reset_shortcut_manager_throttling"
|
||||
android:title="@string/reset_shortcut_manager_throttling" />
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2008 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">
|
||||
<!--We want separate APN setting from reset of settings because-->
|
||||
<!--we want user to change it with caution.-->
|
||||
<PreferenceCategory
|
||||
android:key="category_gsm_apn_key"
|
||||
android:layout="@layout/preference_category_no_label">
|
||||
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="button_gsm_apn_key"
|
||||
android:title="@string/apn_settings"
|
||||
android:persistent="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="carrier_settings_key"
|
||||
android:title="@string/carrier_settings_title">
|
||||
<!-- b/114749736, create a preference controller to build intent -->
|
||||
</PreferenceScreen>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -138,7 +138,7 @@
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="telephony_apn_key"
|
||||
android:persistent="false"
|
||||
android:title="@string/apn_settings"
|
||||
android:title="@string/mobile_network_apn_title"
|
||||
settings:allowDividerAbove="true"
|
||||
settings:controller="com.android.settings.network.telephony.ApnPreferenceController"/>
|
||||
|
||||
|
||||
@@ -19,13 +19,16 @@
|
||||
android:title="@string/print_print_job">
|
||||
|
||||
<Preference
|
||||
android:key="print_job_preference">
|
||||
android:key="print_job_preference"
|
||||
android:title="@string/print_print_job"
|
||||
settings:controller="com.android.settings.print.PrintJobPreferenceController">
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
android:key="print_job_message_preference"
|
||||
android:layout="@layout/print_job_summary"
|
||||
android:selectable="false">
|
||||
android:selectable="false"
|
||||
settings:controller="com.android.settings.print.PrintJobMessagePreferenceController">
|
||||
</Preference>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -120,16 +120,6 @@
|
||||
android:value="com.android.settings.Settings$VrListenersSettingsActivity" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
android:key="special_app_directory_access"
|
||||
android:title="@string/directory_access"
|
||||
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
|
||||
settings:keywords="@string/keywords_directory_access">
|
||||
<extra
|
||||
android:name="classname"
|
||||
android:value="com.android.settings.Settings$DirectoryAccessSettingsActivity" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
android:key="change_wifi_state"
|
||||
android:title="@string/change_wifi_state_title"
|
||||
|
||||
@@ -124,6 +124,15 @@
|
||||
android:order="10"
|
||||
android:fragment="com.android.settings.system.SystemDashboardFragment"/>
|
||||
|
||||
<Preference
|
||||
android:key="top_level_about_device"
|
||||
android:title="@string/about_settings"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:icon="@drawable/ic_homepage_about"
|
||||
android:order="20"
|
||||
android:fragment="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment"
|
||||
settings:controller="com.android.settings.deviceinfo.aboutphone.TopLevelAboutDevicePreferenceController"/>
|
||||
|
||||
<Preference
|
||||
android:key="top_level_support"
|
||||
android:summary="@string/support_summary"
|
||||
|
||||
@@ -120,7 +120,6 @@ public class Settings extends SettingsActivity {
|
||||
public static class PhotosStorageActivity extends SettingsActivity {
|
||||
/* empty */
|
||||
}
|
||||
public static class DirectoryAccessSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
public static class ApnSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class WifiCallingSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
@@ -18,8 +18,10 @@ package com.android.settings.accounts;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public interface AccountFeatureProvider {
|
||||
String getAccountType();
|
||||
Account[] getAccounts(Context context);
|
||||
Intent getAccountSettingsDeeplinkIntent();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.android.settings.accounts;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class AccountFeatureProviderImpl implements AccountFeatureProvider {
|
||||
@Override
|
||||
@@ -13,4 +14,9 @@ public class AccountFeatureProviderImpl implements AccountFeatureProvider {
|
||||
public Account[] getAccounts(Context context) {
|
||||
return new Account[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getAccountSettingsDeeplinkIntent() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,35 +17,81 @@
|
||||
package com.android.settings.accounts;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.SettingsHomepageActivity;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Avatar related work to the onStart method of registered observable classes
|
||||
* in {@link SettingsHomepageActivity}.
|
||||
*/
|
||||
public class AvatarViewMixin implements LifecycleObserver {
|
||||
private Context mContext;
|
||||
private ImageView mAvatarView;
|
||||
private static final String TAG = "AvatarViewMixin";
|
||||
|
||||
public AvatarViewMixin(Context context, ImageView avatarView) {
|
||||
mContext = context.getApplicationContext();
|
||||
@VisibleForTesting
|
||||
static final Intent INTENT_GET_ACCOUNT_DATA =
|
||||
new Intent("android.content.action.SETTINGS_ACCOUNT_DATA");
|
||||
|
||||
private static final String METHOD_GET_ACCOUNT_AVATAR = "getAccountAvatar";
|
||||
private static final String KEY_AVATAR_BITMAP = "account_avatar";
|
||||
private static final int REQUEST_CODE = 1013;
|
||||
|
||||
private final Context mContext;
|
||||
private final ImageView mAvatarView;
|
||||
private final MutableLiveData<Bitmap> mAvatarImage;
|
||||
|
||||
public AvatarViewMixin(SettingsHomepageActivity activity, ImageView avatarView) {
|
||||
mContext = activity.getApplicationContext();
|
||||
mAvatarView = avatarView;
|
||||
mAvatarView.setOnClickListener(v -> {
|
||||
if (hasAccount()) {
|
||||
//TODO(b/117509285) launch the new page of the MeCard
|
||||
} else {
|
||||
final Intent intent = FeatureFactory.getFactory(mContext)
|
||||
.getAccountFeatureProvider()
|
||||
.getAccountSettingsDeeplinkIntent();
|
||||
|
||||
if (intent != null) {
|
||||
activity.startActivityForResult(intent, REQUEST_CODE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mAvatarImage = new MutableLiveData<>();
|
||||
mAvatarImage.observe(activity, bitmap -> {
|
||||
avatarView.setImageBitmap(bitmap);
|
||||
});
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
public void onStart() {
|
||||
if (!mContext.getResources().getBoolean(R.bool.config_show_avatar_in_homepage)) {
|
||||
Log.d(TAG, "Feature disabled. Skipping");
|
||||
return;
|
||||
}
|
||||
if (hasAccount()) {
|
||||
//TODO(b/117509285): To migrate account icon on search bar
|
||||
loadAvatar();
|
||||
} else {
|
||||
mAvatarView.setImageResource(R.drawable.ic_account_circle_24dp);
|
||||
}
|
||||
@@ -57,4 +103,34 @@ public class AvatarViewMixin implements LifecycleObserver {
|
||||
mContext).getAccountFeatureProvider().getAccounts(mContext);
|
||||
return (accounts != null) && (accounts.length > 0);
|
||||
}
|
||||
|
||||
private void loadAvatar() {
|
||||
final String authority = queryProviderAuthority();
|
||||
if (TextUtils.isEmpty(authority)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
final Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(authority)
|
||||
.build();
|
||||
final Bundle bundle = mContext.getContentResolver().call(uri,
|
||||
METHOD_GET_ACCOUNT_AVATAR, null /* arg */, null /* extras */);
|
||||
final Bitmap bitmap = bundle.getParcelable(KEY_AVATAR_BITMAP);
|
||||
mAvatarImage.postValue(bitmap);
|
||||
});
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String queryProviderAuthority() {
|
||||
final List<ResolveInfo> providers =
|
||||
mContext.getPackageManager().queryIntentContentProviders(INTENT_GET_ACCOUNT_DATA,
|
||||
PackageManager.MATCH_SYSTEM_ONLY);
|
||||
if (providers.size() == 1) {
|
||||
return providers.get(0).providerInfo.authority;
|
||||
} else {
|
||||
Log.w(TAG, "The size of the provider is " + providers.size());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COLUMNS;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COL_PACKAGE;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
// TODO(b/72055774): add unit tests
|
||||
public class AppStateDirectoryAccessBridge extends AppStateBaseBridge {
|
||||
|
||||
private static final String TAG = "DirectoryAccessBridge";
|
||||
|
||||
// TODO(b/72055774): set to false once feature is ready (or use Log.isLoggable)
|
||||
static final boolean DEBUG = true;
|
||||
static final boolean VERBOSE = true;
|
||||
|
||||
public AppStateDirectoryAccessBridge(ApplicationsState appState, Callback callback) {
|
||||
super(appState, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAllExtraInfo() { }
|
||||
|
||||
@Override
|
||||
protected void updateExtraInfo(AppEntry app, String pkg, int uid) { }
|
||||
|
||||
public static final AppFilter FILTER_APP_HAS_DIRECTORY_ACCESS = new AppFilter() {
|
||||
|
||||
private Set<String> mPackages;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
throw new UnsupportedOperationException("Need to call constructor that takes context");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
mPackages = null;
|
||||
final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(AUTHORITY).appendPath(TABLE_PACKAGES).appendPath("*")
|
||||
.build();
|
||||
try (Cursor cursor = context.getContentResolver().query(providerUri,
|
||||
TABLE_PACKAGES_COLUMNS, null, null)) {
|
||||
if (cursor == null) {
|
||||
Log.w(TAG, "Didn't get cursor for " + providerUri);
|
||||
return;
|
||||
}
|
||||
final int count = cursor.getCount();
|
||||
if (count == 0) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "No packages anymore (was " + mPackages + ")");
|
||||
}
|
||||
return;
|
||||
}
|
||||
mPackages = new ArraySet<>(count);
|
||||
while (cursor.moveToNext()) {
|
||||
mPackages.add(cursor.getString(TABLE_PACKAGES_COL_PACKAGE));
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "init(): " + mPackages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean filterApp(AppEntry info) {
|
||||
return mPackages != null && mPackages.contains(info.info.packageName);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -18,13 +18,10 @@ package com.android.settings.applications;
|
||||
|
||||
import static android.content.pm.ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
|
||||
import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.GrantedUriPermission;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@@ -32,7 +29,6 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageDataObserver;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@@ -461,17 +457,6 @@ public class AppStorageSettings extends AppInfoWithHeader
|
||||
Context.ACTIVITY_SERVICE);
|
||||
am.clearGrantedUriPermissions(packageName);
|
||||
|
||||
|
||||
// Also update the Scoped Directory Access UI permissions
|
||||
final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(AUTHORITY).appendPath(TABLE_PERMISSIONS).appendPath("*")
|
||||
.build();
|
||||
Log.v(TAG, "Asking " + providerUri + " to delete permissions for " + packageName);
|
||||
final int deleted = context.getContentResolver().delete(providerUri, null, new String[] {
|
||||
packageName
|
||||
});
|
||||
Log.d(TAG, "Deleted " + deleted + " entries for package " + packageName);
|
||||
|
||||
// Update UI
|
||||
refreshGrantedUriPermissions();
|
||||
}
|
||||
|
||||
@@ -1,323 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.COL_GRANTED;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract
|
||||
.TABLE_PERMISSIONS_COLUMNS;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract
|
||||
.TABLE_PERMISSIONS_COL_DIRECTORY;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract
|
||||
.TABLE_PERMISSIONS_COL_GRANTED;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract
|
||||
.TABLE_PERMISSIONS_COL_PACKAGE;
|
||||
import static android.os.storage.StorageVolume.ScopedAccessProviderContract
|
||||
.TABLE_PERMISSIONS_COL_VOLUME_UUID;
|
||||
|
||||
import static com.android.settings.applications.AppStateDirectoryAccessBridge.DEBUG;
|
||||
import static com.android.settings.applications.AppStateDirectoryAccessBridge.VERBOSE;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settings.widget.EntityHeaderController.ActionType;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Detailed settings for an app's directory access permissions (A.K.A Scoped Directory Access).
|
||||
*
|
||||
* <p>Currently, it shows the entry for which the user denied access with the "Do not ask again"
|
||||
* flag checked on: the user than can use the settings toggle to reset that deniel.
|
||||
*
|
||||
* <p>This fragments dynamically lists all such permissions, starting with one preference per
|
||||
* directory in the primary storage, then adding additional entries for the external volumes (one
|
||||
* entry for the whole volume).
|
||||
*/
|
||||
// TODO(b/72055774): add unit tests
|
||||
public class DirectoryAccessDetails extends AppInfoBase {
|
||||
|
||||
@SuppressWarnings("hiding")
|
||||
private static final String TAG = "DirectoryAccessDetails";
|
||||
|
||||
private boolean mCreated;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
if (mCreated) {
|
||||
Log.w(TAG, "onActivityCreated(): ignoring duplicate call");
|
||||
return;
|
||||
}
|
||||
mCreated = true;
|
||||
if (mPackageInfo == null) {
|
||||
Log.w(TAG, "onActivityCreated(): no package info");
|
||||
return;
|
||||
}
|
||||
final Activity activity = getActivity();
|
||||
final Preference pref = EntityHeaderController
|
||||
.newInstance(activity, this, /* header= */ null )
|
||||
.setRecyclerView(getListView(), getSettingsLifecycle())
|
||||
.setIcon(IconDrawableFactory.newInstance(getPrefContext())
|
||||
.getBadgedIcon(mPackageInfo.applicationInfo))
|
||||
.setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
|
||||
.setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
|
||||
.setPackageName(mPackageName)
|
||||
.setUid(mPackageInfo.applicationInfo.uid)
|
||||
.setHasAppInfoLink(false)
|
||||
.setButtonActions(ActionType.ACTION_NONE, ActionType.ACTION_NONE)
|
||||
.done(activity, getPrefContext());
|
||||
getPreferenceScreen().addPreference(pref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.directory_access_details);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean refreshUi() {
|
||||
final Context context = getPrefContext();
|
||||
final PreferenceScreen prefsGroup = getPreferenceScreen();
|
||||
prefsGroup.removeAll();
|
||||
|
||||
final Map<String, ExternalVolume> externalVolumes = new HashMap<>();
|
||||
|
||||
final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(AUTHORITY).appendPath(TABLE_PERMISSIONS).appendPath("*")
|
||||
.build();
|
||||
// Query provider for entries.
|
||||
try (Cursor cursor = context.getContentResolver().query(providerUri,
|
||||
TABLE_PERMISSIONS_COLUMNS, null, new String[] { mPackageName }, null)) {
|
||||
if (cursor == null) {
|
||||
Log.w(TAG, "Didn't get cursor for " + mPackageName);
|
||||
return true;
|
||||
}
|
||||
final int count = cursor.getCount();
|
||||
if (count == 0) {
|
||||
// This setting screen should not be reached if there was no permission, so just
|
||||
// ignore it
|
||||
Log.w(TAG, "No permissions for " + mPackageName);
|
||||
return true;
|
||||
}
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
final String pkg = cursor.getString(TABLE_PERMISSIONS_COL_PACKAGE);
|
||||
final String uuid = cursor.getString(TABLE_PERMISSIONS_COL_VOLUME_UUID);
|
||||
final String dir = cursor.getString(TABLE_PERMISSIONS_COL_DIRECTORY);
|
||||
final boolean granted = cursor.getInt(TABLE_PERMISSIONS_COL_GRANTED) == 1;
|
||||
if (VERBOSE) {
|
||||
Log.v(TAG, "Pkg:" + pkg + " uuid: " + uuid + " dir: " + dir
|
||||
+ " granted:" + granted);
|
||||
}
|
||||
|
||||
if (!mPackageName.equals(pkg)) {
|
||||
// Sanity check, shouldn't happen
|
||||
Log.w(TAG, "Ignoring " + uuid + "/" + dir + " due to package mismatch: "
|
||||
+ "expected " + mPackageName + ", got " + pkg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (uuid == null) {
|
||||
if (dir == null) {
|
||||
// Sanity check, shouldn't happen
|
||||
Log.wtf(TAG, "Ignoring permission on primary storage root");
|
||||
} else {
|
||||
// Primary storage entry: add right away
|
||||
prefsGroup.addPreference(newPreference(context, dir, providerUri,
|
||||
/* uuid= */ null, dir, granted, /* children= */ null));
|
||||
}
|
||||
} else {
|
||||
// External volume entry: save it for later.
|
||||
ExternalVolume externalVolume = externalVolumes.get(uuid);
|
||||
if (externalVolume == null) {
|
||||
externalVolume = new ExternalVolume(uuid);
|
||||
externalVolumes.put(uuid, externalVolume);
|
||||
}
|
||||
if (dir == null) {
|
||||
// Whole volume
|
||||
externalVolume.granted = granted;
|
||||
} else {
|
||||
// Directory only
|
||||
externalVolume.children.add(new Pair<>(dir, granted));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (VERBOSE) {
|
||||
Log.v(TAG, "external volumes: " + externalVolumes);
|
||||
}
|
||||
|
||||
if (externalVolumes.isEmpty()) {
|
||||
// We're done!
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add entries from external volumes
|
||||
|
||||
// Query StorageManager to get the user-friendly volume names.
|
||||
final StorageManager sm = context.getSystemService(StorageManager.class);
|
||||
final List<VolumeInfo> volumes = sm.getVolumes();
|
||||
if (volumes.isEmpty()) {
|
||||
Log.w(TAG, "StorageManager returned no secondary volumes");
|
||||
return true;
|
||||
}
|
||||
final Map<String, String> volumeNames = new HashMap<>(volumes.size());
|
||||
for (VolumeInfo volume : volumes) {
|
||||
final String uuid = volume.getFsUuid();
|
||||
if (uuid == null) continue; // Primary storage; not used.
|
||||
|
||||
String name = sm.getBestVolumeDescription(volume);
|
||||
if (name == null) {
|
||||
Log.w(TAG, "No description for " + volume + "; using uuid instead: " + uuid);
|
||||
name = uuid;
|
||||
}
|
||||
volumeNames.put(uuid, name);
|
||||
}
|
||||
if (VERBOSE) {
|
||||
Log.v(TAG, "UUID -> name mapping: " + volumeNames);
|
||||
}
|
||||
|
||||
for (ExternalVolume volume : externalVolumes.values()) {
|
||||
final String volumeName = volumeNames.get(volume.uuid);
|
||||
if (volumeName == null) {
|
||||
Log.w(TAG, "Ignoring entry for invalid UUID: " + volume.uuid);
|
||||
continue;
|
||||
}
|
||||
// First add the pref for the whole volume...
|
||||
final PreferenceCategory category = new PreferenceCategory(context);
|
||||
prefsGroup.addPreference(category);
|
||||
final Set<SwitchPreference> children = new HashSet<>(volume.children.size());
|
||||
category.addPreference(newPreference(context, volumeName, providerUri, volume.uuid,
|
||||
/* dir= */ null, volume.granted, children));
|
||||
|
||||
// ... then the children prefs
|
||||
volume.children.forEach((pair) -> {
|
||||
final String dir = pair.first;
|
||||
final String name = context.getResources()
|
||||
.getString(R.string.directory_on_volume, volumeName, dir);
|
||||
final SwitchPreference childPref =
|
||||
newPreference(context, name, providerUri, volume.uuid, dir, pair.second,
|
||||
/* children= */ null);
|
||||
category.addPreference(childPref);
|
||||
children.add(childPref);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private SwitchPreference newPreference(Context context, String title, Uri providerUri,
|
||||
String uuid, String dir, boolean granted, @Nullable Set<SwitchPreference> children) {
|
||||
final SwitchPreference pref = new SwitchPreference(context);
|
||||
pref.setKey(String.format("%s:%s", uuid, dir));
|
||||
pref.setTitle(title);
|
||||
pref.setChecked(granted);
|
||||
pref.setOnPreferenceChangeListener((unused, value) -> {
|
||||
if (!Boolean.class.isInstance(value)) {
|
||||
// Sanity check
|
||||
Log.wtf(TAG, "Invalid value from switch: " + value);
|
||||
return true;
|
||||
}
|
||||
final boolean newValue = ((Boolean) value).booleanValue();
|
||||
|
||||
resetDoNotAskAgain(context, newValue, providerUri, uuid, dir);
|
||||
if (children != null) {
|
||||
// When parent is granted, children should be hidden; and vice versa
|
||||
final boolean newChildValue = !newValue;
|
||||
for (SwitchPreference child : children) {
|
||||
child.setVisible(newChildValue);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return pref;
|
||||
}
|
||||
|
||||
private void resetDoNotAskAgain(Context context, boolean newValue, Uri providerUri,
|
||||
@Nullable String uuid, @Nullable String directory) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Asking " + providerUri + " to update " + uuid + "/" + directory + " to "
|
||||
+ newValue);
|
||||
}
|
||||
final ContentValues values = new ContentValues(1);
|
||||
values.put(COL_GRANTED, newValue);
|
||||
final int updated = context.getContentResolver().update(providerUri, values,
|
||||
null, new String[] { mPackageName, uuid, directory });
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Updated " + updated + " entries for " + uuid + "/" + directory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AlertDialog createDialog(int id, int errorCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.APPLICATIONS_DIRECTORY_ACCESS_DETAIL;
|
||||
}
|
||||
|
||||
private static class ExternalVolume {
|
||||
final String uuid;
|
||||
final List<Pair<String, Boolean>> children = new ArrayList<>();
|
||||
boolean granted;
|
||||
|
||||
ExternalVolume(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ExternalVolume: [uuid=" + uuid + ", granted=" + granted +
|
||||
", children=" + children + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,12 +90,9 @@ public class AppHeaderViewPreferenceController extends BasePreferenceController
|
||||
private void setAppLabelAndIcon(PackageInfo pkgInfo, AppEntry appEntry) {
|
||||
final Activity activity = mParent.getActivity();
|
||||
final boolean isInstantApp = AppUtils.isInstant(pkgInfo.applicationInfo);
|
||||
final CharSequence summary = isInstantApp
|
||||
? null : mContext.getString(Utils.getInstallationStatus(appEntry.info));
|
||||
mEntityHeaderController
|
||||
.setLabel(appEntry)
|
||||
.setIcon(appEntry)
|
||||
.setSummary(summary)
|
||||
.setIsInstantApp(isInstantApp)
|
||||
.done(activity, false /* rebindActions */);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.settings.applications.manageapplications;
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.AppStateDirectoryAccessBridge;
|
||||
import com.android.settings.applications.AppStateInstallAppsBridge;
|
||||
import com.android.settings.applications.AppStateNotificationBridge;
|
||||
import com.android.settings.applications.AppStateOverlayBridge;
|
||||
@@ -70,7 +69,6 @@ public class AppFilterRegistry {
|
||||
public static final int FILTER_APPS_WITH_OVERLAY = 11;
|
||||
public static final int FILTER_APPS_WRITE_SETTINGS = 12;
|
||||
public static final int FILTER_APPS_INSTALL_SOURCES = 13;
|
||||
public static final int FILTER_APP_HAS_DIRECTORY_ACCESS = 14;
|
||||
public static final int FILTER_APP_CAN_CHANGE_WIFI_STATE = 15;
|
||||
public static final int FILTER_APPS_BLOCKED = 16;
|
||||
// Next id: 17
|
||||
@@ -170,12 +168,6 @@ public class AppFilterRegistry {
|
||||
FILTER_APPS_INSTALL_SOURCES,
|
||||
R.string.filter_install_sources_apps);
|
||||
|
||||
// Apps that interacted with directory access permissions (A.K.A. Scoped Directory Access)
|
||||
mFilters[FILTER_APP_HAS_DIRECTORY_ACCESS] = new AppFilterItem(
|
||||
AppStateDirectoryAccessBridge.FILTER_APP_HAS_DIRECTORY_ACCESS,
|
||||
FILTER_APP_HAS_DIRECTORY_ACCESS,
|
||||
R.string.filter_install_sources_apps);
|
||||
|
||||
mFilters[FILTER_APP_CAN_CHANGE_WIFI_STATE] = new AppFilterItem(
|
||||
AppStateChangeWifiStateBridge.FILTER_CHANGE_WIFI_STATE,
|
||||
FILTER_APP_CAN_CHANGE_WIFI_STATE,
|
||||
@@ -208,8 +200,6 @@ public class AppFilterRegistry {
|
||||
return FILTER_APPS_WRITE_SETTINGS;
|
||||
case ManageApplications.LIST_TYPE_MANAGE_SOURCES:
|
||||
return FILTER_APPS_INSTALL_SOURCES;
|
||||
case ManageApplications.LIST_TYPE_DIRECTORY_ACCESS:
|
||||
return FILTER_APP_HAS_DIRECTORY_ACCESS;
|
||||
case ManageApplications.LIST_TYPE_WIFI_ACCESS:
|
||||
return FILTER_APP_CAN_CHANGE_WIFI_STATE;
|
||||
case ManageApplications.LIST_TYPE_NOTIFICATION:
|
||||
|
||||
@@ -90,7 +90,6 @@ import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.applications.AppStateAppOpsBridge.PermissionState;
|
||||
import com.android.settings.applications.AppStateBaseBridge;
|
||||
import com.android.settings.applications.AppStateDirectoryAccessBridge;
|
||||
import com.android.settings.applications.AppStateInstallAppsBridge;
|
||||
import com.android.settings.applications.AppStateNotificationBridge;
|
||||
import com.android.settings.applications.AppStateNotificationBridge.NotificationsSentState;
|
||||
@@ -101,7 +100,6 @@ import com.android.settings.applications.AppStateUsageBridge.UsageState;
|
||||
import com.android.settings.applications.AppStateWriteSettingsBridge;
|
||||
import com.android.settings.applications.AppStorageSettings;
|
||||
import com.android.settings.applications.DefaultAppSettings;
|
||||
import com.android.settings.applications.DirectoryAccessDetails;
|
||||
import com.android.settings.applications.InstalledAppCounter;
|
||||
import com.android.settings.applications.UsageAccessDetails;
|
||||
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
|
||||
@@ -218,7 +216,6 @@ public class ManageApplications extends InstrumentedFragment
|
||||
public static final int LIST_TYPE_GAMES = 9;
|
||||
public static final int LIST_TYPE_MOVIES = 10;
|
||||
public static final int LIST_TYPE_PHOTOGRAPHY = 11;
|
||||
public static final int LIST_TYPE_DIRECTORY_ACCESS = 12;
|
||||
public static final int LIST_TYPE_WIFI_ACCESS = 13;
|
||||
|
||||
// List types that should show instant apps.
|
||||
@@ -293,9 +290,6 @@ public class ManageApplications extends InstrumentedFragment
|
||||
mListType = LIST_TYPE_PHOTOGRAPHY;
|
||||
mSortOrder = R.id.sort_order_size;
|
||||
mStorageType = args.getInt(EXTRA_STORAGE_TYPE, STORAGE_TYPE_DEFAULT);
|
||||
} else if (className.equals(Settings.DirectoryAccessSettingsActivity.class.getName())) {
|
||||
mListType = LIST_TYPE_DIRECTORY_ACCESS;
|
||||
screenTitle = R.string.directory_access;
|
||||
} else if (className.equals(Settings.ChangeWifiStateActivity.class.getName())) {
|
||||
mListType = LIST_TYPE_WIFI_ACCESS;
|
||||
screenTitle = R.string.change_wifi_state_title;
|
||||
@@ -479,8 +473,6 @@ public class ManageApplications extends InstrumentedFragment
|
||||
return MetricsEvent.SYSTEM_ALERT_WINDOW_APPS;
|
||||
case LIST_TYPE_MANAGE_SOURCES:
|
||||
return MetricsEvent.MANAGE_EXTERNAL_SOURCES;
|
||||
case LIST_TYPE_DIRECTORY_ACCESS:
|
||||
return MetricsEvent.DIRECTORY_ACCESS;
|
||||
case LIST_TYPE_WIFI_ACCESS:
|
||||
return MetricsEvent.CONFIGURE_WIFI;
|
||||
default:
|
||||
@@ -578,9 +570,6 @@ public class ManageApplications extends InstrumentedFragment
|
||||
case LIST_TYPE_PHOTOGRAPHY:
|
||||
startAppInfoFragment(AppStorageSettings.class, R.string.storage_photos_videos);
|
||||
break;
|
||||
case LIST_TYPE_DIRECTORY_ACCESS:
|
||||
startAppInfoFragment(DirectoryAccessDetails.class, R.string.directory_access);
|
||||
break;
|
||||
case LIST_TYPE_WIFI_ACCESS:
|
||||
startAppInfoFragment(ChangeWifiStateDetails.class,
|
||||
R.string.change_wifi_state_title);
|
||||
@@ -916,8 +905,6 @@ public class ManageApplications extends InstrumentedFragment
|
||||
mExtraInfoBridge = new AppStateWriteSettingsBridge(mContext, mState, this);
|
||||
} else if (mManageApplications.mListType == LIST_TYPE_MANAGE_SOURCES) {
|
||||
mExtraInfoBridge = new AppStateInstallAppsBridge(mContext, mState, this);
|
||||
} else if (mManageApplications.mListType == LIST_TYPE_DIRECTORY_ACCESS) {
|
||||
mExtraInfoBridge = new AppStateDirectoryAccessBridge(mState, this);
|
||||
} else if (mManageApplications.mListType == LIST_TYPE_WIFI_ACCESS) {
|
||||
mExtraInfoBridge = new AppStateChangeWifiStateBridge(mContext, mState, this);
|
||||
} else {
|
||||
@@ -1360,9 +1347,6 @@ public class ManageApplications extends InstrumentedFragment
|
||||
case LIST_TYPE_MANAGE_SOURCES:
|
||||
holder.setSummary(ExternalSourcesDetails.getPreferenceSummary(mContext, entry));
|
||||
break;
|
||||
case LIST_TYPE_DIRECTORY_ACCESS:
|
||||
holder.setSummary(null);
|
||||
break;
|
||||
case LIST_TYPE_WIFI_ACCESS:
|
||||
holder.setSummary(ChangeWifiStateDetails.getSummary(mContext, entry));
|
||||
break;
|
||||
|
||||
@@ -74,7 +74,6 @@ public class AdvancedConnectedDeviceDashboardFragment extends DashboardFragment
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
|
||||
controllers.add(new BluetoothFilesPreferenceController(context));
|
||||
controllers.add(new BluetoothOnWhileDrivingPreferenceController(context));
|
||||
|
||||
final PrintSettingPreferenceController printerController =
|
||||
new PrintSettingPreferenceController(context);
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
|
||||
/** Handles a toggle for a setting to turn on Bluetooth while driving. * */
|
||||
public class BluetoothOnWhileDrivingPreferenceController extends TogglePreferenceController
|
||||
implements PreferenceControllerMixin {
|
||||
static final String KEY_BLUETOOTH_ON_DRIVING = "bluetooth_on_while_driving";
|
||||
|
||||
public BluetoothOnWhileDrivingPreferenceController(Context context) {
|
||||
super(context, KEY_BLUETOOTH_ON_DRIVING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.BLUETOOTH_WHILE_DRIVING)) {
|
||||
return AVAILABLE;
|
||||
}
|
||||
return CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.Secure.getInt(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING,
|
||||
0)
|
||||
!= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
final int value = isChecked ? 1 : 0;
|
||||
return Settings.Secure.putInt(
|
||||
mContext.getContentResolver(), Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING, value);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ package com.android.settings.core;
|
||||
* This class keeps track of all feature flags in Settings.
|
||||
*/
|
||||
public class FeatureFlags {
|
||||
public static final String BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
|
||||
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
|
||||
public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage";
|
||||
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.android.settings.accounts.ChooseAccountFragment;
|
||||
import com.android.settings.accounts.ManagedProfileSettings;
|
||||
import com.android.settings.applications.AppAndNotificationDashboardFragment;
|
||||
import com.android.settings.applications.DefaultAppSettings;
|
||||
import com.android.settings.applications.DirectoryAccessDetails;
|
||||
import com.android.settings.applications.ProcessStatsSummary;
|
||||
import com.android.settings.applications.ProcessStatsUi;
|
||||
import com.android.settings.applications.UsageAccessDetails;
|
||||
@@ -258,7 +257,6 @@ public class SettingsGateway {
|
||||
LockscreenDashboardFragment.class.getName(),
|
||||
BluetoothDeviceDetailsFragment.class.getName(),
|
||||
DataUsageList.class.getName(),
|
||||
DirectoryAccessDetails.class.getName(),
|
||||
ToggleBackupSettingFragment.class.getName(),
|
||||
PreviouslyConnectedDeviceDashboardFragment.class.getName(),
|
||||
};
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
public class DesktopModePreferenceController extends DeveloperOptionsPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String FORCE_DESKTOP_MODE_KEY = "force_desktop_mode_on_external_displays";
|
||||
|
||||
@VisibleForTesting
|
||||
static final int SETTING_VALUE_OFF = 0;
|
||||
@VisibleForTesting
|
||||
static final int SETTING_VALUE_ON = 1;
|
||||
|
||||
public DesktopModePreferenceController(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return FORCE_DESKTOP_MODE_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean isEnabled = (Boolean) newValue;
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
|
||||
isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF);
|
||||
((SwitchPreference) mPreference).setChecked(mode != SETTING_VALUE_OFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF);
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String getBuildType() {
|
||||
return Build.TYPE;
|
||||
}
|
||||
}
|
||||
@@ -27,4 +27,6 @@ public interface DevelopmentOptionsActivityRequestCodes {
|
||||
int REQUEST_MOCK_LOCATION_APP = 2;
|
||||
|
||||
int REQUEST_CODE_ANGLE_ENABLED_APP = 3;
|
||||
|
||||
int REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP = 4;
|
||||
}
|
||||
|
||||
@@ -406,6 +406,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new WaitForDebuggerPreferenceController(context));
|
||||
controllers.add(new EnableGpuDebugLayersPreferenceController(context));
|
||||
controllers.add(new AngleEnabledAppPreferenceController(context, fragment));
|
||||
controllers.add(new UpdatedGfxDriverDevOptInPreferenceController(context, fragment));
|
||||
controllers.add(new VerifyAppsOverUsbPreferenceController(context));
|
||||
controllers.add(new LogdSizePreferenceController(context));
|
||||
controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle));
|
||||
@@ -458,6 +459,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new AllowAppsOnExternalPreferenceController(context));
|
||||
controllers.add(new ResizableActivityPreferenceController(context));
|
||||
controllers.add(new FreeformWindowsPreferenceController(context));
|
||||
controllers.add(new DesktopModePreferenceController(context));
|
||||
controllers.add(new SmsAccessRestrictionPreferenceController(context));
|
||||
controllers.add(new ShortcutManagerThrottlingPreferenceController(context));
|
||||
controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context));
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.settings.development;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
@@ -37,18 +36,11 @@ public class FreeformWindowsPreferenceController extends DeveloperOptionsPrefere
|
||||
static final int SETTING_VALUE_OFF = 0;
|
||||
@VisibleForTesting
|
||||
static final int SETTING_VALUE_ON = 1;
|
||||
@VisibleForTesting
|
||||
static final String USER_BUILD_TYPE = "user";
|
||||
|
||||
public FreeformWindowsPreferenceController(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !TextUtils.equals(USER_BUILD_TYPE, getBuildType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return ENABLE_FREEFORM_SUPPORT_KEY;
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes
|
||||
.REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
// TODO(b/119221883): Need to override isAvailable() to return false when updatable graphics driver is not supported.
|
||||
public class UpdatedGfxDriverDevOptInPreferenceController
|
||||
extends DeveloperOptionsPreferenceController
|
||||
implements PreferenceControllerMixin, OnActivityResultListener {
|
||||
|
||||
private static final String UPDATED_GFX_DRIVER_DEV_OPT_IN_APP_KEY =
|
||||
"updated_gfx_driver_dev_opt_in_app";
|
||||
|
||||
private final DevelopmentSettingsDashboardFragment mFragment;
|
||||
private final PackageManager mPackageManager;
|
||||
|
||||
public UpdatedGfxDriverDevOptInPreferenceController(Context context,
|
||||
DevelopmentSettingsDashboardFragment fragment) {
|
||||
super(context);
|
||||
mFragment = fragment;
|
||||
mPackageManager = mContext.getPackageManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return UPDATED_GFX_DRIVER_DEV_OPT_IN_APP_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (UPDATED_GFX_DRIVER_DEV_OPT_IN_APP_KEY.equals(preference.getKey())) {
|
||||
// pass it on to settings
|
||||
final Intent intent = getActivityStartIntent();
|
||||
mFragment.startActivityForResult(intent,
|
||||
REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
updatePreferenceSummary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode != REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP
|
||||
|| resultCode != Activity.RESULT_OK) {
|
||||
return false;
|
||||
}
|
||||
Settings.Global.putString(mContext.getContentResolver(),
|
||||
Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP, data.getAction());
|
||||
updatePreferenceSummary();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
mPreference.setSummary(mContext.getResources().getString(
|
||||
R.string.updated_gfx_driver_dev_opt_in_app_not_set));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Intent getActivityStartIntent() {
|
||||
Intent intent = new Intent(mContext, AppPicker.class);
|
||||
intent.putExtra(AppPicker.EXTRA_NON_SYSTEM, true /* value */);
|
||||
return intent;
|
||||
}
|
||||
|
||||
private void updatePreferenceSummary() {
|
||||
final String updatedGfxDriverDevOptInApp = Settings.Global.getString(
|
||||
mContext.getContentResolver(), Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP);
|
||||
if (updatedGfxDriverDevOptInApp != null && !updatedGfxDriverDevOptInApp.isEmpty()) {
|
||||
mPreference.setSummary(mContext.getResources().getString(
|
||||
R.string.updated_gfx_driver_dev_opt_in_app_set,
|
||||
getAppLabel(updatedGfxDriverDevOptInApp)));
|
||||
} else {
|
||||
mPreference.setSummary(mContext.getResources().getString(
|
||||
R.string.updated_gfx_driver_dev_opt_in_app_not_set));
|
||||
}
|
||||
}
|
||||
|
||||
private String getAppLabel(String applicationPackageName) {
|
||||
try {
|
||||
final ApplicationInfo ai = mPackageManager.getApplicationInfo(applicationPackageName,
|
||||
PackageManager.GET_DISABLED_COMPONENTS);
|
||||
final CharSequence lab = mPackageManager.getApplicationLabel(ai);
|
||||
return lab != null ? lab.toString() : applicationPackageName;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return applicationPackageName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,12 +79,7 @@ public class DeviceModelPreferenceController extends BasePreferenceController {
|
||||
}
|
||||
|
||||
public static String getDeviceModel() {
|
||||
FutureTask<String> msvSuffixTask = new FutureTask<String>(new Callable<String>() {
|
||||
@Override
|
||||
public String call() {
|
||||
return DeviceInfoUtils.getMsvSuffix();
|
||||
}
|
||||
});
|
||||
FutureTask<String> msvSuffixTask = new FutureTask<>(() -> DeviceInfoUtils.getMsvSuffix());
|
||||
|
||||
msvSuffixTask.run();
|
||||
try {
|
||||
|
||||
@@ -181,25 +181,6 @@ public class MyDeviceInfoFragment extends DashboardFragment
|
||||
controller.updateDeviceName(confirm);
|
||||
}
|
||||
|
||||
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
|
||||
|
||||
private final SummaryLoader mSummaryLoader;
|
||||
|
||||
public SummaryProvider(SummaryLoader summaryLoader) {
|
||||
mSummaryLoader = summaryLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
if (listening) {
|
||||
mSummaryLoader.setSummary(this, DeviceModelPreferenceController.getDeviceModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
|
||||
= (activity, summaryLoader) -> new SummaryProvider(summaryLoader);
|
||||
|
||||
/**
|
||||
* For Search.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.deviceinfo.aboutphone;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.deviceinfo.DeviceModelPreferenceController;
|
||||
|
||||
public class TopLevelAboutDevicePreferenceController extends BasePreferenceController {
|
||||
|
||||
public TopLevelAboutDevicePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return DeviceModelPreferenceController.getDeviceModel();
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
@@ -109,16 +111,24 @@ public class ActionDisabledByAdminDialogHelper {
|
||||
if (admin == null) {
|
||||
return;
|
||||
}
|
||||
ImageView supportIconView = root.requireViewById(R.id.admin_support_icon);
|
||||
if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(mActivity, admin)
|
||||
|| !RestrictedLockUtils.isCurrentUserOrProfile(mActivity, userId)) {
|
||||
admin = null;
|
||||
|
||||
supportIconView.setImageDrawable(
|
||||
mActivity.getDrawable(com.android.internal.R.drawable.ic_info));
|
||||
|
||||
TypedArray ta = mActivity.obtainStyledAttributes(new int[]{android.R.attr.colorAccent});
|
||||
supportIconView.setImageTintList(ColorStateList.valueOf(ta.getColor(0, 0)));
|
||||
ta.recycle();
|
||||
} else {
|
||||
final Drawable badgedIcon = Utils.getBadgedIcon(
|
||||
IconDrawableFactory.newInstance(mActivity),
|
||||
mActivity.getPackageManager(),
|
||||
admin.getPackageName(),
|
||||
userId);
|
||||
((ImageView) root.findViewById(R.id.admin_support_icon)).setImageDrawable(badgedIcon);
|
||||
supportIconView.setImageDrawable(badgedIcon);
|
||||
}
|
||||
|
||||
setAdminSupportTitle(root, restriction);
|
||||
|
||||
@@ -235,10 +235,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
||||
controller.setLabel(mAppEntry);
|
||||
controller.setIcon(mAppEntry);
|
||||
boolean isInstantApp = AppUtils.isInstant(mAppEntry.info);
|
||||
CharSequence summary = isInstantApp
|
||||
? null : getString(Utils.getInstallationStatus(mAppEntry.info));
|
||||
controller.setIsInstantApp(AppUtils.isInstant(mAppEntry.info));
|
||||
controller.setSummary(summary);
|
||||
}
|
||||
|
||||
controller.done(context, true /* rebindActions */);
|
||||
|
||||
@@ -201,7 +201,7 @@ public class CardDatabaseHelper extends SQLiteOpenHelper {
|
||||
final String selection = CardColumns.CARD_DISMISSED + "=0";
|
||||
Cursor cursor = db.query(CARD_TABLE, null /* columns */, selection,
|
||||
null /* selectionArgs */, null /* groupBy */, null /* having */,
|
||||
null /* orderBy */);
|
||||
CardColumns.SCORE + " DESC" /* orderBy */);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,12 +33,12 @@ public class ContextualCard {
|
||||
/**
|
||||
* Flags indicating the type of the ContextualCard.
|
||||
*/
|
||||
@IntDef({CardType.DEFAULT, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
|
||||
@IntDef({CardType.DEFAULT, CardType.SLICE, CardType.LEGACY_SUGGESTION, CardType.CONDITIONAL})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface CardType {
|
||||
int DEFAULT = 0;
|
||||
int SLICE = 1;
|
||||
int SUGGESTION = 2;
|
||||
int LEGACY_SUGGESTION = 2;
|
||||
int CONDITIONAL = 3;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,16 @@ package com.android.settings.homepage.contextualcards;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
|
||||
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
|
||||
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
|
||||
import com.android.settings.homepage.contextualcards.legacysuggestion
|
||||
.LegacySuggestionContextualCardController;
|
||||
import com.android.settings.homepage.contextualcards.legacysuggestion
|
||||
.LegacySuggestionContextualCardRenderer;
|
||||
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
|
||||
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
|
||||
|
||||
@@ -34,6 +39,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class ContextualCardLookupTable {
|
||||
private static final String TAG = "ContextualCardLookup";
|
||||
|
||||
static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> {
|
||||
@CardType
|
||||
final int mCardType;
|
||||
@@ -41,7 +47,7 @@ public class ContextualCardLookupTable {
|
||||
final Class<? extends ContextualCardController> mControllerClass;
|
||||
final Class<? extends ContextualCardRenderer> mRendererClass;
|
||||
|
||||
ControllerRendererMapping(@CardType int cardType, int viewType,
|
||||
ControllerRendererMapping(@CardType int cardType, @LayoutRes int viewType,
|
||||
Class<? extends ContextualCardController> controllerClass,
|
||||
Class<? extends ContextualCardRenderer> rendererClass) {
|
||||
mCardType = cardType;
|
||||
@@ -69,6 +75,10 @@ public class ContextualCardLookupTable {
|
||||
ConditionContextualCardRenderer.FULL_WIDTH_VIEW_TYPE,
|
||||
ConditionContextualCardController.class,
|
||||
ConditionContextualCardRenderer.class));
|
||||
add(new ControllerRendererMapping(CardType.LEGACY_SUGGESTION,
|
||||
LegacySuggestionContextualCardRenderer.VIEW_TYPE,
|
||||
LegacySuggestionContextualCardController.class,
|
||||
LegacySuggestionContextualCardRenderer.class));
|
||||
add(new ControllerRendererMapping(CardType.SLICE,
|
||||
SliceContextualCardRenderer.VIEW_TYPE,
|
||||
SliceContextualCardController.class,
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package com.android.settings.homepage.contextualcards;
|
||||
|
||||
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;
|
||||
import static com.android.settings.homepage.contextualcards.ContextualCardLoader
|
||||
.CARD_CONTENT_LOADER_ID;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
|
||||
@@ -57,8 +58,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
||||
|
||||
private static final String TAG = "ContextualCardManager";
|
||||
//The list for Settings Custom Card
|
||||
@ContextualCard.CardType
|
||||
private static final int[] SETTINGS_CARDS = {ContextualCard.CardType.CONDITIONAL};
|
||||
private static final int[] SETTINGS_CARDS =
|
||||
{ContextualCard.CardType.CONDITIONAL, ContextualCard.CardType.LEGACY_SUGGESTION};
|
||||
|
||||
private final Context mContext;
|
||||
private final ControllerRendererPool mControllerRendererPool;
|
||||
@@ -68,14 +69,14 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
||||
|
||||
private ContextualCardUpdateListener mListener;
|
||||
|
||||
public ContextualCardManager(Context context, @NonNull Lifecycle lifecycle) {
|
||||
public ContextualCardManager(Context context, Lifecycle lifecycle) {
|
||||
mContext = context;
|
||||
mLifecycle = lifecycle;
|
||||
mContextualCards = new ArrayList<>();
|
||||
mLifecycleObservers = new ArrayList<>();
|
||||
mControllerRendererPool = new ControllerRendererPool();
|
||||
//for data provided by Settings
|
||||
for (int cardType : SETTINGS_CARDS) {
|
||||
for (@ContextualCard.CardType int cardType : SETTINGS_CARDS) {
|
||||
setupController(cardType);
|
||||
}
|
||||
}
|
||||
@@ -94,7 +95,7 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
||||
}
|
||||
}
|
||||
|
||||
private void setupController(int cardType) {
|
||||
private void setupController(@ContextualCard.CardType int cardType) {
|
||||
final ContextualCardController controller = mControllerRendererPool.getController(mContext,
|
||||
cardType);
|
||||
if (controller == null) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.homepage.contextualcards;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
@@ -28,6 +29,7 @@ public interface ContextualCardRenderer {
|
||||
/**
|
||||
* The layout type of the renderer.
|
||||
*/
|
||||
@LayoutRes
|
||||
int getViewType(boolean isHalfWidth);
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.homepage.contextualcards;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -31,5 +33,6 @@ public interface ContextualCardUpdateListener {
|
||||
* null, which means all cards from corresponding {@link
|
||||
* ContextualCard.CardType} are removed.
|
||||
*/
|
||||
@MainThread
|
||||
void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards);
|
||||
}
|
||||
@@ -26,6 +26,10 @@ import androidx.lifecycle.LifecycleOwner;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
|
||||
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
|
||||
import com.android.settings.homepage.contextualcards.legacysuggestion
|
||||
.LegacySuggestionContextualCardController;
|
||||
import com.android.settings.homepage.contextualcards.legacysuggestion
|
||||
.LegacySuggestionContextualCardRenderer;
|
||||
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
|
||||
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
|
||||
|
||||
@@ -111,6 +115,8 @@ public class ControllerRendererPool {
|
||||
return new ConditionContextualCardController(context);
|
||||
} else if (SliceContextualCardController.class == clz) {
|
||||
return new SliceContextualCardController();
|
||||
} else if (LegacySuggestionContextualCardController.class == clz) {
|
||||
return new LegacySuggestionContextualCardController(context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -118,9 +124,12 @@ public class ControllerRendererPool {
|
||||
private ContextualCardRenderer createCardRenderer(Context context,
|
||||
LifecycleOwner lifecycleOwner, Class<?> clz) {
|
||||
if (ConditionContextualCardRenderer.class == clz) {
|
||||
return new ConditionContextualCardRenderer(context, this /*controllerRendererPool*/);
|
||||
return new ConditionContextualCardRenderer(context, this /* controllerRendererPool */);
|
||||
} else if (SliceContextualCardRenderer.class == clz) {
|
||||
return new SliceContextualCardRenderer(context, lifecycleOwner);
|
||||
} else if (LegacySuggestionContextualCardRenderer.class == clz) {
|
||||
return new LegacySuggestionContextualCardRenderer(context,
|
||||
this /* controllerRendererPool */);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
@@ -37,7 +38,9 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
* Card renderer for {@link ConditionalContextualCard}.
|
||||
*/
|
||||
public class ConditionContextualCardRenderer implements ContextualCardRenderer {
|
||||
@LayoutRes
|
||||
public static final int HALF_WIDTH_VIEW_TYPE = R.layout.homepage_condition_half_tile;
|
||||
@LayoutRes
|
||||
public static final int FULL_WIDTH_VIEW_TYPE = R.layout.homepage_condition_full_tile;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
public class LegacySuggestionContextualCard extends ContextualCard {
|
||||
|
||||
private final PendingIntent mPendingIntent;
|
||||
|
||||
public LegacySuggestionContextualCard(Builder builder) {
|
||||
super(builder);
|
||||
mPendingIntent = builder.mPendingIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardType() {
|
||||
return CardType.LEGACY_SUGGESTION;
|
||||
}
|
||||
|
||||
public PendingIntent getPendingIntent() {
|
||||
return mPendingIntent;
|
||||
}
|
||||
|
||||
public static class Builder extends ContextualCard.Builder {
|
||||
|
||||
private PendingIntent mPendingIntent;
|
||||
|
||||
public Builder setPendingIntent(PendingIntent pendingIntent) {
|
||||
mPendingIntent = pendingIntent;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder setCardType(int cardType) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot change card type for " + getClass().getName());
|
||||
}
|
||||
|
||||
public LegacySuggestionContextualCard build() {
|
||||
return new LegacySuggestionContextualCard(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCardController;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
import com.android.settingslib.suggestions.SuggestionController;
|
||||
import com.android.settingslib.suggestions.SuggestionController.ServiceConnectionListener;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class LegacySuggestionContextualCardController implements ContextualCardController,
|
||||
LifecycleObserver, OnStart, OnStop, ServiceConnectionListener {
|
||||
|
||||
private static final String TAG = "LegacySuggestCardCtrl";
|
||||
|
||||
@VisibleForTesting
|
||||
SuggestionController mSuggestionController;
|
||||
|
||||
private ContextualCardUpdateListener mCardUpdateListener;
|
||||
private final Context mContext;
|
||||
|
||||
|
||||
public LegacySuggestionContextualCardController(Context context) {
|
||||
mContext = context;
|
||||
if (!mContext.getResources().getBoolean(R.bool.config_use_legacy_suggestion)) {
|
||||
Log.w(TAG, "Legacy suggestion contextual card disabled, skipping.");
|
||||
return;
|
||||
}
|
||||
final ComponentName suggestionServiceComponent =
|
||||
FeatureFactory.getFactory(mContext).getSuggestionFeatureProvider(mContext)
|
||||
.getSuggestionServiceComponent();
|
||||
mSuggestionController = new SuggestionController(
|
||||
mContext, suggestionServiceComponent, this /* listener */);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardType() {
|
||||
return ContextualCard.CardType.LEGACY_SUGGESTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrimaryClick(ContextualCard card) {
|
||||
try {
|
||||
((LegacySuggestionContextualCard) card).getPendingIntent().send();
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
Log.w(TAG, "Failed to start suggestion " + card.getTitleText());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionClick(ContextualCard card) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCardUpdateListener(ContextualCardUpdateListener listener) {
|
||||
mCardUpdateListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (mSuggestionController == null) {
|
||||
return;
|
||||
}
|
||||
mSuggestionController.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (mSuggestionController == null) {
|
||||
return;
|
||||
}
|
||||
mSuggestionController.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
loadSuggestions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected() {
|
||||
|
||||
}
|
||||
|
||||
private void loadSuggestions() {
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
if (mSuggestionController == null || mCardUpdateListener == null) {
|
||||
return;
|
||||
}
|
||||
final List<Suggestion> suggestions = mSuggestionController.getSuggestions();
|
||||
Log.d(TAG, "Loaded suggests: "
|
||||
+ suggestions == null ? "null" : String.valueOf(suggestions.size()));
|
||||
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
if (suggestions != null) {
|
||||
// Convert suggestion to ContextualCard
|
||||
for (Suggestion suggestion : suggestions) {
|
||||
final LegacySuggestionContextualCard.Builder cardBuilder =
|
||||
new LegacySuggestionContextualCard.Builder();
|
||||
if (suggestion.getIcon() != null) {
|
||||
cardBuilder.setIconDrawable(suggestion.getIcon().loadDrawable(mContext));
|
||||
}
|
||||
cardBuilder
|
||||
.setPendingIntent(suggestion.getPendingIntent())
|
||||
.setName(suggestion.getId())
|
||||
.setTitleText(suggestion.getTitle().toString())
|
||||
.setSummaryText(suggestion.getSummary().toString());
|
||||
|
||||
cards.add(cardBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
// Update adapter
|
||||
final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
|
||||
suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, cards);
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
|
||||
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
|
||||
|
||||
public class LegacySuggestionContextualCardRenderer implements ContextualCardRenderer {
|
||||
|
||||
@LayoutRes
|
||||
public static final int VIEW_TYPE = R.layout.homepage_suggestion_tile;
|
||||
|
||||
private final Context mContext;
|
||||
private final ControllerRendererPool mControllerRendererPool;
|
||||
|
||||
public LegacySuggestionContextualCardRenderer(Context context,
|
||||
ControllerRendererPool controllerRendererPool) {
|
||||
mContext = context;
|
||||
mControllerRendererPool = controllerRendererPool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewType(boolean isHalfWidth) {
|
||||
return VIEW_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder createViewHolder(View view) {
|
||||
return new LegacySuggestionViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
|
||||
final LegacySuggestionViewHolder vh = (LegacySuggestionViewHolder) holder;
|
||||
vh.icon.setImageDrawable(card.getIconDrawable());
|
||||
vh.title.setText(card.getTitleText());
|
||||
vh.summary.setText(card.getSummaryText());
|
||||
vh.itemView.setOnClickListener(v ->
|
||||
mControllerRendererPool.getController(mContext,
|
||||
card.getCardType()).onPrimaryClick(card));
|
||||
}
|
||||
|
||||
private static class LegacySuggestionViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public final ImageView icon;
|
||||
public final TextView title;
|
||||
public final TextView summary;
|
||||
|
||||
public LegacySuggestionViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(android.R.id.icon);
|
||||
title = itemView.findViewById(android.R.id.title);
|
||||
summary = itemView.findViewById(android.R.id.summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,18 +25,15 @@ import android.telephony.SubscriptionManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
public class ApnPreference extends Preference implements
|
||||
CompoundButton.OnCheckedChangeListener, OnClickListener {
|
||||
public class ApnPreference extends Preference implements CompoundButton.OnCheckedChangeListener {
|
||||
final static String TAG = "ApnPreference";
|
||||
|
||||
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
@@ -82,11 +79,6 @@ public class ApnPreference extends Preference implements
|
||||
rb.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
View textLayout = view.findViewById(R.id.text_layout);
|
||||
if ((textLayout != null) && textLayout instanceof RelativeLayout) {
|
||||
textLayout.setOnClickListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
@@ -116,16 +108,16 @@ public class ApnPreference extends Preference implements
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(android.view.View v) {
|
||||
if ((v != null) && (R.id.text_layout == v.getId())) {
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
int pos = Integer.parseInt(getKey());
|
||||
Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
|
||||
Intent editIntent = new Intent(Intent.ACTION_EDIT, url);
|
||||
editIntent.putExtra(ApnSettings.SUB_ID, mSubId);
|
||||
context.startActivity(editIntent);
|
||||
}
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
int pos = Integer.parseInt(getKey());
|
||||
Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
|
||||
Intent editIntent = new Intent(Intent.ACTION_EDIT, url);
|
||||
editIntent.putExtra(ApnSettings.SUB_ID, mSubId);
|
||||
context.startActivity(editIntent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -65,8 +64,7 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ApnSettings extends RestrictedSettingsFragment implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
public class ApnSettings extends RestrictedSettingsFragment {
|
||||
static final String TAG = "ApnSettings";
|
||||
|
||||
public static final String EXTRA_POSITION = "position";
|
||||
@@ -313,7 +311,6 @@ public class ApnSettings extends RestrictedSettingsFragment implements
|
||||
pref.setTitle(name);
|
||||
pref.setSummary(apn);
|
||||
pref.setPersistent(false);
|
||||
pref.setOnPreferenceChangeListener(this);
|
||||
pref.setSubId(subId);
|
||||
|
||||
boolean selectable = ((type == null) || !type.equals("mms"));
|
||||
@@ -405,14 +402,6 @@ public class ApnSettings extends RestrictedSettingsFragment implements
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(Preference preference) {
|
||||
int pos = Integer.parseInt(preference.getKey());
|
||||
Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
|
||||
startActivity(new Intent(Intent.ACTION_EDIT, url));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
Log.d(TAG, "onPreferenceChange(): Preference - " + preference
|
||||
+ ", newValue - " + newValue + ", newValue type - "
|
||||
|
||||
@@ -180,7 +180,7 @@ public class EnabledNetworkModePreferenceController extends BasePreferenceContro
|
||||
preference.setEntryValues(
|
||||
R.array.enabled_networks_tdscdma_values);
|
||||
} else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)
|
||||
&& !resources.getBoolean(R.bool.config_enabled_lte)) {
|
||||
&& !carrierConfig.getBoolean(CarrierConfigManager.KEY_LTE_ENABLED_BOOL)) {
|
||||
preference.setEntries(R.array.enabled_networks_except_gsm_lte_choices);
|
||||
preference.setEntryValues(R.array.enabled_networks_except_gsm_lte_values);
|
||||
} else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
|
||||
@@ -190,7 +190,7 @@ public class EnabledNetworkModePreferenceController extends BasePreferenceContro
|
||||
preference.setEntries(select);
|
||||
preference.setEntryValues(
|
||||
R.array.enabled_networks_except_gsm_values);
|
||||
} else if (!resources.getBoolean(R.bool.config_enabled_lte)) {
|
||||
} else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_LTE_ENABLED_BOOL)) {
|
||||
preference.setEntries(
|
||||
R.array.enabled_networks_except_lte_choices);
|
||||
preference.setEntryValues(
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.database.Cursor;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.SystemProperties;
|
||||
import android.provider.Settings;
|
||||
import android.service.carrier.CarrierMessagingService;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
@@ -329,28 +330,11 @@ public class MobileNetworkUtils {
|
||||
* settings
|
||||
*/
|
||||
public static boolean isWorldMode(Context context, int subId) {
|
||||
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(subId);
|
||||
boolean worldModeOn = false;
|
||||
final String configString = context.getString(R.string.config_world_mode);
|
||||
|
||||
if (!TextUtils.isEmpty(configString)) {
|
||||
String[] configArray = configString.split(";");
|
||||
// Check if we have World mode configuration set to True only or config is set to True
|
||||
// and SIM GID value is also set and matches to the current SIM GID.
|
||||
if (configArray != null &&
|
||||
((configArray.length == 1 && configArray[0].equalsIgnoreCase("true"))
|
||||
|| (configArray.length == 2 && !TextUtils.isEmpty(configArray[1])
|
||||
&& telephonyManager != null
|
||||
&& configArray[1].equalsIgnoreCase(
|
||||
telephonyManager.getGroupIdLevel1())))) {
|
||||
worldModeOn = true;
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(TAG, "isWorldMode=" + worldModeOn);
|
||||
|
||||
return worldModeOn;
|
||||
final PersistableBundle carrierConfig = context.getSystemService(
|
||||
CarrierConfigManager.class).getConfigForSubId(subId);
|
||||
return carrierConfig == null
|
||||
? false
|
||||
: carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,14 +380,21 @@ public class MobileNetworkUtils {
|
||||
|
||||
//TODO(b/117651939): move it to telephony
|
||||
private static boolean isTdscdmaSupported(Context context, TelephonyManager telephonyManager) {
|
||||
if (context.getResources().getBoolean(R.bool.config_support_tdscdma)) {
|
||||
final PersistableBundle carrierConfig = context.getSystemService(
|
||||
CarrierConfigManager.class).getConfig();
|
||||
|
||||
if (carrierConfig == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (carrierConfig.getBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String operatorNumeric = telephonyManager.getServiceState().getOperatorNumeric();
|
||||
String[] numericArray = context.getResources().getStringArray(
|
||||
R.array.config_support_tdscdma_roaming_on_networks);
|
||||
if (numericArray.length == 0 || operatorNumeric == null) {
|
||||
String[] numericArray = carrierConfig.getStringArray(
|
||||
CarrierConfigManager.KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY);
|
||||
if (numericArray == null || operatorNumeric == null) {
|
||||
return false;
|
||||
}
|
||||
for (String numeric : numericArray) {
|
||||
@@ -413,4 +404,4 @@ public class MobileNetworkUtils {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,6 +264,10 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Class<? extends ChooseLockGeneric.InternalActivity> getInternalActivityClass() {
|
||||
return ChooseLockGeneric.InternalActivity.class;
|
||||
}
|
||||
|
||||
protected void addHeaderView() {
|
||||
if (mForFingerprint) {
|
||||
setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
|
||||
@@ -291,7 +295,7 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
return true;
|
||||
} else if (KEY_SKIP_FINGERPRINT.equals(key) || KEY_SKIP_FACE.equals(key)) {
|
||||
Intent chooseLockGenericIntent = new Intent(getActivity(),
|
||||
ChooseLockGeneric.InternalActivity.class);
|
||||
getInternalActivityClass());
|
||||
chooseLockGenericIntent.setAction(getIntent().getAction());
|
||||
// Forward the target user id to ChooseLockGeneric.
|
||||
chooseLockGenericIntent.putExtra(Intent.EXTRA_USER_ID, mUserId);
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -135,6 +136,11 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ChooseLockGeneric.InternalActivity> getInternalActivityClass() {
|
||||
return SetupChooseLockGeneric.InternalActivity.class;
|
||||
}
|
||||
|
||||
/***
|
||||
* Disables preferences that are less secure than required quality and shows only secure
|
||||
* screen lock options here.
|
||||
@@ -207,4 +213,25 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric {
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InternalActivity extends ChooseLockGeneric.InternalActivity {
|
||||
@Override
|
||||
protected boolean isValidFragment(String fragmentName) {
|
||||
return InternalSetupChooseLockGenericFragment.class.getName().equals(fragmentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
/* package */ Class<? extends Fragment> getFragmentClass() {
|
||||
return InternalSetupChooseLockGenericFragment.class;
|
||||
}
|
||||
|
||||
public static class InternalSetupChooseLockGenericFragment
|
||||
extends ChooseLockGenericFragment {
|
||||
@Override
|
||||
protected boolean canRunBeforeDeviceProvisioned() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print;
|
||||
|
||||
import android.content.Context;
|
||||
import android.print.PrintJob;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.text.TextUtils;
|
||||
|
||||
public class PrintJobMessagePreferenceController extends PrintJobPreferenceControllerBase {
|
||||
|
||||
public PrintJobMessagePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateUi() {
|
||||
final PrintJob printJob = getPrintJob();
|
||||
|
||||
if (printJob == null) {
|
||||
mFragment.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (printJob.isCancelled() || printJob.isCompleted()) {
|
||||
mFragment.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
final PrintJobInfo info = printJob.getInfo();
|
||||
final CharSequence status = info.getStatus(mContext.getPackageManager());
|
||||
mPreference.setVisible(!TextUtils.isEmpty(status));
|
||||
mPreference.setSummary(status);
|
||||
}
|
||||
}
|
||||
115
src/com/android/settings/print/PrintJobPreferenceController.java
Normal file
115
src/com/android/settings/print/PrintJobPreferenceController.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.print.PrintJob;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.text.format.DateUtils;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.text.DateFormat;
|
||||
|
||||
public class PrintJobPreferenceController extends PrintJobPreferenceControllerBase {
|
||||
|
||||
public PrintJobPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateUi() {
|
||||
final PrintJob printJob = getPrintJob();
|
||||
|
||||
if (printJob == null) {
|
||||
mFragment.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (printJob.isCancelled() || printJob.isCompleted()) {
|
||||
mFragment.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
PrintJobInfo info = printJob.getInfo();
|
||||
|
||||
switch (info.getState()) {
|
||||
case PrintJobInfo.STATE_CREATED: {
|
||||
mPreference.setTitle(mContext.getString(
|
||||
R.string.print_configuring_state_title_template, info.getLabel()));
|
||||
}
|
||||
break;
|
||||
case PrintJobInfo.STATE_QUEUED:
|
||||
case PrintJobInfo.STATE_STARTED: {
|
||||
if (!printJob.getInfo().isCancelling()) {
|
||||
mPreference.setTitle(mContext.getString(
|
||||
R.string.print_printing_state_title_template, info.getLabel()));
|
||||
} else {
|
||||
mPreference.setTitle(mContext.getString(
|
||||
R.string.print_cancelling_state_title_template, info.getLabel()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PrintJobInfo.STATE_FAILED: {
|
||||
mPreference.setTitle(mContext.getString(
|
||||
R.string.print_failed_state_title_template, info.getLabel()));
|
||||
}
|
||||
break;
|
||||
|
||||
case PrintJobInfo.STATE_BLOCKED: {
|
||||
if (!printJob.getInfo().isCancelling()) {
|
||||
mPreference.setTitle(mContext.getString(
|
||||
R.string.print_blocked_state_title_template, info.getLabel()));
|
||||
} else {
|
||||
mPreference.setTitle(mContext.getString(
|
||||
R.string.print_cancelling_state_title_template, info.getLabel()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
mPreference.setSummary(mContext.getString(R.string.print_job_summary,
|
||||
info.getPrinterName(), DateUtils.formatSameDayTime(
|
||||
info.getCreationTime(), info.getCreationTime(), DateFormat.SHORT,
|
||||
DateFormat.SHORT)));
|
||||
|
||||
TypedArray a = mContext.obtainStyledAttributes(new int[]{
|
||||
android.R.attr.colorControlNormal});
|
||||
int tintColor = a.getColor(0, 0);
|
||||
a.recycle();
|
||||
|
||||
switch (info.getState()) {
|
||||
case PrintJobInfo.STATE_QUEUED:
|
||||
case PrintJobInfo.STATE_STARTED: {
|
||||
Drawable icon = mContext.getDrawable(com.android.internal.R.drawable.ic_print);
|
||||
icon.setTint(tintColor);
|
||||
mPreference.setIcon(icon);
|
||||
break;
|
||||
}
|
||||
|
||||
case PrintJobInfo.STATE_FAILED:
|
||||
case PrintJobInfo.STATE_BLOCKED: {
|
||||
Drawable icon = mContext.getDrawable(
|
||||
com.android.internal.R.drawable.ic_print_error);
|
||||
icon.setTint(tintColor);
|
||||
mPreference.setIcon(icon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print;
|
||||
|
||||
import android.content.Context;
|
||||
import android.print.PrintJob;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
|
||||
public abstract class PrintJobPreferenceControllerBase extends BasePreferenceController implements
|
||||
LifecycleObserver, OnStart, OnStop, PrintManager.PrintJobStateChangeListener {
|
||||
private static final String TAG = "PrintJobPrefCtrlBase";
|
||||
|
||||
private static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
|
||||
|
||||
private final PrintManager mPrintManager;
|
||||
protected Preference mPreference;
|
||||
protected PrintJobSettingsFragment mFragment;
|
||||
protected PrintJobId mPrintJobId;
|
||||
|
||||
public PrintJobPreferenceControllerBase(Context context, String key) {
|
||||
super(context, key);
|
||||
mPrintManager = ((PrintManager) mContext.getSystemService(
|
||||
Context.PRINT_SERVICE)).getGlobalPrintManagerForUser(mContext.getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
mPrintManager.addPrintJobStateChangeListener(this);
|
||||
updateUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
mPrintManager.removePrintJobStateChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintJobStateChanged(PrintJobId printJobId) {
|
||||
updateUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
public void init(PrintJobSettingsFragment fragment) {
|
||||
mFragment = fragment;
|
||||
processArguments();
|
||||
}
|
||||
|
||||
protected PrintJob getPrintJob() {
|
||||
return mPrintManager.getPrintJob(mPrintJobId);
|
||||
}
|
||||
|
||||
protected abstract void updateUi();
|
||||
|
||||
private void processArguments() {
|
||||
String printJobId = mFragment.getArguments().getString(EXTRA_PRINT_JOB_ID);
|
||||
if (printJobId == null) {
|
||||
printJobId = mFragment.getActivity().getIntent().getStringExtra(EXTRA_PRINT_JOB_ID);
|
||||
|
||||
if (printJobId == null) {
|
||||
Log.w(TAG, EXTRA_PRINT_JOB_ID + " not set");
|
||||
mFragment.finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
mPrintJobId = PrintJobId.unflattenFromString(printJobId);
|
||||
}
|
||||
}
|
||||
@@ -17,114 +17,59 @@
|
||||
package com.android.settings.print;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.print.PrintJob;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.print.PrintManager.PrintJobStateChangeListener;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
|
||||
/**
|
||||
* Fragment for management of a print job.
|
||||
*/
|
||||
public class PrintJobSettingsFragment extends SettingsPreferenceFragment {
|
||||
private static final String LOG_TAG = PrintJobSettingsFragment.class.getSimpleName();
|
||||
public class PrintJobSettingsFragment extends DashboardFragment {
|
||||
private static final String TAG = "PrintJobSettingsFragment";
|
||||
|
||||
private static final int MENU_ITEM_ID_CANCEL = 1;
|
||||
private static final int MENU_ITEM_ID_RESTART = 2;
|
||||
|
||||
private static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.print_job_settings;
|
||||
}
|
||||
|
||||
private static final String PRINT_JOB_PREFERENCE = "print_job_preference";
|
||||
private static final String PRINT_JOB_MESSAGE_PREFERENCE = "print_job_message_preference";
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
private final PrintJobStateChangeListener mPrintJobStateChangeListener =
|
||||
new PrintJobStateChangeListener() {
|
||||
@Override
|
||||
public void onPrintJobStateChanged(PrintJobId printJobId) {
|
||||
updateUi();
|
||||
}
|
||||
};
|
||||
|
||||
private PrintManager mPrintManager;
|
||||
|
||||
private Preference mPrintJobPreference;
|
||||
private Preference mMessagePreference;
|
||||
|
||||
private PrintJobId mPrintJobId;
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(PrintJobPreferenceController.class).init(this);
|
||||
use(PrintJobMessagePreferenceController.class).init(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.PRINT_JOB_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.print_job_settings);
|
||||
mPrintJobPreference = findPreference(PRINT_JOB_PREFERENCE);
|
||||
mMessagePreference = findPreference(PRINT_JOB_MESSAGE_PREFERENCE);
|
||||
|
||||
mPrintManager = ((PrintManager) getActivity().getSystemService(
|
||||
Context.PRINT_SERVICE)).getGlobalPrintManagerForUser(
|
||||
getActivity().getUserId());
|
||||
|
||||
getActivity().getActionBar().setTitle(R.string.print_print_job);
|
||||
|
||||
processArguments();
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
getListView().setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mPrintManager.addPrintJobStateChangeListener(
|
||||
mPrintJobStateChangeListener);
|
||||
updateUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mPrintManager.removePrintJobStateChangeListener(
|
||||
mPrintJobStateChangeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
|
||||
PrintJob printJob = getPrintJob();
|
||||
final PrintJob printJob = use(PrintJobPreferenceController.class).getPrintJob();
|
||||
if (printJob == null) {
|
||||
return;
|
||||
}
|
||||
@@ -144,7 +89,7 @@ public class PrintJobSettingsFragment extends SettingsPreferenceFragment {
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
PrintJob printJob = getPrintJob();
|
||||
final PrintJob printJob = use(PrintJobPreferenceController.class).getPrintJob();
|
||||
|
||||
if (printJob != null) {
|
||||
switch (item.getItemId()) {
|
||||
@@ -164,113 +109,4 @@ public class PrintJobSettingsFragment extends SettingsPreferenceFragment {
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void processArguments() {
|
||||
String printJobId = getArguments().getString(EXTRA_PRINT_JOB_ID);
|
||||
if (printJobId == null) {
|
||||
printJobId = getIntent().getStringExtra(EXTRA_PRINT_JOB_ID);
|
||||
|
||||
if (printJobId == null) {
|
||||
Log.w(LOG_TAG, EXTRA_PRINT_JOB_ID + " not set");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mPrintJobId = PrintJobId.unflattenFromString(printJobId);
|
||||
}
|
||||
|
||||
private PrintJob getPrintJob() {
|
||||
return mPrintManager.getPrintJob(mPrintJobId);
|
||||
}
|
||||
|
||||
private void updateUi() {
|
||||
PrintJob printJob = getPrintJob();
|
||||
|
||||
if (printJob == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (printJob.isCancelled() || printJob.isCompleted()) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
PrintJobInfo info = printJob.getInfo();
|
||||
|
||||
switch (info.getState()) {
|
||||
case PrintJobInfo.STATE_CREATED: {
|
||||
mPrintJobPreference.setTitle(getString(
|
||||
R.string.print_configuring_state_title_template, info.getLabel()));
|
||||
} break;
|
||||
case PrintJobInfo.STATE_QUEUED:
|
||||
case PrintJobInfo.STATE_STARTED: {
|
||||
if (!printJob.getInfo().isCancelling()) {
|
||||
mPrintJobPreference.setTitle(getString(
|
||||
R.string.print_printing_state_title_template, info.getLabel()));
|
||||
} else {
|
||||
mPrintJobPreference.setTitle(getString(
|
||||
R.string.print_cancelling_state_title_template, info.getLabel()));
|
||||
}
|
||||
} break;
|
||||
|
||||
case PrintJobInfo.STATE_FAILED: {
|
||||
mPrintJobPreference.setTitle(getString(
|
||||
R.string.print_failed_state_title_template, info.getLabel()));
|
||||
} break;
|
||||
|
||||
case PrintJobInfo.STATE_BLOCKED: {
|
||||
if (!printJob.getInfo().isCancelling()) {
|
||||
mPrintJobPreference.setTitle(getString(
|
||||
R.string.print_blocked_state_title_template, info.getLabel()));
|
||||
} else {
|
||||
mPrintJobPreference.setTitle(getString(
|
||||
R.string.print_cancelling_state_title_template, info.getLabel()));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
mPrintJobPreference.setSummary(getString(R.string.print_job_summary,
|
||||
info.getPrinterName(), DateUtils.formatSameDayTime(
|
||||
info.getCreationTime(), info.getCreationTime(), DateFormat.SHORT,
|
||||
DateFormat.SHORT)));
|
||||
|
||||
TypedArray a = getActivity().obtainStyledAttributes(new int[]{
|
||||
android.R.attr.colorControlNormal});
|
||||
int tintColor = a.getColor(0, 0);
|
||||
a.recycle();
|
||||
|
||||
switch (info.getState()) {
|
||||
case PrintJobInfo.STATE_QUEUED:
|
||||
case PrintJobInfo.STATE_STARTED: {
|
||||
Drawable icon = getActivity().getDrawable(com.android.internal.R.drawable.ic_print);
|
||||
icon.setTint(tintColor);
|
||||
mPrintJobPreference.setIcon(icon);
|
||||
break;
|
||||
}
|
||||
|
||||
case PrintJobInfo.STATE_FAILED:
|
||||
case PrintJobInfo.STATE_BLOCKED: {
|
||||
Drawable icon = getActivity().getDrawable(
|
||||
com.android.internal.R.drawable.ic_print_error);
|
||||
icon.setTint(tintColor);
|
||||
mPrintJobPreference.setIcon(icon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CharSequence status = info.getStatus(getPackageManager());
|
||||
if (!TextUtils.isEmpty(status)) {
|
||||
if (getPreferenceScreen().findPreference(PRINT_JOB_MESSAGE_PREFERENCE) == null) {
|
||||
getPreferenceScreen().addPreference(mMessagePreference);
|
||||
}
|
||||
mMessagePreference.setSummary(status);
|
||||
} else {
|
||||
getPreferenceScreen().removePreference(mMessagePreference);
|
||||
}
|
||||
|
||||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,6 +454,13 @@ public class WifiConfigController implements TextWatcher,
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isValidSaePassword(String password) {
|
||||
if (password.length() >= 1 && password.length() <= 63) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isSubmittable() {
|
||||
boolean enabled = false;
|
||||
boolean passwordInvalid = false;
|
||||
@@ -461,7 +468,9 @@ public class WifiConfigController implements TextWatcher,
|
||||
&& ((mAccessPointSecurity == AccessPoint.SECURITY_WEP
|
||||
&& mPasswordView.length() == 0)
|
||||
|| (mAccessPointSecurity == AccessPoint.SECURITY_PSK
|
||||
&& !isValidPsk(mPasswordView.getText().toString())))) {
|
||||
&& !isValidPsk(mPasswordView.getText().toString()))
|
||||
|| (mAccessPointSecurity == AccessPoint.SECURITY_SAE
|
||||
&& !isValidSaePassword(mPasswordView.getText().toString())))) {
|
||||
passwordInvalid = true;
|
||||
}
|
||||
if ((mSsidView != null && mSsidView.length() == 0)
|
||||
@@ -475,7 +484,9 @@ public class WifiConfigController implements TextWatcher,
|
||||
} else {
|
||||
enabled = ipAndProxyFieldsAreValid();
|
||||
}
|
||||
if (mAccessPointSecurity == AccessPoint.SECURITY_EAP && mEapCaCertSpinner != null
|
||||
if ((mAccessPointSecurity == AccessPoint.SECURITY_EAP ||
|
||||
mAccessPointSecurity == AccessPoint.SECURITY_EAP_SUITE_B)
|
||||
&& mEapCaCertSpinner != null
|
||||
&& mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) {
|
||||
String caCertSelection = (String) mEapCaCertSpinner.getSelectedItem();
|
||||
if (caCertSelection.equals(mUnspecifiedCertString)) {
|
||||
@@ -492,7 +503,9 @@ public class WifiConfigController implements TextWatcher,
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
if (mAccessPointSecurity == AccessPoint.SECURITY_EAP && mEapUserCertSpinner != null
|
||||
if ((mAccessPointSecurity == AccessPoint.SECURITY_EAP ||
|
||||
mAccessPointSecurity == AccessPoint.SECURITY_EAP_SUITE_B)
|
||||
&& mEapUserCertSpinner != null
|
||||
&& mView.findViewById(R.id.l_user_cert).getVisibility() != View.GONE
|
||||
&& mEapUserCertSpinner.getSelectedItem().equals(mUnspecifiedCertString)) {
|
||||
// Disallow submit if the user has not selected a user certificate for an EAP network
|
||||
@@ -590,8 +603,18 @@ public class WifiConfigController implements TextWatcher,
|
||||
break;
|
||||
|
||||
case AccessPoint.SECURITY_EAP:
|
||||
case AccessPoint.SECURITY_EAP_SUITE_B:
|
||||
config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
|
||||
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
|
||||
if (mAccessPointSecurity == AccessPoint.SECURITY_EAP_SUITE_B) {
|
||||
config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
|
||||
config.requirePMF = true;
|
||||
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
|
||||
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
|
||||
config.allowedGroupMgmtCiphers.set(WifiConfiguration.GroupMgmtCipher
|
||||
.BIP_GMAC_256);
|
||||
config.allowedSuiteBCiphers.set(WifiConfiguration.SuiteBCipher.ECDHE_RSA);
|
||||
}
|
||||
config.enterpriseConfig = new WifiEnterpriseConfig();
|
||||
int eapMethod = mEapMethodSpinner.getSelectedItemPosition();
|
||||
int phase2Method = mPhase2Spinner.getSelectedItemPosition();
|
||||
@@ -700,6 +723,20 @@ public class WifiConfigController implements TextWatcher,
|
||||
config.enterpriseConfig.setPassword(mPasswordView.getText().toString());
|
||||
}
|
||||
break;
|
||||
case AccessPoint.SECURITY_SAE:
|
||||
config.allowedKeyManagement.set(KeyMgmt.SAE);
|
||||
config.requirePMF = true;
|
||||
if (mPasswordView.length() != 0) {
|
||||
String password = mPasswordView.getText().toString();
|
||||
config.preSharedKey = '"' + password + '"';
|
||||
}
|
||||
break;
|
||||
|
||||
case AccessPoint.SECURITY_OWE:
|
||||
config.allowedKeyManagement.set(KeyMgmt.OWE);
|
||||
config.requirePMF = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -851,7 +888,8 @@ public class WifiConfigController implements TextWatcher,
|
||||
}
|
||||
|
||||
private void showSecurityFields() {
|
||||
if (mAccessPointSecurity == AccessPoint.SECURITY_NONE) {
|
||||
if (mAccessPointSecurity == AccessPoint.SECURITY_NONE ||
|
||||
mAccessPointSecurity == AccessPoint.SECURITY_OWE) {
|
||||
mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
@@ -870,7 +908,8 @@ public class WifiConfigController implements TextWatcher,
|
||||
}
|
||||
}
|
||||
|
||||
if (mAccessPointSecurity != AccessPoint.SECURITY_EAP) {
|
||||
if (mAccessPointSecurity != AccessPoint.SECURITY_EAP &&
|
||||
mAccessPointSecurity != AccessPoint.SECURITY_EAP_SUITE_B) {
|
||||
mView.findViewById(R.id.eap).setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -488,7 +488,8 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
|
||||
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
|
||||
if (nfcAdapter != null && nfcAdapter.isEnabled() &&
|
||||
mSelectedAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
|
||||
(!(mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
|
||||
(mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE))) {
|
||||
// Only allow writing of NFC tags for password-protected networks.
|
||||
menu.add(Menu.NONE, MENU_ID_WRITE_NFC, 0, R.string.wifi_menu_write_to_nfc);
|
||||
}
|
||||
@@ -506,7 +507,8 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
boolean isSavedNetwork = mSelectedAccessPoint.isSaved();
|
||||
if (isSavedNetwork) {
|
||||
connect(mSelectedAccessPoint.getConfig(), isSavedNetwork);
|
||||
} else if (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) {
|
||||
} else if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
|
||||
(mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) {
|
||||
/** Bypass dialog for unsecured networks */
|
||||
mSelectedAccessPoint.generateOpenNetworkConfig();
|
||||
connect(mSelectedAccessPoint.getConfig(), isSavedNetwork);
|
||||
@@ -552,7 +554,8 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
* networks, or Passpoint provided networks.
|
||||
*/
|
||||
WifiConfiguration config = mSelectedAccessPoint.getConfig();
|
||||
if (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) {
|
||||
if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
|
||||
(mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) {
|
||||
mSelectedAccessPoint.generateOpenNetworkConfig();
|
||||
connect(mSelectedAccessPoint.getConfig(), mSelectedAccessPoint.isSaved());
|
||||
} else if (mSelectedAccessPoint.isSaved() && config != null
|
||||
@@ -772,7 +775,8 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
preference.setKey(key);
|
||||
preference.setOrder(index);
|
||||
if (mOpenSsid != null && mOpenSsid.equals(accessPoint.getSsidStr())
|
||||
&& accessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
|
||||
&& (accessPoint.getSecurity() != AccessPoint.SECURITY_NONE &&
|
||||
accessPoint.getSecurity() != AccessPoint.SECURITY_OWE)) {
|
||||
if (!accessPoint.isSaved() || isDisabledByWrongPassword(accessPoint)) {
|
||||
onPreferenceTreeClick(preference);
|
||||
mOpenSsid = null;
|
||||
|
||||
@@ -67,7 +67,7 @@ public class WifiPrivacyPreferenceController extends BasePreferenceController im
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (mWifiConfiguration != null) {
|
||||
//TODO(b/117957974): update MAC randomization level to WifiManager
|
||||
mWifiConfiguration.macRandomizationSetting = Integer.parseInt((String) newValue);
|
||||
mWifiManager.updateNetwork(mWifiConfiguration);
|
||||
}
|
||||
updateSummary((DropDownPreference) preference, Integer.parseInt((String) newValue));
|
||||
@@ -77,10 +77,9 @@ public class WifiPrivacyPreferenceController extends BasePreferenceController im
|
||||
@VisibleForTesting
|
||||
int getRandomizationValue() {
|
||||
if (mWifiConfiguration != null) {
|
||||
//TODO(b/117957974): get real MAC randomization level from WifiManager
|
||||
return 0;
|
||||
return mWifiConfiguration.macRandomizationSetting;
|
||||
}
|
||||
return 0;
|
||||
return WifiConfiguration.RANDOMIZATION_PERSISTENT;
|
||||
}
|
||||
|
||||
private void updateSummary(DropDownPreference preference, int macRandomized) {
|
||||
|
||||
@@ -15,7 +15,6 @@ com.android.settings.applications.appinfo.WriteSettingsDetails
|
||||
com.android.settings.applications.AppLaunchSettings
|
||||
com.android.settings.applications.AppStorageSettings
|
||||
com.android.settings.applications.ConfirmConvertToFbe
|
||||
com.android.settings.applications.DirectoryAccessDetails
|
||||
com.android.settings.applications.ProcessStatsDetail
|
||||
com.android.settings.applications.ProcessStatsSummary
|
||||
com.android.settings.applications.ProcessStatsUi
|
||||
@@ -59,6 +58,7 @@ com.android.settings.notification.RedactionInterstitial$RedactionInterstitialFra
|
||||
com.android.settings.notification.ZenModeEventRuleSettings
|
||||
com.android.settings.notification.ZenModeScheduleRuleSettings
|
||||
com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
|
||||
com.android.settings.password.SetupChooseLockGeneric$InternalActivity$InternalSetupChooseLockGenericFragment
|
||||
com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
|
||||
com.android.settings.print.PrintJobSettingsFragment
|
||||
com.android.settings.print.PrintServiceSettingsFragment
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
<bool name="config_show_wifi_mac_address">false</bool>
|
||||
<bool name="config_disable_uninstall_update">true</bool>
|
||||
<bool name="config_show_device_name">false</bool>
|
||||
<bool name="config_use_legacy_suggestion">false</bool>
|
||||
<bool name="config_show_avatar_in_homepage">true</bool>
|
||||
|
||||
<!-- Whether or not extra preview panels should be used for screen zoom setting. -->
|
||||
<bool name="config_enable_extra_screen_zoom_preview">false</bool>
|
||||
|
||||
@@ -18,18 +18,22 @@ package com.android.settings.accounts;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.settings.homepage.SettingsHomepageActivity;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
@@ -39,50 +43,92 @@ import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class AvatarViewMixinTest {
|
||||
private static final String DUMMY_ACCOUNT = "test@domain.com";
|
||||
private static final String DUMMY_DOMAIN = "domain.com";
|
||||
private static final String DUMMY_AUTHORITY = "authority.domain.com";
|
||||
|
||||
private Context mContext;
|
||||
private ImageView mImageView;
|
||||
private ActivityController mController;
|
||||
private SettingsHomepageActivity mActivity;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mImageView = new ImageView(mContext);
|
||||
mController = Robolectric.buildActivity(SettingsHomepageActivity.class).create();
|
||||
mActivity = (SettingsHomepageActivity) mController.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasAccount_useDefaultAccountData_returnFalse() {
|
||||
final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mContext, mImageView);
|
||||
final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
|
||||
assertThat(avatarViewMixin.hasAccount()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowAccountFeatureProviderImpl.class)
|
||||
public void hasAccount_useShadowAccountData_returnTrue() {
|
||||
final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mContext, mImageView);
|
||||
final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
|
||||
assertThat(avatarViewMixin.hasAccount()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
|
||||
final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mContext, mImageView));
|
||||
public void onStart_configDisabled_doNothing() {
|
||||
final AvatarViewMixin mixin = spy(new AvatarViewMixin(mActivity, mImageView));
|
||||
mixin.onStart();
|
||||
|
||||
final ActivityController controller = Robolectric.buildActivity(
|
||||
SettingsHomepageActivity.class).create();
|
||||
final SettingsHomepageActivity settingsHomepageActivity =
|
||||
(SettingsHomepageActivity) controller.get();
|
||||
settingsHomepageActivity.getLifecycle().addObserver(mockAvatar);
|
||||
controller.start();
|
||||
|
||||
verify(mockAvatar).onStart();
|
||||
verify(mixin, never()).hasAccount();
|
||||
}
|
||||
|
||||
@Implements(AccountFeatureProviderImpl.class)
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
|
||||
final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mActivity, mImageView));
|
||||
|
||||
mActivity.getLifecycle().addObserver(mockAvatar);
|
||||
mController.start();
|
||||
|
||||
verify(mockAvatar).hasAccount();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryProviderAuthority_useShadowPackagteManager_returnNull() {
|
||||
final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
|
||||
|
||||
assertThat(avatarViewMixin.queryProviderAuthority()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryProviderAuthority_useNewShadowPackagteManager_returnAuthority() {
|
||||
final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
|
||||
ShadowPackageManager shadowPackageManager = Shadow.extract(mContext.getPackageManager());
|
||||
final PackageInfo accountProvider = new PackageInfo();
|
||||
accountProvider.packageName = "test.pkg";
|
||||
accountProvider.applicationInfo = new ApplicationInfo();
|
||||
accountProvider.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
|
||||
accountProvider.applicationInfo.packageName = accountProvider.packageName;
|
||||
accountProvider.providers = new ProviderInfo[1];
|
||||
accountProvider.providers[0] = new ProviderInfo();
|
||||
accountProvider.providers[0].authority = DUMMY_AUTHORITY;
|
||||
accountProvider.providers[0].packageName = accountProvider.packageName;
|
||||
accountProvider.providers[0].name = "test.class";
|
||||
accountProvider.providers[0].applicationInfo = accountProvider.applicationInfo;
|
||||
|
||||
final ResolveInfo resolveInfo = new ResolveInfo();
|
||||
resolveInfo.providerInfo = accountProvider.providers[0];
|
||||
shadowPackageManager.addResolveInfoForIntent(AvatarViewMixin.INTENT_GET_ACCOUNT_DATA,
|
||||
resolveInfo);
|
||||
assertThat(avatarViewMixin.queryProviderAuthority()).isEqualTo(DUMMY_AUTHORITY);
|
||||
}
|
||||
|
||||
@Implements(value = AccountFeatureProviderImpl.class)
|
||||
public static class ShadowAccountFeatureProviderImpl {
|
||||
|
||||
@Implementation
|
||||
|
||||
@@ -106,15 +106,12 @@ public class AppHeaderViewPreferenceControllerTest {
|
||||
|
||||
|
||||
final TextView title = mHeader.findViewById(R.id.entity_header_title);
|
||||
final TextView summary = mHeader.findViewById(R.id.entity_header_summary);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.refreshUi();
|
||||
|
||||
assertThat(title).isNotNull();
|
||||
assertThat(title.getText()).isEqualTo(appLabel);
|
||||
assertThat(summary).isNotNull();
|
||||
assertThat(summary.getText()).isEqualTo(mContext.getString(R.string.installed));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
package com.android.settings.connecteddevice;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class BluetoothOnWhileDrivingPreferenceControllerTest {
|
||||
|
||||
private BluetoothOnWhileDrivingPreferenceController mController;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new BluetoothOnWhileDrivingPreferenceController(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_onWhenEnabled() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.BLUETOOTH_WHILE_DRIVING, true);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_offWhenDisabled() {
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_togglesSettingSecure() {
|
||||
mController.setChecked(true);
|
||||
|
||||
final String name = Secure.BLUETOOTH_ON_WHILE_DRIVING;
|
||||
assertThat(Settings.Secure.getInt(mContext.getContentResolver(), name, 0)).isEqualTo(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
|
||||
|
||||
import static com.android.settings.development.DesktopModePreferenceController.SETTING_VALUE_OFF;
|
||||
import static com.android.settings.development.DesktopModePreferenceController.SETTING_VALUE_ON;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
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;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class DesktopModePreferenceControllerTest {
|
||||
|
||||
private static final String ENG_BUILD_TYPE = "eng";
|
||||
private static final String USER_BUILD_TYPE = "user";
|
||||
|
||||
@Mock
|
||||
private SwitchPreference mPreference;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
private Context mContext;
|
||||
private DesktopModePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new DesktopModePreferenceController(mContext);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_engBuild_shouldBeTrue() {
|
||||
mController = spy(mController);
|
||||
doReturn(ENG_BUILD_TYPE).when(mController).getBuildType();
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvaiable_userBuild_shouldBeTrue() {
|
||||
mController = spy(mController);
|
||||
doReturn(USER_BUILD_TYPE).when(mController).getBuildType();
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_switchEnabled_shouldEnableFreeformWindows() {
|
||||
mController.onPreferenceChange(mPreference, true /* new value */);
|
||||
|
||||
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
|
||||
assertThat(mode).isEqualTo(SETTING_VALUE_ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_switchDisabled_shouldDisableFreeformWindows() {
|
||||
mController.onPreferenceChange(mPreference, false /* new value */);
|
||||
|
||||
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
|
||||
assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_settingEnabled_preferenceShouldBeChecked() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_ON);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
|
||||
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
|
||||
assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
|
||||
verify(mPreference).setEnabled(false);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package com.android.settings.development;
|
||||
import static com.android.settings.development.FreeformWindowsPreferenceController
|
||||
.SETTING_VALUE_OFF;
|
||||
import static com.android.settings.development.FreeformWindowsPreferenceController.SETTING_VALUE_ON;
|
||||
import static com.android.settings.development.FreeformWindowsPreferenceController.USER_BUILD_TYPE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -47,6 +46,7 @@ import org.robolectric.RuntimeEnvironment;
|
||||
public class FreeformWindowsPreferenceControllerTest {
|
||||
|
||||
private static final String ENG_BUILD_TYPE = "eng";
|
||||
private static final String USER_BUILD_TYPE = "user";
|
||||
|
||||
@Mock
|
||||
private SwitchPreference mPreference;
|
||||
@@ -74,11 +74,11 @@ public class FreeformWindowsPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvaiable_userBuild_shouldBeFalse() {
|
||||
public void isAvaiable_userBuild_shouldBeTrue() {
|
||||
mController = spy(mController);
|
||||
doReturn(USER_BUILD_TYPE).when(mController).getBuildType();
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes.REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
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.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class UpdatedGfxDriverDevOptInPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock
|
||||
private DevelopmentSettingsDashboardFragment mFragment;
|
||||
|
||||
private Context mContext;
|
||||
private Preference mPreference;
|
||||
private UpdatedGfxDriverDevOptInPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = spy(new UpdatedGfxDriverDevOptInPreferenceController(mContext, mFragment));
|
||||
mPreference = new Preference(mContext);
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
|
||||
when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
|
||||
.thenReturn(mPreference);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePreferenceTreeClick_preferenceClicked_launchActivity() {
|
||||
final Intent activityStartIntent = new Intent(mContext, AppPicker.class);
|
||||
final String preferenceKey = mController.getPreferenceKey();
|
||||
doReturn(activityStartIntent).when(mController).getActivityStartIntent();
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
|
||||
verify(mFragment).startActivityForResult(activityStartIntent,
|
||||
REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_foobarAppSelected_shouldUpdateSummaryWithUpdatedDriverDevOptInAppLabel() {
|
||||
final String selectedApp = "foobar";
|
||||
final ContentResolver contentResolver = mContext.getContentResolver();
|
||||
Settings.Global.putString(contentResolver,
|
||||
Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP, selectedApp);
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.updated_gfx_driver_dev_opt_in_app_set, selectedApp));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_noAppSelected_shouldUpdateSummaryWithNoAppSelected() {
|
||||
final String selectedApp = null;
|
||||
final ContentResolver contentResolver = mContext.getContentResolver();
|
||||
Settings.Global.putString(contentResolver,
|
||||
Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP, selectedApp);
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.updated_gfx_driver_dev_opt_in_app_not_set));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActivityResult_foobarAppSelected_shouldUpdateSummaryWithUpdatedDriverDevOptInLabel() {
|
||||
Intent activityResultIntent = new Intent(mContext, AppPicker.class);
|
||||
final String appLabel = "foobar";
|
||||
activityResultIntent.setAction(appLabel);
|
||||
final boolean result = mController
|
||||
.onActivityResult(REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP, Activity.RESULT_OK,
|
||||
activityResultIntent);
|
||||
|
||||
assertThat(result).isTrue();
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.updated_gfx_driver_dev_opt_in_app_set, appLabel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActivityResult_badRequestCode_shouldReturnFalse() {
|
||||
assertThat(mController.onActivityResult(
|
||||
-1 /* requestCode */, -1 /* resultCode */, null /* intent */)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.updated_gfx_driver_dev_opt_in_app_not_set));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,20 @@
|
||||
package com.android.settings.deviceinfo.deviceinfo;
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.deviceinfo.aboutphone;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -6,8 +22,6 @@ import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
|
||||
import com.android.settings.deviceinfo.aboutphone.DeviceNameWarningDialog;
|
||||
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.deviceinfo;
|
||||
package com.android.settings.deviceinfo.aboutphone;
|
||||
|
||||
import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
|
||||
|
||||
@@ -35,7 +35,7 @@ import android.util.ArrayMap;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
|
||||
import com.android.settings.deviceinfo.BuildNumberPreferenceController;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.deviceinfo.aboutphone;
|
||||
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class TopLevelAboutDevicePreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private TopLevelAboutDevicePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new TopLevelAboutDevicePreferenceController(mContext, "test_key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityState_shouldBeAvailable() {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_shouldReturnDeviceModel() {
|
||||
assertThat(mController.getSummary().toString()).isEqualTo(Build.MODEL);
|
||||
}
|
||||
}
|
||||
@@ -258,7 +258,6 @@ public class AdvancedPowerUsageDetailTest {
|
||||
verify(mEntityHeaderController).setIcon(mAppEntry);
|
||||
verify(mEntityHeaderController).setLabel(mAppEntry);
|
||||
verify(mEntityHeaderController).setIsInstantApp(true);
|
||||
verify(mEntityHeaderController).setSummary((CharSequence) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -18,10 +18,12 @@ package com.android.settings.homepage.contextualcards;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import com.android.settings.intelligence.ContextualCardProto;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -30,6 +32,9 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class CardDatabaseHelperTest {
|
||||
|
||||
@@ -80,4 +85,38 @@ public class CardDatabaseHelperTest {
|
||||
assertThat(columnNames).isEqualTo(expectedNames);
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getContextualCards_shouldSortByScore() {
|
||||
insertFakeCard(mDatabase, "card1", 1, "uri1");
|
||||
insertFakeCard(mDatabase, "card2", 0, "uri2");
|
||||
insertFakeCard(mDatabase, "card3", 10, "uri3");
|
||||
// Should sort as 3,1,2
|
||||
try (final Cursor cursor = CardDatabaseHelper.getInstance(mContext).getContextualCards()) {
|
||||
assertThat(cursor.getCount()).isEqualTo(3);
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
||||
cards.add(new ContextualCard(cursor));
|
||||
}
|
||||
assertThat(cards.get(0).getName()).isEqualTo("card3");
|
||||
assertThat(cards.get(1).getName()).isEqualTo("card1");
|
||||
assertThat(cards.get(2).getName()).isEqualTo("card2");
|
||||
}
|
||||
}
|
||||
|
||||
private static void insertFakeCard(SQLiteDatabase db, String name, double score, String uri) {
|
||||
final ContentValues value = new ContentValues();
|
||||
value.put(CardDatabaseHelper.CardColumns.NAME, name);
|
||||
value.put(CardDatabaseHelper.CardColumns.SCORE, score);
|
||||
value.put(CardDatabaseHelper.CardColumns.SLICE_URI, uri);
|
||||
|
||||
value.put(CardDatabaseHelper.CardColumns.TYPE, ContextualCard.CardType.SLICE);
|
||||
value.put(CardDatabaseHelper.CardColumns.CATEGORY,
|
||||
ContextualCardProto.ContextualCard.Category.DEFAULT.getNumber());
|
||||
value.put(CardDatabaseHelper.CardColumns.PACKAGE_NAME,
|
||||
RuntimeEnvironment.application.getPackageName());
|
||||
value.put(CardDatabaseHelper.CardColumns.APP_VERSION, 1);
|
||||
|
||||
db.insert(CardDatabaseHelper.CARD_TABLE, null, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class ConditionalContextualCardTest {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void newInstance_changeCardType_shouldCrash() {
|
||||
new ConditionalContextualCard.Builder()
|
||||
.setCardType(ContextualCard.CardType.SUGGESTION)
|
||||
.setCardType(ContextualCard.CardType.LEGACY_SUGGESTION)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||
import com.android.settingslib.suggestions.SuggestionController;
|
||||
|
||||
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;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowThreadUtils.class)
|
||||
public class LegacySuggestionContextualCardControllerTest {
|
||||
|
||||
@Mock
|
||||
private SuggestionController mSuggestionController;
|
||||
@Mock
|
||||
private ContextualCardUpdateListener mCardUpdateListener;
|
||||
|
||||
private Context mContext;
|
||||
private LegacySuggestionContextualCardController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
FakeFeatureFactory.setupForTest();
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new LegacySuggestionContextualCardController(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void init_configOn_shouldCreateSuggestionController() {
|
||||
final LegacySuggestionContextualCardController controller =
|
||||
new LegacySuggestionContextualCardController(mContext);
|
||||
assertThat(controller.mSuggestionController).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void init_configOff_shouldNotCreateSuggestionController() {
|
||||
final LegacySuggestionContextualCardController controller =
|
||||
new LegacySuggestionContextualCardController(mContext);
|
||||
|
||||
assertThat(controller.mSuggestionController).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void goThroughLifecycle_hasSuggestionController_shouldStartStopController() {
|
||||
mController.mSuggestionController = mSuggestionController;
|
||||
mController.onStart();
|
||||
verify(mSuggestionController).start();
|
||||
|
||||
mController.onStop();
|
||||
verify(mSuggestionController).stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onServiceConnected_shouldLoadSuggestion() {
|
||||
mController.mSuggestionController = mSuggestionController;
|
||||
mController.setCardUpdateListener(mCardUpdateListener);
|
||||
mController.onServiceConnected();
|
||||
|
||||
verify(mSuggestionController).getSuggestions();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
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;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class LegacySuggestionContextualCardRendererTest {
|
||||
@Mock
|
||||
private ControllerRendererPool mControllerRendererPool;
|
||||
@Mock
|
||||
private LegacySuggestionContextualCardController mController;
|
||||
private Context mContext;
|
||||
private LegacySuggestionContextualCardRenderer mRenderer;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mRenderer = new LegacySuggestionContextualCardRenderer(mContext, mControllerRendererPool);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindView_shouldSetListener() {
|
||||
final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
|
||||
final RecyclerView recyclerView = new RecyclerView(mContext);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
|
||||
final View card = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
|
||||
final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
|
||||
|
||||
when(mControllerRendererPool.getController(mContext,
|
||||
ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
|
||||
|
||||
mRenderer.bindView(viewHolder, buildContextualCard());
|
||||
|
||||
assertThat(card).isNotNull();
|
||||
assertThat(card.hasOnClickListeners()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void viewClick_shouldInvokeControllerPrimaryClick() {
|
||||
final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
|
||||
final RecyclerView recyclerView = new RecyclerView(mContext);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
|
||||
final View card = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
|
||||
final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
|
||||
when(mControllerRendererPool.getController(mContext,
|
||||
ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
|
||||
|
||||
mRenderer.bindView(viewHolder, buildContextualCard());
|
||||
|
||||
assertThat(card).isNotNull();
|
||||
card.performClick();
|
||||
|
||||
verify(mController).onPrimaryClick(any(ContextualCard.class));
|
||||
}
|
||||
|
||||
private ContextualCard buildContextualCard() {
|
||||
return new LegacySuggestionContextualCard.Builder()
|
||||
.setName("test_name")
|
||||
.setTitleText("test_title")
|
||||
.setSummaryText("test_summary")
|
||||
.setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class LegacySuggestionContextualCardTest {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void newInstance_changeCardType_shouldCrash() {
|
||||
new LegacySuggestionContextualCard.Builder()
|
||||
.setCardType(ContextualCard.CardType.CONDITIONAL)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCardType_shouldAlwaysBeSuggestionType() {
|
||||
assertThat(new LegacySuggestionContextualCard.Builder().build().getCardType())
|
||||
.isEqualTo(ContextualCard.CardType.LEGACY_SUGGESTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void build_shouldSetPendingIntent() {
|
||||
assertThat(new LegacySuggestionContextualCard.Builder()
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.build()
|
||||
.getPendingIntent()).isNotNull();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -165,7 +165,8 @@ public class MobileNetworkUtilsTest {
|
||||
@Test
|
||||
public void isCdmaOptions_worldModeWithGsmWcdma_returnTrue() {
|
||||
when(mTelephonyManager.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
|
||||
when(mContext.getString(R.string.config_world_mode)).thenReturn("true");
|
||||
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true);
|
||||
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1,
|
||||
TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA);
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print;
|
||||
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_START;
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.print.PrintJob;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
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;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class PrintJobMessagePreferenceControllerTest {
|
||||
private static final String PREF_KEY = "print_job_message_preference";
|
||||
|
||||
@Mock
|
||||
private PrintManager mPrintManager;
|
||||
@Mock
|
||||
private PrintJob mPrintJob;
|
||||
@Mock
|
||||
private PrintJobInfo mPrintJobInfo;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
private Context mContext;
|
||||
private PrintJobMessagePreferenceController mController;
|
||||
private Preference mPreference;
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Lifecycle mLifecycle;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mPreference = new Preference(mContext);
|
||||
when(mContext.getSystemService(Context.PRINT_SERVICE)).thenReturn(mPrintManager);
|
||||
when(mPrintManager.getGlobalPrintManagerForUser(anyInt())).thenReturn(mPrintManager);
|
||||
when(mPrintManager.getPrintJob(anyObject())).thenReturn(mPrintJob);
|
||||
when(mPrintJob.getInfo()).thenReturn(mPrintJobInfo);
|
||||
mController = new PrintJobMessagePreferenceController(mContext, PREF_KEY);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
mLifecycle.addObserver(mController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStartStop_shouldRegisterPrintStateListener() {
|
||||
mLifecycle.handleLifecycleEvent(ON_START);
|
||||
mLifecycle.handleLifecycleEvent(ON_STOP);
|
||||
|
||||
verify(mPrintManager).addPrintJobStateChangeListener(mController);
|
||||
verify(mPrintManager).removePrintJobStateChangeListener(mController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_visiblePreference() {
|
||||
when(mPrintJobInfo.getStatus(anyObject())).thenReturn("TestPrint");
|
||||
mLifecycle.handleLifecycleEvent(ON_START);
|
||||
|
||||
assertThat(mPreference.isVisible()).isTrue();
|
||||
|
||||
mLifecycle.handleLifecycleEvent(ON_STOP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_invisiblePreference() {
|
||||
when(mPrintJobInfo.getStatus(anyObject())).thenReturn(null);
|
||||
mLifecycle.handleLifecycleEvent(ON_START);
|
||||
|
||||
assertThat(mPreference.isVisible()).isFalse();
|
||||
|
||||
mLifecycle.handleLifecycleEvent(ON_STOP);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print;
|
||||
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_START;
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.print.PrintJob;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
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;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class PrintJobPreferenceControllerTest {
|
||||
private static final String PREF_KEY = "print_job_preference";
|
||||
|
||||
@Mock
|
||||
private PrintManager mPrintManager;
|
||||
@Mock
|
||||
private PrintJob mPrintJob;
|
||||
@Mock
|
||||
private PrintJobInfo mPrintJobInfo;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
private Context mContext;
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Lifecycle mLifecycle;
|
||||
private PrintJobPreferenceController mController;
|
||||
private Preference mPreference;
|
||||
private String mTestLabel;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mPreference = new Preference(mContext);
|
||||
mTestLabel = "PrintTest";
|
||||
when(mContext.getSystemService(Context.PRINT_SERVICE)).thenReturn(mPrintManager);
|
||||
when(mPrintManager.getGlobalPrintManagerForUser(anyInt())).thenReturn(mPrintManager);
|
||||
when(mPrintManager.getPrintJob(anyObject())).thenReturn(mPrintJob);
|
||||
when(mPrintJob.getInfo()).thenReturn(mPrintJobInfo);
|
||||
mController = new PrintJobPreferenceController(mContext, PREF_KEY);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
when(mPrintJobInfo.getLabel()).thenReturn(mTestLabel);
|
||||
mController.displayPreference(mScreen);
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
mLifecycle.addObserver(mController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStartStop_shouldRegisterPrintStateListener() {
|
||||
mLifecycle.handleLifecycleEvent(ON_START);
|
||||
mLifecycle.handleLifecycleEvent(ON_STOP);
|
||||
|
||||
verify(mPrintManager).addPrintJobStateChangeListener(mController);
|
||||
verify(mPrintManager).removePrintJobStateChangeListener(mController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_jobState_STATE_CREATED() {
|
||||
when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_CREATED);
|
||||
|
||||
mController.onStart();
|
||||
String title = mContext.getString(
|
||||
R.string.print_configuring_state_title_template, mTestLabel);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_jobState_STATE_QUEUED() {
|
||||
when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_QUEUED);
|
||||
|
||||
mController.onStart();
|
||||
String title = mContext.getString(
|
||||
R.string.print_printing_state_title_template, mTestLabel);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_jobState_STATE_STARTED() {
|
||||
when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_STARTED);
|
||||
|
||||
mController.onStart();
|
||||
String title = mContext.getString(
|
||||
R.string.print_printing_state_title_template, mTestLabel);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_jobState_STATE_QUEUED_and_jobInfo_CANCELLING() {
|
||||
when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_QUEUED);
|
||||
when(mPrintJobInfo.isCancelling()).thenReturn(true);
|
||||
|
||||
mController.onStart();
|
||||
String title = mContext.getString(
|
||||
R.string.print_cancelling_state_title_template, mTestLabel);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_jobState_STATE_STARTED_and_jobInfo_CANCELLING() {
|
||||
when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_STARTED);
|
||||
when(mPrintJobInfo.isCancelling()).thenReturn(true);
|
||||
|
||||
mController.onStart();
|
||||
String title = mContext.getString(
|
||||
R.string.print_cancelling_state_title_template, mTestLabel);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_jobState_STATE_FAILED() {
|
||||
when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_FAILED);
|
||||
|
||||
mController.onStart();
|
||||
String title = mContext.getString(
|
||||
R.string.print_failed_state_title_template, mTestLabel);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_jobState_STATE_BLOCKED() {
|
||||
when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_BLOCKED);
|
||||
|
||||
mController.onStart();
|
||||
String title = mContext.getString(
|
||||
R.string.print_blocked_state_title_template, mTestLabel);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUi_jobState_STATE_BLOCKED_and_jobInfo_CANCELLING() {
|
||||
when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_BLOCKED);
|
||||
when(mPrintJobInfo.isCancelling()).thenReturn(true);
|
||||
|
||||
mController.onStart();
|
||||
String title = mContext.getString(
|
||||
R.string.print_cancelling_state_title_template, mTestLabel);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(title);
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public class WifiTetherSecurityPreferenceControllerTest {
|
||||
public void onPreferenceChange_securityValueUpdated() {
|
||||
mController.onPreferenceChange(mPreference, WPA2_PSK);
|
||||
assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
|
||||
assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
|
||||
assertThat(mPreference.getSummary()).isEqualTo("WPA2-Personal");
|
||||
|
||||
mController.onPreferenceChange(mPreference, NONE);
|
||||
assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.NONE);
|
||||
@@ -75,11 +75,11 @@ public class WifiTetherSecurityPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void updateDisplay_preferenceUpdated() {
|
||||
// test defaulting to WPA2 PSK on new config
|
||||
// test defaulting to WPA2-Personal on new config
|
||||
when(mWifiManager.getWifiApConfiguration()).thenReturn(null);
|
||||
mController.updateDisplay();
|
||||
assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
|
||||
assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
|
||||
assertThat(mPreference.getSummary()).isEqualTo("WPA2-Personal");
|
||||
|
||||
// test open tether network
|
||||
when(mWifiManager.getWifiApConfiguration()).thenReturn(mConfig);
|
||||
@@ -89,11 +89,11 @@ public class WifiTetherSecurityPreferenceControllerTest {
|
||||
assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.NONE);
|
||||
assertThat(mPreference.getSummary()).isEqualTo("None");
|
||||
|
||||
// test WPA2 PSK tether network
|
||||
// test WPA2-Personal tether network
|
||||
mConfig.allowedKeyManagement.clear();
|
||||
mConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
|
||||
mController.updateDisplay();
|
||||
assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
|
||||
assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
|
||||
assertThat(mPreference.getSummary()).isEqualTo("WPA2-Personal");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +166,6 @@ Device name;device_name
|
||||
Device security;security_category
|
||||
Device theme;theme
|
||||
Dial pad tones;dial_pad_tones
|
||||
Directory access;special_app_directory_access
|
||||
Disable Bluetooth A2DP hardware offload;bluetooth_disable_a2dp_hw_offload
|
||||
Disable HW overlays;disable_overlays
|
||||
Disable USB audio routing;usb_audio
|
||||
@@ -236,6 +235,7 @@ Force 4x MSAA;force_msaa
|
||||
Force RTL layout direction;force_rtl_layout_all_locales
|
||||
Force activities to be resizable;force_resizable_activities
|
||||
Force allow apps on external;force_allow_on_external
|
||||
Force desktop mode;force_desktop_mode_on_external_displays
|
||||
Force full GNSS measurements;enable_gnss_raw_meas_full_tracking
|
||||
Free up space;storage_settings_free_space
|
||||
Games;pref_games
|
||||
@@ -620,4 +620,4 @@ Your access to this device;device_access_category
|
||||
;auto_brightness_video
|
||||
;battery_header
|
||||
;battery_tip
|
||||
;feature_flag_category
|
||||
;feature_flag_category
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.password;
|
||||
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
|
||||
import static android.support.test.InstrumentationRegistry.getInstrumentation;
|
||||
import static android.support.test.InstrumentationRegistry.getTargetContext;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
|
||||
import android.support.test.runner.lifecycle.Stage;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiSelector;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Tests for {@link SetupChooseLockGenericTest}
|
||||
*
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class SetupChooseLockGenericTest {
|
||||
|
||||
private UiDevice mDevice;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
mContext = getInstrumentation().getTargetContext();
|
||||
Settings.Global.putInt(
|
||||
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
Settings.Global.putInt(
|
||||
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickSkipFigerprintPreference_deviceNotProvisioned_shouldBeAbleToProceed()
|
||||
throws Throwable {
|
||||
final Intent newPasswordIntent =
|
||||
new Intent(getTargetContext(), SetupChooseLockGeneric.class)
|
||||
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true)
|
||||
.setAction(ACTION_SET_NEW_PASSWORD)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
|
||||
getInstrumentation().getContext().startActivity(newPasswordIntent);
|
||||
mDevice.waitForIdle();
|
||||
mDevice.findObject(new UiSelector().textContains("Continue without ")).click();
|
||||
|
||||
final Activity activity = getCurrentActivity();
|
||||
assertThat(activity).isInstanceOf(SetupChooseLockGeneric.InternalActivity.class);
|
||||
}
|
||||
|
||||
private Activity getCurrentActivity() throws Throwable {
|
||||
getInstrumentation().waitForIdleSync();
|
||||
final Activity[] activity = new Activity[1];
|
||||
getInstrumentation().runOnMainSync(() -> {
|
||||
Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance()
|
||||
.getActivitiesInStage(Stage.RESUMED);
|
||||
activity[0] = activities.iterator().next();
|
||||
});
|
||||
return activity[0];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user