Merge "Replace SliceAction deprecated method"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 312e5c9..787c559 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -2,6 +2,18 @@
<issues format="4">
<issue
+ id="LintError"
+ severity="Error"
+ message="No `.class` files were found in project ".", so none of the classfile based checks could be run. Does the project need to be built first?"
+ category="Lint"
+ priority="10"
+ summary="Lint Failure"
+ explanation="This issue type represents a problem running lint itself. Examples include failure to find bytecode for source files (which means certain detectors could not be run), parsing errors in lint configuration files, etc.
These errors are not errors in your own code, but they are shown to make it clear that some checks were not completed.">
+ <location
+ file="."/>
+ </issue>
+
+ <issue
id="HardCodedColor"
severity="Error"
message="Avoid using hardcoded color"
@@ -809,8 +821,8 @@
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="wifi_details_icon_color">#8A000000</color>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ errorLine1=" <color name="fallback_tintColor">#89000000</color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
line="87"
@@ -1561,22 +1573,6 @@
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:tint="@color/wifi_details_icon_color">"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/drawable/ic_frequency_antenna.xml"
- line="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
@@ -1897,22 +1893,6 @@
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:tint="@color/wifi_details_icon_color">"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/drawable/ic_security_lock_24dp.xml"
- line="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=" <background android:drawable="@color/shortcut_background"/>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -2493,7 +2473,7 @@
errorLine2=" ^">
<location
file="res/values/styles.xml"
- line="422"
+ line="425"
column="44"/>
</issue>
@@ -2509,7 +2489,7 @@
errorLine2=" ^">
<location
file="res/values/styles.xml"
- line="428"
+ line="431"
column="44"/>
</issue>
@@ -2525,7 +2505,7 @@
errorLine2=" ^">
<location
file="res/values/styles.xml"
- line="429"
+ line="432"
column="44"/>
</issue>
@@ -2541,7 +2521,23 @@
errorLine2=" ^">
<location
file="res/values/styles.xml"
- line="464"
+ line="467"
+ column="34"/>
+ </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=" <item name="strokeColor">@color/homepage_card_stroke_color</item>"
+ errorLine2=" ^">
+ <location
+ file="res/values/styles.xml"
+ line="474"
column="34"/>
</issue>
diff --git a/res/drawable/ic_frequency_antenna.xml b/res/drawable/ic_frequency_antenna.xml
index 581b83e..716a98a 100644
--- a/res/drawable/ic_frequency_antenna.xml
+++ b/res/drawable/ic_frequency_antenna.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:width="24dp"
android:height="24dp"
- android:tint="@color/wifi_details_icon_color">
+ android:tint="?android:attr/colorControlNormal">
<path
android:pathData="M12,5c-3.9,0-7,3.1-7,7h2c0-2.8,2.2-5,5-5s5,2.2,5,5h2C19,8.1,15.9,5,12,5z M13,14.3c0.9-0.4,1.5-1.3,1.5-2.3
c0-1.4-1.1-2.5-2.5-2.5S9.5,10.6,9.5,12c0,1,0.6,1.9,1.5,2.3v3.3L7.6,21L9,22.4l3-3l3,3l1.4-1.4L13,17.6V14.3z M12,1
diff --git a/res/drawable/ic_security_lock_24dp.xml b/res/drawable/ic_security_lock_24dp.xml
index fd49b23..40b5109 100644
--- a/res/drawable/ic_security_lock_24dp.xml
+++ b/res/drawable/ic_security_lock_24dp.xml
@@ -19,7 +19,7 @@
android:viewportHeight="24"
android:width="24dp"
android:height="24dp"
- android:tint="@color/wifi_details_icon_color">
+ android:tint="?android:attr/colorControlNormal">
<path
android:pathData="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"
android:fillColor="#FFFFFFFF" />
diff --git a/res/layout-land/panel_layout.xml b/res/layout-land/panel_layout.xml
new file mode 100644
index 0000000..3975bfe
--- /dev/null
+++ b/res/layout-land/panel_layout.xml
@@ -0,0 +1,42 @@
+<?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
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:paddingBottom="24dp"
+ android:paddingTop="18dp"
+ android:textColor="?android:attr/colorPrimary"
+ android:textSize="20sp"/>
+
+ <include layout="@layout/horizontal_divider"/>
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/panel_parent_layout"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <include layout="@layout/panel_buttons"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
new file mode 100644
index 0000000..0c938f8
--- /dev/null
+++ b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
@@ -0,0 +1,51 @@
+<?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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <include layout="@layout/wifi_dpp_fragment_header"/>
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <SurfaceView
+ android:id="@+id/preview_view"
+ android:layout_width="426dp"
+ android:layout_height="320dp"
+ android:layout_gravity="center"/>
+ <com.android.settings.wifi.qrcode.QrDecorateView
+ android:id="@+id/decorate_view"
+ android:layout_width="426dp"
+ android:layout_height="320dp"
+ android:layout_gravity="center"/>
+ </FrameLayout>
+
+ <TextView android:id="@+id/error_message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"/>
+
+ <include layout="@layout/wifi_dpp_fragment_footer"
+ android:gravity="center|bottom"/>
+
+</LinearLayout>
+
diff --git a/res/layout/panel_buttons.xml b/res/layout/panel_buttons.xml
new file mode 100644
index 0000000..1bb3898
--- /dev/null
+++ b/res/layout/panel_buttons.xml
@@ -0,0 +1,45 @@
+<?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
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="14dp"
+ android:paddingBottom="14dp"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/see_more"
+ style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="20dp"
+ android:text="@string/see_more"/>
+
+ <Space
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+
+ <Button
+ android:id="@+id/done"
+ style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="20dp"
+ android:text="@string/done"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
index cbdd53f..a6f62a4 100644
--- a/res/layout/panel_layout.xml
+++ b/res/layout/panel_layout.xml
@@ -14,13 +14,30 @@
See the License for the specific language governing permissions and
limitations under the License
-->
+
+<!-- Note: There is a landscape version of this layout. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/panel_parent_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="24dp"
- android:paddingRight="24dp"
- android:paddingBottom="8dp"
- android:layout_margin="4dp"
- android:orientation="vertical">
+ android:gravity="center"
+ android:paddingBottom="24dp"
+ android:paddingTop="18dp"
+ android:textColor="?android:attr/colorPrimary"
+ android:textSize="20sp"/>
+
+ <include layout="@layout/horizontal_divider"/>
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/panel_parent_layout"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <include layout="@layout/panel_buttons"/>
</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/panel_slice_row.xml b/res/layout/panel_slice_row.xml
new file mode 100644
index 0000000..4ce3494
--- /dev/null
+++ b/res/layout/panel_slice_row.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <androidx.slice.widget.SliceView
+ android:id="@+id/slice_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="20dp"
+ android:paddingEnd="20dp" />
+
+ <include layout="@layout/horizontal_divider"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/search_bar.xml b/res/layout/search_bar.xml
index 9135ebf..be8aa3b 100644
--- a/res/layout/search_bar.xml
+++ b/res/layout/search_bar.xml
@@ -15,42 +15,33 @@
limitations under the License.
-->
-<FrameLayout
+<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/search_bar_container"
+ android:id="@+id/search_bar"
+ style="@style/SearchBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="?android:attr/colorBackground"
- android:theme="@style/ThemeOverlay.Settings.SearchBar"
app:layout_scrollFlags="scroll|enterAlways">
- <androidx.cardview.widget.CardView
- android:id="@+id/search_bar"
+ <Toolbar
+ android:id="@+id/search_action_bar"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="@dimen/search_bar_margin"
- app:cardCornerRadius="@dimen/search_bar_corner_radius"
- app:cardElevation="@dimen/search_bar_card_elevation">
- <Toolbar
- android:id="@+id/search_action_bar"
- android:layout_width="match_parent"
- android:layout_height="@dimen/search_bar_height"
- android:background="?android:attr/selectableItemBackground"
- android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
- android:navigationIcon="@drawable/ic_search_24dp">
- <TextView
- android:id="@+id/search_action_bar_title"
- style="@style/TextAppearance.SearchBar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/search_menu"/>
- </Toolbar>
- <ImageView
- android:id="@+id/account_avatar"
- android:layout_marginStart="@dimen/search_bar_avatar_start_margin"
- android:layout_marginEnd="@dimen/search_bar_avatar_end_margin"
- android:layout_width="@dimen/search_bar_avatar_size"
- android:layout_height="@dimen/search_bar_avatar_size"
- android:layout_gravity="end|center_vertical"/>
- </androidx.cardview.widget.CardView>
-</FrameLayout>
\ No newline at end of file
+ android:layout_height="@dimen/search_bar_height"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
+ android:navigationIcon="@drawable/ic_search_24dp">
+ <TextView
+ android:id="@+id/search_action_bar_title"
+ style="@style/TextAppearance.SearchBar"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/search_menu"/>
+ </Toolbar>
+ <ImageView
+ android:id="@+id/account_avatar"
+ android:layout_marginStart="@dimen/search_bar_avatar_start_margin"
+ android:layout_marginEnd="@dimen/search_bar_avatar_end_margin"
+ android:layout_width="@dimen/search_bar_avatar_size"
+ android:layout_height="@dimen/search_bar_avatar_size"
+ android:layout_gravity="end|center_vertical"/>
+</com.google.android.material.card.MaterialCardView>
diff --git a/res/layout/settings_homepage_container.xml b/res/layout/settings_homepage_container.xml
index 0223573..8d81e82 100644
--- a/res/layout/settings_homepage_container.xml
+++ b/res/layout/settings_homepage_container.xml
@@ -23,11 +23,12 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ android:background="@android:color/transparent"
+ app:elevation="0dp">
<include layout="@layout/search_bar"/>
</com.google.android.material.appbar.AppBarLayout>
-
<androidx.core.widget.NestedScrollView
android:id="@+id/main_content_scrollable_container"
android:layout_width="match_parent"
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index a864f51..ab38ac1 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -32,7 +32,7 @@
android:layout_width="320dp"
android:layout_height="426dp"
android:layout_gravity="center"/>
- <ImageView
+ <com.android.settings.wifi.qrcode.QrDecorateView
android:id="@+id/decorate_view"
android:layout_width="320dp"
android:layout_height="426dp"
diff --git a/res/values/colors.xml b/res/values/colors.xml
index d10cb5f..587184b 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -83,8 +83,8 @@
<!-- Color for the background of the shortcut icons.-->
<color name="shortcut_background">#fff5f5f5</color>
- <!-- Color for preference icons on the Wifi Network Details page -->
- <color name="wifi_details_icon_color">#8A000000</color>
+ <!-- The fallback color for tinting icons. Only used when colorControlNormal is unavailable -->
+ <color name="fallback_tintColor">#89000000</color>
<!-- Dashboard/homepage icon background colors -->
<color name="homepage_network_background">#2196F3</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f55ef10..83848af 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -95,11 +95,7 @@
<dimen name="switchbar_subsettings_margin_start">72dp</dimen>
<dimen name="switchbar_subsettings_margin_end">16dp</dimen>
- <!-- The following two margins need to match, with the caveat that
- the second should be negative. The second one ensures that the icons and text
- align despite the additional padding caused by the search bar's card background. -->
<dimen name="search_bar_margin">16dp</dimen>
- <dimen name="search_bar_negative_margin">-16dp</dimen>
<dimen name="search_bar_height">48dp</dimen>
<dimen name="search_bar_corner_radius">2dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e1948d4..fb8ab20 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3456,9 +3456,9 @@
<!-- Button title to factory data reset the entire device. The "(factory reset)" part is optional for translation. [CHAR LIMIT=30 BACKUP_MESSAGE_ID=3531267871084279512]-->
<string name="master_clear_short_title">Erase all data (factory reset)</string>
<!-- SD card & phone storage settings screen, message on screen after user selects Factory data reset [CHAR LIMIT=NONE] -->
- <string name="master_clear_desc" product="tablet">"This will erase all data from your tablet\u2019s <b>internal storage</b>, including:\n\n<li>Your Google account</li>\n<li>System and app data and settings</li>\n<li>Downloaded apps</li>"</string>
+ <string name="master_clear_desc" product="tablet">"This will erase all data from your tablet\u2019s <b>internal storage</b>, including:\n\n<li>Your Google Account</li>\n<li>System and app data and settings</li>\n<li>Downloaded apps</li>"</string>
<!-- SD card & phone storage settings screen, message on screen after user selects Factory data reset [CHAR LIMIT=NONE] -->
- <string name="master_clear_desc" product="default">"This will erase all data from your phone\u2019s <b>internal storage</b>, including:\n\n<li>Your Google account</li>\n<li>System and app data and settings</li>\n<li>Downloaded apps</li>"</string>
+ <string name="master_clear_desc" product="default">"This will erase all data from your phone\u2019s <b>internal storage</b>, including:\n\n<li>Your Google Account</li>\n<li>System and app data and settings</li>\n<li>Downloaded apps</li>"</string>
<!-- SD card & phone storage settings screen, instructions and list of current accounts. The list of accounts follows this text[CHAR LIMIT=NONE] -->
<string name="master_clear_accounts" product="default">"\n\nYou are currently signed into the following accounts:\n"</string>
<!-- SD card & phone storage settings screen, notification if other users are present on the device [CHAR LIMIT=NONE] -->
@@ -3488,17 +3488,17 @@
<!-- SD card & phone storage settings screen, description for check box to erase eSIMs for tablets [CHAR LIMIT=NONE] -->
<string name="erase_esim_storage_description" product="tablet">Erase all eSIMs on the tablet. This will not cancel your mobile service plan.</string>
<!-- SD card & phone storage settings screen, button on screen after user selects Factory data reset -->
- <string name="master_clear_button_text" product="tablet">Reset tablet</string>
+ <string name="master_clear_button_text" product="tablet">Erase all data</string>
<!-- SD card & phone storage settings screen, button on screen after user selects Factory data reset -->
- <string name="master_clear_button_text" product="default">Reset phone</string>
+ <string name="master_clear_button_text" product="default">Erase all data</string>
<!-- SD card & phone storage settings screen, message on screen after user selects Reset phone button -->
- <string name="master_clear_final_desc">Erase all your personal information and downloaded apps? You can\u2019t undo this action!</string>
+ <string name="master_clear_final_desc">All of your personal information and downloaded apps will be deleted. You can\u2019t undo this action!</string>
<!-- SD card & phone storage settings screen, button on screen after user selects Reset phone button -->
<string name="master_clear_final_button_text">Erase everything</string>
<!-- Master clear failed message -->
<string name="master_clear_failed">No reset was performed because the System Clear service isn\u2019t available.</string>
<!-- Master clear confirmation screen title [CHAR LIMIT=30] -->
- <string name="master_clear_confirm_title">Reset?</string>
+ <string name="master_clear_confirm_title">Erase all data?</string>
<!-- Error message for users that aren't allowed to factory reset [CHAR LIMIT=none] -->
<string name="master_clear_not_available">Factory reset is not available for this user</string>
<!-- Master clear progress screen title [CHAR LIMIT=30] -->
@@ -10238,9 +10238,9 @@
<!-- UI debug setting: force desktop mode summary [CHAR LIMIT=NONE] -->
<string name="force_desktop_mode_summary">Force experimental desktop mode on secondary displays</string>
- <!-- UI debug setting: Force enable "smart dark" UI rendering feature [CHAR LIMIT=40] -->
+ <!-- UI debug setting: Force enable "smart dark" UI rendering feature [CHAR LIMIT=60] -->
<string name="hwui_force_dark_title">Override force-dark</string>
- <!-- UI debug setting: Force enable "smart dark" UI rendering feature summary [CHAR LIMIT=100] -->
+ <!-- UI debug setting: Force enable "smart dark" UI rendering feature summary [CHAR LIMIT=NONE] -->
<string name="hwui_force_dark_summary">Overrides the force-dark feature to be always-on</string>
<!-- Title for the top level Privacy Settings [CHAR LIMIT=30]-->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 1b311aa..8a92eaa 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -17,7 +17,7 @@
<resources>
<style name="Widget.ActionBar.Base"
- parent="@android:style/Widget.DeviceDefault.Light.ActionBar.Solid"/>
+ parent="@android:style/Widget.DeviceDefault.Light.ActionBar.Solid"/>
<style name="Widget.ActionBar"
parent="Widget.ActionBar.Base">
@@ -259,7 +259,8 @@
<style name="TextAppearance.Medium" parent="@android:style/TextAppearance.Material.Medium"/>
<style name="TextAppearance.Small" parent="@android:style/TextAppearance.Material.Small"/>
- <style name="TextAppearance.Switch" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+ <style name="TextAppearance.Switch"
+ parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
<item name="android:textSize">16sp</item>
</style>
@@ -400,9 +401,11 @@
<style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
- <style name="SettingsActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
+ <style name="SettingsActionButton"
+ parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
<item name="android:drawablePadding">4dp</item>
- <item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item>
+ <item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material
+ </item>
<item name="android:layout_marginEnd">8dp</item>
<item name="android:paddingTop">20dp</item>
<item name="android:paddingBottom">20dp</item>
@@ -465,6 +468,13 @@
<item name="strokeWidth">1dp</item>
</style>
+ <style name="SearchBarStyle">
+ <item name="android:layout_margin">@dimen/search_bar_margin</item>
+ <item name="cardCornerRadius">8dp</item>
+ <item name="strokeColor">@color/homepage_card_stroke_color</item>
+ <item name="strokeWidth">1dp</item>
+ </style>
+
<style name="ConditionCardBorderlessButton"
parent="android:Widget.DeviceDefault.Button.Borderless">
<item name="android:textColor">?android:attr/colorAccent</item>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 873216d..be57bd3 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -195,13 +195,11 @@
<item name="android:windowLightNavigationBar">true</item>
</style>
- <style name="ThemeOverlay.Settings.SearchBar" parent="Theme.Settings">
- <item name="android:colorBackground">?android:attr/colorPrimary</item>
- <item name="cardBackgroundColor">?android:attr/colorBackground</item>
- </style>
-
<style name="Theme.BottomDialog" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
<item name="android:windowBackground">@drawable/settings_panel_background</item>
+ <item name="android:dividerHorizontal">@*android:drawable/list_divider_material</item>
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
</style>
</resources>
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index b0e362c..50a5649 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -44,7 +44,6 @@
android:title="@string/auto_brightness_title"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.display.AutoBrightnessSettings"
- settings:searchable="false"
settings:controller="com.android.settings.display.AutoBrightnessPreferenceController" />
<com.android.settingslib.RestrictedPreference
diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java
index 8f0026f..24192cd 100644
--- a/src/com/android/settings/datausage/DataUsageList.java
+++ b/src/com/android/settings/datausage/DataUsageList.java
@@ -193,17 +193,13 @@
public void onResume() {
super.onResume();
mDataStateListener.setListener(true, mSubId, getContext());
- updateBody();
// kick off background task to update stats
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
- // wait a few seconds before kicking off
- Thread.sleep(2 * DateUtils.SECOND_IN_MILLIS);
services.mStatsService.forceUpdate();
- } catch (InterruptedException e) {
} catch (RemoteException e) {
}
return null;
@@ -211,9 +207,7 @@
@Override
protected void onPostExecute(Void result) {
- if (isAdded()) {
- updateBody();
- }
+ updateBody();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
diff --git a/src/com/android/settings/datausage/DataUsageListV2.java b/src/com/android/settings/datausage/DataUsageListV2.java
index 4432fee..3a71935 100644
--- a/src/com/android/settings/datausage/DataUsageListV2.java
+++ b/src/com/android/settings/datausage/DataUsageListV2.java
@@ -187,28 +187,6 @@
super.onResume();
mDataStateListener.setListener(true, mSubId, getContext());
updateBody();
-
- // kick off background task to update stats
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- try {
- // wait a few seconds before kicking off
- Thread.sleep(2 * DateUtils.SECOND_IN_MILLIS);
- services.mStatsService.forceUpdate();
- } catch (InterruptedException e) {
- } catch (RemoteException e) {
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (isAdded()) {
- updateBody();
- }
- }
- }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index 3f5f2b0..3b53fa8 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -52,7 +52,7 @@
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available)
- ? AVAILABLE_UNSEARCHABLE
+ ? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@@ -67,4 +67,4 @@
? R.string.auto_brightness_summary_on
: R.string.auto_brightness_summary_off);
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/panel/InternetConnectivityPanel.java b/src/com/android/settings/panel/InternetConnectivityPanel.java
index 1e01e71..5b7bc32 100644
--- a/src/com/android/settings/panel/InternetConnectivityPanel.java
+++ b/src/com/android/settings/panel/InternetConnectivityPanel.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.slices.CustomSliceRegistry;
@@ -60,6 +61,6 @@
@Override
public Intent getSeeMoreIntent() {
- return null;
+ return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
}
}
diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java
index bbdaec3..e61b8f8 100644
--- a/src/com/android/settings/panel/PanelFragment.java
+++ b/src/com/android/settings/panel/PanelFragment.java
@@ -16,19 +16,20 @@
package com.android.settings.panel;
-import android.net.Uri;
+import android.content.Intent;
import android.os.Bundle;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.LinearLayout;
+import android.widget.Button;
+import android.widget.TextView;
-import androidx.lifecycle.LiveData;
-import androidx.slice.Slice;
-import androidx.slice.widget.SliceLiveData;
-import androidx.slice.widget.SliceView;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import androidx.annotation.NonNull;
@@ -38,20 +39,24 @@
import com.android.settings.overlay.FeatureFactory;
-import java.util.ArrayList;
-import java.util.List;
-
public class PanelFragment extends Fragment {
private static final String TAG = "PanelFragment";
- private List<SliceView> mSliceViewList;
- private List<LiveData<Slice>> mSliceDataList;
- private LinearLayout mPanelLayout;
+ private TextView mTitleView;
+ private Button mSeeMoreButton;
+ private Button mDoneButton;
+ private RecyclerView mPanelSlices;
+
+ @VisibleForTesting
+ PanelSlicesAdapter mAdapter;
+
+ private View.OnClickListener mDoneButtonListener = (v) -> {
+ Log.d(TAG, "Closing dialog");
+ getActivity().finish();
+ };
public PanelFragment() {
- mSliceViewList = new ArrayList<>();
- mSliceDataList = new ArrayList<>();
}
@Nullable
@@ -61,28 +66,37 @@
final FragmentActivity activity = getActivity();
final View view = inflater.inflate(R.layout.panel_layout, container, false);
- mPanelLayout = view.findViewById(R.id.panel_parent_layout);
- final Bundle arguments = getArguments();
+ mPanelSlices = view.findViewById(R.id.panel_parent_layout);
+ mSeeMoreButton = view.findViewById(R.id.see_more);
+ mDoneButton = view.findViewById(R.id.done);
+ mTitleView = view.findViewById(R.id.title);
+ final Bundle arguments = getArguments();
final String panelType = arguments.getString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT);
final PanelContent panel = FeatureFactory.getFactory(activity)
.getPanelFeatureProvider()
.getPanel(activity, panelType);
- activity.setTitle(panel.getTitle());
+ mAdapter = new PanelSlicesAdapter(this, panel.getSlices());
+ mPanelSlices.setHasFixedSize(true);
+ mPanelSlices.setLayoutManager(new LinearLayoutManager((activity)));
+ mPanelSlices.setAdapter(mAdapter);
- for (Uri uri : panel.getSlices()) {
- final SliceView sliceView = new SliceView(activity);
- mPanelLayout.addView(sliceView);
- final LiveData<Slice> liveData = SliceLiveData.fromUri(activity, uri);
- liveData.observe(this /* lifecycleOwner */, sliceView);
+ mTitleView.setText(panel.getTitle());
- mSliceDataList.add(liveData);
- mSliceViewList.add(sliceView);
- }
+ mSeeMoreButton.setOnClickListener(getSeeMoreListener(panel.getSeeMoreIntent()));
+ mDoneButton.setOnClickListener(mDoneButtonListener);
return view;
}
+
+ private View.OnClickListener getSeeMoreListener(final Intent intent) {
+ return (v) -> {
+ final FragmentActivity activity = getActivity();
+ activity.startActivity(intent);
+ activity.finish();
+ };
+ }
}
diff --git a/src/com/android/settings/panel/PanelSlicesAdapter.java b/src/com/android/settings/panel/PanelSlicesAdapter.java
new file mode 100644
index 0000000..f688512
--- /dev/null
+++ b/src/com/android/settings/panel/PanelSlicesAdapter.java
@@ -0,0 +1,100 @@
+/*
+ * 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.panel;
+
+import android.content.Context;
+import android.net.Uri;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.LiveData;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.slice.Slice;
+import androidx.slice.widget.SliceLiveData;
+import androidx.slice.widget.SliceView;
+
+import com.android.settings.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * RecyclerView adapter for Slices in Settings Panels.
+ */
+public class PanelSlicesAdapter
+ extends RecyclerView.Adapter<PanelSlicesAdapter.SliceRowViewHolder> {
+
+ private final List<Uri> mSliceUris;
+ private final PanelFragment mPanelFragment;
+
+ public PanelSlicesAdapter(PanelFragment fragment, List<Uri> sliceUris) {
+ mPanelFragment = fragment;
+ mSliceUris = new ArrayList<>(sliceUris);
+ }
+
+ @NonNull
+ @Override
+ public SliceRowViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
+ final Context context = viewGroup.getContext();
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ final View view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
+
+ return new SliceRowViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull SliceRowViewHolder sliceRowViewHolder, int position) {
+ sliceRowViewHolder.onBind(mPanelFragment, mSliceUris.get(position));
+ }
+
+ @Override
+ public int getItemCount() {
+ return mSliceUris.size();
+ }
+
+ @VisibleForTesting
+ List<Uri> getData() {
+ return mSliceUris;
+ }
+
+ /**
+ * ViewHolder for binding Slices to SliceViews.
+ */
+ public static class SliceRowViewHolder extends RecyclerView.ViewHolder {
+
+ @VisibleForTesting
+ LiveData<Slice> sliceLiveData;
+
+ @VisibleForTesting
+ final SliceView sliceView;
+
+ public SliceRowViewHolder(View view) {
+ super(view);
+ sliceView = view.findViewById(R.id.slice_view);
+ sliceView.setMode(SliceView.MODE_LARGE);
+ }
+
+ public void onBind(PanelFragment fragment, Uri sliceUri) {
+ final Context context = sliceView.getContext();
+ sliceLiveData = SliceLiveData.fromUri(context, sliceUri);
+ sliceLiveData.observe(fragment.getViewLifecycleOwner(), sliceView);
+ }
+ }
+}
diff --git a/src/com/android/settings/slices/SlicesDatabaseAccessor.java b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
index 35a0a5d..c75f3ef 100644
--- a/src/com/android/settings/slices/SlicesDatabaseAccessor.java
+++ b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
@@ -71,6 +71,9 @@
*/
public SliceData getSliceDataFromUri(Uri uri) {
Pair<Boolean, String> pathData = SliceBuilderUtils.getPathData(uri);
+ if (pathData == null) {
+ throw new IllegalStateException("Invalid Slices uri: " + uri);
+ }
Cursor cursor = getIndexedSliceData(pathData.second /* key */);
return buildSliceData(cursor, uri, pathData.first /* isIntentOnly */);
}
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 48446c9..ba8241a 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -408,8 +408,7 @@
mEntityHeaderController.setIcon(wifiIcon).done(mFragment.getActivity(), true /* rebind */);
Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate();
- wifiIconDark.setTint(mContext.getResources().getColor(
- R.color.wifi_details_icon_color, mContext.getTheme()));
+ wifiIconDark.setTintList(Utils.getColorAttr(mContext, android.R.attr.colorControlNormal));
mSignalStrengthPref.setIcon(wifiIconDark);
mSignalStrengthPref.setSummary(mSignalStr[mRssiSignalLevel]);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index e631c84..72fa7fe 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -21,6 +21,7 @@
import android.os.Bundle;
import android.util.Log;
+import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
@@ -86,21 +87,21 @@
}
private void addQrCodeScannerFragment() {
- WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
+ final WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
mFragmentTransaction.add(R.id.fragment_container, fragment);
- mFragmentTransaction.addToBackStack(null);
+ mFragmentTransaction.addToBackStack(/* name */ null);
mFragmentTransaction.commit();
}
private void addQrCodeGeneratorFragment() {
- WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
+ final WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
mFragmentTransaction.add(R.id.fragment_container, fragment);
- mFragmentTransaction.addToBackStack(null);
+ mFragmentTransaction.addToBackStack(/* name */ null);
mFragmentTransaction.commit();
}
private void addChooseSavedWifiNetworkFragment() {
- ActionBar action = getActionBar();
+ final ActionBar action = getActionBar();
if (action != null) {
action.hide();
}
@@ -108,7 +109,18 @@
WifiDppChooseSavedWifiNetworkFragment fragment =
new WifiDppChooseSavedWifiNetworkFragment();
mFragmentTransaction.add(R.id.fragment_container, fragment);
- mFragmentTransaction.addToBackStack(null);
+ mFragmentTransaction.addToBackStack(/* name */ null);
mFragmentTransaction.commit();
}
+
+ @Override
+ protected void onStop() {
+ final Fragment fragment = mFragmentManager.findFragmentById(R.id.fragment_container);
+ if (fragment != null) {
+ // Remove it to prevent stacking multiple fragments after screen rotated.
+ mFragmentManager.beginTransaction().remove(fragment).commit();
+ }
+
+ super.onStop();
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index cbaa5d5..3e4ac61 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -16,37 +16,120 @@
package com.android.settings.wifi.dpp;
+import android.annotation.Nullable;
import android.app.Activity;
import android.content.Intent;
+import android.graphics.Rect;
import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Size;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
import com.android.settings.R;
+import com.android.settings.wifi.qrcode.QrCamera;
+import com.android.settings.wifi.qrcode.QrDecorateView;
-public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment {
+public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
+ SurfaceHolder.Callback,
+ QrCamera.ScannerCallback {
+ private QrCamera mCamera;
+ private SurfaceView mSurfaceView;
+ private QrDecorateView mDecorateView;
+
@Override
protected int getLayout() {
return R.layout.wifi_dpp_qrcode_scanner_fragment;
}
@Override
- public void onActivityCreated (Bundle savedInstanceState) {
- super.onActivityCreated (savedInstanceState);
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
setTitle(getString(R.string.wifi_dpp_add_device_to_network));
- String ssid = "";
- Intent intent = getActivity().getIntent();
- if (intent != null)
+ String ssid = null;
+ final Intent intent = getActivity().getIntent();
+ if (intent != null) {
ssid = intent.getStringExtra(WifiDppConfiguratorActivity.EXTRA_SSID);
- String description = getString(R.string.wifi_dpp_center_qr_code, ssid);
- setDescription(description);
+ }
+ if (TextUtils.isEmpty(ssid)) {
+ throw new IllegalArgumentException("Invalid SSID");
+ }
+ setDescription(getString(R.string.wifi_dpp_center_qr_code, ssid));
hideRightButton();
setLeftButtonText(getString(android.R.string.cancel));
setLeftButtonOnClickListener((view) -> {
- getActivity().setResult(Activity.RESULT_CANCELED);
- getActivity().finish();});
+ getActivity().setResult(Activity.RESULT_CANCELED);
+ getActivity().finish();
+ });
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mSurfaceView = (SurfaceView) view.findViewById(R.id.preview_view);
+ final SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
+ surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ surfaceHolder.addCallback(this);
+
+ mDecorateView = (QrDecorateView) view.findViewById(R.id.decorate_view);
+ }
+
+ @Override
+ public void surfaceCreated(final SurfaceHolder holder) {
+ initCamera(holder);
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ destroyCamera();
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ // Do nothing
+ }
+
+ @Override
+ public Size getViewSize() {
+ return new Size(mSurfaceView.getWidth(), mSurfaceView.getHeight());
+ }
+
+ @Override
+ public Rect getFramePosition(Size previewSize, int cameraOrientation) {
+ return new Rect(0, 0, previewSize.getHeight(), previewSize.getHeight());
+ }
+
+ @Override
+ public void handleSuccessfulResult(String qrCode) {
+ destroyCamera();
+ mDecorateView.setFocused(true);
+ // TODO(b/120243131): Add a network by Wi-Fi Network config shared via QR code.
+ }
+
+ @Override
+ public void handleCameraFailure() {
+ destroyCamera();
+ }
+
+ private void initCamera(SurfaceHolder holder) {
+ // Check if the camera has already created.
+ if (mCamera == null) {
+ mCamera = new QrCamera(getContext(), this);
+ mCamera.start(holder);
+ }
+ }
+
+ private void destroyCamera() {
+ if (mCamera != null) {
+ mCamera.stop();
+ mCamera = null;
+ }
}
}
diff --git a/src/com/android/settings/wifi/qrcode/QrCamera.java b/src/com/android/settings/wifi/qrcode/QrCamera.java
index c29236c..dc650b9 100644
--- a/src/com/android/settings/wifi/qrcode/QrCamera.java
+++ b/src/com/android/settings/wifi/qrcode/QrCamera.java
@@ -43,6 +43,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import androidx.annotation.VisibleForTesting;
@@ -85,14 +86,26 @@
mReader.setHints(HINTS);
}
- void start(SurfaceHolder surfaceHolder) {
+ /**
+ * The function start camera preview and capture pictures to decode QR code continuously in a
+ * background task.
+ *
+ * @param surfaceHolder the Surface to be used for live preview, must already contain a surface
+ * when this method is called.
+ */
+ public void start(SurfaceHolder surfaceHolder) {
if (mDecodeTask == null) {
mDecodeTask = new DecodingTask(surfaceHolder);
- mDecodeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ // Execute in the separate thread pool to prevent block other AsyncTask.
+ mDecodeTask.executeOnExecutor(Executors.newSingleThreadExecutor());
}
}
- void stop() {
+ /**
+ * The function stop camera preview and background decode task. Caller call this function when
+ * the surface is being destroyed.
+ */
+ public void stop() {
removeMessages(MSG_AUTO_FOCUS);
if (mDecodeTask != null) {
mDecodeTask.cancel(true);
@@ -104,7 +117,7 @@
}
/** The scanner which includes this QrCamera class should implement this */
- interface ScannerCallback {
+ public interface ScannerCallback {
/**
* The function used to handle the decoding result of the QR code.
diff --git a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java
new file mode 100644
index 0000000..60f0d5d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java
@@ -0,0 +1,56 @@
+/*
+ * 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.panel;
+
+import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
+
+import android.content.Intent;
+import android.net.Uri;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Fake PanelContent for testing.
+ */
+public class FakePanelContent implements PanelContent {
+
+ public static final String FAKE_KEY = "fake_key";
+
+ public static final CharSequence TITLE = "title";
+
+ public static final List<Uri> SLICE_URIS = Arrays.asList(
+ WIFI_SLICE_URI
+ );
+
+ public static final Intent INTENT = new Intent();
+
+ @Override
+ public CharSequence getTitle() {
+ return TITLE;
+ }
+
+ @Override
+ public List<Uri> getSlices() {
+ return SLICE_URIS;
+ }
+
+ @Override
+ public Intent getSeeMoreIntent() {
+ return INTENT;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/panel/FakeSettingsPanelActivity.java b/tests/robotests/src/com/android/settings/panel/FakeSettingsPanelActivity.java
new file mode 100644
index 0000000..afd0bec
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/panel/FakeSettingsPanelActivity.java
@@ -0,0 +1,34 @@
+/*
+ * 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.panel;
+
+import android.content.ComponentName;
+import android.content.Intent;
+
+public class FakeSettingsPanelActivity extends SettingsPanelActivity {
+ @Override
+ public ComponentName getCallingActivity() {
+ return new ComponentName("fake-package", "fake-class");
+ }
+
+ @Override
+ public Intent getIntent() {
+ final Intent intent = new Intent();
+ intent.putExtra(SettingsPanelActivity.EXTRA_PANEL_TYPE, FakePanelContent.FAKE_KEY);
+ return intent;
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java b/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java
index 243c19b..aae85ab 100644
--- a/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java
+++ b/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java
@@ -49,4 +49,9 @@
assertThat(uris).containsExactly(CustomSliceRegistry.WIFI_SLICE_URI,
CustomSliceRegistry.AIRPLANE_URI);
}
+
+ @Test
+ public void getSeeMoreIntent_notNull() {
+ assertThat(mPanel.getSeeMoreIntent()).isNotNull();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
new file mode 100644
index 0000000..9b29d48
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.panel;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.widget.LinearLayout;
+
+import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PanelFragmentTest {
+
+ private Context mContext;
+ private PanelFragment mPanelFragment;
+ private FakeFeatureFactory mFakeFeatureFactory;
+ private PanelFeatureProvider mPanelFeatureProvider;
+ private FakePanelContent mFakePanelContent;
+
+ private final String FAKE_EXTRA = "fake_extra";
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+
+ mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
+ mFakePanelContent = new FakePanelContent();
+ doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any());
+
+
+ ActivityController<FakeSettingsPanelActivity> activityController =
+ Robolectric.buildActivity(FakeSettingsPanelActivity.class);
+ activityController.setup();
+
+ mPanelFragment =
+ spy((PanelFragment)
+ activityController
+ .get()
+ .getSupportFragmentManager()
+ .findFragmentById(R.id.main_content));
+ }
+
+ @Test
+ public void onCreateView_adapterGetsDataset() {
+ final Bundle bundle = new Bundle();
+ bundle.putString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT, FAKE_EXTRA);
+ doReturn(bundle).when(mPanelFragment).getArguments();
+ mPanelFragment.onCreateView(LayoutInflater.from(mContext),
+ new LinearLayout(mContext), null);
+ PanelSlicesAdapter adapter = mPanelFragment.mAdapter;
+
+ assertThat(adapter.getData()).containsAllIn(mFakePanelContent.getSlices());
+ }
+
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java b/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java
new file mode 100644
index 0000000..bfd7863
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.panel;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+
+import org.junit.Test;
+
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PanelSlicesAdapterTest {
+
+ private Context mContext;
+ private PanelFragment mPanelFragment;
+ private FakePanelContent mFakePanelContent;
+ private FakeFeatureFactory mFakeFeatureFactory;
+ private PanelFeatureProvider mPanelFeatureProvider;
+
+ private PanelSlicesAdapter mAdapter;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+
+ final ActivityController<FakeSettingsPanelActivity> activityController =
+ Robolectric.buildActivity(FakeSettingsPanelActivity.class);
+ activityController.setup();
+
+ mPanelFragment =
+ spy((PanelFragment)
+ activityController
+ .get()
+ .getSupportFragmentManager()
+ .findFragmentById(R.id.main_content));
+
+ mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
+ mFakePanelContent = new FakePanelContent();
+ doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any());
+
+ mAdapter = new PanelSlicesAdapter(mPanelFragment, mFakePanelContent.getSlices());
+ }
+
+ @Test
+ public void onCreateViewHolder_returnsSliceRowViewHolder() {
+ final ViewGroup view = new FrameLayout(mContext);
+ final PanelSlicesAdapter.SliceRowViewHolder viewHolder =
+ mAdapter.onCreateViewHolder(view, 0);
+
+ assertThat(viewHolder.sliceView).isNotNull();
+ }
+
+ @Test
+ public void onBindViewHolder_bindsSlice() {
+ final int position = 0;
+ final ViewGroup view = new FrameLayout(mContext);
+ final PanelSlicesAdapter.SliceRowViewHolder viewHolder =
+ mAdapter.onCreateViewHolder(view, 0 /* view type*/);
+
+ mAdapter.onBindViewHolder(viewHolder, position);
+
+ assertThat(viewHolder.sliceLiveData).isNotNull();
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 978dd7d..bb475f3 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -63,9 +63,9 @@
public final UserFeatureProvider userFeatureProvider;
public final AssistGestureFeatureProvider assistGestureFeatureProvider;
public final AccountFeatureProvider mAccountFeatureProvider;
- public final PanelFeatureProvider mPanelFeatureProvider;
public final ContextualCardFeatureProvider mContextualCardFeatureProvider;
+ public PanelFeatureProvider panelFeatureProvider;
public SlicesFeatureProvider slicesFeatureProvider;
public SearchFeatureProvider searchFeatureProvider;
@@ -106,8 +106,8 @@
assistGestureFeatureProvider = mock(AssistGestureFeatureProvider.class);
slicesFeatureProvider = mock(SlicesFeatureProvider.class);
mAccountFeatureProvider = mock(AccountFeatureProvider.class);
- mPanelFeatureProvider = mock(PanelFeatureProvider.class);
mContextualCardFeatureProvider = mock(ContextualCardFeatureProvider.class);
+ panelFeatureProvider = mock(PanelFeatureProvider.class);
}
@Override
@@ -192,7 +192,7 @@
@Override
public PanelFeatureProvider getPanelFeatureProvider() {
- return mPanelFeatureProvider;
+ return panelFeatureProvider;
}
public ContextualCardFeatureProvider getContextualCardFeatureProvider() {
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
index 0f4bfd9..c46db2c 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
@@ -24,6 +24,7 @@
import android.app.Activity;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
@@ -53,4 +54,12 @@
assertThat(mActivityRule.getActivityResult().getResultCode()).
isEqualTo(Activity.RESULT_CANCELED);
}
+
+ @Test
+ public void rotateScreen_shouldNotCrash() {
+ mActivityRule.getActivity().setRequestedOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ mActivityRule.getActivity().setRequestedOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ }
}