Merge "Remove hidden @Transport usage" into sc-dev
diff --git a/res/drawable/accessibility_magnification_full_screen.png b/res/drawable/accessibility_magnification_full_screen.png
deleted file mode 100644
index 2e87ab8..0000000
--- a/res/drawable/accessibility_magnification_full_screen.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/accessibility_magnification_full_screen.xml b/res/drawable/accessibility_magnification_full_screen.xml
new file mode 100644
index 0000000..09d1a7e
--- /dev/null
+++ b/res/drawable/accessibility_magnification_full_screen.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="77dp"
+    android:height="134dp"
+    android:viewportWidth="77"
+    android:viewportHeight="134">
+  <path
+      android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
+      android:strokeWidth="1.8"
+      android:fillColor="#F2F3F4"
+      android:strokeColor="#DADCE0"/>
+  <group>
+    <clip-path
+        android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
+    <path
+        android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
+        android:fillColor="#ffffff"/>
+    <group>
+      <clip-path
+          android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
+      <path
+          android:pathData="M13,5L65,5A8,8 0,0 1,73 13L73,120A8,8 0,0 1,65 128L13,128A8,8 0,0 1,5 120L5,13A8,8 0,0 1,13 5z"
+          android:strokeLineJoin="bevel"
+          android:strokeWidth="10"
+          android:fillColor="#00000000"
+          android:strokeColor="#F29900"/>
+      <path
+          android:pathData="M51.077,14V18.314H56.612L50,24.958L53.037,28L59.692,21.334V26.921H64V14H51.077Z"
+          android:fillColor="#F29900"/>
+      <path
+          android:pathData="M25.963,104L19.308,110.655V105.077H15V118H27.923V113.692H22.366L29,107.037L25.963,104Z"
+          android:fillColor="#F29900"/>
+    </group>
+  </group>
+</vector>
diff --git a/res/drawable/accessibility_magnification_switch.xml b/res/drawable/accessibility_magnification_switch.xml
new file mode 100644
index 0000000..21e0cef
--- /dev/null
+++ b/res/drawable/accessibility_magnification_switch.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="77dp"
+    android:height="134dp"
+    android:viewportWidth="77"
+    android:viewportHeight="134">
+  <path
+      android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
+      android:strokeWidth="1.8"
+      android:fillColor="#F2F3F4"
+      android:strokeColor="#DADCE0"/>
+  <group>
+    <clip-path
+        android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
+    <path
+        android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
+        android:fillColor="#ffffff"/>
+    <group>
+      <clip-path
+          android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
+      <path
+          android:pathData="M39,94h24v24h-24z"
+          android:fillColor="#000000"
+          android:fillAlpha="0.7"/>
+      <path
+          android:pathData="M51.414,98.138H45.138C44.033,98.138 43.138,99.033 43.138,100.138V112.689C43.138,113.794 44.033,114.689 45.138,114.689H57.69C58.794,114.689 59.69,113.794 59.69,112.689L59.69,106.414H57.69L57.69,112.689L45.138,112.689V100.138H51.414V98.138ZM49.414,108.414H48.448V109.379H49.414V108.414ZM48.448,106.414H46.448V108.414V109.379V111.379H48.448H49.414H51.414V109.379V108.414V106.414H49.414H48.448ZM55.891,103.103L58.035,103.103V104.758L53.069,104.758V99.793L54.724,99.793V101.936L58.275,98.378L59.45,99.553L55.891,103.103Z"
+          android:fillColor="#ffffff"
+          android:fillType="evenOdd"/>
+      <path
+          android:pathData="M13,5L65,5A8,8 0,0 1,73 13L73,120A8,8 0,0 1,65 128L13,128A8,8 0,0 1,5 120L5,13A8,8 0,0 1,13 5z"
+          android:strokeLineJoin="bevel"
+          android:strokeWidth="10"
+          android:fillColor="#00000000"
+          android:strokeColor="#F29900"/>
+    </group>
+  </group>
+</vector>
diff --git a/res/drawable/accessibility_magnification_window_screen.png b/res/drawable/accessibility_magnification_window_screen.png
deleted file mode 100644
index a7f2a25..0000000
--- a/res/drawable/accessibility_magnification_window_screen.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/accessibility_magnification_window_screen.xml b/res/drawable/accessibility_magnification_window_screen.xml
new file mode 100644
index 0000000..d7e164c
--- /dev/null
+++ b/res/drawable/accessibility_magnification_window_screen.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="77dp"
+    android:height="134dp"
+    android:viewportWidth="77"
+    android:viewportHeight="134">
+  <path
+      android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
+      android:strokeWidth="1.8"
+      android:fillColor="#F2F3F4"
+      android:strokeColor="#DADCE0"/>
+  <group>
+    <clip-path
+        android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
+    <path
+        android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
+        android:fillColor="#ffffff"/>
+    <group>
+      <clip-path
+          android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
+      <path
+          android:pathData="M15,47L64,47A2,2 0,0 1,66 49L66,84A2,2 0,0 1,64 86L15,86A2,2 0,0 1,13 84L13,49A2,2 0,0 1,15 47z"
+          android:strokeLineJoin="bevel"
+          android:strokeWidth="5"
+          android:fillColor="#00000000"
+          android:strokeColor="#F29900"/>
+      <path
+          android:pathData="M47.077,53V57.314H52.612L46,63.958L49.037,67L55.692,60.334V65.921H60V53H47.077Z"
+          android:fillColor="#F29900"/>
+      <path
+          android:pathData="M29.963,66L23.308,72.655V67.077H19V80H31.923V75.692H26.366L33,69.037L29.963,66Z"
+          android:fillColor="#F29900"/>
+    </group>
+  </group>
+</vector>
diff --git a/res/layout/accessibility_edit_magnification_mode.xml b/res/layout/accessibility_edit_magnification_mode.xml
deleted file mode 100644
index e4f3132..0000000
--- a/res/layout/accessibility_edit_magnification_mode.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License
-  -->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/container_layout"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:scrollbarStyle="outsideOverlay">
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:padding="24dp">
-
-        <TextView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/accessibility_magnification_area_settings_message"
-            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
-            android:textColor="?android:attr/textColorSecondary"
-            android:layout_marginBottom="24dp"/>
-
-        <include
-            android:id="@+id/magnify_full_screen"
-            layout="@layout/accessibility_edit_shortcut_component"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginBottom="32dp" />
-
-        <include
-            android:id="@+id/magnify_window_screen"
-            layout="@layout/accessibility_edit_shortcut_component" />
-
-    </LinearLayout>
-
-</ScrollView>
diff --git a/res/layout/accessibility_edit_shortcut_component.xml b/res/layout/accessibility_edit_shortcut_component.xml
index 0ccc88d..0d3324f 100644
--- a/res/layout/accessibility_edit_shortcut_component.xml
+++ b/res/layout/accessibility_edit_shortcut_component.xml
@@ -55,8 +55,8 @@
 
     <ImageView
         android:id="@+id/image"
-        android:layout_width="176dp"
-        android:layout_height="176dp"
+        android:layout_width="@dimen/accessibility_imageview_size"
+        android:layout_height="@dimen/accessibility_imageview_size"
         android:layout_marginStart="44dp"
         android:scaleType="fitCenter" />
 
diff --git a/res/layout/accessibility_magnification_mode_header.xml b/res/layout/accessibility_magnification_mode_header.xml
new file mode 100644
index 0000000..e476553
--- /dev/null
+++ b/res/layout/accessibility_magnification_mode_header.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="?android:attr/dialogPreferredPadding">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/accessibility_magnification_area_settings_message"
+        android:textSize="16sp"
+        style="?android:attr/textAppearanceMedium"
+        android:textColor="?android:attr/textColorAlertDialogListItem"/>
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_single_radio_choice_list_item.xml b/res/layout/dialog_single_radio_choice_list_item.xml
new file mode 100644
index 0000000..5842528
--- /dev/null
+++ b/res/layout/dialog_single_radio_choice_list_item.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<com.android.settings.widget.CheckableRelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="?android:attr/selectableItemBackground"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/dialogPreferredPadding"
+    android:paddingBottom="12dp"
+    android:paddingTop="12dp">
+
+    <RadioButton
+        android:id="@+id/radioButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true"
+        android:clickable="false"
+        android:focusable="false" />
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@id/radioButton"
+        android:layout_marginStart="8dp"
+        android:layout_toEndOf="@+id/radioButton"
+        android:gravity="center_vertical|start"
+        style="?android:attr/textAppearanceMedium"
+        android:textSize="16sp" />
+
+    <TextView
+        android:id="@+id/summary"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:layout_marginTop="8dp"
+        android:layout_alignLeft="@id/title"
+        android:layout_below="@id/title" />
+
+    <ImageView
+        android:id="@+id/image"
+        android:layout_width="@dimen/accessibility_imageview_size"
+        android:layout_height="@dimen/accessibility_imageview_size"
+        android:layout_marginTop="16dp"
+        android:scaleType="fitStart"
+        android:layout_alignLeft="@id/title"
+        android:layout_below="@id/summary"/>
+</com.android.settings.widget.CheckableRelativeLayout>
\ No newline at end of file
diff --git a/res/menu/storage_volume.xml b/res/menu/storage_volume.xml
index bf9f985..87f7515 100644
--- a/res/menu/storage_volume.xml
+++ b/res/menu/storage_volume.xml
@@ -28,9 +28,21 @@
         android:id="@+id/storage_format"
         android:title="@string/storage_menu_format" />
     <item
+        android:id="@+id/storage_format_as_portable"
+        android:title="@string/storage_menu_format_public"
+        android:visible="false" />
+    <item
+        android:id="@+id/storage_format_as_internal"
+        android:title="@string/storage_menu_format_private"
+        android:visible="false" />
+    <item
         android:id="@+id/storage_migrate"
         android:title="@string/storage_menu_migrate" />
     <item
         android:id="@+id/storage_free"
         android:title="@string/storage_menu_free" />
+    <item
+        android:id="@+id/storage_forget"
+        android:title="@string/storage_menu_forget"
+        android:visible="false" />
 </menu>
diff --git a/res/values-af/arrays.xml b/res/values-af/arrays.xml
index b2d5ff1..53e1730 100644
--- a/res/values-af/arrays.xml
+++ b/res/values-af/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Geel op blou"</item>
     <item msgid="747238414788976867">"Gepasmaak"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Sweef oor ander programme"</item>
+    <item msgid="3605616699204153590">"Navigasiebalk"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Klein"</item>
+    <item msgid="1666628329913333563">"Groot"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN met voorafgedeelde sleutels"</item>
diff --git a/res/values-am/arrays.xml b/res/values-am/arrays.xml
index b51723b..8e67eff 100644
--- a/res/values-am/arrays.xml
+++ b/res/values-am/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"ቢጫ በሰማያዊ ላይ"</item>
     <item msgid="747238414788976867">"ብጁ"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"በሌሎች መተግበሪያዎች ላይ በመንሳፈፍ ላይበሪያዎች ላይ መቀያየር"</item>
+    <item msgid="3605616699204153590">"የአሰሳ አሞሌ"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"ትንሽ"</item>
+    <item msgid="1666628329913333563">"ትልቅ"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN ከቅድመ-ተጋሪ ቁልፎች ጋር"</item>
diff --git a/res/values-ar/arrays.xml b/res/values-ar/arrays.xml
index e5082bf..d802340 100644
--- a/res/values-ar/arrays.xml
+++ b/res/values-ar/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"أصفر في أزرق"</item>
     <item msgid="747238414788976867">"مخصص"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"عائم فوق التطبيقات الأخرى"</item>
+    <item msgid="3605616699204153590">"شريط التنقل"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"صغير"</item>
+    <item msgid="1666628329913333563">"كبير"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"‏شبكة افتراضية خاصة (VPN) عبر PPTP"</item>
     <item msgid="2552427673212085780">"‏شبكة افتراضية خاصة (VPN) لـ L2TP/IPSec مزودة بمفاتيح مشتركة مسبقًا"</item>
diff --git a/res/values-as/arrays.xml b/res/values-as/arrays.xml
index ff25aa7..c9cc034 100644
--- a/res/values-as/arrays.xml
+++ b/res/values-as/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"নীলাৰ ওপৰত হালধীয়া"</item>
     <item msgid="747238414788976867">"নিজৰ উপযোগিতা অনুযায়ী তৈয়াৰ কৰা"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"অন্য এপৰ ওপৰত ওপঙি আছে"</item>
+    <item msgid="3605616699204153590">"নেভিগেশ্বন বাৰ"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"সৰু"</item>
+    <item msgid="1666628329913333563">"ডাঙৰ"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"পিপিটিপি ভিপিএন"</item>
     <item msgid="2552427673212085780">"পূৰ্বে ভাগ-বতৰা কৰা কীসমূহৰ সৈতে L2TP/IPSec ভিপিএন"</item>
diff --git a/res/values-az/arrays.xml b/res/values-az/arrays.xml
index 2f6a67a..41c78a6 100644
--- a/res/values-az/arrays.xml
+++ b/res/values-az/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Mavi üstündə sarı"</item>
     <item msgid="747238414788976867">"Fərd"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Digər tətbiqlərin üzərində üzür"</item>
+    <item msgid="3605616699204153590">"Naviqasiya paneli"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Kiçik"</item>
+    <item msgid="1666628329913333563">"Böyük"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"Öncədən paylaşılmış açarlar ilə L2TP/IPSec VPN"</item>
diff --git a/res/values-b+sr+Latn/arrays.xml b/res/values-b+sr+Latn/arrays.xml
index 8b6de00..52c60b6 100644
--- a/res/values-b+sr+Latn/arrays.xml
+++ b/res/values-b+sr+Latn/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Žuto na plavo"</item>
     <item msgid="747238414788976867">"Prilagođeno"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Pluta preko drugih aplikacija"</item>
+    <item msgid="3605616699204153590">"Traka za navigaciju"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Mala"</item>
+    <item msgid="1666628329913333563">"Velika"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN sa unapred deljenim ključevima"</item>
diff --git a/res/values-be/arrays.xml b/res/values-be/arrays.xml
index 090b0f7..e96e881 100644
--- a/res/values-be/arrays.xml
+++ b/res/values-be/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Жоўты на сінім"</item>
     <item msgid="747238414788976867">"Карыстальніцкі"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Плаваючая кнопка паверх праграм"</item>
+    <item msgid="3605616699204153590">"Панэль навігацыі"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Маленькая"</item>
+    <item msgid="1666628329913333563">"Вялікая"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN з загадзя размеркаванымі ключамі"</item>
diff --git a/res/values-bg/arrays.xml b/res/values-bg/arrays.xml
index baf8536..7ab3d37 100644
--- a/res/values-bg/arrays.xml
+++ b/res/values-bg/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Жълто върху синьо"</item>
     <item msgid="747238414788976867">"Персонализиран"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Плаващ елемент над други приложения"</item>
+    <item msgid="3605616699204153590">"Лента за навигация"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Малък"</item>
+    <item msgid="1666628329913333563">"Голям"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN с PPTP"</item>
     <item msgid="2552427673212085780">"VPN с L2TP/IPSec с предварително споделени ключове"</item>
diff --git a/res/values-bn/arrays.xml b/res/values-bn/arrays.xml
index 7a0afc9..b97e0b5 100644
--- a/res/values-bn/arrays.xml
+++ b/res/values-bn/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"নীলের উপর হলুদ"</item>
     <item msgid="747238414788976867">"কাস্টম"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"মাল্টিটাস্কিং করতে অন্যান্য অ্যাপের উপরে ভেসে থাকা"</item>
+    <item msgid="3605616699204153590">"নেভিগেশন বার"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"ছোট"</item>
+    <item msgid="1666628329913333563">"বড়"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"আগে থেকে শেয়ার করা কীগুলির সাথে L2TP/IPSec VPN"</item>
diff --git a/res/values-bs/arrays.xml b/res/values-bs/arrays.xml
index 2c095f5..0ce7093 100644
--- a/res/values-bs/arrays.xml
+++ b/res/values-bs/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Žuto na plavom"</item>
     <item msgid="747238414788976867">"Prilagođeno"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Plutanje preko drugih aplikacija"</item>
+    <item msgid="3605616699204153590">"Navigaciona traka"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Malo"</item>
+    <item msgid="1666628329913333563">"Veliko"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN sa pre-shared lozinkama"</item>
diff --git a/res/values-ca/arrays.xml b/res/values-ca/arrays.xml
index b73e650..9f062ca 100644
--- a/res/values-ca/arrays.xml
+++ b/res/values-ca/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Groc sobre blau"</item>
     <item msgid="747238414788976867">"Personalitzat"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flotant sobre altres aplicacions"</item>
+    <item msgid="3605616699204153590">"Barra de navegació"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Petit"</item>
+    <item msgid="1666628329913333563">"Gran"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"VPN L2TP/IPSec amb claus prèviament compartides"</item>
diff --git a/res/values-cs/arrays.xml b/res/values-cs/arrays.xml
index 0a8a790..625f457 100644
--- a/res/values-cs/arrays.xml
+++ b/res/values-cs/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Žluté na modrém"</item>
     <item msgid="747238414788976867">"Vlastní"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Plovoucí přes ostatní aplikace"</item>
+    <item msgid="3605616699204153590">"Navigační panel"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Malé"</item>
+    <item msgid="1666628329913333563">"Velké"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN s protokolem PPTP"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN s předsdílenými klíči"</item>
diff --git a/res/values-da/arrays.xml b/res/values-da/arrays.xml
index 7d7b686..6cac514 100644
--- a/res/values-da/arrays.xml
+++ b/res/values-da/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Gult på blåt"</item>
     <item msgid="747238414788976867">"Tilpasset"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Vises over andre apps"</item>
+    <item msgid="3605616699204153590">"Navigationslinje"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Lille"</item>
+    <item msgid="1666628329913333563">"Stor"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP-VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPsec VPN med forhåndsdelte nøgler"</item>
diff --git a/res/values-de/arrays.xml b/res/values-de/arrays.xml
index 18358ac..aeaee4a 100644
--- a/res/values-de/arrays.xml
+++ b/res/values-de/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Gelb auf Blau"</item>
     <item msgid="747238414788976867">"Personalisiert"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Unverankert über anderen Apps"</item>
+    <item msgid="3605616699204153590">"Navigationsleiste"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Klein"</item>
+    <item msgid="1666628329913333563">"Groß"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP-VPN"</item>
     <item msgid="2552427673212085780">"L2TP-/IPSec-VPN mit vorinstallierten Schlüsseln"</item>
diff --git a/res/values-el/arrays.xml b/res/values-el/arrays.xml
index d5f9fab..6532ab6 100644
--- a/res/values-el/arrays.xml
+++ b/res/values-el/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Κίτρινο σε μπλε"</item>
     <item msgid="747238414788976867">"Προσαρμογή"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Κινούμενο πάνω από άλλες εφαρμογές"</item>
+    <item msgid="3605616699204153590">"Γραμμή πλοήγησης"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Μικρό"</item>
+    <item msgid="1666628329913333563">"Μεγάλο"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN με κλειδιά μοιρασμένα εκ των προτέρων"</item>
diff --git a/res/values-en-rAU/arrays.xml b/res/values-en-rAU/arrays.xml
index abf2d74..196868c 100644
--- a/res/values-en-rAU/arrays.xml
+++ b/res/values-en-rAU/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Yellow on blue"</item>
     <item msgid="747238414788976867">"Customise"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Floating over other apps"</item>
+    <item msgid="3605616699204153590">"Navigation bar"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Small"</item>
+    <item msgid="1666628329913333563">"Large"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN with preshared keys"</item>
diff --git a/res/values-en-rCA/arrays.xml b/res/values-en-rCA/arrays.xml
index 54395da..015530f 100644
--- a/res/values-en-rCA/arrays.xml
+++ b/res/values-en-rCA/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Yellow on blue"</item>
     <item msgid="747238414788976867">"Customise"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Floating over other apps"</item>
+    <item msgid="3605616699204153590">"Navigation bar"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Small"</item>
+    <item msgid="1666628329913333563">"Large"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN with preshared keys"</item>
diff --git a/res/values-en-rGB/arrays.xml b/res/values-en-rGB/arrays.xml
index abf2d74..196868c 100644
--- a/res/values-en-rGB/arrays.xml
+++ b/res/values-en-rGB/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Yellow on blue"</item>
     <item msgid="747238414788976867">"Customise"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Floating over other apps"</item>
+    <item msgid="3605616699204153590">"Navigation bar"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Small"</item>
+    <item msgid="1666628329913333563">"Large"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN with preshared keys"</item>
diff --git a/res/values-en-rIN/arrays.xml b/res/values-en-rIN/arrays.xml
index abf2d74..196868c 100644
--- a/res/values-en-rIN/arrays.xml
+++ b/res/values-en-rIN/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Yellow on blue"</item>
     <item msgid="747238414788976867">"Customise"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Floating over other apps"</item>
+    <item msgid="3605616699204153590">"Navigation bar"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Small"</item>
+    <item msgid="1666628329913333563">"Large"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN with preshared keys"</item>
diff --git a/res/values-en-rXC/arrays.xml b/res/values-en-rXC/arrays.xml
index 0144775..a5a9a76 100644
--- a/res/values-en-rXC/arrays.xml
+++ b/res/values-en-rXC/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‎‎Yellow on blue‎‏‎‎‏‎"</item>
     <item msgid="747238414788976867">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎Custom‎‏‎‎‏‎"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎Floating over other apps‎‏‎‎‏‎"</item>
+    <item msgid="3605616699204153590">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎Navigation bar‎‏‎‎‏‎"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎Small‎‏‎‎‏‎"</item>
+    <item msgid="1666628329913333563">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎Large‎‏‎‎‏‎"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‎PPTP VPN‎‏‎‎‏‎"</item>
     <item msgid="2552427673212085780">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎L2TP/IPSec VPN with pre-shared keys‎‏‎‎‏‎"</item>
diff --git a/res/values-es-rUS/arrays.xml b/res/values-es-rUS/arrays.xml
index af9cd1e..37f174e 100644
--- a/res/values-es-rUS/arrays.xml
+++ b/res/values-es-rUS/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Amarillo sobre azul"</item>
     <item msgid="747238414788976867">"Personalizado"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flotando encima de otras apps"</item>
+    <item msgid="3605616699204153590">"Barra de navegación"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Pequeño"</item>
+    <item msgid="1666628329913333563">"Grande"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"Claves precompartidas de VPN L2TP/IPSec"</item>
diff --git a/res/values-es/arrays.xml b/res/values-es/arrays.xml
index 650379f..6c757bb 100644
--- a/res/values-es/arrays.xml
+++ b/res/values-es/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Amarillo sobre azul"</item>
     <item msgid="747238414788976867">"Personalizado"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Se muestra sobre otras aplicaciones"</item>
+    <item msgid="3605616699204153590">"Barra de navegación"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Pequeño"</item>
+    <item msgid="1666628329913333563">"Grande"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"Red privada virtual PPTP"</item>
     <item msgid="2552427673212085780">"Red privada virtual L2TP/IPSec con claves precompartidas"</item>
diff --git a/res/values-et/arrays.xml b/res/values-et/arrays.xml
index c10f340..e5d08c9 100644
--- a/res/values-et/arrays.xml
+++ b/res/values-et/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Kollane sinisel"</item>
     <item msgid="747238414788976867">"Kohandatud"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Hõljub teiste rakenduste kohal"</item>
+    <item msgid="3605616699204153590">"Navigeerimisriba"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Väike"</item>
+    <item msgid="1666628329913333563">"Suur"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN eeljagatud võtmetega"</item>
diff --git a/res/values-eu/arrays.xml b/res/values-eu/arrays.xml
index 3a4694b..e558843 100644
--- a/res/values-eu/arrays.xml
+++ b/res/values-eu/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Horia urdinaren gainean"</item>
     <item msgid="747238414788976867">"Pertsonalizatua"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Beste aplikazio batzuen gainean"</item>
+    <item msgid="3605616699204153590">"Nabigazio-barra"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Txikia"</item>
+    <item msgid="1666628329913333563">"Handia"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPNa aurrez partekatutako gakoekin"</item>
diff --git a/res/values-fa/arrays.xml b/res/values-fa/arrays.xml
index 186afff..fabe268 100644
--- a/res/values-fa/arrays.xml
+++ b/res/values-fa/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"زرد در آبی"</item>
     <item msgid="747238414788976867">"سفارشی"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"شناور روی برنامه‌های دیگر"</item>
+    <item msgid="3605616699204153590">"نوار پیمایش"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"کوچک"</item>
+    <item msgid="1666628329913333563">"بزرگ"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"‏L2TP/IPSec VPN با کلیدهای از قبل به اشتراک گذاشته شده"</item>
diff --git a/res/values-fi/arrays.xml b/res/values-fi/arrays.xml
index bdf4085..cedbcaf 100644
--- a/res/values-fi/arrays.xml
+++ b/res/values-fi/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Keltainen sinisellä"</item>
     <item msgid="747238414788976867">"Muokattu"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Kelluu muiden sovellusten päällä"</item>
+    <item msgid="3605616699204153590">"Siirtymispalkki"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Pieni"</item>
+    <item msgid="1666628329913333563">"Suuri"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"Esijaettuun avaimeen perustuva L2TP-/IPSec-VPN-verkko"</item>
diff --git a/res/values-fr-rCA/arrays.xml b/res/values-fr-rCA/arrays.xml
index daf452c..0035d24 100644
--- a/res/values-fr-rCA/arrays.xml
+++ b/res/values-fr-rCA/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Texte jaune sur fond bleu"</item>
     <item msgid="747238414788976867">"Personnalisé"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flottant par-dessus d\'autres applis"</item>
+    <item msgid="3605616699204153590">"Barre de navigation"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Petite"</item>
+    <item msgid="1666628329913333563">"Grande"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"RPV PPTP"</item>
     <item msgid="2552427673212085780">"RPV L2TP/IPSec avec clés pré-partagées"</item>
diff --git a/res/values-fr/arrays.xml b/res/values-fr/arrays.xml
index c5f3c4a..39954d0 100644
--- a/res/values-fr/arrays.xml
+++ b/res/values-fr/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Texte jaune sur fond bleu"</item>
     <item msgid="747238414788976867">"Personnalisé"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flottant sur les autres applis"</item>
+    <item msgid="3605616699204153590">"Barre de navigation"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Petit"</item>
+    <item msgid="1666628329913333563">"Grand"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"VPN L2TP/IPSec avec clés pré-partagées"</item>
diff --git a/res/values-gl/arrays.xml b/res/values-gl/arrays.xml
index 8de9e56..e688500 100644
--- a/res/values-gl/arrays.xml
+++ b/res/values-gl/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Amarelo sobre azul"</item>
     <item msgid="747238414788976867">"Personalizado"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flotando sobre outras aplicacións"</item>
+    <item msgid="3605616699204153590">"Barra de navegación"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Pequeno"</item>
+    <item msgid="1666628329913333563">"Grande"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"VPN L2TP/IPSec con claves precompartidas"</item>
diff --git a/res/values-gu/arrays.xml b/res/values-gu/arrays.xml
index e4d4264..555707c 100644
--- a/res/values-gu/arrays.xml
+++ b/res/values-gu/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"વાદળી પર પીળી"</item>
     <item msgid="747238414788976867">"કસ્ટમ"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"અન્ય ઍપની ઉપર ફ્લોટિંગ"</item>
+    <item msgid="3605616699204153590">"નૅવિગેશન બાર"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"નાનું"</item>
+    <item msgid="1666628329913333563">"મોટું"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"પહેલાંથી શેર કરેલ કીઝ સાથે L2TP/IPSec VPN"</item>
diff --git a/res/values-hi/arrays.xml b/res/values-hi/arrays.xml
index c719208..d7cf7a2 100644
--- a/res/values-hi/arrays.xml
+++ b/res/values-hi/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"नीले पर पीला"</item>
     <item msgid="747238414788976867">"पसंद के मुताबिक"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"दूसरे ऐप्लिकेशन के ऊपर फ़्लोट कर रहा है"</item>
+    <item msgid="3605616699204153590">"नेविगेशन बार"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"छोटा"</item>
+    <item msgid="1666628329913333563">"बड़ा"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"पहले से शेयर की गई कुंजी के साथ L2TP/IPSec VPN"</item>
diff --git a/res/values-hr/arrays.xml b/res/values-hr/arrays.xml
index 15583bf..a792e90 100644
--- a/res/values-hr/arrays.xml
+++ b/res/values-hr/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Žuto na plavom"</item>
     <item msgid="747238414788976867">"Prilagođeno"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Plutanje preko drugih aplikacija"</item>
+    <item msgid="3605616699204153590">"Navigacijska traka"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Malen"</item>
+    <item msgid="1666628329913333563">"Velik"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN s unaprijed dijeljenim ključevima"</item>
diff --git a/res/values-hu/arrays.xml b/res/values-hu/arrays.xml
index 41ba9d5..a253054 100644
--- a/res/values-hu/arrays.xml
+++ b/res/values-hu/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Kék alapon sárga"</item>
     <item msgid="747238414788976867">"Egyedi"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Lebegés más alkalmazások fölött"</item>
+    <item msgid="3605616699204153590">"Navigációs sáv"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Kicsi"</item>
+    <item msgid="1666628329913333563">"Nagy"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN megosztott kulcsokkal"</item>
diff --git a/res/values-hy/arrays.xml b/res/values-hy/arrays.xml
index 605f265..a39b732 100644
--- a/res/values-hy/arrays.xml
+++ b/res/values-hy/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Դեղինը կապույտի վրա"</item>
     <item msgid="747238414788976867">"Հատուկ"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Ցուցադրվում է այլ հավելվածների վրայից"</item>
+    <item msgid="3605616699204153590">"Նավիգացիայի գոտի"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Փոքր"</item>
+    <item msgid="1666628329913333563">"Մեծ"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN նախորոշված ստեղներով"</item>
diff --git a/res/values-in/arrays.xml b/res/values-in/arrays.xml
index f2a40a7..c46d3c8 100644
--- a/res/values-in/arrays.xml
+++ b/res/values-in/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Kuning berlatar biru"</item>
     <item msgid="747238414788976867">"Khusus"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Mengambang di atas aplikasi lain"</item>
+    <item msgid="3605616699204153590">"Menu navigasi"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Kecil"</item>
+    <item msgid="1666628329913333563">"Besar"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN dengan kunci pra-bagi"</item>
diff --git a/res/values-is/arrays.xml b/res/values-is/arrays.xml
index b67be26..b8739ca 100644
--- a/res/values-is/arrays.xml
+++ b/res/values-is/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Gult á bláu"</item>
     <item msgid="747238414788976867">"Sérsniðið"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Fljótandi yfir öðrum forritum"</item>
+    <item msgid="3605616699204153590">"Yfirlitsstika"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Lítill"</item>
+    <item msgid="1666628329913333563">"Stór"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN með lyklum sem hefur verið deilt"</item>
diff --git a/res/values-it/arrays.xml b/res/values-it/arrays.xml
index a4c0443..717a4da 100644
--- a/res/values-it/arrays.xml
+++ b/res/values-it/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Giallo su blu"</item>
     <item msgid="747238414788976867">"Personalizzato"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Mobile sopra altre app"</item>
+    <item msgid="3605616699204153590">"Barra di navigazione"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Piccolo"</item>
+    <item msgid="1666628329913333563">"Grande"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"VPN L2TP/IPSec con chiavi precondivise"</item>
diff --git a/res/values-iw/arrays.xml b/res/values-iw/arrays.xml
index cfa1350..7ba72f5 100644
--- a/res/values-iw/arrays.xml
+++ b/res/values-iw/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"צהוב על גבי כחול"</item>
     <item msgid="747238414788976867">"מותאם אישית"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"צף מעל אפליקציות אחרות"</item>
+    <item msgid="3605616699204153590">"סרגל ניווט"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"קטן"</item>
+    <item msgid="1666628329913333563">"גדול"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"‏L2TP/IPSec VPN עם מפתחות משותפים מראש"</item>
diff --git a/res/values-ja/arrays.xml b/res/values-ja/arrays.xml
index 6a4e186..4431a17 100644
--- a/res/values-ja/arrays.xml
+++ b/res/values-ja/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"青地に黄色"</item>
     <item msgid="747238414788976867">"カスタム"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"他のアプリの上にフローティング"</item>
+    <item msgid="3605616699204153590">"ナビゲーション バー"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"小"</item>
+    <item msgid="1666628329913333563">"大"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"事前共有鍵付きのL2TP/IPSec VPN"</item>
diff --git a/res/values-ka/arrays.xml b/res/values-ka/arrays.xml
index d6c826e..8e0e04f 100644
--- a/res/values-ka/arrays.xml
+++ b/res/values-ka/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"ყვითელი ლურჯზე"</item>
     <item msgid="747238414788976867">"მორგებული"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"გადაფარვითი ჩვენება სხვა აპებზე ლივლივით"</item>
+    <item msgid="3605616699204153590">"ნავიგაციის ზოლი"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"პატარა"</item>
+    <item msgid="1666628329913333563">"დიდი"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN წინასწარ გაზიარებული ღილაკებით"</item>
diff --git a/res/values-kk/arrays.xml b/res/values-kk/arrays.xml
index b499a8e..58922a3 100644
--- a/res/values-kk/arrays.xml
+++ b/res/values-kk/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Көк түсте сарымен"</item>
     <item msgid="747238414788976867">"Басқа"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Басқа қолданбалар үстінен қалқу"</item>
+    <item msgid="3605616699204153590">"Навигация жолағы"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Кішкентай"</item>
+    <item msgid="1666628329913333563">"Үлкен"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec, пернелері ортақ ВЖЖ"</item>
diff --git a/res/values-km/arrays.xml b/res/values-km/arrays.xml
index 052f638..9e7f634 100644
--- a/res/values-km/arrays.xml
+++ b/res/values-km/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"ពណ៌លឿង​លើ​ពណ៌ខៀវ"</item>
     <item msgid="747238414788976867">"តាម​បំណង"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"កំពុងអណ្ដែតពីលើ​កម្មវិធីផ្សេងទៀត"</item>
+    <item msgid="3605616699204153590">"របាររុករក"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"តូច"</item>
+    <item msgid="1666628329913333563">"ធំ"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN ជា​មួយ​សោ​ចែករំលែក​ជាមុន"</item>
diff --git a/res/values-kn/arrays.xml b/res/values-kn/arrays.xml
index 4ee2b13..eeca4c9 100644
--- a/res/values-kn/arrays.xml
+++ b/res/values-kn/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"ನೀಲಿ ಬಣ್ಣದಲ್ಲಿ ಹಳದಿ"</item>
     <item msgid="747238414788976867">"ಕಸ್ಟಮ್"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"ಇತರೆ ಆ್ಯಪ್‌ಗಳಲ್ಲೂ ರನ್ ಆಗುತ್ತಿದೆ"</item>
+    <item msgid="3605616699204153590">"ನ್ಯಾವಿಗೇಷನ್ ಬಾರ್"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"ಸಣ್ಣದು"</item>
+    <item msgid="1666628329913333563">"ದೊಡ್ಡದು"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"ಪೂರ್ವ-ಹಂಚಿಕೆಯಾದ ಕೀಗಳನ್ನು ಹೊಂದಿರುವ L2TP/IPSec VPN"</item>
diff --git a/res/values-ko/arrays.xml b/res/values-ko/arrays.xml
index e574fa5..a806d87 100644
--- a/res/values-ko/arrays.xml
+++ b/res/values-ko/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"파란색 바탕에 노란색"</item>
     <item msgid="747238414788976867">"맞춤설정"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"다른 앱 위에 플로팅"</item>
+    <item msgid="3605616699204153590">"탐색 메뉴"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"작게"</item>
+    <item msgid="1666628329913333563">"크게"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"사전 공유 키를 사용하는 L2TP/IPSec VPN"</item>
diff --git a/res/values-ky/arrays.xml b/res/values-ky/arrays.xml
index 9e70efd..dab63c2 100644
--- a/res/values-ky/arrays.xml
+++ b/res/values-ky/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Сары көктө"</item>
     <item msgid="747238414788976867">"Өзгөчөлөнгөн"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Башка колдонмолордун үстүнөн көрсөтүү"</item>
+    <item msgid="3605616699204153590">"Чабыттоо тилкеси"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Кичине"</item>
+    <item msgid="1666628329913333563">"Чоң"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"Алдын ала бөлүшүлгөн ачкычтары бар L2TP/IPSec VPN"</item>
diff --git a/res/values-lo/arrays.xml b/res/values-lo/arrays.xml
index cc5f45b..47906e0 100644
--- a/res/values-lo/arrays.xml
+++ b/res/values-lo/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"ສີເຫຼືອງພື້ນຟ້າ"</item>
     <item msgid="747238414788976867">"ກຳນົດເອງ"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"ລອຍຢູ່ເທິງແອັບອື່ນ"</item>
+    <item msgid="3605616699204153590">"ແຖບການນຳທາງ"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"ນ້ອຍ"</item>
+    <item msgid="1666628329913333563">"ໃຫຍ່"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN ທີ່ມີກະແຈທີ່ແບ່ງປັນລ່ວງໜ້າ"</item>
diff --git a/res/values-lt/arrays.xml b/res/values-lt/arrays.xml
index c04c608..a2351d1 100644
--- a/res/values-lt/arrays.xml
+++ b/res/values-lt/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Geltonas ant mėlyno"</item>
     <item msgid="747238414788976867">"Tinkintas"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Rodomas virš kitų programų"</item>
+    <item msgid="3605616699204153590">"Naršymo juosta"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Mažas"</item>
+    <item msgid="1666628329913333563">"Didelis"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP / „IPSec“ VPN su iš anksto bendrinamais raktais"</item>
diff --git a/res/values-lv/arrays.xml b/res/values-lv/arrays.xml
index 54e659a..5bd48d0 100644
--- a/res/values-lv/arrays.xml
+++ b/res/values-lv/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Dzeltens uz zila"</item>
     <item msgid="747238414788976867">"Pielāgots"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Peldoša poga virs lietotnēm"</item>
+    <item msgid="3605616699204153590">"Navigācijas joslā"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Maza"</item>
+    <item msgid="1666628329913333563">"Liela"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"Otrā slāņa tunelēšanas protokola/protokola IPsec VPN ar iepriekš kopīgotām atslēgām"</item>
diff --git a/res/values-mk/arrays.xml b/res/values-mk/arrays.xml
index 16e12e4..d3f382c 100644
--- a/res/values-mk/arrays.xml
+++ b/res/values-mk/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Жолти на сино"</item>
     <item msgid="747238414788976867">"Приспособено"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Лебди над други апликации"</item>
+    <item msgid="3605616699204153590">"Лента за навигација"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Мало"</item>
+    <item msgid="1666628329913333563">"Големо"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN со претходно споделени клучеви"</item>
diff --git a/res/values-ml/arrays.xml b/res/values-ml/arrays.xml
index 0553306..cd8edbc 100644
--- a/res/values-ml/arrays.xml
+++ b/res/values-ml/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"നീലയിൽ മഞ്ഞ"</item>
     <item msgid="747238414788976867">"ഇഷ്‌ടാനുസൃതം"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"മറ്റ് ആപ്പുകൾക്ക് മുകളിലൂടെ നീങ്ങുന്നു"</item>
+    <item msgid="3605616699204153590">"നാവിഗേഷൻ ബാർ"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"ചെറുത്"</item>
+    <item msgid="1666628329913333563">"വലുത്"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"മുമ്പ് പങ്കിട്ട കീകൾ ഉപയോഗിക്കുന്ന L2TP/IPSec VPN"</item>
diff --git a/res/values-mn/arrays.xml b/res/values-mn/arrays.xml
index 0430de7..ddc8d40 100644
--- a/res/values-mn/arrays.xml
+++ b/res/values-mn/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Цэнхэр дээр шар"</item>
     <item msgid="747238414788976867">"Өөрчлөх"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Бусад апп дээр хөвөх"</item>
+    <item msgid="3605616699204153590">"Навигацын самбар"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Жижиг"</item>
+    <item msgid="1666628329913333563">"Том"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"Урьдчилан хуваалцсан L2TP/IPSec VPN түлхүүртэй"</item>
diff --git a/res/values-mr/arrays.xml b/res/values-mr/arrays.xml
index 7f7abb4..60dc05a 100644
--- a/res/values-mr/arrays.xml
+++ b/res/values-mr/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"निळ्यावर पिवळे"</item>
     <item msgid="747238414788976867">"कस्टम"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"इतर ॲप्सवर फ्लोट करतात"</item>
+    <item msgid="3605616699204153590">"नेव्हिगेशन बार"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"लहान"</item>
+    <item msgid="1666628329913333563">"मोठा"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"पूर्व-शेअर की सह L2TP/IPSec VPN"</item>
diff --git a/res/values-ms/arrays.xml b/res/values-ms/arrays.xml
index 0dbd497..793f729 100644
--- a/res/values-ms/arrays.xml
+++ b/res/values-ms/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Kuning pada biru"</item>
     <item msgid="747238414788976867">"Peribadi"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Terapung di atas apl lain"</item>
+    <item msgid="3605616699204153590">"Bar navigasi"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Kecil"</item>
+    <item msgid="1666628329913333563">"Besar"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"VPN L2TP/IPSec dengan kunci prakongsi"</item>
diff --git a/res/values-my/arrays.xml b/res/values-my/arrays.xml
index b425af6..ad7140e 100644
--- a/res/values-my/arrays.xml
+++ b/res/values-my/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"အပြာပေါ်အဝါ"</item>
     <item msgid="747238414788976867">"စိတ်ကြိုက်"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"အခြားအက်ပ်များပေါ်တွင် မြင်ရခြင်း"</item>
+    <item msgid="3605616699204153590">"လမ်းညွှန်ဘား"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"သေး"</item>
+    <item msgid="1666628329913333563">"ကြီး"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"ကြိုတင် ပေးထားတဲ့ ကီးပါရှိသောL2TP/IPSec VPN"</item>
diff --git a/res/values-nb/arrays.xml b/res/values-nb/arrays.xml
index 02044dc..d893b40 100644
--- a/res/values-nb/arrays.xml
+++ b/res/values-nb/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Gult på blått"</item>
     <item msgid="747238414788976867">"Egendefinert"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flytende over andre apper"</item>
+    <item msgid="3605616699204153590">"Navigasjonsrad"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Liten"</item>
+    <item msgid="1666628329913333563">"Stor"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN med forhåndsdelte nøkler"</item>
diff --git a/res/values-ne/arrays.xml b/res/values-ne/arrays.xml
index bacf02a..40e4b30 100644
--- a/res/values-ne/arrays.xml
+++ b/res/values-ne/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"नीलोमा पहेँलो"</item>
     <item msgid="747238414788976867">"आफू अनुकूल"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"अन्य एपहरूमाथि तैरने"</item>
+    <item msgid="3605616699204153590">"नेभिगेसन बार"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"सानो"</item>
+    <item msgid="1666628329913333563">"ठुलो"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN पूर्व साझेदारी कुञ्जीकासँग"</item>
diff --git a/res/values-nl/arrays.xml b/res/values-nl/arrays.xml
index 627fa59..eafae00 100644
--- a/res/values-nl/arrays.xml
+++ b/res/values-nl/arrays.xml
@@ -274,7 +274,7 @@
     <item msgid="2297727967385895059">"locatie met hoog energieverbruik controleren"</item>
     <item msgid="8700593962030471569">"gebruiksstatistieken ophalen"</item>
     <item msgid="4140820386622184831">"microfoon uit-/aanzetten"</item>
-    <item msgid="317746827951691657">"toast weergeven"</item>
+    <item msgid="317746827951691657">"toast tonen"</item>
     <item msgid="5679422988212309779">"media projecteren"</item>
     <item msgid="6454031639780101439">"VPN activeren"</item>
     <item msgid="2441327072846850561">"achtergrond schrijven"</item>
@@ -341,7 +341,7 @@
     <item msgid="5186169827582545242">"Locatie"</item>
     <item msgid="6122293931012635638">"Gebruiksstatistieken ophalen"</item>
     <item msgid="2526677383312751932">"Microfoon uit-/aanzetten"</item>
-    <item msgid="4000577305179914546">"Toast weergeven"</item>
+    <item msgid="4000577305179914546">"Toast tonen"</item>
     <item msgid="8660207174515570558">"Media projecteren"</item>
     <item msgid="3904996949561946108">"VPN activeren"</item>
     <item msgid="504052124101832515">"Achtergrond schrijven"</item>
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Geel op blauw"</item>
     <item msgid="747238414788976867">"Aangepast"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Zwevend over andere apps"</item>
+    <item msgid="3605616699204153590">"Navigatiebalk"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Klein"</item>
+    <item msgid="1666628329913333563">"Groot"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP-VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec-VPN met van tevoren gedeelde sleutels"</item>
diff --git a/res/values-or/arrays.xml b/res/values-or/arrays.xml
index 10a8ca8..dfdaa2e 100644
--- a/res/values-or/arrays.xml
+++ b/res/values-or/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"ନୀଳ ଉପରେ ହଳଦିଆ"</item>
     <item msgid="747238414788976867">"କଷ୍ଟମ୍‌"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"ଅନ୍ୟ ଆପଗୁଡ଼ିକ ଉପରେ ଫ୍ଲୋଟ୍ ହେଉଛି"</item>
+    <item msgid="3605616699204153590">"ନାଭିଗେସନ୍ ବାର୍"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"ଛୋଟ"</item>
+    <item msgid="1666628329913333563">"ବଡ଼"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"ପୂର୍ବରୁ ସେୟାର୍‌ ହୋଇଥିବା କୀଗୁଡ଼ିକ ସହ L2TP/IPSec VPN"</item>
diff --git a/res/values-pa/arrays.xml b/res/values-pa/arrays.xml
index b19666c..4838f68 100644
--- a/res/values-pa/arrays.xml
+++ b/res/values-pa/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"ਨੀਲੇ \'ਤੇ ਪੀਲਾ"</item>
     <item msgid="747238414788976867">"ਵਿਉਂਂਤੀ"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"ਦੂਜੀਆਂ ਐਪਾਂ \'ਤੇ ਫ਼ਲੋਟ ਕਰਨਾ"</item>
+    <item msgid="3605616699204153590">"ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਪੱਟੀ"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"ਛੋਟਾ"</item>
+    <item msgid="1666628329913333563">"ਵੱਡਾ"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"ਪ੍ਰੀ-ਸ਼ੇਅਰ ਕੀਤੀਆਂ ਕੁੰਜੀਆਂ ਨਾਲ L2TP/IPSec VPN"</item>
diff --git a/res/values-pl/arrays.xml b/res/values-pl/arrays.xml
index 4a47bac..518e302 100644
--- a/res/values-pl/arrays.xml
+++ b/res/values-pl/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Żółty na niebieskim"</item>
     <item msgid="747238414788976867">"Niestandardowy"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Pływający nad innymi aplikacjami"</item>
+    <item msgid="3605616699204153590">"Pasek nawigacyjny"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Mały"</item>
+    <item msgid="1666628329913333563">"Duży"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"Sieć VPN wykorzystująca protokół PPTP"</item>
     <item msgid="2552427673212085780">"Sieć VPN wykorzystująca protokół L2TP/IPSec z kluczami wspólnymi"</item>
diff --git a/res/values-pt-rBR/arrays.xml b/res/values-pt-rBR/arrays.xml
index 58b4e61..640ebbd 100644
--- a/res/values-pt-rBR/arrays.xml
+++ b/res/values-pt-rBR/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Amarelo em azul"</item>
     <item msgid="747238414788976867">"Personalizado"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flutuando sobre outros apps"</item>
+    <item msgid="3605616699204153590">"Barra de navegação"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Pequeno"</item>
+    <item msgid="1666628329913333563">"Grande"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN com chaves pré-compartilhadas"</item>
diff --git a/res/values-pt-rPT/arrays.xml b/res/values-pt-rPT/arrays.xml
index d387923..1937541 100644
--- a/res/values-pt-rPT/arrays.xml
+++ b/res/values-pt-rPT/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Amarelo em azul"</item>
     <item msgid="747238414788976867">"Personalizado"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flutuante sobre outras apps"</item>
+    <item msgid="3605616699204153590">"Barra de navegação"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Pequeno"</item>
+    <item msgid="1666628329913333563">"Grande"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"VPN L2TP/IPSec com chaves pré-partilhadas"</item>
diff --git a/res/values-pt/arrays.xml b/res/values-pt/arrays.xml
index 58b4e61..640ebbd 100644
--- a/res/values-pt/arrays.xml
+++ b/res/values-pt/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Amarelo em azul"</item>
     <item msgid="747238414788976867">"Personalizado"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flutuando sobre outros apps"</item>
+    <item msgid="3605616699204153590">"Barra de navegação"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Pequeno"</item>
+    <item msgid="1666628329913333563">"Grande"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN com chaves pré-compartilhadas"</item>
diff --git a/res/values-ro/arrays.xml b/res/values-ro/arrays.xml
index c4c6284..4f282e2 100644
--- a/res/values-ro/arrays.xml
+++ b/res/values-ro/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Galben pe albastru"</item>
     <item msgid="747238414788976867">"Personalizat"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Se afișează peste alte aplicații"</item>
+    <item msgid="3605616699204153590">"Bară de navigare"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Mic"</item>
+    <item msgid="1666628329913333563">"Mare"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN cu chei predistribuite"</item>
diff --git a/res/values-ru/arrays.xml b/res/values-ru/arrays.xml
index 98d2439..cdcf10b 100644
--- a/res/values-ru/arrays.xml
+++ b/res/values-ru/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Желтый на синем"</item>
     <item msgid="747238414788976867">"Специальный"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Поверх других приложений"</item>
+    <item msgid="3605616699204153590">"Панель навигации"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Маленькая кнопка"</item>
+    <item msgid="1666628329913333563">"Большая кнопка"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN-подключение по протоколу PPTP"</item>
     <item msgid="2552427673212085780">"VPN-соединение по протоколу L2TP/IPSec с общими ключами"</item>
diff --git a/res/values-si/arrays.xml b/res/values-si/arrays.xml
index f3944d9..c0f8dbb 100644
--- a/res/values-si/arrays.xml
+++ b/res/values-si/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"නිල් මත කහ"</item>
     <item msgid="747238414788976867">"අභිරුචි"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"යෙදුම්වලට උඩින් පාවීම"</item>
+    <item msgid="3605616699204153590">"සංචලන තීරුව"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"කුඩා"</item>
+    <item msgid="1666628329913333563">"විශාල"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"පෙර බෙදාගත් යතුරු සමඟ L2TP/IPSec VPN"</item>
diff --git a/res/values-sk/arrays.xml b/res/values-sk/arrays.xml
index 5ec1c81..2d6e38a 100644
--- a/res/values-sk/arrays.xml
+++ b/res/values-sk/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Žlté na modrom"</item>
     <item msgid="747238414788976867">"Vlastné"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Plávajúce nad ostatnými aplikáciami"</item>
+    <item msgid="3605616699204153590">"Navigačný panel"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Malé"</item>
+    <item msgid="1666628329913333563">"Veľké"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN s protokolom PPTP"</item>
     <item msgid="2552427673212085780">"Sieť VPN založená na protokole L2TP/IPSec s predzdieľanými kľúčmi"</item>
diff --git a/res/values-sl/arrays.xml b/res/values-sl/arrays.xml
index 8ed2d74..9931395 100644
--- a/res/values-sl/arrays.xml
+++ b/res/values-sl/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Rumeno na modrem"</item>
     <item msgid="747238414788976867">"Po meri"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Prekrivanje drugih aplikacij"</item>
+    <item msgid="3605616699204153590">"Vrstica za krmarjenje"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Majhen"</item>
+    <item msgid="1666628329913333563">"Velik"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN s ključi v predhodni skupni rabi"</item>
diff --git a/res/values-sq/arrays.xml b/res/values-sq/arrays.xml
index 9a348bf..4ade61a 100644
--- a/res/values-sq/arrays.xml
+++ b/res/values-sq/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"E verdhë mbi të kaltër"</item>
     <item msgid="747238414788976867">"Të personalizuara"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Pluskon mbi aplikacionet e tjera"</item>
+    <item msgid="3605616699204153590">"Shiriti i navigimit"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"I vogël"</item>
+    <item msgid="1666628329913333563">"I madh"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"VPN PPTP"</item>
     <item msgid="2552427673212085780">"Rrjeti VPN L2TP/IPSec me çelësat e ndarë paraprakisht"</item>
diff --git a/res/values-sr/arrays.xml b/res/values-sr/arrays.xml
index 18bf8fe..ca536c9 100644
--- a/res/values-sr/arrays.xml
+++ b/res/values-sr/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Жуто на плаво"</item>
     <item msgid="747238414788976867">"Прилагођено"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Плута преко других апликација"</item>
+    <item msgid="3605616699204153590">"Трака за навигацију"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Мала"</item>
+    <item msgid="1666628329913333563">"Велика"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN са унапред дељеним кључевима"</item>
diff --git a/res/values-sv/arrays.xml b/res/values-sv/arrays.xml
index 5d3dc63..365e4fa 100644
--- a/res/values-sv/arrays.xml
+++ b/res/values-sv/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Gult på blått"</item>
     <item msgid="747238414788976867">"Anpassat"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Flytande över andra appar"</item>
+    <item msgid="3605616699204153590">"Navigeringsfält"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Liten"</item>
+    <item msgid="1666628329913333563">"Stor"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP-VPN"</item>
     <item msgid="2552427673212085780">"L2TP-/IPSec-VPN med nycklar som delats i förväg"</item>
diff --git a/res/values-sw/arrays.xml b/res/values-sw/arrays.xml
index 89fb40c..0dd92d5 100644
--- a/res/values-sw/arrays.xml
+++ b/res/values-sw/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Manjano kwenye samawati"</item>
     <item msgid="747238414788976867">"Maalum"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Kuelea juu ya programu zingine"</item>
+    <item msgid="3605616699204153590">"Sehemu ya viungo muhimu"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Kidogo"</item>
+    <item msgid="1666628329913333563">"Kikubwa"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN na vitufe vilivyoshirikishwa kabla"</item>
diff --git a/res/values-ta/arrays.xml b/res/values-ta/arrays.xml
index e5c4a79..96f97c0 100644
--- a/res/values-ta/arrays.xml
+++ b/res/values-ta/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"நீலத்தில் மஞ்சள்"</item>
     <item msgid="747238414788976867">"பிரத்தியேகம்"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"பிற ஆப்ஸ் மீது தோன்றுதல்"</item>
+    <item msgid="3605616699204153590">"வழிசெலுத்தல் பட்டி"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"சிறியது"</item>
+    <item msgid="1666628329913333563">"பெரியது"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"பாதுகாப்பு விசைகளுடன் கூடிய L2TP/IPSec VPN"</item>
diff --git a/res/values-te/arrays.xml b/res/values-te/arrays.xml
index 18bb6bc..00a56f7 100644
--- a/res/values-te/arrays.xml
+++ b/res/values-te/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"నీలి నేపథ్యంలో పసుపు రంగు"</item>
     <item msgid="747238414788976867">"అనుకూలం"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"ఇతర యాప్‌ల మీద తేలియాడుతోంది"</item>
+    <item msgid="3605616699204153590">"నావిగేషన్ బార్"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"చిన్నది"</item>
+    <item msgid="1666628329913333563">"పెద్దది"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"పూర్వ-భాగస్వామ్య కీలతో L2TP/IPSec VPN"</item>
diff --git a/res/values-th/arrays.xml b/res/values-th/arrays.xml
index 1e4de9c3..a659bda 100644
--- a/res/values-th/arrays.xml
+++ b/res/values-th/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"สีเหลืองบนพื้นสีน้ำเงิน"</item>
     <item msgid="747238414788976867">"กำหนดเอง"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"ลอยเหนือแอปอื่นๆ"</item>
+    <item msgid="3605616699204153590">"แถบนำทาง"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"เล็ก"</item>
+    <item msgid="1666628329913333563">"ใหญ่"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN พร้อมด้วยคีย์ที่แชร์ไว้ล่วงหน้า"</item>
diff --git a/res/values-tl/arrays.xml b/res/values-tl/arrays.xml
index 938eff5..b65b170 100644
--- a/res/values-tl/arrays.xml
+++ b/res/values-tl/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Dilaw sa asul"</item>
     <item msgid="747238414788976867">"Custom"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Nasa ibabaw ng iba pang app"</item>
+    <item msgid="3605616699204153590">"Navigation bar"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Maliit"</item>
+    <item msgid="1666628329913333563">"Malaki"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN na may mga paunang nabahaging key"</item>
diff --git a/res/values-tr/arrays.xml b/res/values-tr/arrays.xml
index 5ed1d6c..c55df18 100644
--- a/res/values-tr/arrays.xml
+++ b/res/values-tr/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Mavi üzerine sarı"</item>
     <item msgid="747238414788976867">"Özel"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Diğer uygulamaların üzerinde kayan"</item>
+    <item msgid="3605616699204153590">"Gezinme çubuğu"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Küçük"</item>
+    <item msgid="1666628329913333563">"Büyük"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"Önceden paylaşılan anahtara sahip L2TP/IPSec VPN"</item>
diff --git a/res/values-uk/arrays.xml b/res/values-uk/arrays.xml
index 5bbc7ac..9c85a16 100644
--- a/res/values-uk/arrays.xml
+++ b/res/values-uk/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Жовтий на синьому"</item>
     <item msgid="747238414788976867">"Спеціальний"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Плаває поверх інших додатків"</item>
+    <item msgid="3605616699204153590">"Панель навігації"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Мала"</item>
+    <item msgid="1666628329913333563">"Велика"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN зі спільними ключами"</item>
diff --git a/res/values-ur/arrays.xml b/res/values-ur/arrays.xml
index a336c3c..4e5af0b 100644
--- a/res/values-ur/arrays.xml
+++ b/res/values-ur/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"نیلے پر پیلا"</item>
     <item msgid="747238414788976867">"حسب ضرورت"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"دیگر ایپس پر فلوٹنگ ہو رہی ہے"</item>
+    <item msgid="3605616699204153590">"نیویگیشن بار"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"چھوٹا"</item>
+    <item msgid="1666628329913333563">"بڑا"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"‏پہلے سے اشتراک کردہ کلیدوں کے ساتھ L2TP/IPSec VPN"</item>
diff --git a/res/values-uz/arrays.xml b/res/values-uz/arrays.xml
index 56f7063..c24ba87 100644
--- a/res/values-uz/arrays.xml
+++ b/res/values-uz/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Ko‘k ustida sariq"</item>
     <item msgid="747238414788976867">"Maxsus"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Boshqa ilovalar ustidan chiqishi"</item>
+    <item msgid="3605616699204153590">"Navigatsiya paneli"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Kichik"</item>
+    <item msgid="1666628329913333563">"Yirik"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN avval ulashilgan kalitlar bilan"</item>
diff --git a/res/values-vi/arrays.xml b/res/values-vi/arrays.xml
index ad319ac..a1158fc 100644
--- a/res/values-vi/arrays.xml
+++ b/res/values-vi/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Chữ vàng trên nền xanh lam"</item>
     <item msgid="747238414788976867">"Tùy chỉnh"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Nổi trên các ứng dụng khác"</item>
+    <item msgid="3605616699204153590">"Thanh điều hướng"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Nhỏ"</item>
+    <item msgid="1666628329913333563">"Lớn"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN có khóa chia sẻ trước"</item>
diff --git a/res/values-zh-rCN/arrays.xml b/res/values-zh-rCN/arrays.xml
index 19deb1e..073df09 100644
--- a/res/values-zh-rCN/arrays.xml
+++ b/res/values-zh-rCN/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"蓝底黄字"</item>
     <item msgid="747238414788976867">"自定义"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"悬浮在其他应用的上层"</item>
+    <item msgid="3605616699204153590">"导航栏"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"小"</item>
+    <item msgid="1666628329913333563">"大"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"具有预共享密钥的 L2TP/IPSec VPN"</item>
diff --git a/res/values-zh-rHK/arrays.xml b/res/values-zh-rHK/arrays.xml
index e876134..a91a444 100644
--- a/res/values-zh-rHK/arrays.xml
+++ b/res/values-zh-rHK/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"藍底黃字"</item>
     <item msgid="747238414788976867">"自訂"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"浮動顯示在其他應用程式上"</item>
+    <item msgid="3605616699204153590">"導覽列"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"小"</item>
+    <item msgid="1666628329913333563">"大"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN (預先共用密鑰)"</item>
diff --git a/res/values-zh-rTW/arrays.xml b/res/values-zh-rTW/arrays.xml
index dee72bc..1a49712 100644
--- a/res/values-zh-rTW/arrays.xml
+++ b/res/values-zh-rTW/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"藍底黃字"</item>
     <item msgid="747238414788976867">"自訂"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"浮動顯示在其他應用程式上"</item>
+    <item msgid="3605616699204153590">"導覽列"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"小"</item>
+    <item msgid="1666628329913333563">"大"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"L2TP/IPSec VPN (預先共用金鑰)"</item>
diff --git a/res/values-zu/arrays.xml b/res/values-zu/arrays.xml
index 40edd11..26d2e8b 100644
--- a/res/values-zu/arrays.xml
+++ b/res/values-zu/arrays.xml
@@ -419,6 +419,14 @@
     <item msgid="2836895041823327816">"Okuliphuzi kokuluhlaza"</item>
     <item msgid="747238414788976867">"Ngokwezifiso"</item>
   </string-array>
+  <string-array name="accessibility_button_location_selector_titles">
+    <item msgid="6485511780196327736">"Intanta phezu kwamanye ama-app"</item>
+    <item msgid="3605616699204153590">"Ibha yokuzula"</item>
+  </string-array>
+  <string-array name="accessibility_button_size_selector_titles">
+    <item msgid="7482952318152486459">"Esincane"</item>
+    <item msgid="1666628329913333563">"Esikhulu"</item>
+  </string-array>
   <string-array name="vpn_types_long">
     <item msgid="6621806338070912611">"PPTP VPN"</item>
     <item msgid="2552427673212085780">"i-L2TP/IPSec VPN nokhiye okwabeliswaniwa ngabo"</item>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index dbf21fc..0ee39cd 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -295,6 +295,7 @@
     <!-- Accessibility Settings -->
     <dimen name="accessibility_layout_margin_start_end">16dp</dimen>
     <dimen name="accessibility_button_preference_padding_top_bottom">18dp</dimen>
+    <dimen name="accessibility_imageview_size">176dp</dimen>
 
     <!-- Restricted icon in switch bar -->
     <dimen name="restricted_icon_margin_end">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 46bd351..7755da4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3368,6 +3368,10 @@
     <string name="storage_menu_manage">Manage storage</string>
     <!-- Storage setting. Keywords for Free up space. [CHAR LIMIT=NONE] -->
     <string name="keywords_storage_menu_free">clean, storage</string>
+    <!-- Storage setting. Title for storage free up option. [CHAR LIMIT=30] -->
+    <string name="storage_free_up_space_title">Free up space</string>
+    <!-- Storage setting. Summary for storage free up option. [CHAR LIMIT=NONE] -->
+    <string name="storage_free_up_space_summary">Go to Files app to manage and free up space</string>
 
     <!-- Storage setting.  Title for USB transfer settings [CHAR LIMIT=30]-->
     <string name="storage_title_usb">USB computer connection</string>
@@ -5039,7 +5043,7 @@
     <!-- Title for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=35] -->
     <string name="accessibility_screen_magnification_title">Magnification</string>
     <!-- Title for the accessibility preference screen to edit magnification area. [CHAR LIMIT=35] -->
-    <string name="accessibility_magnification_mode_title">Choose how to magnify</string>
+    <string name="accessibility_magnification_mode_title">Magnification type</string>
     <!-- Message for the accessibility preference screen to edit magnification area dialog. [CHAR LIMIT=none] -->
     <string name="accessibility_magnification_area_settings_message">Magnify your full screen, a specific area, or switch between both options</string>
     <!-- Summary for the accessibility preference screen to edit full screen. [CHAR LIMIT=none] -->
@@ -5048,10 +5052,16 @@
     <string name="accessibility_magnification_area_settings_window_screen_summary">Partial screen</string>
     <!-- Summary for the accessibility preference screen to edit full and partial screen. [CHAR LIMIT=none] -->
     <string name="accessibility_magnification_area_settings_all_summary">Switch between full and partial screen</string>
-    <!-- Message for the accessibility preference screen to edit the full screen. [CHAR LIMIT=none] -->
-    <string name="accessibility_magnification_area_settings_full_screen">Magnify full screen</string>
-    <!-- Message for the accessibility preference screen to edit part of screen. [CHAR LIMIT=none] -->
-    <string name="accessibility_magnification_area_settings_window_screen">Magnify part of screen</string>
+    <!-- dialog title for magnification mode  selection. [CHAR LIMIT=35] -->
+    <string name="accessibility_magnification_mode_dialog_title">Choose how to magnify</string>
+    <!-- Option title of full-screen magnification mode in the mode selection dialog. [CHAR LIMIT=50] -->
+    <string name="accessibility_magnification_mode_dialog_option_full_screen">Magnify full screen</string>
+    <!-- Option title of window magnification mode in the mode selection dialog. [CHAR LIMIT=50] -->
+    <string name="accessibility_magnification_mode_dialog_option_window">Magnify part of screen</string>
+    <!-- Option title of full magnification mode in the mode selection dialog. [CHAR LIMIT=50] -->
+    <string name="accessibility_magnification_mode_dialog_option_switch">Switch between full and partial screen</string>
+    <!-- Message of the magnification mode option to choose the magnification mode. [CHAR LIMIT=none] -->
+    <string name="accessibility_magnification_area_settings_mode_switch_summary">Tap the switch button to move between both options</string>
     <!-- Title for the accessibility magnification switch shortcut dialog. [CHAR LIMIT=48] -->
     <string name="accessibility_magnification_switch_shortcut_title">Switch to accessibility button?</string>
     <!-- Message for the accessibility magnification switch shortcut dialog. [CHAR LIMIT=none] -->
@@ -11565,6 +11575,10 @@
     <!-- Follows the percent of storage used by a storage volume. Exposed inside of a donut graph. [CHAR LIMIT=7]-->
     <string name="storage_percent_full">used</string>
 
+    <!-- Summary of a single storage volume used space. [CHAR LIMIT=24] -->
+    <string name="storage_usage_summary"><xliff:g id="number" example="128">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g> used</string>
+    <!-- Summary of a single storage volume total space. [CHAR LIMIT=24] -->
+    <string name="storage_total_summary">Total <xliff:g id="number" example="128">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g></string>
 
     <!-- Label for button allow user to remove the instant app from the device. -->
     <string name="clear_instant_app_data">Clear app</string>
@@ -12916,4 +12930,10 @@
 
     <!-- Label for extra app info settings for a specific app [CHAR LIMIT=40] -->
     <string name="extra_app_info_label" translatable="false"></string>
+
+    <!-- Title for toggle controlling whether notifications are shown when an app pastes from clipboard. [CHAR LIMIT=50] -->
+    <string name="show_clip_access_notification">Copy &amp; paste notifications</string>
+
+    <!-- Summary for toggle controlling whether notifications are shown when an app pastes from clipboard. [CHAR LIMIT=NONE] -->
+    <string name="show_clip_access_notification_summary">Show a message when apps access text or data you have copied</string>
 </resources>
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index 75bbca0..8c6fe41 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -40,32 +40,30 @@
         android:title="@string/summary_placeholder"
         settings:controller="com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController" />
 
-    <PreferenceCategory>
-        <SwitchPreference
-            android:key="battery_percentage"
-            android:title="@string/battery_percentage"
-            android:summary="@string/battery_percentage_description"
-            settings:controller="com.android.settings.display.BatteryPercentagePreferenceController" />
-    </PreferenceCategory>
+    <Preference
+        android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
+        android:key="battery_saver_summary"
+        android:title="@string/battery_saver"
+        app:iconSpaceReserved="false"
+        settings:controller="com.android.settings.fuelgauge.BatterySaverController" />
 
-    <PreferenceCategory>
-        <Preference
-            android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
-            android:key="battery_saver_summary"
-            android:title="@string/battery_saver"
-            settings:controller="com.android.settings.fuelgauge.BatterySaverController" />
+    <Preference
+        android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"
+        android:key="smart_battery_manager"
+        android:title="@string/smart_battery_manager_title"
+        app:iconSpaceReserved="false"
+        settings:controller="com.android.settings.fuelgauge.batterytip.BatteryManagerPreferenceController" />
 
-        <Preference
-            android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"
-            android:key="smart_battery_manager"
-            android:title="@string/smart_battery_manager_title"
-            settings:controller="com.android.settings.fuelgauge.batterytip.BatteryManagerPreferenceController" />
-    </PreferenceCategory>
+    <SwitchPreference
+        android:key="battery_percentage"
+        android:title="@string/battery_percentage"
+        android:summary="@string/battery_percentage_description"
+        app:iconSpaceReserved="false"
+        settings:controller="com.android.settings.display.BatteryPercentagePreferenceController" />
 
     <com.android.settingslib.widget.FooterPreference
         android:key="power_usage_footer"
         android:title="@string/battery_footer_summary"
         android:selectable="false"
-        settings:searchable="false"
-        settings:allowDividerAbove="true" />
+        settings:searchable="false" />
 </PreferenceScreen>
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index f79da61..bd6a954 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -116,4 +116,11 @@
         settings:controller="com.android.settings.privacy.EnableContentCaptureWithServiceSettingsPreferenceController">
     </com.android.settings.widget.PrimarySwitchPreference>
 
+    <!-- Clipboard access notifications -->
+    <SwitchPreference
+        android:key="show_clip_access_notification"
+        android:title="@string/show_clip_access_notification"
+        android:summary="@string/show_clip_access_notification_summary"
+        settings:controller="com.android.settings.privacy.ShowClipAccessNotificationPreferenceController"/>
+
 </PreferenceScreen>
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index bc58d7e..b49228e 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -19,11 +19,22 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/storage_settings"
     android:orderingFromXml="false">
-    <com.android.settings.deviceinfo.storage.StorageSummaryDonutPreference
-        android:key="storage_summary"
-        android:order="0"
+    <com.android.settingslib.widget.SettingsSpinnerPreference
+        android:key="storage_spinner"
+        android:order="-2"
         settings:searchable="false"
-        settings:controller="com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController"/>
+        settings:controller="com.android.settings.deviceinfo.storage.StorageSelectionPreferenceController"/>
+    <com.android.settingslib.widget.UsageProgressBarPreference
+        android:key="storage_summary"
+        android:order="-1"
+        settings:searchable="false"
+        settings:controller="com.android.settings.deviceinfo.storage.StorageUsageProgressBarPreferenceController"/>
+    <Preference
+        android:key="free_up_space"
+        android:order="0"
+        android:title="@string/storage_free_up_space_title"
+        android:summary="@string/storage_free_up_space_summary"
+        settings:allowDividerAbove="true"/>
     <com.android.settings.widget.PrimarySwitchPreference
         android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
         android:key="toggle_asm"
@@ -74,4 +85,4 @@
         android:key="pref_secondary_users"
         android:title="@string/storage_other_users"
         android:order="200" />
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>
diff --git a/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java b/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
index 6b31988..5d2a3fa 100644
--- a/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
+++ b/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.accessibility.ItemInfoArrayAdapter.ItemInfo;
+
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
@@ -29,15 +31,20 @@
 import android.text.style.ImageSpan;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.ListView;
 import android.widget.ScrollView;
 import android.widget.TextView;
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
 import androidx.core.content.ContextCompat;
 
@@ -47,6 +54,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
 
 /**
  * Utility class for creating the edit dialog.
@@ -61,15 +70,13 @@
     @IntDef({
          DialogType.EDIT_SHORTCUT_GENERIC,
          DialogType.EDIT_SHORTCUT_MAGNIFICATION,
-         DialogType.EDIT_MAGNIFICATION_MODE,
          DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT,
     })
 
     private @interface DialogType {
         int EDIT_SHORTCUT_GENERIC = 0;
         int EDIT_SHORTCUT_MAGNIFICATION = 1;
-        int EDIT_MAGNIFICATION_MODE = 2;
-        int EDIT_MAGNIFICATION_SWITCH_SHORTCUT = 3;
+        int EDIT_MAGNIFICATION_SWITCH_SHORTCUT = 2;
     }
 
     /**
@@ -107,23 +114,6 @@
     }
 
     /**
-     * Method to show the magnification mode dialog in Magnification.
-     *
-     * @param context A valid context
-     * @param dialogTitle The title of magnify mode dialog
-     * @param listener The listener to determine the action of magnify mode dialog
-     * @return A magnification mode dialog in Magnification
-     */
-    public static AlertDialog showMagnificationModeDialog(Context context,
-            CharSequence dialogTitle, DialogInterface.OnClickListener listener) {
-        final AlertDialog alertDialog = createDialog(context,
-                DialogType.EDIT_MAGNIFICATION_MODE, dialogTitle, listener);
-        alertDialog.show();
-        setScrollIndicators(alertDialog);
-        return alertDialog;
-    }
-
-    /**
      * Method to show the magnification edit shortcut dialog in Magnification.
      *
      * @param context A valid context
@@ -163,11 +153,21 @@
      */
     private static void setScrollIndicators(AlertDialog dialog) {
         final ScrollView scrollView = dialog.findViewById(R.id.container_layout);
-        scrollView.setScrollIndicators(
+        setScrollIndicators(scrollView);
+    }
+
+    /**
+     * Sets the scroll indicators for dialog view. The indicators appear while content view is
+     * out of vision for vertical scrolling.
+     *
+     * @param view The view contains customized dialog content. Usually it is {@link ScrollView} or
+     *             {@link AbsListView}
+     */
+    private static void setScrollIndicators(@NonNull View view) {
+        view.setScrollIndicators(
                 View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM,
                 View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
     }
-
     private static void setEditShortcutButtonsListener(AlertDialog dialog,
             View.OnClickListener listener) {
         final View contentView = dialog.findViewById(R.id.container_layout);
@@ -212,12 +212,6 @@
                 initMagnifyShortcut(context, contentView);
                 initAdvancedWidget(contentView);
                 break;
-            case DialogType.EDIT_MAGNIFICATION_MODE:
-                contentView = inflater.inflate(
-                        R.layout.accessibility_edit_magnification_mode, null);
-                initMagnifyFullScreen(context, contentView);
-                initMagnifyWindowScreen(context, contentView);
-                break;
             case DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT:
                 contentView = inflater.inflate(
                         R.layout.accessibility_edit_magnification_shortcut, null);
@@ -229,25 +223,6 @@
         return contentView;
     }
 
-    private static void initMagnifyFullScreen(Context context, View view) {
-        final View dialogView = view.findViewById(R.id.magnify_full_screen);
-        final CharSequence title = context.getText(
-                R.string.accessibility_magnification_area_settings_full_screen);
-        setupShortcutWidget(dialogView, title, R.drawable.accessibility_magnification_full_screen);
-    }
-
-    private static void initMagnifyWindowScreen(Context context, View view) {
-        final View dialogView = view.findViewById(R.id.magnify_window_screen);
-        final CharSequence title = context.getText(
-                R.string.accessibility_magnification_area_settings_window_screen);
-        setupShortcutWidget(dialogView, title,
-                R.drawable.accessibility_magnification_window_screen);
-    }
-
-    private static void setupShortcutWidget(View view, CharSequence titleText, int imageResId) {
-        setupShortcutWidget(view, titleText, null, imageResId);
-    }
-
     private static void setupShortcutWidget(View view, CharSequence titleText,
             CharSequence summaryText, int imageResId) {
         final CheckBox checkBox = view.findViewById(R.id.checkbox);
@@ -345,7 +320,6 @@
         spannableMessage.setSpan(
                 imageSpan, indexIconStart, indexIconEnd,
                 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-
         return spannableMessage;
     }
 
@@ -368,4 +342,52 @@
         typedArray.recycle();
         return colorResId;
     }
+
+    /**
+     * Creates a dialog with the given view.
+     *
+     * @param context A valid context
+     * @param dialogTitle The title of the dialog
+     * @param customView The customized view
+     * @param listener This listener will be invoked when the positive button in the dialog is
+     *                 clicked
+     * @return the {@link Dialog} with the given view
+     */
+    public static Dialog createCustomDialog(Context context, CharSequence dialogTitle,
+            View customView, DialogInterface.OnClickListener listener) {
+        final AlertDialog alertDialog = new AlertDialog.Builder(context)
+                .setView(customView)
+                .setTitle(dialogTitle)
+                .setCancelable(true)
+                .setPositiveButton(R.string.save, listener)
+                .setNegativeButton(R.string.cancel, null)
+                .create();
+        if (customView instanceof ScrollView || customView instanceof AbsListView) {
+            setScrollIndicators(customView);
+        }
+        return alertDialog;
+    }
+
+    /**
+     * Creates a single choice {@link ListView} with given {@link ItemInfo} list.
+     *
+     * @param context A context.
+     * @param itemInfoList A {@link ItemInfo} list.
+     * @param itemListener The listener will be invoked when the item is clicked.
+     */
+    @NonNull
+    public static ListView createSingleChoiceListView(@NonNull Context context,
+            @NonNull List<? extends ItemInfo> itemInfoList,
+            @Nullable AdapterView.OnItemClickListener itemListener) {
+        final ListView list = new ListView(context);
+        // Set an id to save its state.
+        list.setId(android.R.id.list);
+        list.setDivider(/* divider= */ null);
+        list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        final ItemInfoArrayAdapter
+                adapter = new ItemInfoArrayAdapter(context, itemInfoList);
+        list.setAdapter(adapter);
+        list.setOnItemClickListener(itemListener);
+        return list;
+    }
 }
diff --git a/src/com/android/settings/accessibility/ItemInfoArrayAdapter.java b/src/com/android/settings/accessibility/ItemInfoArrayAdapter.java
new file mode 100644
index 0000000..edb16a2
--- /dev/null
+++ b/src/com/android/settings/accessibility/ItemInfoArrayAdapter.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.settings.R;
+
+import java.util.List;
+
+/**
+ * An {@link ArrayAdapter} to fill the information of {@link ItemInfo} in the item view. The item
+ * view must have textview to set the title.
+ *
+ * @param <T> the type of elements in the array, inherited from {@link ItemInfo}.
+ */
+public class ItemInfoArrayAdapter<T extends ItemInfoArrayAdapter.ItemInfo> extends ArrayAdapter<T> {
+
+    public ItemInfoArrayAdapter(@NonNull Context context, @NonNull List<T> items) {
+        super(context, R.layout.dialog_single_radio_choice_list_item, R.id.title, items);
+    }
+
+    @NonNull
+    @Override
+    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+        final View root = super.getView(position, convertView, parent);
+
+        final ItemInfo item = getItem(position);
+        final TextView title = root.findViewById(R.id.title);
+        title.setText(item.mTitle);
+        final TextView summary = root.findViewById(R.id.summary);
+        if (!TextUtils.isEmpty(item.mSummary)) {
+            summary.setVisibility(View.VISIBLE);
+            summary.setText(item.mSummary);
+        } else {
+            summary.setVisibility(View.GONE);
+        }
+        final ImageView image = root.findViewById(R.id.image);
+        image.setImageResource(item.mDrawableId);
+        return root;
+    }
+
+    /**
+     * Presents a data structure shown in the item view.
+     */
+    public static class ItemInfo {
+        @NonNull
+        public final CharSequence mTitle;
+        @Nullable
+        public final CharSequence mSummary;
+        @DrawableRes
+        public final int mDrawableId;
+
+        public ItemInfo(@NonNull CharSequence title, @Nullable CharSequence summary,
+                @DrawableRes int drawableId) {
+            mTitle = title;
+            mSummary = summary;
+            mDrawableId = drawableId;
+        }
+    }
+}
diff --git a/src/com/android/settings/accessibility/MagnificationSettingsFragment.java b/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
index 6003a6d..c4d6fd5 100644
--- a/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
+++ b/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
@@ -26,20 +26,26 @@
 import android.os.Bundle;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
+import android.widget.AdapterView;
+import android.widget.ListView;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 
 import com.android.settings.R;
+import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.StringJoiner;
 
 /** Settings page for magnification. */
@@ -52,6 +58,7 @@
     static final int DIALOG_MAGNIFICATION_CAPABILITY = 1;
     @VisibleForTesting
     static final int DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = 2;
+
     @VisibleForTesting
     static final String EXTRA_CAPABILITY = "capability";
     private static final int NONE = 0;
@@ -60,13 +67,13 @@
     private Preference mModePreference;
     @VisibleForTesting
     Dialog mDialog;
-    @VisibleForTesting
-    CheckBox mMagnifyFullScreenCheckBox;
-    @VisibleForTesting
-    CheckBox mMagnifyWindowCheckBox;
 
+    @VisibleForTesting
+    ListView mMagnificationModesListView;
     private int mCapabilities = NONE;
 
+    private final List<MagnificationModeInfo> mModeInfos = new ArrayList<>();
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -77,6 +84,7 @@
         if (mCapabilities == NONE) {
             mCapabilities = MagnificationCapabilities.getCapabilities(getPrefContext());
         }
+        initModeInfos();
     }
 
     @Override
@@ -121,13 +129,10 @@
     @Override
     public Dialog onCreateDialog(int dialogId) {
         final CharSequence title;
+
         switch (dialogId) {
             case DIALOG_MAGNIFICATION_CAPABILITY:
-                title = getPrefContext().getString(
-                        R.string.accessibility_magnification_mode_title);
-                mDialog = AccessibilityEditDialogUtils.showMagnificationModeDialog(getPrefContext(),
-                        title, this::callOnAlertDialogCheckboxClicked);
-                initializeDialogCheckBox(mDialog);
+                mDialog = createMagnificationModeDialog();
                 return mDialog;
             case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
                 title = getPrefContext().getString(
@@ -136,10 +141,97 @@
                         getPrefContext(), title, this::onSwitchShortcutDialogPositiveButtonClicked);
                 return mDialog;
         }
-
         throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
     }
 
+    private Dialog createMagnificationModeDialog() {
+        mMagnificationModesListView = AccessibilityEditDialogUtils.createSingleChoiceListView(
+                getPrefContext(), mModeInfos, this::onMagnificationModeSelected);
+
+        final View headerView = LayoutInflater.from(getPrefContext()).inflate(
+                R.layout.accessibility_magnification_mode_header, mMagnificationModesListView,
+                false);
+        mMagnificationModesListView.addHeaderView(headerView, null, /* isSelectable= */false);
+
+        mMagnificationModesListView.setItemChecked(computeSelectedMagnificationModeIndex(), true);
+        final CharSequence title = getPrefContext().getString(
+                R.string.accessibility_magnification_mode_dialog_title);
+
+        return AccessibilityEditDialogUtils.createCustomDialog(getPrefContext(), title,
+                mMagnificationModesListView, this::onMagnificationModeDialogPositiveButtonClicked);
+    }
+
+    private int computeSelectedMagnificationModeIndex() {
+        final int size = mModeInfos.size();
+        for (int i = 0; i < size; i++) {
+            if (mModeInfos.get(i).mMagnificationMode == mCapabilities) {
+                return i + mMagnificationModesListView.getHeaderViewsCount();
+            }
+        }
+        Log.w(TAG, "chosen mode" + mCapabilities + "is not in the list");
+        return 0;
+    }
+
+    private void onMagnificationModeSelected(AdapterView<?> parent, View view, int position,
+            long id) {
+        final MagnificationModeInfo modeInfo =
+                (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(position);
+        if (modeInfo.mMagnificationMode == mCapabilities) {
+            return;
+        }
+        mCapabilities = modeInfo.mMagnificationMode;
+        if (isTripleTapEnabled() && mCapabilities != MagnificationMode.FULLSCREEN) {
+            showDialog(DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+        }
+    }
+
+    private void onMagnificationModeDialogPositiveButtonClicked(DialogInterface dialogInterface,
+            int which) {
+        final int selectedIndex = mMagnificationModesListView.getCheckedItemPosition();
+        if (selectedIndex != AdapterView.INVALID_POSITION) {
+            final MagnificationModeInfo modeInfo =
+                    (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
+                            selectedIndex);
+            updateCapabilities(modeInfo.mMagnificationMode);
+        } else {
+            Log.w(TAG, "no checked item in the list");
+        }
+    }
+
+    private void updateCapabilities(int mode) {
+        mCapabilities = mode;
+        MagnificationCapabilities.setCapabilities(getPrefContext(), mCapabilities);
+        mModePreference.setSummary(
+                MagnificationCapabilities.getSummary(getPrefContext(), mCapabilities));
+    }
+
+    private void initModeInfos() {
+        mModeInfos.clear();
+        mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
+                R.string.accessibility_magnification_mode_dialog_option_full_screen), null,
+                R.drawable.accessibility_magnification_full_screen, MagnificationMode.FULLSCREEN));
+        mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
+                R.string.accessibility_magnification_mode_dialog_option_window), null,
+                R.drawable.accessibility_magnification_window_screen, MagnificationMode.WINDOW));
+        mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
+                R.string.accessibility_magnification_mode_dialog_option_switch),
+                getPrefContext().getText(
+                        R.string.accessibility_magnification_area_settings_mode_switch_summary),
+                R.drawable.accessibility_magnification_switch, MagnificationMode.ALL));
+    }
+
+    @VisibleForTesting
+    static class MagnificationModeInfo extends ItemInfoArrayAdapter.ItemInfo {
+        @MagnificationMode
+        public final int mMagnificationMode;
+
+        MagnificationModeInfo(@NonNull CharSequence title, @Nullable CharSequence summary,
+                @DrawableRes int drawableId, @MagnificationMode int magnificationMode) {
+            super(title, summary, drawableId);
+            mMagnificationMode = magnificationMode;
+        }
+    }
+
     private void initModePreference() {
         mModePreference = findPreference(PREF_KEY_MODE);
         mModePreference.setOnPreferenceClickListener(preference -> {
@@ -149,12 +241,6 @@
         });
     }
 
-    private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
-        updateCapabilities(true);
-        mModePreference.setSummary(
-                MagnificationCapabilities.getSummary(getPrefContext(), mCapabilities));
-    }
-
     private void onSwitchShortcutDialogPositiveButtonClicked(View view) {
         //TODO(b/147990389): Merge this function into util until magnification change format to
         // Component.
@@ -188,95 +274,6 @@
                 joiner.toString());
     }
 
-    private void initializeDialogCheckBox(Dialog dialog) {
-        final View dialogFullScreenView = dialog.findViewById(R.id.magnify_full_screen);
-        final View dialogFullScreenTextArea = dialogFullScreenView.findViewById(R.id.container);
-        mMagnifyFullScreenCheckBox = dialogFullScreenView.findViewById(R.id.checkbox);
-
-        final View dialogWidowView = dialog.findViewById(R.id.magnify_window_screen);
-        final View dialogWindowTextArea = dialogWidowView.findViewById(R.id.container);
-        mMagnifyWindowCheckBox = dialogWidowView.findViewById(R.id.checkbox);
-
-        updateAlertDialogCheckState();
-        updateAlertDialogEnableState(dialogFullScreenTextArea, dialogWindowTextArea);
-
-        setTextAreasClickListener(dialogFullScreenTextArea, mMagnifyFullScreenCheckBox,
-                dialogWindowTextArea, mMagnifyWindowCheckBox);
-    }
-
-    private void setTextAreasClickListener(View fullScreenTextArea, CheckBox fullScreenCheckBox,
-            View windowTextArea, CheckBox windowCheckBox) {
-        fullScreenTextArea.setOnClickListener(v -> {
-            fullScreenCheckBox.toggle();
-            updateCapabilities(false);
-            updateAlertDialogEnableState(fullScreenTextArea, windowTextArea);
-        });
-
-        windowTextArea.setOnClickListener(v -> {
-            windowCheckBox.toggle();
-            updateCapabilities(false);
-            updateAlertDialogEnableState(fullScreenTextArea, windowTextArea);
-
-            if (isTripleTapEnabled() && windowCheckBox.isChecked()) {
-                showDialog(DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
-            }
-        });
-    }
-
-    private void updateAlertDialogCheckState() {
-        updateCheckStatus(mMagnifyWindowCheckBox,
-                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-        updateCheckStatus(mMagnifyFullScreenCheckBox,
-                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-
-    }
-
-    private void updateCheckStatus(CheckBox checkBox, int mode) {
-        checkBox.setChecked((mode & mCapabilities) != 0);
-    }
-
-    private void updateAlertDialogEnableState(View fullScreenTextArea, View windowTextArea) {
-        switch (mCapabilities) {
-            case Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN:
-                setViewAndChildrenEnabled(fullScreenTextArea, false);
-                break;
-            case Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
-                setViewAndChildrenEnabled(windowTextArea, false);
-                break;
-            case Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL:
-                setViewAndChildrenEnabled(fullScreenTextArea, true);
-                setViewAndChildrenEnabled(windowTextArea, true);
-                break;
-            default:
-                throw new IllegalArgumentException(
-                        "Unsupported ACCESSIBILITY_MAGNIFICATION_CAPABILITY " + mCapabilities);
-        }
-    }
-
-    private void setViewAndChildrenEnabled(View view, boolean enabled) {
-        view.setEnabled(enabled);
-        if (view instanceof ViewGroup) {
-            final ViewGroup viewGroup = (ViewGroup) view;
-            for (int i = 0; i < viewGroup.getChildCount(); i++) {
-                View child = viewGroup.getChildAt(i);
-                setViewAndChildrenEnabled(child, enabled);
-            }
-        }
-    }
-
-    private void updateCapabilities(boolean saveToDB) {
-        int capabilities = 0;
-        capabilities |=
-                mMagnifyFullScreenCheckBox.isChecked()
-                        ? Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN : 0;
-        capabilities |= mMagnifyWindowCheckBox.isChecked()
-                ? Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW : 0;
-        mCapabilities = capabilities;
-        if (saveToDB) {
-            MagnificationCapabilities.setCapabilities(getPrefContext(), mCapabilities);
-        }
-    }
-
     private boolean isTripleTapEnabled() {
         return Settings.Secure.getInt(getPrefContext().getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON;
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuController.java b/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuController.java
deleted file mode 100644
index 00a79a0..0000000
--- a/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuController.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.deviceinfo;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.storage.VolumeInfo;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-
-import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
-import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
-import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
-
-import java.util.Objects;
-
-/**
- * Handles the option menu on the Storage settings.
- */
-public class PrivateVolumeOptionMenuController implements LifecycleObserver, OnCreateOptionsMenu,
-        OnPrepareOptionsMenu, OnOptionsItemSelected {
-    private static final int OPTIONS_MENU_MIGRATE_DATA = 100;
-
-    private Context mContext;
-    private VolumeInfo mVolumeInfo;
-    private PackageManager mPm;
-
-    public PrivateVolumeOptionMenuController(
-            Context context, VolumeInfo volumeInfo, PackageManager packageManager) {
-        mContext = context;
-        mVolumeInfo = volumeInfo;
-        mPm = packageManager;
-    }
-
-    @Override
-    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
-        menu.add(Menu.NONE, OPTIONS_MENU_MIGRATE_DATA, 0, R.string.storage_menu_migrate);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        if (mVolumeInfo == null) {
-            return;
-        }
-
-        // Only offer to migrate when not current storage
-        final VolumeInfo privateVol = mPm.getPrimaryStorageCurrentVolume();
-        final MenuItem migrate = menu.findItem(OPTIONS_MENU_MIGRATE_DATA);
-        if (migrate != null) {
-            migrate.setVisible((privateVol != null)
-                    && (privateVol.getType() == VolumeInfo.TYPE_PRIVATE)
-                    && !Objects.equals(mVolumeInfo, privateVol)
-                    && privateVol.isMountedWritable());
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem menuItem) {
-        if (menuItem.getItemId() == OPTIONS_MENU_MIGRATE_DATA) {
-            final Intent intent = new Intent(mContext, StorageWizardMigrateConfirm.class);
-            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, mVolumeInfo.getId());
-            mContext.startActivity(intent);
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 10c3a43..7af4f0c 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -20,13 +20,18 @@
 import android.app.settings.SettingsEnums;
 import android.app.usage.StorageStatsManager;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.storage.DiskInfo;
+import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
 import android.provider.SearchIndexableResource;
+import android.text.TextUtils;
 import android.util.SparseArray;
 import android.view.View;
 
@@ -41,15 +46,22 @@
 import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
 import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
+import com.android.settings.deviceinfo.storage.DiskInitFragment;
 import com.android.settings.deviceinfo.storage.SecondaryUserController;
 import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
+import com.android.settings.deviceinfo.storage.StorageEntry;
 import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
+import com.android.settings.deviceinfo.storage.StorageSelectionPreferenceController;
+import com.android.settings.deviceinfo.storage.StorageUsageProgressBarPreferenceController;
+import com.android.settings.deviceinfo.storage.StorageUtils;
 import com.android.settings.deviceinfo.storage.UserIconLoader;
 import com.android.settings.deviceinfo.storage.VolumeSizesLoader;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.applications.StorageStatsSource;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.deviceinfo.PrivateStorageInfo;
 import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
 import com.android.settingslib.search.SearchIndexable;
@@ -57,48 +69,227 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @SearchIndexable
 public class StorageDashboardFragment extends DashboardFragment
         implements
-        LoaderManager.LoaderCallbacks<SparseArray<StorageAsyncLoader.AppsStorageResult>> {
+        LoaderManager.LoaderCallbacks<SparseArray<StorageAsyncLoader.AppsStorageResult>>,
+        Preference.OnPreferenceClickListener {
     private static final String TAG = "StorageDashboardFrag";
     private static final String SUMMARY_PREF_KEY = "storage_summary";
+    private static final String FREE_UP_SPACE_PREF_KEY = "free_up_space";
+    private static final String SELECTED_STORAGE_ENTRY_KEY = "selected_storage_entry_key";
     private static final int STORAGE_JOB_ID = 0;
     private static final int ICON_JOB_ID = 1;
     private static final int VOLUME_SIZE_JOB_ID = 2;
 
-    private VolumeInfo mVolume;
+    private StorageManager mStorageManager;
+    private final List<StorageEntry> mStorageEntries = new ArrayList<>();
+    private StorageEntry mSelectedStorageEntry;
     private PrivateStorageInfo mStorageInfo;
     private SparseArray<StorageAsyncLoader.AppsStorageResult> mAppsResult;
     private CachedStorageValuesHelper mCachedStorageValuesHelper;
 
     private StorageItemPreferenceController mPreferenceController;
-    private PrivateVolumeOptionMenuController mOptionMenuController;
+    private VolumeOptionMenuController mOptionMenuController;
+    private StorageSelectionPreferenceController mStorageSelectionController;
+    private StorageUsageProgressBarPreferenceController mStorageUsageProgressBarController;
     private List<AbstractPreferenceController> mSecondaryUsers;
     private boolean mPersonalOnly;
+    private Preference mFreeUpSpacePreference;
+
+    private final StorageEventListener mStorageEventListener = new StorageEventListener() {
+        @Override
+        public void onVolumeStateChanged(VolumeInfo volumeInfo, int oldState, int newState) {
+            if (!isInteresting(volumeInfo)) {
+                return;
+            }
+
+            final StorageEntry changedStorageEntry = new StorageEntry(getContext(), volumeInfo);
+            switch (volumeInfo.getState()) {
+                case VolumeInfo.STATE_MOUNTED:
+                case VolumeInfo.STATE_MOUNTED_READ_ONLY:
+                case VolumeInfo.STATE_UNMOUNTABLE:
+                    // Add mounted or unmountable storage in the list and show it on spinner.
+                    // Unmountable storages are the storages which has a problem format and android
+                    // is not able to mount it automatically.
+                    // Users can format an unmountable storage by the UI and then use the storage.
+                    mStorageEntries.removeIf(storageEntry -> {
+                        return storageEntry.equals(changedStorageEntry);
+                    });
+                    mStorageEntries.add(changedStorageEntry);
+                    if (changedStorageEntry.equals(mSelectedStorageEntry)) {
+                        mSelectedStorageEntry = changedStorageEntry;
+                    }
+                    refreshUi();
+                    break;
+                case VolumeInfo.STATE_REMOVED:
+                case VolumeInfo.STATE_UNMOUNTED:
+                case VolumeInfo.STATE_BAD_REMOVAL:
+                case VolumeInfo.STATE_EJECTING:
+                    // Remove removed storage from list and don't show it on spinner.
+                    if (mStorageEntries.remove(changedStorageEntry)) {
+                        if (changedStorageEntry.equals(mSelectedStorageEntry)) {
+                            mSelectedStorageEntry =
+                                    StorageEntry.getDefaultInternalStorageEntry(getContext());
+                        }
+                        refreshUi();
+                    }
+                    break;
+                default:
+                    // Do nothing.
+            }
+        }
+
+        @Override
+        public void onVolumeRecordChanged(VolumeRecord volumeRecord) {
+            if (isVolumeRecordMissed(volumeRecord)) {
+                // VolumeRecord is a metadata of VolumeInfo, if a VolumeInfo is missing
+                // (e.g., internal SD card is removed.) show the missing storage to users,
+                // users can insert the SD card or manually forget the storage from the device.
+                final StorageEntry storageEntry = new StorageEntry(volumeRecord);
+                if (!mStorageEntries.contains(storageEntry)) {
+                    mStorageEntries.add(storageEntry);
+                    refreshUi();
+                }
+            } else {
+                // Find mapped VolumeInfo and replace with existing one for something changed.
+                // (e.g., Renamed.)
+                final VolumeInfo mappedVolumeInfo =
+                            mStorageManager.findVolumeByUuid(volumeRecord.getFsUuid());
+                if (mappedVolumeInfo == null) {
+                    return;
+                }
+
+                final boolean removeMappedStorageEntry = mStorageEntries.removeIf(storageEntry ->
+                        storageEntry.isVolumeInfo()
+                            && TextUtils.equals(storageEntry.getFsUuid(), volumeRecord.getFsUuid())
+                );
+                if (removeMappedStorageEntry) {
+                    mStorageEntries.add(new StorageEntry(getContext(), mappedVolumeInfo));
+                    refreshUi();
+                }
+            }
+        }
+
+        @Override
+        public void onVolumeForgotten(String fsUuid) {
+            final StorageEntry storageEntry = new StorageEntry(
+                    new VolumeRecord(VolumeInfo.TYPE_PUBLIC, fsUuid));
+            if (mStorageEntries.remove(storageEntry)) {
+                if (mSelectedStorageEntry.equals(storageEntry)) {
+                    mSelectedStorageEntry =
+                            StorageEntry.getDefaultInternalStorageEntry(getContext());
+                }
+                refreshUi();
+            }
+        }
+
+        @Override
+        public void onDiskScanned(DiskInfo disk, int volumeCount) {
+            if (!isDiskUnsupported(disk)) {
+                return;
+            }
+            final StorageEntry storageEntry = new StorageEntry(disk);
+            if (!mStorageEntries.contains(storageEntry)) {
+                mStorageEntries.add(storageEntry);
+                refreshUi();
+            }
+        }
+
+        @Override
+        public void onDiskDestroyed(DiskInfo disk) {
+            final StorageEntry storageEntry = new StorageEntry(disk);
+            if (mStorageEntries.remove(storageEntry)) {
+                if (mSelectedStorageEntry.equals(storageEntry)) {
+                    mSelectedStorageEntry =
+                            StorageEntry.getDefaultInternalStorageEntry(getContext());
+                }
+                refreshUi();
+            }
+        }
+    };
+
+    private static boolean isInteresting(VolumeInfo volumeInfo) {
+        switch (volumeInfo.getType()) {
+            case VolumeInfo.TYPE_PRIVATE:
+            case VolumeInfo.TYPE_PUBLIC:
+            case VolumeInfo.TYPE_STUB:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * VolumeRecord is a metadata of VolumeInfo, this is the case where a VolumeInfo is missing.
+     * (e.g., internal SD card is removed.)
+     */
+    private boolean isVolumeRecordMissed(VolumeRecord volumeRecord) {
+        return volumeRecord.getType() == VolumeInfo.TYPE_PRIVATE
+                && mStorageManager.findVolumeByUuid(volumeRecord.getFsUuid()) == null;
+    }
+
+    /**
+     * A unsupported disk is the disk of problem format, android is not able to mount automatically.
+     */
+    private static boolean isDiskUnsupported(DiskInfo disk) {
+        return disk.volumeCount == 0 && disk.size > 0;
+    }
+
+    private void refreshUi() {
+        mStorageSelectionController.setStorageEntries(mStorageEntries);
+        mStorageSelectionController.setSelectedStorageEntry(mSelectedStorageEntry);
+        mStorageUsageProgressBarController.setSelectedStorageEntry(mSelectedStorageEntry);
+
+        mOptionMenuController.setSelectedStorageEntry(mSelectedStorageEntry);
+        getActivity().invalidateOptionsMenu();
+
+        mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
+
+        if (mSelectedStorageEntry.isMounted()) {
+            getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
+            getLoaderManager()
+                 .restartLoader(VOLUME_SIZE_JOB_ID, Bundle.EMPTY, new VolumeSizeCallbacks());
+            getLoaderManager().restartLoader(ICON_JOB_ID, Bundle.EMPTY, new IconLoaderCallbacks());
+        } else {
+            mPreferenceController.clearStorageSizeDisplay();
+        }
+    }
 
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        // Initialize the storage sizes that we can quickly calc.
         final Activity activity = getActivity();
-        StorageManager sm = activity.getSystemService(StorageManager.class);
-        mVolume = Utils.maybeInitializeVolume(sm, getArguments());
+        mStorageManager = activity.getSystemService(StorageManager.class);
         mPersonalOnly = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE)
                 == ProfileSelectFragment.ProfileType.PERSONAL;
-        if (mVolume == null) {
-            activity.finish();
-            return;
+
+        if (icicle == null) {
+            final VolumeInfo specifiedVolumeInfo =
+                    Utils.maybeInitializeVolume(mStorageManager, getArguments());
+            mSelectedStorageEntry = specifiedVolumeInfo == null
+                    ? StorageEntry.getDefaultInternalStorageEntry(getContext())
+                    : new StorageEntry(getContext(), specifiedVolumeInfo);
+        } else {
+            mSelectedStorageEntry = icicle.getParcelable(SELECTED_STORAGE_ENTRY_KEY);
         }
+
+        initializePreference();
         initializeOptionsMenu(activity);
+    }
+
+    private void initializePreference() {
         if (mPersonalOnly) {
             final Preference summary = getPreferenceScreen().findPreference(SUMMARY_PREF_KEY);
             if (summary != null) {
                 summary.setVisible(false);
             }
         }
+        mFreeUpSpacePreference = getPreferenceScreen().findPreference(FREE_UP_SPACE_PREF_KEY);
+        mFreeUpSpacePreference.setOnPreferenceClickListener(this);
     }
 
     @Override
@@ -106,12 +297,25 @@
         super.onAttach(context);
         use(AutomaticStorageManagementSwitchPreferenceController.class).setFragmentManager(
                 getFragmentManager());
+        mStorageSelectionController = use(StorageSelectionPreferenceController.class);
+        mStorageSelectionController.setOnItemSelectedListener(storageEntry -> {
+            mSelectedStorageEntry = storageEntry;
+            refreshUi();
+
+            if (storageEntry.isDiskInfoUnsupported() || storageEntry.isUnmountable()) {
+                DiskInitFragment.show(this, R.string.storage_dialog_unmountable,
+                        storageEntry.getDiskId());
+            } else if (storageEntry.isVolumeRecordMissed()) {
+                StorageUtils.launchForgetMissingVolumeRecordFragment(getContext(), storageEntry);
+            }
+        });
+        mStorageUsageProgressBarController = use(StorageUsageProgressBarPreferenceController.class);
     }
 
     @VisibleForTesting
     void initializeOptionsMenu(Activity activity) {
-        mOptionMenuController = new PrivateVolumeOptionMenuController(
-                activity, mVolume, activity.getPackageManager());
+        mOptionMenuController = new VolumeOptionMenuController(activity, this,
+                mSelectedStorageEntry);
         getSettingsLifecycle().addObserver(mOptionMenuController);
         setHasOptionsMenu(true);
         activity.invalidateOptionsMenu();
@@ -133,10 +337,34 @@
     @Override
     public void onResume() {
         super.onResume();
-        getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
-        getLoaderManager()
-                .restartLoader(VOLUME_SIZE_JOB_ID, Bundle.EMPTY, new VolumeSizeCallbacks());
-        getLoaderManager().restartLoader(ICON_JOB_ID, Bundle.EMPTY, new IconLoaderCallbacks());
+
+        mStorageEntries.clear();
+        mStorageEntries.addAll(mStorageManager.getVolumes().stream()
+                .filter(volumeInfo -> isInteresting(volumeInfo))
+                .map(volumeInfo -> new StorageEntry(getContext(), volumeInfo))
+                .collect(Collectors.toList()));
+        mStorageEntries.addAll(mStorageManager.getDisks().stream()
+                .filter(disk -> isDiskUnsupported(disk))
+                .map(disk -> new StorageEntry(disk))
+                .collect(Collectors.toList()));
+        mStorageEntries.addAll(mStorageManager.getVolumeRecords().stream()
+                .filter(volumeRecord -> isVolumeRecordMissed(volumeRecord))
+                .map(volumeRecord -> new StorageEntry(volumeRecord))
+                .collect(Collectors.toList()));
+        refreshUi();
+        mStorageManager.registerListener(mStorageEventListener);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mStorageManager.unregisterListener(mStorageEventListener);
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        outState.putParcelable(SELECTED_STORAGE_ENTRY_KEY, mSelectedStorageEntry);
+        super.onSaveInstanceState(outState);
     }
 
     @Override
@@ -148,7 +376,7 @@
         boolean stopLoading = false;
         if (mStorageInfo != null) {
             long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
-            mPreferenceController.setVolume(mVolume);
+            mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
             mPreferenceController.setUsedSize(privateUsedBytes);
             mPreferenceController.setTotalSize(mStorageInfo.totalBytes);
             for (int i = 0, size = mSecondaryUsers.size(); i < size; i++) {
@@ -197,7 +425,7 @@
 
         StorageManager sm = context.getSystemService(StorageManager.class);
         mPreferenceController = new StorageItemPreferenceController(context, this,
-                mVolume, new StorageManagerVolumeProvider(sm));
+                null /* volume */, new StorageManagerVolumeProvider(sm));
         controllers.add(mPreferenceController);
 
         final UserManager userManager = context.getSystemService(UserManager.class);
@@ -209,7 +437,7 @@
 
     @VisibleForTesting
     protected void setVolume(VolumeInfo info) {
-        mVolume = info;
+        mSelectedStorageEntry = new StorageEntry(getContext(), info);
     }
 
     /**
@@ -260,7 +488,7 @@
             Bundle args) {
         final Context context = getContext();
         return new StorageAsyncLoader(context, context.getSystemService(UserManager.class),
-                mVolume.fsUuid,
+                mSelectedStorageEntry.getFsUuid(),
                 new StorageStatsSource(context),
                 context.getPackageManager());
     }
@@ -277,6 +505,21 @@
     public void onLoaderReset(Loader<SparseArray<StorageAsyncLoader.AppsStorageResult>> loader) {
     }
 
+    @Override
+    public boolean onPreferenceClick(Preference preference) {
+        if (preference == mFreeUpSpacePreference) {
+            final Context context = getContext();
+            final MetricsFeatureProvider metricsFeatureProvider =
+                    FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+            metricsFeatureProvider.logClickedPreference(preference, getMetricsCategory());
+            metricsFeatureProvider.action(context, SettingsEnums.STORAGE_FREE_UP_SPACE_NOW);
+            final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
+            context.startActivity(intent);
+            return true;
+        }
+        return false;
+    }
+
     @VisibleForTesting
     public void setCachedStorageValuesHelper(CachedStorageValuesHelper helper) {
         mCachedStorageValuesHelper = helper;
@@ -340,8 +583,9 @@
     }
 
     private boolean isQuotaSupported() {
-        final StorageStatsManager stats = getActivity().getSystemService(StorageStatsManager.class);
-        return stats.isQuotaSupported(mVolume.fsUuid);
+        return mSelectedStorageEntry.isMounted()
+                && getActivity().getSystemService(StorageStatsManager.class)
+                        .isQuotaSupported(mSelectedStorageEntry.getFsUuid());
     }
 
     /**
@@ -378,11 +622,12 @@
             implements LoaderManager.LoaderCallbacks<PrivateStorageInfo> {
         @Override
         public Loader<PrivateStorageInfo> onCreateLoader(int id, Bundle args) {
-            Context context = getContext();
-            StorageManager sm = context.getSystemService(StorageManager.class);
-            StorageManagerVolumeProvider smvp = new StorageManagerVolumeProvider(sm);
+            final Context context = getContext();
+            final StorageManagerVolumeProvider smvp =
+                    new StorageManagerVolumeProvider(mStorageManager);
             final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
-            return new VolumeSizesLoader(context, smvp, stats, mVolume);
+            return new VolumeSizesLoader(context, smvp, stats,
+                    mSelectedStorageEntry.getVolumeInfo());
         }
 
         @Override
diff --git a/src/com/android/settings/deviceinfo/VolumeOptionMenuController.java b/src/com/android/settings/deviceinfo/VolumeOptionMenuController.java
new file mode 100644
index 0000000..0932447
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/VolumeOptionMenuController.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo;
+
+import android.app.ActivityManager;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.os.storage.DiskInfo;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.deviceinfo.StorageSettings.MountTask;
+import com.android.settings.deviceinfo.StorageSettings.UnmountTask;
+import com.android.settings.deviceinfo.storage.StorageEntry;
+import com.android.settings.deviceinfo.storage.StorageRenameFragment;
+import com.android.settings.deviceinfo.storage.StorageUtils;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
+import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
+
+import java.util.Objects;
+
+/**
+ * Handles the option menu on the Storage settings.
+ */
+public class VolumeOptionMenuController implements LifecycleObserver, OnCreateOptionsMenu,
+        OnPrepareOptionsMenu, OnOptionsItemSelected {
+
+    @VisibleForTesting
+    MenuItem mRename;
+    @VisibleForTesting
+    MenuItem mMount;
+    @VisibleForTesting
+    MenuItem mUnmount;
+    @VisibleForTesting
+    MenuItem mFormat;
+    @VisibleForTesting
+    MenuItem mFormatAsPortable;
+    @VisibleForTesting
+    MenuItem mFormatAsInternal;
+    @VisibleForTesting
+    MenuItem mMigrate;
+    @VisibleForTesting
+    MenuItem mFree;
+    @VisibleForTesting
+    MenuItem mForget;
+
+    private final Context mContext;
+    private final Fragment mFragment;
+    private final PackageManager mPackageManager;
+    private final StorageManager mStorageManager;
+    private StorageEntry mStorageEntry;
+
+    public VolumeOptionMenuController(Context context, Fragment parent, StorageEntry storageEntry) {
+        mContext = context;
+        mFragment = parent;
+        mPackageManager = context.getPackageManager();
+        mStorageManager = context.getSystemService(StorageManager.class);
+        mStorageEntry = storageEntry;
+    }
+
+    @Override
+    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+        inflater.inflate(R.menu.storage_volume, menu);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        mRename = menu.findItem(R.id.storage_rename);
+        mMount = menu.findItem(R.id.storage_mount);
+        mUnmount = menu.findItem(R.id.storage_unmount);
+        mFormat = menu.findItem(R.id.storage_format);
+        mFormatAsPortable = menu.findItem(R.id.storage_format_as_portable);
+        mFormatAsInternal = menu.findItem(R.id.storage_format_as_internal);
+        mMigrate = menu.findItem(R.id.storage_migrate);
+        mFree = menu.findItem(R.id.storage_free);
+        mForget = menu.findItem(R.id.storage_forget);
+
+        mRename.setVisible(false);
+        mMount.setVisible(false);
+        mUnmount.setVisible(false);
+        mFormat.setVisible(false);
+        mFormatAsPortable.setVisible(false);
+        mFormatAsInternal.setVisible(false);
+        mMigrate.setVisible(false);
+        mFree.setVisible(false);
+        mForget.setVisible(false);
+
+        if (mStorageEntry.isDiskInfoUnsupported()) {
+            mFormat.setVisible(true);
+            return;
+        }
+        if (mStorageEntry.isVolumeRecordMissed()) {
+            mForget.setVisible(true);
+            return;
+        }
+        if (mStorageEntry.isUnmounted()) {
+            mMount.setVisible(true);
+            return;
+        }
+        if (!mStorageEntry.isMounted()) {
+            return;
+        }
+
+        if (mStorageEntry.isPrivate()) {
+            if (!mStorageEntry.isDefaultInternalStorage()) {
+                mRename.setVisible(true);
+                mUnmount.setVisible(true);
+                mFormatAsPortable.setVisible(true);
+            }
+
+            // Only offer to migrate when not current storage.
+            final VolumeInfo primaryVolumeInfo = mPackageManager.getPrimaryStorageCurrentVolume();
+            final VolumeInfo selectedVolumeInfo = mStorageEntry.getVolumeInfo();
+            mMigrate.setVisible(primaryVolumeInfo != null
+                    && primaryVolumeInfo.getType() == VolumeInfo.TYPE_PRIVATE
+                    && !Objects.equals(selectedVolumeInfo, primaryVolumeInfo)
+                    && primaryVolumeInfo.isMountedWritable());
+            return;
+        }
+
+        if (mStorageEntry.isPublic()) {
+            mRename.setVisible(true);
+            mUnmount.setVisible(true);
+            mFormat.setVisible(true);
+            final DiskInfo diskInfo = mStorageManager.findDiskById(mStorageEntry.getDiskId());
+            mFormatAsInternal.setVisible(diskInfo != null
+                    && diskInfo.isAdoptable()
+                    && UserManager.get(mContext).isAdminUser()
+                    && !ActivityManager.isUserAMonkey());
+            return;
+        }
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem menuItem) {
+        if (!mFragment.isAdded()) {
+            return false;
+        }
+
+        final int menuId = menuItem.getItemId();
+        if (menuId == R.id.storage_mount) {
+            if (mStorageEntry.isUnmounted()) {
+                new MountTask(mFragment.getActivity(), mStorageEntry.getVolumeInfo()).execute();
+                return true;
+            }
+            return false;
+        }
+        if (menuId == R.id.storage_unmount) {
+            if (mStorageEntry.isMounted()) {
+                if (mStorageEntry.isPublic()) {
+                    new UnmountTask(mFragment.getActivity(),
+                            mStorageEntry.getVolumeInfo()).execute();
+                    return true;
+                }
+                if (mStorageEntry.isPrivate() && !mStorageEntry.isDefaultInternalStorage()) {
+                    final Bundle args = new Bundle();
+                    args.putString(VolumeInfo.EXTRA_VOLUME_ID, mStorageEntry.getId());
+                    new SubSettingLauncher(mContext)
+                            .setDestination(PrivateVolumeUnmount.class.getCanonicalName())
+                            .setTitleRes(R.string.storage_menu_unmount)
+                            .setSourceMetricsCategory(SettingsEnums.DEVICEINFO_STORAGE)
+                            .setArguments(args)
+                            .launch();
+                    return true;
+                }
+            }
+            return false;
+        }
+        if (menuId == R.id.storage_rename) {
+            if ((mStorageEntry.isPrivate() && !mStorageEntry.isDefaultInternalStorage())
+                    ||  mStorageEntry.isPublic()) {
+                StorageRenameFragment.show(mFragment, mStorageEntry.getVolumeInfo());
+                return true;
+            }
+            return false;
+        }
+        if (menuId == R.id.storage_format) {
+            if (mStorageEntry.isDiskInfoUnsupported() || mStorageEntry.isPublic()) {
+                StorageWizardFormatConfirm.showPublic(mFragment.getActivity(),
+                        mStorageEntry.getDiskId());
+                return true;
+            }
+            return false;
+        }
+        if (menuId == R.id.storage_format_as_portable) {
+            if (mStorageEntry.isPrivate()) {
+                final Bundle args = new Bundle();
+                args.putString(VolumeInfo.EXTRA_VOLUME_ID, mStorageEntry.getId());
+                new SubSettingLauncher(mContext)
+                        .setDestination(PrivateVolumeFormat.class.getCanonicalName())
+                        .setTitleRes(R.string.storage_menu_format)
+                        .setSourceMetricsCategory(SettingsEnums.DEVICEINFO_STORAGE)
+                        .setArguments(args)
+                        .launch();
+                return true;
+            }
+            return false;
+        }
+        if (menuId == R.id.storage_format_as_internal) {
+            if (mStorageEntry.isPublic()) {
+                StorageWizardFormatConfirm.showPrivate(mFragment.getActivity(),
+                        mStorageEntry.getDiskId());
+                return true;
+            }
+            return false;
+        }
+        if (menuId == R.id.storage_migrate) {
+            if (mStorageEntry.isPrivate()) {
+                final Intent intent = new Intent(mContext, StorageWizardMigrateConfirm.class);
+                intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, mStorageEntry.getId());
+                mContext.startActivity(intent);
+                return true;
+            }
+            return false;
+        }
+        if (menuId == R.id.storage_forget) {
+            if (mStorageEntry.isVolumeRecordMissed()) {
+                StorageUtils.launchForgetMissingVolumeRecordFragment(mContext, mStorageEntry);
+                return true;
+            }
+            return false;
+        }
+        return false;
+    }
+
+    public void setSelectedStorageEntry(StorageEntry storageEntry) {
+        mStorageEntry = storageEntry;
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/storage/DiskInitFragment.java b/src/com/android/settings/deviceinfo/storage/DiskInitFragment.java
new file mode 100644
index 0000000..1e6a98d
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/DiskInitFragment.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.storage.DiskInfo;
+import android.os.storage.StorageManager;
+import android.text.TextUtils;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.deviceinfo.StorageWizardInit;
+
+/** A dialog which guides users to initialize a specified unsupported disk. */
+public class DiskInitFragment extends InstrumentedDialogFragment {
+
+    private static final String TAG_DISK_INIT = "disk_init";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DIALOG_VOLUME_INIT;
+    }
+
+    /** Shows the dialog for the specified diskId from DiskInfo. */
+    public static void show(Fragment parent, int resId, String diskId) {
+        final Bundle args = new Bundle();
+        args.putInt(Intent.EXTRA_TEXT, resId);
+        args.putString(DiskInfo.EXTRA_DISK_ID, diskId);
+
+        final DiskInitFragment dialog = new DiskInitFragment();
+        dialog.setArguments(args);
+        dialog.setTargetFragment(parent, 0);
+        dialog.show(parent.getFragmentManager(), TAG_DISK_INIT);
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final Context context = getActivity();
+        final StorageManager storageManager = context.getSystemService(StorageManager.class);
+        final int resId = getArguments().getInt(Intent.EXTRA_TEXT);
+        final String diskId = getArguments().getString(DiskInfo.EXTRA_DISK_ID);
+        final DiskInfo disk = storageManager.findDiskById(diskId);
+
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        return builder.setMessage(TextUtils.expandTemplate(getText(resId), disk.getDescription()))
+                .setPositiveButton(R.string.storage_menu_set_up, (dialog, which) -> {
+                    final Intent intent = new Intent(context, StorageWizardInit.class);
+                    intent.putExtra(DiskInfo.EXTRA_DISK_ID, diskId);
+                    startActivity(intent); })
+                .setNegativeButton(R.string.cancel, null)
+                .create();
+    }
+}
+
diff --git a/src/com/android/settings/deviceinfo/storage/StorageEntry.java b/src/com/android/settings/deviceinfo/storage/StorageEntry.java
new file mode 100644
index 0000000..f718116
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageEntry.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.storage.DiskInfo;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+import android.text.TextUtils;
+
+import java.io.File;
+
+/**
+ * This object contains a {@link VolumeInfo} for a mountable storage or a {@link DiskInfo} for an
+ * unsupported disk which is not able to be mounted automatically.
+ */
+public class StorageEntry implements Comparable<StorageEntry>, Parcelable {
+
+    private final VolumeInfo mVolumeInfo;
+    private final DiskInfo mUnsupportedDiskInfo;
+    private final VolumeRecord mMissingVolumeRecord;
+
+    private final String mVolumeInfoDescription;
+
+    public StorageEntry(@NonNull Context context, @NonNull VolumeInfo volumeInfo) {
+        mVolumeInfo = volumeInfo;
+        mUnsupportedDiskInfo = null;
+        mMissingVolumeRecord = null;
+        mVolumeInfoDescription = context.getSystemService(StorageManager.class)
+                .getBestVolumeDescription(mVolumeInfo);
+    }
+
+    public StorageEntry(@NonNull DiskInfo diskInfo) {
+        mVolumeInfo = null;
+        mUnsupportedDiskInfo = diskInfo;
+        mMissingVolumeRecord = null;
+        mVolumeInfoDescription = null;
+    }
+
+    public StorageEntry(@NonNull VolumeRecord volumeRecord) {
+        mVolumeInfo = null;
+        mUnsupportedDiskInfo = null;
+        mMissingVolumeRecord = volumeRecord;
+        mVolumeInfoDescription = null;
+    }
+
+    private StorageEntry(Parcel in) {
+        mVolumeInfo = in.readParcelable(VolumeInfo.class.getClassLoader());
+        mUnsupportedDiskInfo = in.readParcelable(DiskInfo.class.getClassLoader());
+        mMissingVolumeRecord = in.readParcelable(VolumeRecord.class.getClassLoader());
+        mVolumeInfoDescription = in.readString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(mVolumeInfo, 0 /* parcelableFlags */);
+        out.writeParcelable(mUnsupportedDiskInfo, 0 /* parcelableFlags */);
+        out.writeParcelable(mMissingVolumeRecord , 0 /* parcelableFlags */);
+        out.writeString(mVolumeInfoDescription);
+    }
+
+    public static final Parcelable.Creator<StorageEntry> CREATOR =
+            new Parcelable.Creator<StorageEntry>() {
+                public StorageEntry createFromParcel(Parcel in) {
+                    return new StorageEntry(in);
+                }
+
+                public StorageEntry[] newArray(int size) {
+                    return new StorageEntry[size];
+                }
+            };
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof StorageEntry)) {
+            return false;
+        }
+
+        final StorageEntry StorageEntry = (StorageEntry) o;
+        if (isVolumeInfo()) {
+            return mVolumeInfo.equals(StorageEntry.mVolumeInfo);
+        }
+        if (isDiskInfoUnsupported()) {
+            return mUnsupportedDiskInfo.equals(StorageEntry.mUnsupportedDiskInfo);
+        }
+        return mMissingVolumeRecord.equals(StorageEntry.mMissingVolumeRecord);
+    }
+
+    @Override
+    public int hashCode() {
+        if (isVolumeInfo()) {
+            return mVolumeInfo.hashCode();
+        }
+        if (isDiskInfoUnsupported()) {
+            return mUnsupportedDiskInfo.hashCode();
+        }
+        return mMissingVolumeRecord.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        if (isVolumeInfo()) {
+            return mVolumeInfo.toString();
+        }
+        if (isDiskInfoUnsupported()) {
+            return mUnsupportedDiskInfo.toString();
+        }
+        return mMissingVolumeRecord.toString();
+    }
+
+    @Override
+    public int compareTo(StorageEntry other) {
+        if (isDefaultInternalStorage() && !other.isDefaultInternalStorage()) {
+            return -1;
+        }
+        if (!isDefaultInternalStorage() && other.isDefaultInternalStorage()) {
+            return 1;
+        }
+
+        if (isVolumeInfo() && !other.isVolumeInfo()) {
+            return -1;
+        }
+        if (!isVolumeInfo() && other.isVolumeInfo()) {
+            return 1;
+        }
+
+        if (isPrivate() && !other.isPrivate()) {
+            return -1;
+        }
+        if (!isPrivate() && other.isPrivate()) {
+            return 1;
+        }
+
+        if (isMounted() && !other.isMounted()) {
+            return -1;
+        }
+        if (!isMounted() && other.isMounted()) {
+            return 1;
+        }
+
+        if (!isVolumeRecordMissed() && other.isVolumeRecordMissed()) {
+            return -1;
+        }
+        if (isVolumeRecordMissed() && !other.isVolumeRecordMissed()) {
+            return 1;
+        }
+
+        if (getDescription() == null) {
+            return 1;
+        }
+        if (other.getDescription() == null) {
+            return -1;
+        }
+        return getDescription().compareTo(other.getDescription());
+    }
+
+    /** Returns default internal storage. */
+    public static StorageEntry getDefaultInternalStorageEntry(Context context) {
+        return new StorageEntry(context, context.getSystemService(StorageManager.class)
+                .findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL));
+    }
+
+    /** If it's a VolumeInfo. */
+    public boolean isVolumeInfo() {
+        return mVolumeInfo != null;
+    }
+
+    /** If it's an unsupported DiskInfo. */
+    public boolean isDiskInfoUnsupported() {
+        return mUnsupportedDiskInfo != null;
+    }
+
+    /** If it's a missing VolumeRecord. */
+    public boolean isVolumeRecordMissed() {
+        return mMissingVolumeRecord != null;
+    }
+
+    /** If it's a default internal storage. */
+    public boolean isDefaultInternalStorage() {
+        if (isVolumeInfo()) {
+            return mVolumeInfo.getType() == VolumeInfo.TYPE_PRIVATE
+                    && TextUtils.equals(mVolumeInfo.getId(), VolumeInfo.ID_PRIVATE_INTERNAL);
+        }
+        return false;
+    }
+
+    /** If it's a mounted storage. */
+    public boolean isMounted() {
+        return mVolumeInfo == null ? false : (mVolumeInfo.getState() == VolumeInfo.STATE_MOUNTED
+                || mVolumeInfo.getState() == VolumeInfo.STATE_MOUNTED_READ_ONLY);
+    }
+
+    /** If it's an unmounted storage. */
+    public boolean isUnmounted() {
+        return mVolumeInfo == null ? false : (mVolumeInfo.getState() == VolumeInfo.STATE_UNMOUNTED);
+    }
+
+    /** If it's an unmountable storage. */
+    public boolean isUnmountable() {
+        return mVolumeInfo == null ? false : mVolumeInfo.getState() == VolumeInfo.STATE_UNMOUNTABLE;
+    }
+
+    /** If it's a private storage. */
+    public boolean isPrivate() {
+        return mVolumeInfo == null ? false : mVolumeInfo.getType() == VolumeInfo.TYPE_PRIVATE;
+    }
+
+    /** If it's a public storage. */
+    public boolean isPublic() {
+        return mVolumeInfo == null ? false : mVolumeInfo.getType() == VolumeInfo.TYPE_PUBLIC;
+    }
+
+    /** Returns description. */
+    public String getDescription() {
+        if (isVolumeInfo()) {
+            return mVolumeInfoDescription;
+        }
+        if (isDiskInfoUnsupported()) {
+            return mUnsupportedDiskInfo.getDescription();
+        }
+        return mMissingVolumeRecord.getNickname();
+    }
+
+    /** Returns ID. */
+    public String getId() {
+        if (isVolumeInfo()) {
+            return mVolumeInfo.getId();
+        }
+        if (isDiskInfoUnsupported()) {
+            return mUnsupportedDiskInfo.getId();
+        }
+        return mMissingVolumeRecord.getFsUuid();
+    }
+
+    /** Returns disk ID. */
+    public String getDiskId() {
+        if (isVolumeInfo()) {
+            return mVolumeInfo.getDiskId();
+        }
+        if (isDiskInfoUnsupported()) {
+            return mUnsupportedDiskInfo.getId();
+        }
+        return null;
+    }
+
+    /** Returns fsUuid. */
+    public String getFsUuid() {
+        if (isVolumeInfo()) {
+            return mVolumeInfo.getFsUuid();
+        }
+        if (isDiskInfoUnsupported()) {
+            return null;
+        }
+        return mMissingVolumeRecord.getFsUuid();
+    }
+
+    /** Returns root file if it's a VolumeInfo. */
+    public File getPath() {
+        return mVolumeInfo == null ? null : mVolumeInfo.getPath();
+    }
+
+    /** Returns VolumeInfo of the StorageEntry. */
+    public VolumeInfo getVolumeInfo() {
+        return mVolumeInfo;
+    }
+}
+
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index c2a0b62..dba72ba 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -158,6 +158,9 @@
                 intent = getAppsIntent();
                 break;
             case FILES_KEY:
+                if (mVolume == null) {
+                    break;
+                }
                 intent = getFilesIntent();
                 FeatureFactory.getFactory(mContext).getMetricsFeatureProvider().action(
                         mContext, SettingsEnums.STORAGE_FILES);
@@ -293,6 +296,17 @@
         mTotalSize = totalSizeBytes;
     }
 
+    /** Set storage size to 0 for each preference. */
+    public void clearStorageSizeDisplay() {
+        mPhotoPreference.setStorageSize(0L, 0L);
+        mAudioPreference.setStorageSize(0L, 0L);
+        mGamePreference.setStorageSize(0L, 0L);
+        mMoviesPreference.setStorageSize(0L, 0L);
+        mAppPreference.setStorageSize(0L, 0L);
+        mFilePreference.setStorageSize(0L, 0L);
+        mSystemPreference.setStorageSize(0L, 0L);
+    }
+
     /**
      * Returns a list of keys used by this preference controller.
      */
diff --git a/src/com/android/settings/deviceinfo/storage/StorageRenameFragment.java b/src/com/android/settings/deviceinfo/storage/StorageRenameFragment.java
new file mode 100644
index 0000000..c67fe33
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageRenameFragment.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+/**
+ * Dialog that allows editing of volume nickname.
+ */
+public class StorageRenameFragment extends InstrumentedDialogFragment {
+    private static final String TAG_RENAME = "rename";
+
+    /** Shows the rename dialog. */
+    public static void show(Fragment parent, VolumeInfo vol) {
+        final StorageRenameFragment dialog = new StorageRenameFragment();
+        dialog.setTargetFragment(parent, 0 /* requestCode */);
+        final Bundle args = new Bundle();
+        args.putString(VolumeRecord.EXTRA_FS_UUID, vol.getFsUuid());
+        dialog.setArguments(args);
+        dialog.show(parent.getFragmentManager(), TAG_RENAME);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DIALOG_VOLUME_RENAME;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final Context context = getActivity();
+        final StorageManager storageManager = context.getSystemService(StorageManager.class);
+
+        final String fsUuid = getArguments().getString(VolumeRecord.EXTRA_FS_UUID);
+        final VolumeRecord rec = storageManager.findRecordByUuid(fsUuid);
+
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
+
+        final View view = dialogInflater.inflate(R.layout.dialog_edittext, null, false);
+        final EditText nickname = (EditText) view.findViewById(R.id.edittext);
+        nickname.setText(rec.getNickname());
+
+        return builder.setTitle(R.string.storage_rename_title)
+                .setView(view)
+                .setPositiveButton(R.string.save, (dialog, which) ->
+                    // TODO: move to background thread
+                    storageManager.setVolumeNickname(fsUuid, nickname.getText().toString()))
+                .setNegativeButton(R.string.cancel, null)
+                .create();
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceController.java
new file mode 100644
index 0000000..03fddec
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceController.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.SettingsSpinnerPreference;
+import com.android.settingslib.widget.settingsspinner.SettingsSpinnerAdapter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Shows a spinner for users to select a storage volume.
+ */
+public class StorageSelectionPreferenceController extends BasePreferenceController implements
+        AdapterView.OnItemSelectedListener {
+
+    @VisibleForTesting
+    SettingsSpinnerPreference mSpinnerPreference;
+    @VisibleForTesting
+    StorageAdapter mStorageAdapter;
+
+    private final List<StorageEntry> mStorageEntries = new ArrayList<>();
+
+    /** The interface for spinner selection callback. */
+    public interface OnItemSelectedListener {
+        /** Callbacked when the spinner selection is changed. */
+        void onItemSelected(StorageEntry storageEntry);
+    }
+    private OnItemSelectedListener mOnItemSelectedListener;
+
+    public StorageSelectionPreferenceController(Context context, String key) {
+        super(context, key);
+
+        mStorageAdapter = new StorageAdapter(context);
+    }
+
+    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
+        mOnItemSelectedListener = listener;
+    }
+
+    /** Set the storages in the spinner. */
+    public void setStorageEntries(List<StorageEntry> storageEntries) {
+        mStorageAdapter.clear();
+        mStorageEntries.clear();
+        if (storageEntries == null || storageEntries.isEmpty()) {
+            return;
+        }
+        Collections.sort(mStorageEntries);
+        mStorageEntries.addAll(storageEntries);
+        mStorageAdapter.addAll(storageEntries);
+    }
+
+    /** set selected storage in the spinner. */
+    public void setSelectedStorageEntry(StorageEntry selectedStorageEntry) {
+        if (mSpinnerPreference == null || !mStorageEntries.contains(selectedStorageEntry)) {
+            return;
+        }
+        mSpinnerPreference.setSelection(mStorageAdapter.getPosition(selectedStorageEntry));
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE_UNSEARCHABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        mSpinnerPreference = screen.findPreference(getPreferenceKey());
+        mSpinnerPreference.setAdapter(mStorageAdapter);
+        mSpinnerPreference.setOnItemSelectedListener(this);
+    }
+
+    @Override
+    public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
+        if (mOnItemSelectedListener == null) {
+            return;
+        }
+        mOnItemSelectedListener.onItemSelected(mStorageAdapter.getItem(position));
+    }
+
+    @Override
+    public void onNothingSelected(AdapterView<?> arg0) {
+        // Do nothing.
+    }
+
+    @VisibleForTesting
+    class StorageAdapter extends SettingsSpinnerAdapter<StorageEntry> {
+
+        StorageAdapter(Context context) {
+            super(context);
+        }
+
+        @Override
+        public View getView(int position, View view, ViewGroup parent) {
+            if (view == null) {
+                view = getDefaultView(position, view, parent);
+            }
+
+            TextView textView = null;
+            try {
+                textView = (TextView) view;
+            } catch (ClassCastException e) {
+                throw new IllegalStateException("Default view should be a TextView, ", e);
+            }
+            textView.setText(getItem(position).getDescription());
+            return textView;
+        }
+
+        @Override
+        public View getDropDownView(int position, View view, ViewGroup parent) {
+            if (view == null) {
+                view = getDefaultDropDownView(position, view, parent);
+            }
+
+            TextView textView = null;
+            try {
+                textView = (TextView) view;
+            } catch (ClassCastException e) {
+                throw new IllegalStateException("Default drop down view should be a TextView, ", e);
+            }
+            textView.setText(getItem(position).getDescription());
+            return textView;
+        }
+    }
+}
+
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
new file mode 100644
index 0000000..a00b25a
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import android.app.usage.StorageStatsManager;
+import android.content.Context;
+import android.text.format.Formatter;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.utils.ThreadUtils;
+import com.android.settingslib.widget.UsageProgressBarPreference;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Shows storage summary and progress.
+ */
+public class StorageUsageProgressBarPreferenceController extends BasePreferenceController {
+
+    private static final String TAG = "StorageProgressCtrl";
+
+    private final StorageStatsManager mStorageStatsManager;
+    @VisibleForTesting
+    long mUsedBytes;
+    @VisibleForTesting
+    long mTotalBytes;
+    private UsageProgressBarPreference mUsageProgressBarPreference;
+    private StorageEntry mStorageEntry;
+
+    public StorageUsageProgressBarPreferenceController(Context context, String key) {
+        super(context, key);
+
+        mStorageStatsManager = context.getSystemService(StorageStatsManager.class);
+    }
+
+    /** Set StorageEntry to display. */
+    public void setSelectedStorageEntry(StorageEntry storageEntry) {
+        mStorageEntry = storageEntry;
+        getStorageStatsAndUpdateUi();
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE_UNSEARCHABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        mUsageProgressBarPreference = screen.findPreference(getPreferenceKey());
+        getStorageStatsAndUpdateUi();
+    }
+
+    private void getStorageStatsAndUpdateUi() {
+        ThreadUtils.postOnBackgroundThread(() -> {
+            try {
+                if (mStorageEntry == null || !mStorageEntry.isMounted()) {
+                    throw new IOException();
+                }
+
+                if (mStorageEntry.isPrivate()) {
+                    // StorageStatsManager can only query private storages.
+                    mTotalBytes = mStorageStatsManager.getTotalBytes(mStorageEntry.getFsUuid());
+                    mUsedBytes = mTotalBytes
+                            - mStorageStatsManager.getFreeBytes(mStorageEntry.getFsUuid());
+                } else {
+                    final File rootFile = mStorageEntry.getPath();
+                    if (rootFile == null) {
+                        Log.d(TAG, "Mounted public storage has null root path: " + mStorageEntry);
+                        throw new IOException();
+                    }
+                    mTotalBytes = rootFile.getTotalSpace();
+                    mUsedBytes = mTotalBytes - rootFile.getFreeSpace();
+                }
+            } catch (IOException e) {
+                // The storage device isn't present.
+                mTotalBytes = 0;
+                mUsedBytes = 0;
+            }
+
+            if (mUsageProgressBarPreference == null) {
+                return;
+            }
+            ThreadUtils.postOnMainThread(() ->
+                    updateState(mUsageProgressBarPreference)
+            );
+        });
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        mUsageProgressBarPreference.setUsageSummary(
+                getStorageSummary(R.string.storage_usage_summary, mUsedBytes));
+        mUsageProgressBarPreference.setTotalSummary(
+                getStorageSummary(R.string.storage_total_summary, mTotalBytes));
+        mUsageProgressBarPreference.setPercent(mUsedBytes, mTotalBytes);
+    }
+
+    private String getStorageSummary(int resId, long bytes) {
+        final Formatter.BytesResult result = Formatter.formatBytes(mContext.getResources(),
+                bytes, 0);
+        return mContext.getString(resId, result.value, result.units);
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUtils.java b/src/com/android/settings/deviceinfo/storage/StorageUtils.java
new file mode 100644
index 0000000..26bdec0
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageUtils.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.storage.VolumeRecord;
+
+import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.deviceinfo.PrivateVolumeForget;
+
+/** Storage utilities */
+public class StorageUtils {
+
+    /** Launches the fragment to forget a specified missing volume record. */
+    public static void launchForgetMissingVolumeRecordFragment(Context context,
+            StorageEntry storageEntry) {
+        if (storageEntry == null || !storageEntry.isVolumeRecordMissed()) {
+            return;
+        }
+
+        final Bundle args = new Bundle();
+        args.putString(VolumeRecord.EXTRA_FS_UUID, storageEntry.getFsUuid());
+        new SubSettingLauncher(context)
+                .setDestination(PrivateVolumeForget.class.getCanonicalName())
+                .setTitleRes(R.string.storage_menu_forget)
+                .setSourceMetricsCategory(SettingsEnums.SETTINGS_STORAGE_CATEGORY)
+                .setArguments(args)
+                .launch();
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/storage/VolumeSizesLoader.java b/src/com/android/settings/deviceinfo/storage/VolumeSizesLoader.java
index d95befa..64510c6 100644
--- a/src/com/android/settings/deviceinfo/storage/VolumeSizesLoader.java
+++ b/src/com/android/settings/deviceinfo/storage/VolumeSizesLoader.java
@@ -26,6 +26,7 @@
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
+import java.io.File;
 import java.io.IOException;
 
 public class VolumeSizesLoader extends AsyncLoaderCompat<PrivateStorageInfo> {
@@ -49,6 +50,11 @@
 
     @Override
     public PrivateStorageInfo loadInBackground() {
+        if (mVolume == null || (mVolume.getState() != VolumeInfo.STATE_MOUNTED
+                && mVolume.getState() != VolumeInfo.STATE_MOUNTED_READ_ONLY)) {
+            return new PrivateStorageInfo(0L /* freeBytes */, 0L /* totalBytes */);
+        }
+
         PrivateStorageInfo volumeSizes;
         try {
             volumeSizes = getVolumeSize(mVolumeProvider, mStats, mVolume);
@@ -62,8 +68,14 @@
     static PrivateStorageInfo getVolumeSize(
             StorageVolumeProvider storageVolumeProvider, StorageStatsManager stats, VolumeInfo info)
             throws IOException {
-        long privateTotalBytes = storageVolumeProvider.getTotalBytes(stats, info);
-        long privateFreeBytes = storageVolumeProvider.getFreeBytes(stats, info);
-        return new PrivateStorageInfo(privateFreeBytes, privateTotalBytes);
+        if (info.getType() == VolumeInfo.TYPE_PRIVATE) {
+            return new PrivateStorageInfo(storageVolumeProvider.getFreeBytes(stats, info),
+                    storageVolumeProvider.getTotalBytes(stats, info));
+        }
+        // TODO(b/174964885): It's confusing to use PrivateStorageInfo for a public storage,
+        //                    replace it with a new naming or a different object.
+        final File rootFile = info.getPath();
+        return rootFile == null ? new PrivateStorageInfo(0L /* freeBytes */, 0L /* totalBytes */)
+                : new PrivateStorageInfo(rootFile.getFreeSpace(), rootFile.getTotalSpace());
     }
 }
diff --git a/src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceController.java b/src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceController.java
new file mode 100644
index 0000000..4622431
--- /dev/null
+++ b/src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceController.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.privacy;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.core.TogglePreferenceController;
+
+/**
+ * Controller for preference to toggle whether clipboard access notifications should be shown.
+ */
+public class ShowClipAccessNotificationPreferenceController extends TogglePreferenceController {
+
+    private static final String KEY_SHOW_CLIP_ACCESS_NOTIFICATION = "show_clip_access_notification";
+
+    public ShowClipAccessNotificationPreferenceController(Context context) {
+        super(context, KEY_SHOW_CLIP_ACCESS_NOTIFICATION);
+    }
+
+    @Override
+    public boolean isChecked() {
+        // TODO(b/182349993) Retrieve default value from DeviceConfig.
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, 1) != 0;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, isChecked ? 1 : 0);
+        return true;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+}
diff --git a/src/com/android/settings/widget/CheckableRelativeLayout.java b/src/com/android/settings/widget/CheckableRelativeLayout.java
new file mode 100644
index 0000000..d26c042
--- /dev/null
+++ b/src/com/android/settings/widget/CheckableRelativeLayout.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.Checkable;
+import android.widget.RelativeLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * A RelativeLayout which implements {@link Checkable}. With this implementation, it could be used
+ * in the list item layout for {@link android.widget.AbsListView} to change UI after item click.
+ * Its checked state would be propagated to the checkable child.
+ *
+ * <p>
+ * To support accessibility, the state description is from the checkable view and is
+ * changed with {@link #setChecked(boolean)}. We make the checkable child unclickable, unfocusable
+ * and non-important for accessibility, so that the announcement wouldn't include
+ * the checkable view.
+ * <
+ */
+public class CheckableRelativeLayout extends RelativeLayout implements Checkable {
+
+    private Checkable mCheckable;
+    private View mCheckableChild;
+    private boolean mChecked;
+
+    public CheckableRelativeLayout(Context context) {
+        super(context);
+    }
+
+    public CheckableRelativeLayout(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        mCheckableChild = findFirstCheckableView(this);
+        if (mCheckableChild != null) {
+            mCheckableChild.setClickable(false);
+            mCheckableChild.setFocusable(false);
+            mCheckableChild.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
+            mCheckable = (Checkable) mCheckableChild;
+            mCheckable.setChecked(isChecked());
+            setStateDescriptionIfNeeded();
+        }
+        super.onFinishInflate();
+    }
+
+    @Nullable
+    private static View findFirstCheckableView(@NonNull ViewGroup viewGroup) {
+        final int childCount = viewGroup.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = viewGroup.getChildAt(i);
+            if (child instanceof Checkable) {
+                return child;
+            }
+            if (child instanceof ViewGroup) {
+                findFirstCheckableView((ViewGroup) child);
+            }
+        }
+        return  null;
+    }
+
+    @Override
+    public void setChecked(boolean checked) {
+        if (mChecked != checked) {
+            mChecked = checked;
+            if (mCheckable != null) {
+                mCheckable.setChecked(checked);
+            }
+        }
+        setStateDescriptionIfNeeded();
+        notifyViewAccessibilityStateChangedIfNeeded(
+                AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+    }
+
+    private void setStateDescriptionIfNeeded() {
+        if (mCheckableChild == null) {
+            return;
+        }
+        setStateDescription(mCheckableChild.getStateDescription());
+    }
+
+    @Override
+    public boolean isChecked() {
+        return mChecked;
+    }
+
+    @Override
+    public void toggle() {
+        setChecked(!mChecked);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        event.setChecked(mChecked);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setChecked(mChecked);
+    }
+}
diff --git a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
index b154a9b..104761f 100644
--- a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
+++ b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
@@ -75,7 +75,8 @@
     // Interval between initiating SavedNetworkTracker scans
     private static final long SCAN_INTERVAL_MILLIS = 10_000;
 
-    private NetworkDetailsTracker mNetworkDetailsTracker;
+    @VisibleForTesting
+    NetworkDetailsTracker mNetworkDetailsTracker;
     private HandlerThread mWorkerThread;
     private WifiDetailPreferenceController2 mWifiDetailPreferenceController2;
     private List<WifiDialog2.WifiDialog2Listener> mWifiDialogListeners = new ArrayList<>();
@@ -125,9 +126,11 @@
 
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.wifi_modify);
-        item.setIcon(com.android.internal.R.drawable.ic_mode_edit);
-        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+        if (isEditable()) {
+            MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.wifi_modify);
+            item.setIcon(com.android.internal.R.drawable.ic_mode_edit);
+            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+        }
         super.onCreateOptionsMenu(menu, inflater);
     }
 
@@ -252,6 +255,17 @@
                         getArguments().getString(KEY_CHOSEN_WIFIENTRY_KEY));
     }
 
+    private boolean isEditable() {
+        if (mNetworkDetailsTracker == null) {
+            return false;
+        }
+        final WifiEntry wifiEntry = mNetworkDetailsTracker.getWifiEntry();
+        if (wifiEntry == null) {
+            return false;
+        }
+        return wifiEntry.isSaved();
+    }
+
     /**
      * API call for refreshing the preferences in this fragment.
      */
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationSettingsFragmentTest.java
index d49213c..11128e4 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationSettingsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationSettingsFragmentTest.java
@@ -16,12 +16,15 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
 import static com.android.settings.accessibility.MagnificationPreferenceFragment.ON;
+import static com.android.settings.accessibility.MagnificationSettingsFragment.MagnificationModeInfo;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -29,7 +32,8 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.provider.Settings;
-import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
 
 import androidx.fragment.app.FragmentManager;
 import androidx.preference.PreferenceManager;
@@ -77,7 +81,7 @@
     }
 
     @Test
-    public void onCreateDialog_capabilitiesInBundle_matchCheckBoxStatus() {
+    public void onCreateDialog_capabilitiesInBundle_checkedModeInDialogIsExpected() {
         final Bundle windowModeSavedInstanceState = new Bundle();
         windowModeSavedInstanceState.putInt(EXTRA_CAPABILITY,
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
@@ -85,23 +89,21 @@
         mFragment.onCreate(windowModeSavedInstanceState);
         mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
 
-        assertThat(mFragment.mMagnifyFullScreenCheckBox.isChecked()).isFalse();
-        assertThat(mFragment.mMagnifyWindowCheckBox.isChecked()).isTrue();
+        assertThat(getChoseModeFromDialog()).isEqualTo(MagnificationMode.WINDOW);
     }
 
     @Test
-    public void onCreateDialog_capabilitiesInSettings_matchCheckBoxStatus() {
+    public void onCreateDialog_capabilitiesInSetting_checkedModeInDialogIsExpected() {
         MagnificationCapabilities.setCapabilities(mContext,
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
         mFragment.onCreate(Bundle.EMPTY);
         mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
 
-        assertThat(mFragment.mMagnifyFullScreenCheckBox.isChecked()).isTrue();
-        assertThat(mFragment.mMagnifyWindowCheckBox.isChecked()).isFalse();
+        assertThat(getChoseModeFromDialog()).isEqualTo(MagnificationMode.FULLSCREEN);
     }
 
     @Test
-    public void onCreateDialog_capabilitiesInSettingsAndBundle_matchBundleValueCheckBoxStatus() {
+    public void onCreateDialog_choseModeIsDifferentFromInSettings_ShowUsersChoseModeInDialog() {
         final Bundle allModeSavedInstanceState = new Bundle();
         allModeSavedInstanceState.putInt(EXTRA_CAPABILITY,
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
@@ -111,37 +113,93 @@
         mFragment.onCreate(allModeSavedInstanceState);
         mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
 
-        assertThat(mFragment.mMagnifyFullScreenCheckBox.isChecked()).isTrue();
-        assertThat(mFragment.mMagnifyWindowCheckBox.isChecked()).isTrue();
+        assertThat(getChoseModeFromDialog()).isEqualTo(MagnificationMode.ALL);
     }
 
     @Test
-    public void onCreateDialog_emptySettingsAndBundle_matchDefaultValueCheckBoxStatus() {
+    public void onCreateDialog_emptySettingsAndBundle_checkedModeInDialogIsDefaultValue() {
         mFragment.onCreate(Bundle.EMPTY);
         mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
 
-        // Compare to default Capabilities
-        assertThat(mFragment.mMagnifyFullScreenCheckBox.isChecked()).isTrue();
-        assertThat(mFragment.mMagnifyWindowCheckBox.isChecked()).isFalse();
+        assertThat(getChoseModeFromDialog()).isEqualTo(MagnificationMode.FULLSCREEN);
     }
 
     @Test
-    public void checkWindowModeCheckBox_tripleTapEnabled_showSwitchShortcutDialog() {
+    public void chooseWindowMode_tripleTapEnabled_showSwitchShortcutDialog() {
+        enableTripleTap();
         final Bundle fullScreenModeSavedInstanceState = new Bundle();
         fullScreenModeSavedInstanceState.putInt(EXTRA_CAPABILITY,
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
         mFragment.onCreate(fullScreenModeSavedInstanceState);
         mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
 
-        enableTripleTap();
-        final View dialogWidowView = mFragment.mDialog.findViewById(R.id.magnify_window_screen);
-        final View dialogWindowTextArea = dialogWidowView.findViewById(R.id.container);
-        dialogWindowTextArea.performClick();
+        performItemClickWith(MagnificationMode.WINDOW);
 
         verify(mFragment).showDialog(
                 MagnificationSettingsFragment.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
     }
 
+    @Test
+    public void chooseModeAll_tripleTapEnabled_showSwitchShortcutDialog() {
+        enableTripleTap();
+        final Bundle fullScreenModeSavedInstanceState = new Bundle();
+        fullScreenModeSavedInstanceState.putInt(EXTRA_CAPABILITY,
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+        mFragment.onCreate(fullScreenModeSavedInstanceState);
+        mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
+
+        performItemClickWith(MagnificationMode.ALL);
+
+        verify(mFragment).showDialog(
+                MagnificationSettingsFragment.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+    }
+
+    @Test
+    public void chooseWindowMode_WindowModeInSettingsAndTripleTapEnabled_notShowShortCutDialog() {
+        enableTripleTap();
+        MagnificationCapabilities.setCapabilities(mContext,
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mFragment.onCreate(Bundle.EMPTY);
+        mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
+
+        performItemClickWith(MagnificationMode.WINDOW);
+
+        verify(mFragment, never()).showDialog(
+                MagnificationSettingsFragment.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+    }
+
+    private int getChoseModeFromDialog() {
+        final ListView listView = mFragment.mMagnificationModesListView;
+        assertThat(listView).isNotNull();
+
+        final int checkedPosition = listView.getCheckedItemPosition();
+        final MagnificationModeInfo modeInfo =
+                (MagnificationModeInfo) listView.getAdapter().getItem(
+                        checkedPosition);
+        return modeInfo.mMagnificationMode;
+    }
+
+    private void performItemClickWith(@MagnificationMode int mode) {
+        final ListView listView = mFragment.mMagnificationModesListView;
+        assertThat(listView).isNotNull();
+
+        int modeIndex = AdapterView.NO_ID;
+        // Index 0 is header.
+        for (int i = 1; i < listView.getAdapter().getCount(); i++) {
+            final MagnificationModeInfo modeInfo =
+                    (MagnificationModeInfo) listView.getAdapter().getItem(i);
+            if (modeInfo.mMagnificationMode == mode) {
+                modeIndex = i;
+                break;
+            }
+        }
+        if (modeIndex == AdapterView.NO_ID) {
+            throw new RuntimeException("The mode is not in the list.");
+        }
+
+        listView.performItemClick(listView.getChildAt(modeIndex), modeIndex, modeIndex);
+    }
+
     private void enableTripleTap() {
         Settings.Secure.putInt(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
deleted file mode 100644
index ed7f16b..0000000
--- a/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.deviceinfo;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Activity;
-import android.content.pm.PackageManager;
-import android.os.storage.VolumeInfo;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-
-import com.android.settings.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.shadows.ShadowApplication;
-
-@RunWith(RobolectricTestRunner.class)
-public class PrivateVolumeOptionMenuControllerTest {
-
-    @Mock
-    private MenuItem mMigrateMenuItem;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Menu mMenu;
-    @Mock
-    private MenuInflater mMenuInflater;
-    @Mock
-    private PackageManager mPm;
-    @Mock
-    private VolumeInfo mVolumeInfo;
-    @Mock
-    private VolumeInfo mPrimaryInfo;
-
-    private PrivateVolumeOptionMenuController mController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
-        when(mVolumeInfo.isMountedWritable()).thenReturn(true);
-        when(mPrimaryInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
-        when(mMenu.findItem(anyInt())).thenReturn(mMigrateMenuItem);
-        when(mMigrateMenuItem.getItemId()).thenReturn(100);
-
-        mController = new PrivateVolumeOptionMenuController(
-                Robolectric.setupActivity(Activity.class), mPrimaryInfo, mPm);
-    }
-
-    @Test
-    public void testMigrateDataMenuItemIsAdded() {
-        mController.onCreateOptionsMenu(mMenu, mMenuInflater);
-
-        verify(mMenu).add(Menu.NONE, 100, Menu.NONE, R.string.storage_menu_migrate);
-    }
-
-    @Test
-    public void testMigrateDataIsNotVisibleNormally() {
-        when(mPm.getPrimaryStorageCurrentVolume()).thenReturn(mPrimaryInfo);
-        when(mPrimaryInfo.isMountedWritable()).thenReturn(true);
-
-        mController.onCreateOptionsMenu(mMenu, mMenuInflater);
-        mController.onPrepareOptionsMenu(mMenu);
-
-        verify(mMigrateMenuItem).setVisible(false);
-    }
-
-    @Test
-    public void testMigrateDataIsVisibleWhenExternalVolumeIsPrimary() {
-        when(mPm.getPrimaryStorageCurrentVolume()).thenReturn(mVolumeInfo);
-
-        mController.onCreateOptionsMenu(mMenu, mMenuInflater);
-        mController.onPrepareOptionsMenu(mMenu);
-
-        verify(mMigrateMenuItem).setVisible(true);
-    }
-
-    @Test
-    public void testMigrateDataIsNotVisibleWhenExternalVolumeIsNotMounted() {
-        when(mPm.getPrimaryStorageCurrentVolume()).thenReturn(mVolumeInfo);
-        when(mVolumeInfo.isMountedWritable()).thenReturn(false);
-
-        mController.onCreateOptionsMenu(mMenu, mMenuInflater);
-        mController.onPrepareOptionsMenu(mMenu);
-
-        verify(mMigrateMenuItem).setVisible(false);
-    }
-
-    @Test
-    public void testMigrateDataGoesToMigrateWizard() {
-        when(mPm.getPrimaryStorageCurrentVolume()).thenReturn(mVolumeInfo);
-
-        mController.onCreateOptionsMenu(mMenu, mMenuInflater);
-        mController.onPrepareOptionsMenu(mMenu);
-
-        assertThat(mController.onOptionsItemSelected(mMigrateMenuItem)).isTrue();
-        ShadowApplication shadowApplication = ShadowApplication.getInstance();
-        assertThat(shadowApplication).isNotNull();
-        assertThat(shadowApplication.getNextStartedActivity().getComponent().getClassName())
-                .isEqualTo(StorageWizardMigrateConfirm.class.getName());
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
index 634b9a8..6b92e57 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
@@ -65,7 +65,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
@@ -233,7 +232,6 @@
     }
 
     @Test
-    @Ignore
     public void updatePreferencesOrFinish_callingAppIsAdmin_deviceNotProvisioned_footerInvisible() {
         Global.putInt(application.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
         initActivity(new Intent().putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true));
diff --git a/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java b/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java
index 79d4b6b..af44d39 100644
--- a/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java
@@ -50,7 +50,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -105,18 +104,17 @@
     }
 
     @Test
-    @Ignore
     public void testSetupChooseLockGeneric() {
         Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
                 Settings.Global.DEVICE_PROVISIONED, 0);
+        Intent intent = new Intent(ACTION_SET_NEW_PASSWORD);
+        intent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true);
         SetNewPasswordActivity activity =
-                Robolectric.buildActivity(SetNewPasswordActivity.class).get();
-        activity.launchChooseLock(new Bundle());
+                Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();
         ShadowActivity shadowActivity = Shadows.shadowOf(activity);
-        Intent intent = getLaunchChooseLockIntent(shadowActivity);
-        intent.putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true);
 
-        assertThat(intent.getComponent())
+        Intent nextIntent = shadowActivity.getNextStartedActivityForResult().intent;
+        assertThat(nextIntent.getComponent())
                 .isEqualTo(new ComponentName(activity, SetupChooseLockGeneric.class));
     }
 
diff --git a/tests/robotests/src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceControllerTest.java
new file mode 100644
index 0000000..c707cd6
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/privacy/ShowClipAccessNotificationPreferenceControllerTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.privacy;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class ShowClipAccessNotificationPreferenceControllerTest {
+
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private ShowClipAccessNotificationPreferenceController mController;
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = ApplicationProvider.getApplicationContext();
+        mController = new ShowClipAccessNotificationPreferenceController(mContext);
+        mPreference = new Preference(mContext);
+        mPreference.setKey(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void isChecked_settingIsOff_shouldReturnFalse() throws Exception {
+        setProperty(0);
+
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void isChecked_settingIsOn_shouldReturnTrue() throws Exception {
+        setProperty(1);
+
+        assertThat(mController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void onPreferenceChange_turnOn_shouldChangeSettingTo1() throws Exception {
+        setProperty(0);
+
+        mController.onPreferenceChange(mPreference, true);
+
+        assertThat(mController.isChecked()).isTrue();
+        assertProperty(1);
+    }
+
+    @Test
+    public void onPreferenceChange_turnOff_shouldChangeSettingTo0() throws Exception {
+        setProperty(1);
+
+        mController.onPreferenceChange(mPreference, false);
+
+        assertThat(mController.isChecked()).isFalse();
+        assertProperty(0);
+    }
+
+    private void setProperty(int newValue) {
+        final ContentResolver contentResolver = mContext.getContentResolver();
+        Settings.Secure.putInt(
+                contentResolver, Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS, newValue);
+    }
+
+    private void assertProperty(int expectedValue) throws SettingNotFoundException {
+        final ContentResolver contentResolver = mContext.getContentResolver();
+        assertThat(Settings.Secure.getInt(
+                contentResolver, Settings.Secure.CLIPBOARD_SHOW_ACCESS_NOTIFICATIONS))
+                .isEqualTo(expectedValue);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java
index e0fb578..66b5bcb 100644
--- a/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java
@@ -24,9 +24,9 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.app.settings.SettingsEnums;
 import android.view.Menu;
@@ -36,12 +36,17 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
+import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.wifitrackerlib.NetworkDetailsTracker;
+import com.android.wifitrackerlib.WifiEntry;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
@@ -52,11 +57,22 @@
 
     final String TEST_PREFERENCE_KEY = "TEST_PREFERENCE_KEY";
 
+    @Mock
+    WifiEntry mWifiEntry;
+    @Mock
+    NetworkDetailsTracker mNetworkDetailsTracker;
+    @Mock
+    Menu mMenu;
     private WifiNetworkDetailsFragment2 mFragment;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mWifiEntry).when(mNetworkDetailsTracker).getWifiEntry();
+        doReturn(true).when(mWifiEntry).isSaved();
+
         mFragment = new WifiNetworkDetailsFragment2();
+        mFragment.mNetworkDetailsTracker = mNetworkDetailsTracker;
     }
 
     @Test
@@ -77,16 +93,24 @@
 
     @Test
     public void onCreateOptionsMenu_shouldSetCorrectIcon() {
-        final Menu menu = mock(Menu.class);
         final MenuItem menuItem = mock(MenuItem.class);
-        doReturn(menuItem).when(menu).add(anyInt(), eq(Menu.FIRST), anyInt(), anyInt());
+        doReturn(menuItem).when(mMenu).add(anyInt(), eq(Menu.FIRST), anyInt(), anyInt());
 
-        mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class));
+        mFragment.onCreateOptionsMenu(mMenu, mock(MenuInflater.class));
 
         verify(menuItem).setIcon(com.android.internal.R.drawable.ic_mode_edit);
     }
 
     @Test
+    public void onCreateOptionsMenu_isNotSavedNetwork_shouldNotAddEditMenu() {
+        doReturn(false).when(mWifiEntry).isSaved();
+
+        mFragment.onCreateOptionsMenu(mMenu, mock(MenuInflater.class));
+
+        verify(mMenu, never()).add(anyInt(), anyInt(), anyInt(), eq(R.string.wifi_modify));
+    }
+
+    @Test
     public void refreshPreferences_controllerShouldUpdateStateAndDisplayPreference() {
         final FakeFragment fragment = spy(new FakeFragment());
         final PreferenceScreen screen = mock(PreferenceScreen.class);
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index b55a788..b7ac4b1 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -32,6 +32,8 @@
         "platform-test-annotations",
         "truth-prebuilt",
         "ub-uiautomator",
+        "SettingsLibSettingsSpinner",
+        "SettingsLibUsageProgressBarPreference",
     ],
 
     // Include all test java files.
diff --git a/tests/unit/src/com/android/settings/deviceinfo/VolumeOptionMenuControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/VolumeOptionMenuControllerTest.java
new file mode 100644
index 0000000..314f8c2
--- /dev/null
+++ b/tests/unit/src/com/android/settings/deviceinfo/VolumeOptionMenuControllerTest.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.storage.DiskInfo;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+import android.view.Menu;
+
+import androidx.fragment.app.Fragment;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.deviceinfo.storage.StorageEntry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class VolumeOptionMenuControllerTest {
+
+    private static final String INTERNAL_VOLUME_ID = "1";
+    private static final String EXTERNAL_VOLUME_ID = "2";
+    private static final String DISK_ID = "3";
+    private static final String VOLUME_RECORD_FSUUID = "volume_record_fsuuid";
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Menu mMenu;
+    @Mock private PackageManager mPackageManager;
+    @Mock private StorageManager mStorageManager;
+    @Mock private VolumeInfo mExternalVolumeInfo;
+    @Mock private VolumeInfo mInternalVolumeInfo;
+
+    private Context mContext;
+    private VolumeOptionMenuController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager);
+
+        when(mInternalVolumeInfo.getId()).thenReturn(INTERNAL_VOLUME_ID);
+        when(mInternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
+        when(mInternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
+        when(mInternalVolumeInfo.isMountedWritable()).thenReturn(true);
+        when(mExternalVolumeInfo.getId()).thenReturn(EXTERNAL_VOLUME_ID);
+
+        final StorageEntry selectedStorageEntry = new StorageEntry(mContext, mInternalVolumeInfo);
+        mController = new VolumeOptionMenuController(mContext, mock(Fragment.class),
+                selectedStorageEntry);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_unSupportedDiskInfo_formatIsVisible() {
+        final StorageEntry unsupportedStorageEntry =
+                new StorageEntry(new DiskInfo(DISK_ID, 0 /* flags */));
+        mController.setSelectedStorageEntry(unsupportedStorageEntry);
+
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mFormat, atLeastOnce()).setVisible(true);
+        verify(mController.mRename, never()).setVisible(true);
+        verify(mController.mMount, never()).setVisible(true);
+        verify(mController.mUnmount, never()).setVisible(true);
+        verify(mController.mFormatAsPortable, never()).setVisible(true);
+        verify(mController.mFormatAsInternal, never()).setVisible(true);
+        verify(mController.mMigrate, never()).setVisible(true);
+        verify(mController.mFree, never()).setVisible(true);
+        verify(mController.mForget, never()).setVisible(true);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_missingVolumeRecord_forgetIsVisible() {
+        final StorageEntry missingStorageEntry =
+                new StorageEntry(new VolumeRecord(0 /* type */, VOLUME_RECORD_FSUUID));
+        mController.setSelectedStorageEntry(missingStorageEntry);
+
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mForget, atLeastOnce()).setVisible(true);
+        verify(mController.mRename, never()).setVisible(true);
+        verify(mController.mMount, never()).setVisible(true);
+        verify(mController.mUnmount, never()).setVisible(true);
+        verify(mController.mFormat, never()).setVisible(true);
+        verify(mController.mFormatAsPortable, never()).setVisible(true);
+        verify(mController.mFormatAsInternal, never()).setVisible(true);
+        verify(mController.mMigrate, never()).setVisible(true);
+        verify(mController.mFree, never()).setVisible(true);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_unmountedStorage_mountIsVisible() {
+        when(mInternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_UNMOUNTED);
+        mController.setSelectedStorageEntry(new StorageEntry(mContext, mInternalVolumeInfo));
+
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mMount, atLeastOnce()).setVisible(true);
+        verify(mController.mRename, never()).setVisible(true);
+        verify(mController.mUnmount, never()).setVisible(true);
+        verify(mController.mFormat, never()).setVisible(true);
+        verify(mController.mFormatAsPortable, never()).setVisible(true);
+        verify(mController.mFormatAsInternal, never()).setVisible(true);
+        verify(mController.mMigrate, never()).setVisible(true);
+        verify(mController.mFree, never()).setVisible(true);
+        verify(mController.mForget, never()).setVisible(true);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_privateNotDefaultInternal_someMenusAreVisible() {
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mRename, atLeastOnce()).setVisible(true);
+        verify(mController.mUnmount, atLeastOnce()).setVisible(true);
+        verify(mController.mFormatAsPortable, atLeastOnce()).setVisible(true);
+        verify(mController.mMount, never()).setVisible(true);
+        verify(mController.mFormat, never()).setVisible(true);
+        verify(mController.mFormatAsInternal, never()).setVisible(true);
+        verify(mController.mFree, never()).setVisible(true);
+        verify(mController.mForget, never()).setVisible(true);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_privateDefaultInternal_mostMenusAreNotVisible() {
+        when(mInternalVolumeInfo.getId()).thenReturn(VolumeInfo.ID_PRIVATE_INTERNAL);
+        when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mInternalVolumeInfo);
+
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mRename, never()).setVisible(true);
+        verify(mController.mUnmount, never()).setVisible(true);
+        verify(mController.mFormatAsPortable, never()).setVisible(true);
+        verify(mController.mMount, never()).setVisible(true);
+        verify(mController.mFormat, never()).setVisible(true);
+        verify(mController.mFormatAsInternal, never()).setVisible(true);
+        verify(mController.mFree, never()).setVisible(true);
+        verify(mController.mForget, never()).setVisible(true);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_publicStorage_someMenusArcVisible() {
+        when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
+        when(mExternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
+        when(mExternalVolumeInfo.getDiskId()).thenReturn(DISK_ID);
+        final DiskInfo externalDiskInfo = mock(DiskInfo.class);
+        when(mStorageManager.findDiskById(DISK_ID)).thenReturn(externalDiskInfo);
+        mController.setSelectedStorageEntry(new StorageEntry(mContext, mExternalVolumeInfo));
+
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mRename, atLeastOnce()).setVisible(true);
+        verify(mController.mUnmount, atLeastOnce()).setVisible(true);
+        verify(mController.mFormat, atLeastOnce()).setVisible(true);
+        verify(mController.mMount, never()).setVisible(true);
+        verify(mController.mFormatAsPortable, never()).setVisible(true);
+        verify(mController.mFormatAsInternal, never()).setVisible(true);
+        verify(mController.mFree, never()).setVisible(true);
+        verify(mController.mForget, never()).setVisible(true);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_noExternalStorage_migrateNotVisible() {
+        when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mInternalVolumeInfo);
+
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mMigrate, atLeastOnce()).setVisible(false);
+        verify(mController.mMigrate, never()).setVisible(true);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_externalPrimaryStorageAvailable_migrateIsVisible() {
+        when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
+        when(mExternalVolumeInfo.isMountedWritable()).thenReturn(true);
+        when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mExternalVolumeInfo);
+
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mMigrate, atLeastOnce()).setVisible(true);
+    }
+
+    @Test
+    public void onPrepareOptionsMenu_externalUnmounted_migrateIsVisible() {
+        when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
+        when(mExternalVolumeInfo.isMountedWritable()).thenReturn(false);
+        when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mExternalVolumeInfo);
+
+        mController.onPrepareOptionsMenu(mMenu);
+
+        verify(mController.mMigrate, atLeastOnce()).setVisible(false);
+        verify(mController.mMigrate, never()).setVisible(true);
+    }
+}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageEntryTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageEntryTest.java
new file mode 100644
index 0000000..cf1b6b2
--- /dev/null
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageEntryTest.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.storage.DiskInfo;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.util.Objects;
+
+@RunWith(AndroidJUnit4.class)
+public class StorageEntryTest {
+
+    private static final String VOLUME_INFO_ID = "volume_info_id";
+    private static final String DISK_INFO_ID = "disk_info_id";
+    private static final String VOLUME_RECORD_UUID = "volume_record_id";
+
+    @Mock
+    private VolumeInfo mVolumeInfo;
+    @Mock
+    private DiskInfo mDiskInfo;
+    @Mock
+    private VolumeRecord mVolumeRecord;
+
+    private Context mContext;
+    @Mock
+    private StorageManager mStorageManager;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager);
+    }
+
+    @Test
+    public void equals_volumesOfSameId_shouldBeTheSame() {
+        final StorageEntry volumeStorage1 = new StorageEntry(mContext,
+                new VolumeInfo(VOLUME_INFO_ID, 0 /* type */, null /* disk */, null /* partGuid */));
+        final StorageEntry volumeStorage2 = new StorageEntry(mContext,
+                new VolumeInfo(VOLUME_INFO_ID, 0 /* type */, null /* disk */, null /* partGuid */));
+        final StorageEntry diskStorage1 =
+                new StorageEntry(new DiskInfo(DISK_INFO_ID, 0 /* flags */));
+        final StorageEntry diskStorage2 =
+                new StorageEntry(new DiskInfo(DISK_INFO_ID, 0 /* flags */));
+        final StorageEntry volumeRecordStorage1 = new StorageEntry(new VolumeRecord(0 /* flags */,
+                VOLUME_RECORD_UUID));
+        final StorageEntry volumeRecordStorage2 = new StorageEntry(new VolumeRecord(0 /* flags */,
+                VOLUME_RECORD_UUID));
+
+        assertThat(Objects.equals(volumeStorage1, volumeStorage2)).isTrue();
+        assertThat(Objects.equals(diskStorage1, diskStorage2)).isTrue();
+        assertThat(Objects.equals(volumeRecordStorage1, volumeRecordStorage2)).isTrue();
+    }
+
+    @Test
+    public void equals_volumesOfDifferentId_shouldBeDifferent() {
+        final StorageEntry volumeStorage1 = new StorageEntry(mContext,
+                new VolumeInfo(VOLUME_INFO_ID, 0 /* type */, null /* disk */, null /* partGuid */));
+        final StorageEntry volumeStorage2 = new StorageEntry(mContext,
+                new VolumeInfo("id2", 0 /* type */, null /* disk */, null /* partGuid */));
+        final StorageEntry diskStorage1 =
+                new StorageEntry(new DiskInfo(DISK_INFO_ID, 0 /* flags */));
+        final StorageEntry diskStorage2 =
+                new StorageEntry(new DiskInfo("id2", 0 /* flags */));
+        final StorageEntry volumeRecordStorage1 = new StorageEntry(new VolumeRecord(0 /* flags */,
+                VOLUME_RECORD_UUID));
+        final StorageEntry volumeRecordStorage2 = new StorageEntry(new VolumeRecord(0 /* flags */,
+                "id2"));
+
+        assertThat(Objects.equals(volumeStorage1, volumeStorage2)).isFalse();
+        assertThat(Objects.equals(diskStorage1, diskStorage2)).isFalse();
+        assertThat(Objects.equals(volumeRecordStorage1, volumeRecordStorage2)).isFalse();
+    }
+
+    @Test
+    public void compareTo_defaultInternalStorage_shouldBeAtTopMost() {
+        final StorageEntry storage1 = mock(StorageEntry.class);
+        when(storage1.isDefaultInternalStorage()).thenReturn(true);
+        final StorageEntry storage2 = mock(StorageEntry.class);
+        when(storage2.isDefaultInternalStorage()).thenReturn(false);
+
+        assertThat(storage1.compareTo(storage2) > 0).isTrue();
+    }
+
+    @Test
+    public void getDefaultInternalStorageEntry_shouldReturnVolumeInfoStorageOfIdPrivateInternal() {
+        final VolumeInfo volumeInfo = mock(VolumeInfo.class);
+        when(mStorageManager.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL)).thenReturn(volumeInfo);
+
+        assertThat(StorageEntry.getDefaultInternalStorageEntry(mContext))
+                .isEqualTo(new StorageEntry(mContext, volumeInfo));
+    }
+
+    @Test
+    public void isVolumeInfo_shouldReturnTrueForVolumeInfo() {
+        final VolumeInfo volumeInfo = mock(VolumeInfo.class);
+        final StorageEntry storage = new StorageEntry(mContext, volumeInfo);
+
+        assertThat(storage.isVolumeInfo()).isTrue();
+        assertThat(storage.isDiskInfoUnsupported()).isFalse();
+        assertThat(storage.isVolumeRecordMissed()).isFalse();
+    }
+
+    @Test
+    public void isDiskInfoUnsupported_shouldReturnTrueForDiskInfo() {
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry storage = new StorageEntry(diskInfo);
+
+        assertThat(storage.isVolumeInfo()).isFalse();
+        assertThat(storage.isDiskInfoUnsupported()).isTrue();
+        assertThat(storage.isVolumeRecordMissed()).isFalse();
+    }
+
+    @Test
+    public void isVolumeRecordMissed_shouldReturnTrueForVolumeRecord() {
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry storage = new StorageEntry(volumeRecord);
+
+        assertThat(storage.isVolumeInfo()).isFalse();
+        assertThat(storage.isDiskInfoUnsupported()).isFalse();
+        assertThat(storage.isVolumeRecordMissed()).isTrue();
+    }
+
+    @Test
+    public void isMounted_mountedOrMountedReadOnly_shouldReturnTrue() {
+        final VolumeInfo mountedVolumeInfo1 = mock(VolumeInfo.class);
+        final StorageEntry mountedStorage1 = new StorageEntry(mContext, mountedVolumeInfo1);
+        when(mountedVolumeInfo1.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
+        final VolumeInfo mountedVolumeInfo2 = mock(VolumeInfo.class);
+        when(mountedVolumeInfo2.getState()).thenReturn(VolumeInfo.STATE_MOUNTED_READ_ONLY);
+        final StorageEntry mountedStorage2 = new StorageEntry(mContext, mountedVolumeInfo2);
+
+        assertThat(mountedStorage1.isMounted()).isTrue();
+        assertThat(mountedStorage2.isMounted()).isTrue();
+    }
+
+    @Test
+    public void isMounted_nonVolumeInfo_shouldReturnFalse() {
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry diskStorage = new StorageEntry(diskInfo);
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry recordStorage2 = new StorageEntry(volumeRecord);
+
+        assertThat(diskStorage.isMounted()).isFalse();
+        assertThat(recordStorage2.isMounted()).isFalse();
+    }
+
+    @Test
+    public void isUnmountable_unmountableVolume_shouldReturnTrue() {
+        final VolumeInfo unmountableVolumeInfo = mock(VolumeInfo.class);
+        final StorageEntry mountedStorage = new StorageEntry(mContext, unmountableVolumeInfo);
+        when(unmountableVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_UNMOUNTABLE);
+
+        assertThat(mountedStorage.isUnmountable()).isTrue();
+    }
+
+    @Test
+    public void isUnmountable_nonVolumeInfo_shouldReturnFalse() {
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry diskStorage = new StorageEntry(diskInfo);
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry recordStorage2 = new StorageEntry(volumeRecord);
+
+        assertThat(diskStorage.isUnmountable()).isFalse();
+        assertThat(recordStorage2.isUnmountable()).isFalse();
+    }
+
+    @Test
+    public void isPrivate_privateVolume_shouldReturnTrue() {
+        final VolumeInfo privateVolumeInfo = mock(VolumeInfo.class);
+        final StorageEntry privateStorage = new StorageEntry(mContext, privateVolumeInfo);
+        when(privateVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
+
+        assertThat(privateStorage.isPrivate()).isTrue();
+    }
+
+    @Test
+    public void isPrivate_nonVolumeInfo_shouldReturnFalse() {
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry diskStorage = new StorageEntry(diskInfo);
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry recordStorage2 = new StorageEntry(volumeRecord);
+
+        assertThat(diskStorage.isPrivate()).isFalse();
+        assertThat(recordStorage2.isPrivate()).isFalse();
+    }
+
+    @Test
+    public void getDescription_shouldReturnDescription() {
+        final String description = "description";
+        final VolumeInfo volumeInfo = mock(VolumeInfo.class);
+        when(mStorageManager.getBestVolumeDescription(volumeInfo)).thenReturn(description);
+        final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry diskStorage = new StorageEntry(diskInfo);
+        when(diskInfo.getDescription()).thenReturn(description);
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry recordStorage = new StorageEntry(volumeRecord);
+        when(volumeRecord.getNickname()).thenReturn(description);
+
+        assertThat(volumeStorage.getDescription()).isEqualTo(description);
+        assertThat(diskStorage.getDescription()).isEqualTo(description);
+        assertThat(recordStorage.getDescription()).isEqualTo(description);
+    }
+
+    @Test
+    public void getDiskId_shouldReturnDiskId() {
+        final VolumeInfo volumeInfo = mock(VolumeInfo.class);
+        final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
+        when(volumeInfo.getDiskId()).thenReturn(VOLUME_INFO_ID);
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry diskStorage = new StorageEntry(diskInfo);
+        when(diskInfo.getId()).thenReturn(DISK_INFO_ID);
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry recordStorage = new StorageEntry(volumeRecord);
+
+        assertThat(volumeStorage.getDiskId()).isEqualTo(VOLUME_INFO_ID);
+        assertThat(diskStorage.getDiskId()).isEqualTo(DISK_INFO_ID);
+        assertThat(recordStorage.getDiskId()).isEqualTo(null);
+    }
+
+    @Test
+    public void getFsUuid_shouldReturnFsUuid() {
+        final VolumeInfo volumeInfo = mock(VolumeInfo.class);
+        final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
+        when(volumeInfo.getFsUuid()).thenReturn(VOLUME_INFO_ID);
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry diskStorage = new StorageEntry(diskInfo);
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry recordStorage = new StorageEntry(volumeRecord);
+        when(volumeRecord.getFsUuid()).thenReturn(VOLUME_RECORD_UUID);
+
+        assertThat(volumeStorage.getFsUuid()).isEqualTo(VOLUME_INFO_ID);
+        assertThat(diskStorage.getFsUuid()).isEqualTo(null);
+        assertThat(recordStorage.getFsUuid()).isEqualTo(VOLUME_RECORD_UUID);
+    }
+
+    @Test
+    public void getPath_shouldReturnPath() {
+        final File file = new File("fakePath");
+        final VolumeInfo volumeInfo = mock(VolumeInfo.class);
+        final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
+        when(volumeInfo.getPath()).thenReturn(file);
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry diskStorage = new StorageEntry(diskInfo);
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry recordStorage = new StorageEntry(volumeRecord);
+
+        assertThat(volumeStorage.getPath()).isEqualTo(file);
+        assertThat(diskStorage.getPath()).isEqualTo(null);
+        assertThat(recordStorage.getPath()).isEqualTo(null);
+    }
+
+    @Test
+    public void getVolumeInfo_shouldVolumeInfo() {
+        final VolumeInfo volumeInfo = mock(VolumeInfo.class);
+        final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
+        final DiskInfo diskInfo = mock(DiskInfo.class);
+        final StorageEntry diskStorage = new StorageEntry(diskInfo);
+        final VolumeRecord volumeRecord = mock(VolumeRecord.class);
+        final StorageEntry recordStorage = new StorageEntry(volumeRecord);
+
+        assertThat(volumeStorage.getVolumeInfo()).isEqualTo(volumeInfo);
+        assertThat(diskStorage.getVolumeInfo()).isEqualTo(null);
+        assertThat(recordStorage.getVolumeInfo()).isEqualTo(null);
+    }
+}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceControllerTest.java
new file mode 100644
index 0000000..86351cb
--- /dev/null
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageSelectionPreferenceControllerTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.Looper;
+import android.os.storage.StorageManager;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settingslib.widget.SettingsSpinnerPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RunWith(AndroidJUnit4.class)
+public class StorageSelectionPreferenceControllerTest {
+
+    private static final String PREFERENCE_KEY = "preference_key";
+
+    private Context mContext;
+    private StorageManager mStorageManager;
+    private StorageSelectionPreferenceController mController;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = ApplicationProvider.getApplicationContext();
+        mStorageManager = mContext.getSystemService(StorageManager.class);
+        mController = new StorageSelectionPreferenceController(mContext, PREFERENCE_KEY);
+    }
+
+    @Test
+    public void setStorageEntries_fromStorageManager_correctAdapterItems() {
+        final List<StorageEntry> storageEntries = mStorageManager.getVolumes().stream()
+                .map(volumeInfo -> new StorageEntry(mContext, volumeInfo))
+                .collect(Collectors.toList());
+
+        mController.setStorageEntries(storageEntries);
+
+        final int adapterItemCount = mController.mStorageAdapter.getCount();
+        assertThat(adapterItemCount).isEqualTo(storageEntries.size());
+        for (int i = 0; i < adapterItemCount; i++) {
+            assertThat(storageEntries.get(i).getDescription())
+                    .isEqualTo(mController.mStorageAdapter.getItem(i).getDescription());
+        }
+    }
+
+    @Test
+    public void setSelectedStorageEntry_primaryStorage_correctSelectedAdapterItem() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        final PreferenceScreen preferenceScreen =
+                preferenceManager.createPreferenceScreen(mContext);
+        final SettingsSpinnerPreference spinnerPreference = new SettingsSpinnerPreference(mContext);
+        spinnerPreference.setKey(PREFERENCE_KEY);
+        preferenceScreen.addPreference(spinnerPreference);
+        mController.displayPreference(preferenceScreen);
+        final StorageEntry primaryStorageEntry =
+                StorageEntry.getDefaultInternalStorageEntry(mContext);
+        mController.setStorageEntries(mStorageManager.getVolumes().stream()
+                .map(volumeInfo -> new StorageEntry(mContext, volumeInfo))
+                .collect(Collectors.toList()));
+
+        mController.setSelectedStorageEntry(primaryStorageEntry);
+
+        assertThat((StorageEntry) mController.mSpinnerPreference.getSelectedItem())
+                .isEqualTo(primaryStorageEntry);
+    }
+}
+
diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceControllerTest.java
new file mode 100644
index 0000000..6d9155a
--- /dev/null
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceControllerTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo.storage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.usage.StorageStatsManager;
+import android.content.Context;
+import android.os.Looper;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settingslib.widget.UsageProgressBarPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+
+@RunWith(AndroidJUnit4.class)
+public class StorageUsageProgressBarPreferenceControllerTest {
+
+    private static final String FAKE_UUID = "95D9-B3A4";
+    private static final long WAIT_TIMEOUT = 10_000L;
+    private static final long FREE_BYTES = 123L;
+    private static final long TOTAL_BYTES = 456L;
+    private static final long USAGE_BYTES = TOTAL_BYTES - FREE_BYTES;
+
+    private Context mContext;
+    private FakeStorageUsageProgressBarPreferenceController mController;
+    private PreferenceScreen mPreferenceScreen;
+    @Mock
+    private StorageStatsManager mStorageStatsManager;
+
+    @Before
+    public void setUp() throws Exception {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(StorageStatsManager.class)).thenReturn(mStorageStatsManager);
+        mController = new FakeStorageUsageProgressBarPreferenceController(mContext, "key");
+        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        mPreferenceScreen = preferenceManager.createPreferenceScreen(mContext);
+        final UsageProgressBarPreference usageProgressBarPreference =
+                new UsageProgressBarPreference(mContext);
+        usageProgressBarPreference.setKey(mController.getPreferenceKey());
+        mPreferenceScreen.addPreference(usageProgressBarPreference);
+    }
+
+    @Test
+    public void setSelectedStorageEntry_primaryStorage_getPrimaryStorageBytes() throws IOException {
+        final StorageEntry defaultInternalStorageEntry =
+                StorageEntry.getDefaultInternalStorageEntry(mContext);
+        when(mStorageStatsManager.getTotalBytes(defaultInternalStorageEntry.getFsUuid()))
+                .thenReturn(TOTAL_BYTES);
+        when(mStorageStatsManager.getFreeBytes(defaultInternalStorageEntry.getFsUuid()))
+                .thenReturn(FREE_BYTES);
+        mController.displayPreference(mPreferenceScreen);
+
+        synchronized (mController.mLock) {
+            mController.setSelectedStorageEntry(defaultInternalStorageEntry);
+            mController.waitUpdateState(WAIT_TIMEOUT);
+        }
+
+        assertThat(mController.mUsedBytes).isEqualTo(USAGE_BYTES);
+        assertThat(mController.mTotalBytes).isEqualTo(TOTAL_BYTES);
+    }
+
+    private class FakeStorageUsageProgressBarPreferenceController
+            extends StorageUsageProgressBarPreferenceController {
+        private final Object mLock = new Object();
+
+        FakeStorageUsageProgressBarPreferenceController(Context context, String key) {
+            super(context, key);
+        }
+
+        @Override
+        public void updateState(Preference preference) {
+            super.updateState(preference);
+            try {
+                mLock.notifyAll();
+            } catch (IllegalMonitorStateException e) {
+                // Catch it for displayPreference to prevent exception by object not locked by
+                // thread before notify. Do nothing.
+            }
+        }
+
+        public void waitUpdateState(long timeout) {
+            try {
+                mLock.wait(timeout);
+            } catch (InterruptedException e) {
+                // Do nothing.
+            }
+        }
+    }
+}
+
diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java
index 79c5db8..77fd963 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java
@@ -34,8 +34,10 @@
 @RunWith(AndroidJUnit4.class)
 public class VolumeSizesLoaderTest {
     @Test
-    public void getVolumeSize_getsValidSizes() throws Exception {
+    public void getVolumeSize_privateMountedVolume_getsValidSizes() throws Exception {
         VolumeInfo info = mock(VolumeInfo.class);
+        when(info.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
+        when(info.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
         StorageVolumeProvider storageVolumeProvider = mock(StorageVolumeProvider.class);
         when(storageVolumeProvider.getTotalBytes(any(), any())).thenReturn(10000L);
         when(storageVolumeProvider.getFreeBytes(any(), any())).thenReturn(1000L);
@@ -46,4 +48,19 @@
         assertThat(storageInfo.freeBytes).isEqualTo(1000L);
         assertThat(storageInfo.totalBytes).isEqualTo(10000L);
     }
+
+    @Test
+    public void getVolumeSize_unmountedVolume_getsValidSizes() throws Exception {
+        VolumeInfo info = mock(VolumeInfo.class);
+        when(info.getState()).thenReturn(VolumeInfo.STATE_UNMOUNTED);
+        StorageVolumeProvider storageVolumeProvider = mock(StorageVolumeProvider.class);
+        when(storageVolumeProvider.getTotalBytes(any(), any())).thenReturn(10000L);
+        when(storageVolumeProvider.getFreeBytes(any(), any())).thenReturn(1000L);
+
+        PrivateStorageInfo storageInfo =
+                VolumeSizesLoader.getVolumeSize(storageVolumeProvider, null, info);
+
+        assertThat(storageInfo.freeBytes).isEqualTo(0L);
+        assertThat(storageInfo.totalBytes).isEqualTo(0L);
+    }
 }