Create a main switch preference widget.

Based on our ux spec, we create this widget to
let everyone can follow up our spec easily.

Bug: 175181773
Test: Run robotest and apply this widget in Settings and see the ui
Change-Id: I4ea5f38c44aacfeb2c8dbe4a7d31159712f95441
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 23cb36f..3834162 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -43,6 +43,7 @@
         "SettingsLibSearchWidget",
         "SettingsLibSettingsSpinner",
         "SettingsLibLayoutPreference",
+        "SettingsLibMainSwitchPreference",
         "SettingsLibActionButtonsPreference",
         "SettingsLibEntityHeaderWidgets",
         "SettingsLibBarChartPreference",
diff --git a/packages/SettingsLib/MainSwitchPreference/Android.bp b/packages/SettingsLib/MainSwitchPreference/Android.bp
new file mode 100644
index 0000000..1dc18f5
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/Android.bp
@@ -0,0 +1,14 @@
+android_library {
+    name: "SettingsLibMainSwitchPreference",
+
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+
+    static_libs: [
+          "androidx.preference_preference",
+          "SettingsLibRestrictedLockUtils",
+    ],
+
+    sdk_version: "system_current",
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml b/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml
new file mode 100644
index 0000000..96d9e51
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.settingslib.widget">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
new file mode 100644
index 0000000..8a73fb5
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval" >
+
+  <size android:height="24dp" android:width="24dp" />
+  <solid android:color="@color/thumb_off" />
+  <stroke android:width="4dp" android:color="@android:color/transparent" />
+
+</shape>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml
new file mode 100644
index 0000000..8a0af00
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval" >
+
+  <size android:height="24dp" android:width="24dp" />
+  <solid android:color="?android:attr/colorAccent" />
+  <stroke android:width="4dp" android:color="@android:color/transparent" />
+
+</shape>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml
new file mode 100644
index 0000000..8cc9bb3
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:drawable="@drawable/thumb_on" android:state_checked="true" />
+  <item android:drawable="@drawable/thumb_off" android:state_checked="false" />
+</selector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off.xml
new file mode 100644
index 0000000..1be3a8e
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:drawable="@drawable/track_off_background" />
+  <item
+      android:width="13.33dp"
+      android:height="1.67dp"
+      android:left="19dp"
+      android:gravity="center"
+      android:drawable="@drawable/track_off_indicator" />
+</layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
new file mode 100644
index 0000000..3cc490f
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="24dp"
+    android:viewportWidth="48"
+    android:viewportHeight="24">
+
+  <group>
+    <clip-path
+        android:pathData="M12 0H36C42.6274 0 48 5.37258 48 12C48 18.6274 42.6274 24 36 24H12C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0Z" />
+
+    <path
+        android:pathData="M0 0V24H48V0"
+        android:fillColor="@color/track_off" />
+  </group>
+
+</vector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_indicator.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_indicator.xml
new file mode 100644
index 0000000..6cc6224
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_indicator.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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="13.33dp"
+    android:height="1.67dp"
+    android:viewportWidth="13.33"
+    android:viewportHeight="1.67">
+
+  <group>
+    <clip-path
+        android:pathData="M0 0H13.3333V1.66667H0V0Z" />
+
+    <path
+        android:pathData="M0 0V1.66667H13.3333V0"
+        android:fillColor="@android:color/white" />
+  </group>
+
+</vector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on.xml
new file mode 100644
index 0000000..2553891
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:drawable="@drawable/track_on_background" />
+  <item
+      android:width="13.19dp"
+      android:height="10.06dp"
+      android:gravity="center"
+      android:right="19dp"
+      android:drawable="@drawable/track_on_indicator" />
+</layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml
new file mode 100644
index 0000000..02e3a84
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="24dp"
+    android:viewportWidth="48"
+    android:viewportHeight="24">
+
+  <group>
+    <clip-path
+        android:pathData="M12 0H36C42.6274 0 48 5.37258 48 12C48 18.6274 42.6274 24 36 24H12C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0Z" />
+
+    <path
+        android:pathData="M0 0V24H48V0"
+        android:fillColor="@color/track_on" />
+  </group>
+
+</vector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_indicator.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_indicator.xml
new file mode 100644
index 0000000..2281d04
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_indicator.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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="13.19dp"
+    android:height="10.06dp"
+    android:viewportWidth="13.19"
+    android:viewportHeight="10.06">
+
+  <group>
+    <path
+        android:pathData="M4.75012 8.12738L1.62262 4.99988L0.557617 6.05738L4.75012 10.2499L13.7501 1.24988L12.6926 0.192383L4.75012 8.12738Z"
+        android:fillColor="@android:color/white" />
+  </group>
+
+</vector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_selector.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_selector.xml
new file mode 100644
index 0000000..5c699be
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_selector.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:drawable="@drawable/track_on" android:state_checked="true" />
+  <item android:drawable="@drawable/track_off" android:state_checked="false" />
+</selector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
new file mode 100644
index 0000000..66bb2f3
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:background="@android:color/transparent"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/frame"
+        android:minHeight="@dimen/min_switch_bar_height"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:background="@android:color/transparent"
+        android:paddingLeft="@dimen/switchbar_margin_start"
+        android:paddingRight="@dimen/switchbar_margin_end">
+
+        <TextView
+            android:id="@+id/switch_text"
+            android:layout_height="wrap_content"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_gravity="center_vertical"
+            android:maxLines="2"
+            android:ellipsize="end"
+            android:textAppearance="?android:attr/textAppearanceListItem"
+            android:textAlignment="viewStart"
+            style="@style/MainSwitchText" />
+
+        <ImageView
+            android:id="@+id/restricted_icon"
+            android:layout_width="@dimen/restricted_icon_size"
+            android:layout_height="@dimen/restricted_icon_size"
+            android:tint="?android:attr/colorAccent"
+            android:theme="@android:style/Theme.Material"
+            android:layout_gravity="center_vertical"
+            android:layout_marginEnd="@dimen/restricted_icon_margin_end"
+            android:src="@*android:drawable/ic_info"
+            android:visibility="gone" />
+
+        <Switch
+            android:id="@android:id/switch_widget"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:track="@drawable/track_selector"
+            android:thumb="@drawable/thumb_selector"
+            android:theme="@style/Settings.MainSwitch"/>
+    </LinearLayout>
+
+    <View
+        android:id="@+id/below_divider"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="?android:attr/listDivider" />
+</LinearLayout>
+
+
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_layout.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_layout.xml
new file mode 100644
index 0000000..efc047c
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_layout.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent" >
+
+    <com.android.settingslib.widget.MainSwitchBar
+        android:id="@+id/main_switch_bar"
+        android:visibility="gone"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml b/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
new file mode 100644
index 0000000..ecbb84a
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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.
+  -->
+
+<resources>
+
+    <color name="title_text_color">@*android:color/primary_text_dark</color>
+    <color name="thumb_off">#BFFFFFFF</color>
+    <color name="track_on">@*android:color/material_grey_600</color>
+    <color name="track_off">@*android:color/material_grey_600</color>
+
+</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml b/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
new file mode 100644
index 0000000..b401398
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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.
+  -->
+
+<resources>
+
+    <color name="background_color">@android:color/transparent</color>
+    <color name="title_text_color">@*android:color/primary_text_light</color>
+    <color name="thumb_off">#BFFFFFFF</color>
+    <color name="track_on">@*android:color/accent_device_default_dark</color>
+    <color name="track_off">@*android:color/material_grey_600</color>
+
+</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
new file mode 100644
index 0000000..dd443de
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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.
+  -->
+
+<resources>
+
+    <!-- Size of layout margin left -->
+    <dimen name="switchbar_margin_start">26dp</dimen>
+
+    <!-- Size of layout margin right -->
+    <dimen name="switchbar_margin_end">24dp</dimen>
+
+    <!-- Minimum width of switch -->
+    <dimen name="min_switch_width">48dp</dimen>
+
+    <!-- Minimum width of switch bar -->
+    <dimen name="min_switch_bar_height">72dp</dimen>
+
+    <!-- Restricted icon size in switch bar -->
+    <dimen name="restricted_icon_size">@*android:dimen/config_restrictedIconSize</dimen>
+
+    <!-- Restricted icon in switch bar -->
+    <dimen name="restricted_icon_margin_end">16dp</dimen>
+</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
new file mode 100644
index 0000000..fbb896c
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+   Copyright (C) 2020 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.
+  -->
+
+<resources>
+
+    <style name="MainSwitchText">
+        <item name="android:textSize">20sp</item>
+        <item name="android:textColor">@color/title_text_color</item>
+    </style>
+
+    <style name="Settings.MainSwitch" parent="@android:style/Widget.Material.CompoundButton.Switch">
+        <item name="android:switchMinWidth">@dimen/min_switch_width</item>
+    </style>
+
+</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
new file mode 100644
index 0000000..1db64e3
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2020 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.settingslib.widget;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import com.android.settingslib.RestrictedLockUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * MainSwitchBar is a View with a customized Switch.
+ * This component is used as the main switch of the page
+ * to enable or disable the prefereces on the page.
+ */
+public class MainSwitchBar extends LinearLayout implements CompoundButton.OnCheckedChangeListener {
+
+    private final List<OnMainSwitchChangeListener> mSwitchChangeListeners = new ArrayList<>();
+
+    private View mAboveDivider;
+    private View mBelowDivider;
+    private TextView mTextView;
+    private ImageView mRestrictedIcon;
+    private Switch mSwitch;
+
+    private RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
+    private boolean mDisabledByAdmin;
+
+    public MainSwitchBar(Context context) {
+        this(context, null);
+    }
+
+    public MainSwitchBar(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public MainSwitchBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MainSwitchBar(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        LayoutInflater.from(context).inflate(R.layout.main_switch_bar, this);
+
+        setFocusable(true);
+        setClickable(true);
+
+        mTextView = (TextView) findViewById(R.id.switch_text);
+        mSwitch = (Switch) findViewById(android.R.id.switch_widget);
+
+        addOnSwitchChangeListener((switchView, isChecked) -> setChecked(isChecked));
+
+        mRestrictedIcon = findViewById(R.id.restricted_icon);
+        mRestrictedIcon.setOnClickListener((View v) -> {
+            if (mDisabledByAdmin) {
+                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, mEnforcedAdmin);
+                onRestrictedIconClick();
+            }
+        });
+
+        setChecked(mSwitch.isChecked());
+    }
+
+    @Override
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        propagateChecked(isChecked);
+    }
+
+    @Override
+    public boolean performClick() {
+        return getDelegatingView().performClick();
+    }
+
+    /**
+     * Update the switch status
+     */
+    public void setChecked(boolean checked) {
+        if (mSwitch != null) {
+            mSwitch.setChecked(checked);
+        }
+    }
+
+    /**
+     * Set the title text
+     */
+    public void setTitle(String text) {
+        if (mTextView != null) {
+            mTextView.setText(text);
+        }
+    }
+
+    /**
+     * Show the MainSwitchBar
+     */
+    public void show() {
+        if (!isShowing()) {
+            setVisibility(View.VISIBLE);
+            mSwitch.setOnCheckedChangeListener(this);
+        }
+    }
+
+    /**
+     * Hide the MainSwitchBar
+     */
+    public void hide() {
+        if (isShowing()) {
+            setVisibility(View.GONE);
+            mSwitch.setOnCheckedChangeListener(null);
+        }
+    }
+
+    /**
+     * Return the displaying status of MainSwitchBar
+     */
+    public boolean isShowing() {
+        return (getVisibility() == View.VISIBLE);
+    }
+
+    /**
+     * Adds a listener for switch changes
+     */
+    public void addOnSwitchChangeListener(OnMainSwitchChangeListener listener) {
+        if (!mSwitchChangeListeners.contains(listener)) {
+            mSwitchChangeListeners.add(listener);
+        }
+    }
+
+    /**
+     * Remove a listener for switch changes
+     */
+    public void removeOnSwitchChangeListener(OnMainSwitchChangeListener listener) {
+        if (mSwitchChangeListeners.contains(listener)) {
+            mSwitchChangeListeners.remove(listener);
+        }
+    }
+
+    /**
+     * If admin is not null, disables the text and switch but keeps the view clickable.
+     * Otherwise, calls setEnabled which will enables the entire view including
+     * the text and switch.
+     */
+    public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
+        mEnforcedAdmin = admin;
+        if (admin != null) {
+            super.setEnabled(true);
+            mDisabledByAdmin = true;
+            mTextView.setEnabled(false);
+            mSwitch.setEnabled(false);
+            mSwitch.setVisibility(View.GONE);
+            mRestrictedIcon.setVisibility(View.VISIBLE);
+        } else {
+            mDisabledByAdmin = false;
+            mSwitch.setVisibility(View.VISIBLE);
+            mRestrictedIcon.setVisibility(View.GONE);
+            setEnabled(true);
+        }
+    }
+
+    /**
+     * Enable or disable the text and switch.
+     */
+    public void setEnabled(boolean enabled) {
+        if (enabled && mDisabledByAdmin) {
+            setDisabledByAdmin(null);
+            return;
+        }
+        super.setEnabled(enabled);
+        mTextView.setEnabled(enabled);
+        mSwitch.setEnabled(enabled);
+    }
+
+    /**
+     * Called by the restricted icon clicked.
+     */
+    protected void onRestrictedIconClick() {
+    }
+
+    private View getDelegatingView() {
+        return mDisabledByAdmin ? mRestrictedIcon : mSwitch;
+    }
+
+    private void propagateChecked(boolean isChecked) {
+        final int count = mSwitchChangeListeners.size();
+        for (int n = 0; n < count; n++) {
+            mSwitchChangeListeners.get(n).onSwitchChanged(mSwitch, isChecked);
+        }
+    }
+
+    static class SavedState extends BaseSavedState {
+        boolean mChecked;
+        boolean mVisible;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        /**
+         * Constructor called from {@link #CREATOR}
+         */
+        private SavedState(Parcel in) {
+            super(in);
+            mChecked = (Boolean) in.readValue(null);
+            mVisible = (Boolean) in.readValue(null);
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeValue(mChecked);
+            out.writeValue(mVisible);
+        }
+
+        @Override
+        public String toString() {
+            return "MainSwitchBar.SavedState{"
+                    + Integer.toHexString(System.identityHashCode(this))
+                    + " checked=" + mChecked
+                    + " visible=" + mVisible + "}";
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
+
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+
+        SavedState ss = new SavedState(superState);
+        ss.mChecked = mSwitch.isChecked();
+        ss.mVisible = isShowing();
+        return ss;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+
+        super.onRestoreInstanceState(ss.getSuperState());
+
+        mSwitch.setChecked(ss.mChecked);
+        setChecked(ss.mChecked);
+        setVisibility(ss.mVisible ? View.VISIBLE : View.GONE);
+        mSwitch.setOnCheckedChangeListener(ss.mVisible ? this : null);
+
+        requestLayout();
+    }
+}
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
new file mode 100644
index 0000000..dae0e70
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2020 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.settingslib.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Switch;
+
+import androidx.preference.PreferenceViewHolder;
+import androidx.preference.TwoStatePreference;
+
+import com.android.settingslib.RestrictedLockUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * MainSwitchPreference is a Preference with a customized Switch.
+ * This component is used as the main switch of the page
+ * to enable or disable the prefereces on the page.
+ */
+public class MainSwitchPreference extends TwoStatePreference {
+
+    private final List<OnMainSwitchChangeListener> mSwitchChangeListeners = new ArrayList<>();
+
+    private MainSwitchBar mMainSwitchBar;
+    private Switch mSwitch;
+    private String mTitle;
+
+    private RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
+
+    public MainSwitchPreference(Context context) {
+        super(context);
+        init();
+    }
+
+    public MainSwitchPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        holder.setDividerAllowedAbove(true);
+        holder.setDividerAllowedBelow(false);
+
+        mMainSwitchBar = (MainSwitchBar) holder.findViewById(R.id.main_switch_bar);
+        updateStatus(isChecked());
+        registerListenerToSwitchBar();
+    }
+
+    private void init() {
+        setLayoutResource(R.layout.main_switch_layout);
+    }
+
+    /**
+     * Set the preference title text
+     */
+    public void setTitle(String text) {
+        mTitle = text;
+        if (mMainSwitchBar != null) {
+            mMainSwitchBar.setTitle(mTitle);
+        }
+    }
+
+    /**
+     * Update the switch status of preference
+     */
+    public void updateStatus(boolean checked) {
+        setChecked(checked);
+        if (mMainSwitchBar != null) {
+            mMainSwitchBar.setChecked(checked);
+            mMainSwitchBar.setTitle(mTitle);
+            mMainSwitchBar.setDisabledByAdmin(mEnforcedAdmin);
+            mMainSwitchBar.show();
+        }
+    }
+
+    /**
+     * Adds a listener for switch changes
+     */
+    public void addOnSwitchChangeListener(OnMainSwitchChangeListener listener) {
+        if (mMainSwitchBar == null) {
+            mSwitchChangeListeners.add(listener);
+        } else {
+            mMainSwitchBar.addOnSwitchChangeListener(listener);
+        }
+    }
+
+    /**
+     * Remove a listener for switch changes
+     */
+    public void removeOnSwitchChangeListener(OnMainSwitchChangeListener listener) {
+        if (mMainSwitchBar == null) {
+            mSwitchChangeListeners.remove(listener);
+        } else {
+            mMainSwitchBar.removeOnSwitchChangeListener(listener);
+        }
+    }
+
+    /**
+     * If admin is not null, disables the text and switch but keeps the view clickable.
+     * Otherwise, calls setEnabled which will enables the entire view including
+     * the text and switch.
+     */
+    public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
+        mEnforcedAdmin = admin;
+        if (mMainSwitchBar != null) {
+            mMainSwitchBar.setDisabledByAdmin(mEnforcedAdmin);
+        }
+    }
+
+    private void registerListenerToSwitchBar() {
+        for (OnMainSwitchChangeListener listener : mSwitchChangeListeners) {
+            mMainSwitchBar.addOnSwitchChangeListener(listener);
+        }
+        mSwitchChangeListeners.clear();
+    }
+}
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java
new file mode 100644
index 0000000..1c610d9
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 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.settingslib.widget;
+
+import android.widget.Switch;
+
+/**
+ * Called when the checked state of the Switch has changed.
+ */
+public interface OnMainSwitchChangeListener {
+    /**
+     * @param switchView The Switch view whose state has changed.
+     * @param isChecked  The new checked state of switchView.
+     */
+    void onSwitchChanged(Switch switchView, boolean isChecked);
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
new file mode 100644
index 0000000..635e3bd
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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.settingslib.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.preference.PreferenceViewHolder;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class MainSwitchPreferenceTest {
+
+    private Context mContext;
+    private View mRootView;
+    private PreferenceViewHolder mHolder;
+    private MainSwitchPreference mPreference;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mRootView = View.inflate(mContext, R.layout.main_switch_layout, null /* parent */);
+        mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
+        mPreference = new MainSwitchPreference(mContext);
+    }
+
+    @Test
+    public void setTitleText_shouldUpdateTitle() {
+        final String defaultOnText = "Test title";
+
+        mPreference.onBindViewHolder(mHolder);
+        mPreference.setTitle(defaultOnText);
+        mPreference.updateStatus(true /* checked */);
+
+        assertThat(((TextView) mRootView.findViewById(R.id.switch_text)).getText())
+                .isEqualTo(defaultOnText);
+    }
+
+    @Test
+    public void shouldAllowDividerBelow() {
+        mPreference.onBindViewHolder(mHolder);
+
+        View divider = mRootView.findViewById(R.id.below_divider);
+
+        assertThat(divider.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void updateStatus_shouldMatchTheStatus() {
+        mPreference.onBindViewHolder(mHolder);
+        mPreference.updateStatus(true);
+
+        assertThat(mPreference.isChecked()).isTrue();
+    }
+
+}