Merge the 2021-03-05 SPL branch from AOSP-Partner

* security-aosp-pi-release:
  RESTRICT AUTOMERGE Update String
  RESTRICT AUTOMERGE Fix phishing attacks over Bluetooth due to unclear warning message

Change-Id: Ia90455c725f93e7328b81ba84bc804e75a074af2
diff --git a/Android.mk b/Android.mk
index e37e9fb..0be3258 100644
--- a/Android.mk
+++ b/Android.mk
@@ -36,7 +36,8 @@
 LOCAL_JAVA_LIBRARIES := \
     bouncycastle \
     telephony-common \
-    ims-common
+    ims-common \
+    com.fairphone.common
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-arch-lifecycle-runtime \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4456aa0..3f09fc5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -109,6 +109,8 @@
             android:appComponentFactory="android.support.v4.app.CoreComponentFactory">
 
         <uses-library android:name="org.apache.http.legacy" />
+
+        <uses-library android:name="com.fairphone.common" />
         <!-- Settings -->
 
         <activity android:name="Settings"
@@ -1256,6 +1258,21 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="Settings$AppOpsSummaryActivity"
+                android:label="@string/privacy_guard_manager_title"
+                android:taskAffinity=""
+                android:excludeFromRecents="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.settings.APP_OPS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE_LAUNCH" />
+                <category android:name="com.android.settings.SHORTCUT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.applications.appops.AppOpsSummary" />
+        </activity>
+
         <activity android:name="Settings$BackgroundCheckSummaryActivity"
                 android:label="@string/background_check_title"
                 android:enabled="false">
@@ -1267,6 +1284,30 @@
                 android:value="com.android.settings.applications.appops.BackgroundCheckSummary" />
         </activity>
 
+        <!-- Still need a top-level activity for showing app ops details.  Aliasing
+             trick is so the code that is now a fragment can still be called
+             AppOpsDetails. -->
+        <activity android:name=".applications.appops.AppOpsDetailsTop"
+                  android:label="@string/privacy_guard_manager_title"
+                  android:exported="true"
+                  android:taskAffinity=""
+                  android:excludeFromRecents="true"
+                  android:parentActivityName="Settings$AppOpsSummaryActivity">
+        </activity>
+
+        <!-- Keep compatibility with old shortcuts. -->
+        <activity-alias android:name=".applications.appops.AppOpsDetails"
+                android:label="@string/privacy_guard_manager_title"
+                android:exported="true"
+                android:excludeFromRecents="true"
+                android:targetActivity=".applications.appops.AppOpsDetailsTop">
+            <intent-filter>
+                <action android:name="android.settings.APP_OPS_DETAILS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="package" />
+            </intent-filter>
+        </activity-alias>
+
         <activity
             android:name="Settings$LocationSettingsActivity"
             android:label="@string/location_settings_title"
@@ -2878,6 +2919,7 @@
         <activity android:name=".sim.SimDialogActivity"
                 android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar"
                 android:label="@string/sim_settings_title"
+                android:process="com.android.phone"
                 android:excludeFromRecents="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/proguard.flags b/proguard.flags
index 43a038b..74cb791 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -29,6 +29,8 @@
     *** get*();
 }
 
+-keep class com.android.settings.lineageos.*Settings
+
 # Keep classes that may be inflated from XML.
 -keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet);
diff --git a/res/drawable/ic_perm_alarm.xml b/res/drawable/ic_perm_alarm.xml
new file mode 100644
index 0000000..3bb90b8
--- /dev/null
+++ b/res/drawable/ic_perm_alarm.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="24.0dp"
+        android:width="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,20A7,7 0 0,1 5,13A7,7 0 0,1 12,6A7,7 0 0,1 19,13A7,7 0 0,1 12,20M12,4A9,9 0 0,0 3,13A9,9 0 0,0 12,22A9,9 0 0,0 21,13A9,9 0 0,0 12,4M12.5,8H11V14L15.75,16.85L16.5,15.62L12.5,13.25V8M7.88,3.39L6.6,1.86L2,5.71L3.29,7.24L7.88,3.39M22,5.72L17.4,1.86L16.11,3.39L20.71,7.25L22,5.72Z" />
+</vector>
diff --git a/res/drawable/ic_perm_audio.xml b/res/drawable/ic_perm_audio.xml
new file mode 100644
index 0000000..3b9c4d2
--- /dev/null
+++ b/res/drawable/ic_perm_audio.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 12 3 v 9.28 c -0.47 -0.17 -0.97 -0.28 -1.5 -0.28 C 8.01 12 6 14.01 6 16.5 S 8.01 21 10.5 21 c 2.31 0 4.2 -1.75 4.45 -4 H 15 V 6 h 4 V 3 h -7 Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_background.xml b/res/drawable/ic_perm_background.xml
new file mode 100644
index 0000000..8d4ab89
--- /dev/null
+++ b/res/drawable/ic_perm_background.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 9 7 H 7 v 2 h 2 V 7 Z m 0 4 H 7 v 2 h 2 v -2 Z m 0 -8 c -1.11 0 -2 0.9 -2 2 h 2 V 3 Z m 4 12 h -2 v 2 h 2 v -2 Z m 6 -12 v 2 h 2 c 0 -1.1 -0.9 -2 -2 -2 Z m -6 0 h -2 v 2 h 2 V 3 Z M 9 17 v -2 H 7 c 0 1.1 0.89 2 2 2 Z m 10 -4 h 2 v -2 h -2 v 2 Z m 0 -4 h 2 V 7 h -2 v 2 Z m 0 8 c 1.1 0 2 -0.9 2 -2 h -2 v 2 Z M 5 7 H 3 v 12 c 0 1.1 0.89 2 2 2 h 12 v -2 H 5 V 7 Z m 10 -2 h 2 V 3 h -2 v 2 Z m 0 12 h 2 v -2 h -2 v 2 Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_bluetooth.xml b/res/drawable/ic_perm_bluetooth.xml
new file mode 100644
index 0000000..f68ba29
--- /dev/null
+++ b/res/drawable/ic_perm_bluetooth.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M14.88,16.29L13,18.17V14.41M13,5.83L14.88,7.71L13,9.58M17.71,7.71L12,2H11V9.58L6.41,5L5,6.41L10.59,12L5,17.58L6.41,19L11,14.41V22H12L17.71,16.29L13.41,12L17.71,7.71Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_boot.xml b/res/drawable/ic_perm_boot.xml
new file mode 100644
index 0000000..197877a
--- /dev/null
+++ b/res/drawable/ic_perm_boot.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,1C8.14,1 5,4.14 5,8A7,7 0 0,0 12,15C15.86,15 19,11.87 19,8C19,4.14 15.86,1 12,1M12,3.15C14.67,3.15 16.85,5.32 16.85,8C16.85,10.68 14.67,12.85 12,12.85A4.85,4.85 0 0,1 7.15,8A4.85,4.85 0 0,1 12,3.15M11,5V8.69L14.19,10.53L14.94,9.23L12.5,7.82V5M4,16V24H6V21H18V24L22,20L18,16V19H6V16"/>
+</vector>
diff --git a/res/drawable/ic_perm_clipboard.xml b/res/drawable/ic_perm_clipboard.xml
new file mode 100644
index 0000000..d9a3c4b
--- /dev/null
+++ b/res/drawable/ic_perm_clipboard.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M17,9H7V7H17M17,13H7V11H17M14,17H7V15H14M12,3A1,1 0 0,1 13,4A1,1 0 0,1 12,5A1,1 0 0,1 11,4A1,1 0 0,1 12,3M19,3H14.82C14.4,1.84 13.3,1 12,1C10.7,1 9.6,1.84 9.18,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_data.xml b/res/drawable/ic_perm_data.xml
new file mode 100644
index 0000000..d258b49c
--- /dev/null
+++ b/res/drawable/ic_perm_data.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M13,2.05V5.08C16.39,5.57 19,8.47 19,12C19,12.9 18.82,13.75 18.5,14.54L21.12,16.07C21.68,14.83 22,13.45 22,12C22,6.82 18.05,2.55 13,2.05M12,19A7,7 0 0,1 5,12C5,8.47 7.61,5.57 11,5.08V2.05C5.94,2.55 2,6.81 2,12A10,10 0 0,0 12,22C15.3,22 18.23,20.39 20.05,17.91L17.45,16.38C16.17,18 14.21,19 12,19Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_drawontop.xml b/res/drawable/ic_perm_drawontop.xml
new file mode 100644
index 0000000..170de0c
--- /dev/null
+++ b/res/drawable/ic_perm_drawontop.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 3 13 h 2 v -2 H 3 v 2 Z m 0 4 h 2 v -2 H 3 v 2 Z m 2 4 v -2 H 3 c 0 1.1 0.89 2 2 2 Z M 3 9 h 2 V 7 H 3 v 2 Z m 12 12 h 2 v -2 h -2 v 2 Z m 4 -18 H 9 c -1.11 0 -2 0.9 -2 2 v 10 c 0 1.1 0.89 2 2 2 h 10 c 1.1 0 2 -0.9 2 -2 V 5 c 0 -1.1 -0.9 -2 -2 -2 Z m 0 12 H 9 V 5 h 10 v 10 Z m -8 6 h 2 v -2 h -2 v 2 Z m -4 0 h 2 v -2 H 7 v 2 Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_location.xml b/res/drawable/ic_perm_location.xml
new file mode 100644
index 0000000..3cba684
--- /dev/null
+++ b/res/drawable/ic_perm_location.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 12 2 C 8.13 2 5 5.13 5 9 c 0 5.25 7 13 7 13 s 7 -7.75 7 -13 c 0 -3.87 -3.13 -7 -7 -7 Z m 0 9.5 c -1.38 0 -2.5 -1.12 -2.5 -2.5 s 1.12 -2.5 2.5 -2.5 s 2.5 1.12 2.5 2.5 s -1.12 2.5 -2.5 2.5 Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_microphone.xml b/res/drawable/ic_perm_microphone.xml
new file mode 100644
index 0000000..d8063ab
--- /dev/null
+++ b/res/drawable/ic_perm_microphone.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,2A3,3 0 0,1 15,5V11A3,3 0 0,1 12,14A3,3 0 0,1 9,11V5A3,3 0 0,1 12,2M19,11C19,14.53 16.39,17.44 13,17.93V21H11V17.93C7.61,17.44 5,14.53 5,11H7A5,5 0 0,0 12,16A5,5 0 0,0 17,11H19Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_nfc.xml b/res/drawable/ic_perm_nfc.xml
new file mode 100644
index 0000000..bbc1732
--- /dev/null
+++ b/res/drawable/ic_perm_nfc.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M18,6H13A2,2 0 0,0 11,8V10.28C10.41,10.62 10,11.26 10,12A2,2 0 0,0 12,14C13.11,14 14,13.1 14,12C14,11.26 13.6,10.62 13,10.28V8H16V16H8V8H10V6H8L6,6V18H18M20,20H4V4H20M20,2H4A2,2 0 0,0 2,4V20A2,2 0 0,0 4,22H20C21.11,22 22,21.1 22,20V4C22,2.89 21.11,2 20,2Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_nosleep.xml b/res/drawable/ic_perm_nosleep.xml
new file mode 100644
index 0000000..1483f1f
--- /dev/null
+++ b/res/drawable/ic_perm_nosleep.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M2,5.27L3.28,4L20,20.72L18.73,22L12.73,16H9V14L9.79,13.06L2,5.27M23,12H17V10L20.39,6H17V4H23V6L19.62,10H23V12M9.82,8H15V10L13.54,11.72L9.82,8M7,20H1V18L4.39,14H1V12H7V14L3.62,18H7V20Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_notifications.xml b/res/drawable/ic_perm_notifications.xml
new file mode 100644
index 0000000..c6f27cd
--- /dev/null
+++ b/res/drawable/ic_perm_notifications.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.0,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0c0.0,1.0 0.89,2.0 2.0,2.0zm6.0,-6.0l0.0,-5.0c0.0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4.0c0.0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.0,0.67 -1.5,1.5l0.0,0.68C7.63,5.36 6.0,7.92 6.0,11.0l0.0,5.0l-2.0,2.0l0.0,1.0l16.0,0.0l0.0,-1.0l-2.0,-2.0z"/>
+</vector>
diff --git a/res/drawable/ic_perm_settings.xml b/res/drawable/ic_perm_settings.xml
new file mode 100644
index 0000000..7562a76
--- /dev/null
+++ b/res/drawable/ic_perm_settings.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 19.43 12.98 c 0.04 -0.32 0.07 -0.64 0.07 -0.98 s -0.03 -0.66 -0.07 -0.98 l 2.11 -1.65 c 0.19 -0.15 0.24 -0.42 0.12 -0.64 l -2 -3.46 c -0.12 -0.22 -0.39 -0.3 -0.61 -0.22 l -2.49 1 c -0.52 -0.4 -1.08 -0.73 -1.69 -0.98 l -0.38 -2.65 C 14.46 2.18 14.25 2 14 2 h -4 c -0.25 0 -0.46 0.18 -0.49 0.42 l -0.38 2.65 c -0.61 0.25 -1.17 0.59 -1.69 0.98 l -2.49 -1 c -0.23 -0.09 -0.49 0 -0.61 0.22 l -2 3.46 c -0.13 0.22 -0.07 0.49 0.12 0.64 l 2.11 1.65 c -0.04 0.32 -0.07 0.65 -0.07 0.98 s 0.03 0.66 0.07 0.98 l -2.11 1.65 c -0.19 0.15 -0.24 0.42 -0.12 0.64 l 2 3.46 c 0.12 0.22 0.39 0.3 0.61 0.22 l 2.49 -1 c 0.52 0.4 1.08 0.73 1.69 0.98 l 0.38 2.65 c 0.03 0.24 0.24 0.42 0.49 0.42 h 4 c 0.25 0 0.46 -0.18 0.49 -0.42 l 0.38 -2.65 c 0.61 -0.25 1.17 -0.59 1.69 -0.98 l 2.49 1 c 0.23 0.09 0.49 0 0.61 -0.22 l 2 -3.46 c 0.12 -0.22 0.07 -0.49 -0.12 -0.64 l -2.11 -1.65 Z M 12 15.5 c -1.93 0 -3.5 -1.57 -3.5 -3.5 s 1.57 -3.5 3.5 -3.5 s 3.5 1.57 3.5 3.5 s -1.57 3.5 -3.5 3.5 Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_sms.xml b/res/drawable/ic_perm_sms.xml
new file mode 100644
index 0000000..25b6393
--- /dev/null
+++ b/res/drawable/ic_perm_sms.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 20 2 H 4 c -1.1 0 -1.99 0.9 -1.99 2 L 2 22 l 4 -4 h 14 c 1.1 0 2 -0.9 2 -2 V 4 c 0 -1.1 -0.9 -2 -2 -2 Z M 9 11 H 7 V 9 h 2 v 2 Z m 4 0 h -2 V 9 h 2 v 2 Z m 4 0 h -2 V 9 h 2 v 2 Z"/>
+</vector>
diff --git a/res/drawable/ic_perm_su.xml b/res/drawable/ic_perm_su.xml
new file mode 100644
index 0000000..0ae4ef2
--- /dev/null
+++ b/res/drawable/ic_perm_su.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.49,15.934h-2.373L9.24,21H6.966l0.89-5.066H5.051v-2.089h3.163l0.63-3.584H5.977V8.148h3.238 l0.902-5.141h2.261l-0.902,5.141h2.373l0.914-5.141h2.261l-0.902,5.141h2.719v2.113h-3.089l-0.63,3.584h2.78v2.089h-3.139L13.874,21 H11.6L12.49,15.934Z M10.488,13.845h2.36l0.63-3.584h-2.373L10.488,13.845z"/>
+</vector>
diff --git a/res/drawable/ic_perm_turnscreenon.xml b/res/drawable/ic_perm_turnscreenon.xml
new file mode 100644
index 0000000..e68ed6c
--- /dev/null
+++ b/res/drawable/ic_perm_turnscreenon.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2017 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M16,1L8,1C6.34,1 5,2.34 5,4v16c0,1.66 1.34,3 3,3h8c1.66,0 3,-1.34 3,-3L19,4c0,-1.66 -1.34,-3 -3,-3zM14,21h-4v-1h4v1zM17.25,18L6.75,18L6.75,4h10.5v14z"/>
+</vector>
diff --git a/res/drawable/ic_perm_vibrate.xml b/res/drawable/ic_perm_vibrate.xml
new file mode 100644
index 0000000..15dade2
--- /dev/null
+++ b/res/drawable/ic_perm_vibrate.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M0 15h2V9H0v6zm3 2h2V7H3v10zm19-8v6h2V9h-2zm-3 8h2V7h-2v10zM16.5 3h-9C6.67 3 6 3.67 6 4.5v15c0 .83.67 1.5 1.5 1.5h9c.83 0 1.5-.67 1.5-1.5v-15c0-.83-.67-1.5-1.5-1.5zM16 19H8V5h8v14z"/>
+</vector>
diff --git a/res/drawable/ic_perm_vpn.xml b/res/drawable/ic_perm_vpn.xml
new file mode 100644
index 0000000..0050c22
--- /dev/null
+++ b/res/drawable/ic_perm_vpn.xml
@@ -0,0 +1,26 @@
+<!--
+    Copyright (C) 2017 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.65,10C11.7,7.31,8.9,5.5,5.78,6.12C3.49,6.58,1.62,8.41,1.14,10.7C0.32,14.57,3.26,18,7,18c2.61,0,4.83-1.67,5.65-4H16
+v2c0,1.1,0.9,2,2,2h0c1.1,0,2-0.9,2-2v-2h1c1.1,0,2-0.9,2-2v0c0-1.1-0.9-2-2-2H12.65z M7,14c-1.1,0-2-0.9-2-2s0.9-2,2-2s2,0.9,2,2 S8.1,14,7,14z"/>
+</vector>
diff --git a/res/drawable/ic_perm_wifi.xml b/res/drawable/ic_perm_wifi.xml
new file mode 100644
index 0000000..db5b477
--- /dev/null
+++ b/res/drawable/ic_perm_wifi.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="#FF000000">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"/>
+</vector>
diff --git a/res/drawable/ic_settings_maintenance.xml b/res/drawable/ic_settings_maintenance.xml
new file mode 100644
index 0000000..6077079
--- /dev/null
+++ b/res/drawable/ic_settings_maintenance.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2020 Fairphone B.V.
+
+    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="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12.09 2.91C10.08 0.9 7.07 0.49 4.65 1.67L8.28 5.3c0.39 0.39 0.39 1.02 0 1.41L6.69 8.3c-0.39 0.4 -1.02 0.4 -1.41 0L1.65 4.67C0.48 7.1 0.89 10.09 2.9 12.1c1.86 1.86 4.58 2.35 6.89 1.48l7.96 7.96c1.03 1.03 2.69 1.03 3.71 0 1.03 -1.03 1.03 -2.69 0 -3.71L13.54 9.9c0.92 -2.34 0.44 -5.1 -1.45 -6.99z"/>
+</vector>
diff --git a/res/layout/app_ops_summary.xml b/res/layout/app_ops_summary.xml
new file mode 100644
index 0000000..2073a00
--- /dev/null
+++ b/res/layout/app_ops_summary.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <android.support.v4.view.ViewPager
+            android:id="@+id/pager"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1">
+        <android.support.v4.view.PagerTabStrip
+                android:id="@+id/tabs"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="top"
+                android:textAppearance="@style/TextAppearance.PagerTabs"
+                android:paddingLeft="@dimen/pager_tabs_padding"
+                android:paddingRight="@dimen/pager_tabs_padding">
+        </android.support.v4.view.PagerTabStrip>
+    </android.support.v4.view.ViewPager>
+
+</LinearLayout>
diff --git a/res/layout/crypt_keeper_settings.xml b/res/layout/crypt_keeper_settings.xml
index 6b33e00..ad82b8c 100644
--- a/res/layout/crypt_keeper_settings.xml
+++ b/res/layout/crypt_keeper_settings.xml
@@ -30,13 +30,14 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical">
-            <TextView
+            <!-- Encryption is disabled in this version of Fairphone OS. -->
+            <!-- <TextView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="8dip"
                 android:layout_marginBottom="16dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
-                android:text="@string/crypt_keeper_desc" />
+                android:text="@string/crypt_keeper_desc" /> -->
             <TextView
                 android:id="@+id/warning_low_charge"
                 android:layout_width="match_parent"
@@ -55,6 +56,14 @@
                 android:textStyle="bold"
                 android:text="@string/crypt_keeper_unplugged_text"
                 android:visibility="gone" />
+            <TextView
+                android:id="@+id/message_unsupported"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="16dip"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textStyle="bold"
+                android:text="@string/crypt_keeper_unsupported_text" />
         </LinearLayout>
     </ScrollView>
     <Button
diff --git a/res/layout/dialog_hardware_info.xml b/res/layout/dialog_hardware_info.xml
index 7ea4783..fb0b15d 100644
--- a/res/layout/dialog_hardware_info.xml
+++ b/res/layout/dialog_hardware_info.xml
@@ -61,5 +61,65 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
 
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/assembly_number_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/assembly_number" />
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/assembly_number_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/processor_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/processor_info" />
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/processor_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/receiver_module_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/receiver_module_info" />
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/receiver_module_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/camera_module_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/camera_module_info" />
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/camera_module_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <TextView
+            style="@style/device_info_dialog_label"
+            android:id="@+id/battery_module_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/battery_module_info" />
+        <TextView
+            style="@style/device_info_dialog_value"
+            android:id="@+id/battery_module_value"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
     </LinearLayout>
 </ScrollView>
\ No newline at end of file
diff --git a/res/layout/preference_appops.xml b/res/layout/preference_appops.xml
new file mode 100644
index 0000000..db3c867
--- /dev/null
+++ b/res/layout/preference_appops.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2017 The LineageOS 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.
+-->
+
+<!-- Based off packages/apps/Settings/res/layout/preference_material_settings.xml
+     but with different paddings -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:gravity="center_vertical"
+    android:paddingStart="16dp"
+    android:paddingEnd="16dp"
+    android:background="?android:attr/activatedBackgroundIndicator"
+    android:clipToPadding="false">
+
+    <LinearLayout
+        android:id="@id/icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minWidth="56dp"
+        android:gravity="start|center_vertical"
+        android:orientation="horizontal"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp">
+        <com.android.internal.widget.PreferenceImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:maxWidth="48dp"
+            android:maxHeight="48dp" />
+    </LinearLayout>
+
+    <RelativeLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:paddingTop="16dp"
+        android:paddingBottom="16dp">
+
+        <TextView android:id="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:textAppearance="?android:attr/textAppearanceListItem"
+            android:ellipsize="marquee" />
+
+        <TextView android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/title"
+            android:layout_alignStart="@android:id/title"
+            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+            android:textColor="?android:attr/textColorSecondary"
+            android:maxLines="10" />
+
+    </RelativeLayout>
+
+    <!-- Preference should place its actual preference widget here. -->
+    <LinearLayout android:id="@android:id/widget_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="end|center_vertical"
+        android:paddingStart="16dp"
+        android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/res/menu/appops_manager.xml b/res/menu/appops_manager.xml
new file mode 100644
index 0000000..f89b738
--- /dev/null
+++ b/res/menu/appops_manager.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The CyanogenMod 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/show_user_apps"
+          android:title="@string/app_ops_show_user_apps"
+          android:checkable="true" />
+    <item android:id="@+id/show_system_apps"
+          android:title="@string/app_ops_show_system_apps"
+          android:checkable="true" />
+    <item android:id="@+id/reset_counters"
+          android:title="@string/app_ops_reset_counters" />
+</menu>
diff --git a/res/values-de/fairphone_strings.xml b/res/values-de/fairphone_strings.xml
new file mode 100644
index 0000000..e89e5a0
--- /dev/null
+++ b/res/values-de/fairphone_strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018-2021 Fairphone B.V.
+
+     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>
+    <string name="crypt_keeper_unsupported_text">
+    Verschlüsselung ist momentan auf Android 9 auf dem FP2 nicht unterstützt. Um
+    dein Telefon zu verschlüsseln, installiere bitte Android 7, verschlüssele
+    dort und installiere dann das Upgrade auf Android 9.
+    </string>
+    <string name="maintenance_preference_title">"Wartung"</string>
+    <string name="proximity_sensor_title">"Näherungssensor"</string>
+    <string name="hiccup_summary">"Stabilitätsberichte"</string>
+    <string name="fairphone_setting_title">"Erweiterte Hardware-Funktionen"</string>
+    <string name="fairphone_settings_summary">"OpenGL ES 3.0 und hardware-beschleunigte Videowiedergabe aktivieren"</string>
+    <string name="assembly_number">"Fertigungsnummer"</string>
+    <string name="processor_info">"Prozessor"</string>
+    <string name="receiver_module_info">"Top-Modul Info"</string>
+    <string name="receiver_module_ov2685">"Front-Kamera 2MP &#8211; OmniVision OV2685"</string>
+    <string name="receiver_module_ov5670">"Front-Kamera 5MP &#8211; OmniVision OV5670"</string>
+    <string name="camera_module_info">"Camera-Modul Info"</string>
+    <string name="camera_module_ov8865">"Hauptkamera 8MP &#8211; OmniVision OV8865"</string>
+    <string name="camera_module_ov12870">"Hauptkamera 12MP &#8211; OmniVision OV12870"</string>
+    <string name="battery_module_info">"Informationen zum Akku"</string>
+</resources>
diff --git a/res/values-es/fairphone_strings.xml b/res/values-es/fairphone_strings.xml
new file mode 100644
index 0000000..dc9da6c
--- /dev/null
+++ b/res/values-es/fairphone_strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018-2021 Fairphone B.V.
+
+     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>
+    <!-- <string name="crypt_keeper_unsupported_text">TODO</string> -->
+    <string name="maintenance_preference_title">"Mantenimiento"</string>
+    <string name="proximity_sensor_title">"Sensor de proximidad"</string>
+    <string name="hiccup_summary">"Informe de estabilidad"</string>
+    <!-- <string name="fairphone_setting_title">TODO</string> -->
+    <!-- <string name="fairphone_settings_summary">TODO</string> -->
+    <string name="assembly_number">"Número de ensamblaje"</string>
+    <string name="processor_info">"Procesador"</string>
+    <string name="receiver_module_info">"Información del módulo superior"</string>
+    <string name="receiver_module_ov2685">"Cámara frontal 2MP &#8211; OmniVision OV2685"</string>
+    <string name="receiver_module_ov5670">"Cámara frontal 5MP &#8211; OmniVision OV5670"</string>
+    <string name="camera_module_info">"Información del módulo de cámara"</string>
+    <string name="camera_module_ov8865">"Cámara principal &#8211; 8MP OmniVision OV8865"</string>
+    <string name="camera_module_ov12870">"Cámara principal &#8211; 12MP OmniVision OV12870"</string>
+    <string name="battery_module_info">"Información sobre la batería"</string>
+</resources>
diff --git a/res/values-fr/fairphone_strings.xml b/res/values-fr/fairphone_strings.xml
new file mode 100644
index 0000000..79ab54c
--- /dev/null
+++ b/res/values-fr/fairphone_strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018-2021 Fairphone B.V.
+
+     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>
+    <string name="crypt_keeper_unsupported_text">
+    "Le cryptage du téléphone n'est actuellement pas pris en charge sur Android
+    9 sur le FP2. Pour l'instant, pour crypter le téléphone, veuillez installer
+    Android 7, crypter et passer à nouveau à Android 9."
+    </string>
+    <string name="maintenance_preference_title">"Maintenance"</string>
+    <string name="proximity_sensor_title">"Capteur de proximité"</string>
+    <string name="hiccup_summary">"Rapport de stabilité"</string>
+    <string name="fairphone_setting_title">"Fonctionnalités matérielles améliorées"</string>
+    <string name="fairphone_settings_summary">"Activer OpenGL ES 3.0 et l'accélération matérielle pour la lecture vidéo"</string>
+    <string name="assembly_number">"Numéro d'assemblage"</string>
+    <string name="processor_info">"Processeur"</string>
+    <string name="receiver_module_info">"Informations sur le module supérieur"</string>
+    <string name="receiver_module_ov2685">"Caméra frontale 2MP &#8211; OmniVision OV2685"</string>
+    <string name="receiver_module_ov5670">"Caméra frontale 5MP &#8211; OmniVision OV5670"</string>
+    <string name="camera_module_info">"Informations sur le module caméra"</string>
+    <string name="camera_module_ov8865">"Caméra principale 8MP &#8211; OmniVision OV8865"</string>
+    <string name="camera_module_ov12870">"Caméra principale 12MP &#8211; OmniVision OV12870"</string>
+    <string name="battery_module_info">"Informations sur la batterie"</string>
+</resources>
diff --git a/res/values-it/fairphone_strings.xml b/res/values-it/fairphone_strings.xml
new file mode 100644
index 0000000..3f5cd67
--- /dev/null
+++ b/res/values-it/fairphone_strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018-2021 Fairphone B.V.
+
+     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>
+    <!-- <string name="crypt_keeper_unsupported_text">TODO</string> -->
+    <!-- <string name="fairphone_setting_title">TODO</string> -->
+    <!-- <string name="fairphone_settings_summary">TODO</string> -->
+    <string name="assembly_number">"Numero di assemblaggio"</string>
+    <string name="processor_info">"Processore"</string>
+    <string name="receiver_module_info">"Informazioni sul modulo superiore"</string>
+    <string name="receiver_module_ov2685">"Fotocamera frontale 2MP &#8211; OmniVision OV2685"</string>
+    <string name="receiver_module_ov5670">"Fotocamera frontale 5MP &#8211; OmniVision OV5670"</string>
+    <string name="camera_module_info">"Informazioni sul modulo fotocamera"</string>
+    <string name="camera_module_ov8865">"Fotocamera principale 8MP &#8211; OmniVision OV8865"</string>
+    <string name="camera_module_ov12870">"Fotocamera principale 12MP &#8211; OmniVision OV12870"</string>
+    <string name="battery_module_info">"Informazioni sulla batteria"</string>
+</resources>
diff --git a/res/values-nl/fairphone_strings.xml b/res/values-nl/fairphone_strings.xml
new file mode 100644
index 0000000..4b0739b
--- /dev/null
+++ b/res/values-nl/fairphone_strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018-2021 Fairphone B.V.
+
+     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>
+    <!-- <string name="crypt_keeper_unsupported_text">TODO</string> -->
+    <string name="maintenance_preference_title">"Onderhoud"</string>
+    <string name="proximity_sensor_title">"Afstandssensor"</string>
+    <string name="hiccup_summary">"Stabiliteitsrapportage"</string>
+    <!-- <string name="fairphone_setting_title">TODO</string> -->
+    <!-- <string name="fairphone_settings_summary">TODO</string> -->
+    <string name="assembly_number">"Assemblagenummer"</string>
+    <string name="processor_info">"Processor"</string>
+    <string name="receiver_module_info">"Bovenste module info"</string>
+    <string name="receiver_module_ov2685">"Camera voorzijde 2MP &#8211; OmniVision OV2685"</string>
+    <string name="receiver_module_ov5670">"Camera voorzijde 5MP &#8211; OmniVision OV5670"</string>
+    <string name="camera_module_info">"Cameramodule info"</string>
+    <string name="camera_module_ov8865">"Primaire camera 8MP &#8211; OmniVision OV8865"</string>
+    <string name="camera_module_ov12870">"Primaire camera 12MP &#8211; OmniVision OV12870"</string>
+    <string name="battery_module_info">"Batterij info"</string>
+</resources>
diff --git a/res/values/cm_plurals.xml b/res/values/cm_plurals.xml
new file mode 100644
index 0000000..af6e6dd
--- /dev/null
+++ b/res/values/cm_plurals.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013-2014 The CyanogenMod 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <plurals name="app_ops_count">
+        <item quantity="one">once</item>
+        <item quantity="other">%d times</item>
+    </plurals>
+</resources>
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
new file mode 100644
index 0000000..5620cc7
--- /dev/null
+++ b/res/values/cm_strings.xml
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2012-2016 The CyanogenMod Project
+     Copyright (C) 2017 The LineageOS 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- App ops permissions -->
+    <string name="app_ops_permissions_allowed">Allowed</string>
+    <string name="app_ops_permissions_ignored">Ignored</string>
+    <string name="app_ops_permissions_always_ask">Always ask</string>
+
+    <!-- App ops detail -->
+    <string name="app_ops_entry_summary"><xliff:g id="op">%1$s</xliff:g> (used <xliff:g id="count">%2$s</xliff:g>)</string>
+    <string name="app_ops_allowed_count">Allowed <xliff:g id="count" example="2 times">%s</xliff:g></string>
+    <string name="app_ops_ignored_count">Denied <xliff:g id="count" example="2 times">%s</xliff:g></string>
+    <string name="app_ops_both_count">Allowed <xliff:g id="count">%1$s</xliff:g>, denied <xliff:g id="count">%2$s</xliff:g></string>
+    <string name="app_ops_no_blockable_permissions">No permissions available to block</string>
+
+    <!-- App ops menu options -->
+    <string name="app_ops_show_user_apps">Show user apps</string>
+    <string name="app_ops_show_system_apps">Show built-in apps</string>
+    <string name="app_ops_reset_counters">Reset allow/deny counters</string>
+    <string name="app_ops_reset_confirm_title">Confirm counters reset</string>
+    <string name="app_ops_reset_confirm_mesg">Are you sure you wish to reset counters?</string>
+
+    <!-- Memory -->
+    <string name="memory_startup_apps_title">Apps started on boot</string>
+
+    <!-- Names of categories of app ops tabs - extension of AOSP -->
+    <string name="app_ops_categories_location">Location</string>
+    <string name="app_ops_categories_personal">Personal</string>
+    <string name="app_ops_categories_messaging">Messaging</string>
+    <string name="app_ops_categories_media">Media</string>
+    <string name="app_ops_categories_device">Device</string>
+    <string name="app_ops_categories_run_in_background">Run in background</string>
+    <string name="app_ops_categories_bootup">Bootup</string>
+    <string name="app_ops_categories_su">Root access</string>
+    <string name="app_ops_categories_other">Other</string>
+
+    <!-- User display names for app ops codes - extension of AOSP -->
+    <string name="app_ops_summaries_accept_handover">handover of a call from another app</string>
+    <string name="app_ops_summaries_access_camera">access the camera</string>
+    <string name="app_ops_summaries_access_notifications">access notifications</string>
+    <string name="app_ops_summaries_activate_vpn">activate VPN</string>
+    <string name="app_ops_summaries_add_voicemail">add voicemail</string>
+    <string name="app_ops_summaries_app_start_foreground">start instant app in foreground</string>
+    <string name="app_ops_summaries_assist_screenshot">assist screenshot</string>
+    <string name="app_ops_summaries_assist_structure">assist structure</string>
+    <string name="app_ops_summaries_audio_accessibility_volume">audio accessibility volume</string>
+    <string name="app_ops_summaries_auto_start">start at power up</string>
+    <string name="app_ops_summaries_bind_accessibility_service">bind accessibility service</string>
+    <string name="app_ops_summaries_bluetooth_scan">bluetooth scan</string>
+    <string name="app_ops_summaries_change_wallpaper">change the wallpaper</string>
+    <string name="app_ops_summaries_coarse_location">coarse location</string>
+    <string name="app_ops_summaries_delete_call_log">delete your call log</string>
+    <string name="app_ops_summaries_delete_contacts">delete your contacts</string>
+    <string name="app_ops_summaries_delete_mms">delete your MMS messages</string>
+    <string name="app_ops_summaries_delete_sms">delete your SMS messages</string>
+    <string name="app_ops_summaries_draw_on_top">draw on top</string>
+    <string name="app_ops_summaries_fine_location">fine location</string>
+    <string name="app_ops_summaries_get_accounts">get accounts</string>
+    <string name="app_ops_summaries_get_usage_stats">get app usage stats</string>
+    <string name="app_ops_summaries_gps">GPS</string>
+    <string name="app_ops_summaries_install_packages">install packages</string>
+    <string name="app_ops_summaries_keep_device_awake">keep your device awake</string>
+    <string name="app_ops_summaries_make_phone_call">make a phone call</string>
+    <string name="app_ops_summaries_manage_ipsec_tunnels">manage ipsec tunnels</string>
+    <string name="app_ops_summaries_mock_location">mock location</string>
+    <string name="app_ops_summaries_modify_calendar">modify calendar</string>
+    <string name="app_ops_summaries_modify_call_log">modify call log</string>
+    <string name="app_ops_summaries_modify_clipboard">modify clipboard</string>
+    <string name="app_ops_summaries_modify_contacts">modify contacts</string>
+    <string name="app_ops_summaries_modify_settings">modify settings</string>
+    <string name="app_ops_summaries_monitor_high_power_location">monitor high power location</string>
+    <string name="app_ops_summaries_monitor_location">monitor location</string>
+    <string name="app_ops_summaries_mute_unmute_microphone">mute/unmute microphone</string>
+    <string name="app_ops_summaries_neighboring_cells">neighboring cells</string>
+    <string name="app_ops_summaries_phone_calls">answer phone calls</string>
+    <string name="app_ops_summaries_picture_in_picture">use picture in picture</string>
+    <string name="app_ops_summaries_play_audio">play audio</string>
+    <string name="app_ops_summaries_post_notification">post a notification</string>
+    <string name="app_ops_summaries_project_media">project media</string>
+    <string name="app_ops_summaries_read_calendar">read calendar</string>
+    <string name="app_ops_summaries_read_call_log">read call log</string>
+    <string name="app_ops_summaries_read_cell_broadcasts">read cell broadcasts</string>
+    <string name="app_ops_summaries_read_clipboard">read clipboard</string>
+    <string name="app_ops_summaries_read_contacts">read contacts</string>
+    <string name="app_ops_summaries_read_external_storage">read external storage</string>
+    <string name="app_ops_summaries_read_mms">read your MMS messages</string>
+    <string name="app_ops_summaries_read_phone_numbers">read phone numbers</string>
+    <string name="app_ops_summaries_read_phone_state">read phone state</string>
+    <string name="app_ops_summaries_read_sms">read SMS</string>
+    <string name="app_ops_summaries_receive_emergency_broadcast">receive an emergency broadcast message</string>
+    <string name="app_ops_summaries_receive_sms">receive SMS</string>
+    <string name="app_ops_summaries_record_audio">record audio</string>
+    <string name="app_ops_summaries_request_delete_packages">request delete packages</string>
+    <string name="app_ops_summaries_run_any_in_background">run any in background</string>
+    <string name="app_ops_summaries_run_in_background">run in background</string>
+    <string name="app_ops_summaries_scan_wifi">scan Wi-Fi networks</string>
+    <string name="app_ops_summaries_send_mms">send an MMS message</string>
+    <string name="app_ops_summaries_send_sms">send SMS</string>
+    <string name="app_ops_summaries_start_at_bootup">start at power up</string>
+    <string name="app_ops_summaries_start_foreground">start foreground</string>
+    <string name="app_ops_summaries_su">get root access</string>
+    <string name="app_ops_summaries_toast_window">display toasts</string>
+    <string name="app_ops_summaries_toggle_bluetooth">toggle Bluetooth</string>
+    <string name="app_ops_summaries_toggle_mobile_data">toggle cellular data</string>
+    <string name="app_ops_summaries_toggle_nfc">toggle NFC</string>
+    <string name="app_ops_summaries_toggle_wifi">toggle Wi-Fi</string>
+    <string name="app_ops_summaries_turn_on_screen">turn the screen on</string>
+    <string name="app_ops_summaries_use_alarm_volume">control alarm volume</string>
+    <string name="app_ops_summaries_use_audio_focus">control the audio focus</string>
+    <string name="app_ops_summaries_use_bluetooth_volume">control the Bluetooth volume</string>
+    <string name="app_ops_summaries_use_body_sensors">use body sensors</string>
+    <string name="app_ops_summaries_use_fingerprint">use fingerprint</string>
+    <string name="app_ops_summaries_use_master_volume">control the master volume</string>
+    <string name="app_ops_summaries_use_media_buttons">use the media buttons</string>
+    <string name="app_ops_summaries_use_media_volume">control the media volume</string>
+    <string name="app_ops_summaries_use_notification_volume">control the notification volume</string>
+    <string name="app_ops_summaries_use_ring_volume">control the ringtone volume</string>
+    <string name="app_ops_summaries_use_vibrate">use haptic feedback</string>
+    <string name="app_ops_summaries_use_voice_volume">control the voice call volume</string>
+    <string name="app_ops_summaries_wifi_change">change Wi-Fi state</string>
+    <string name="app_ops_summaries_write_external_storage">write to external storage</string>
+    <string name="app_ops_summaries_write_mms">write an MMS message</string>
+    <string name="app_ops_summaries_write_sms">write SMS</string>
+
+    <!-- User display names for app ops codes - extension of AOSP -->
+    <string name="app_ops_labels_accept_handover">Handover of a call from another app</string>
+    <string name="app_ops_labels_access_camera">Access the camera</string>
+    <string name="app_ops_labels_access_notifications">Access notifications</string>
+    <string name="app_ops_labels_activate_vpn">Activate VPN</string>
+    <string name="app_ops_labels_add_voicemail">Add voicemail</string>
+    <string name="app_ops_labels_app_start_foreground">Start instant app in foreground</string>
+    <string name="app_ops_labels_assist_screenshot">Assist screenshot</string>
+    <string name="app_ops_labels_assist_structure">Assist structure</string>
+    <string name="app_ops_labels_audio_accessibility_volume">Audio accessibility volume</string>
+    <string name="app_ops_labels_auto_start">Start at power up</string>
+    <string name="app_ops_labels_bind_accessibility_service">Bind accessibility service</string>
+    <string name="app_ops_labels_bluetooth_scan">Bluetooth scan</string>
+    <string name="app_ops_labels_change_wallpaper">Change the wallpaper</string>
+    <string name="app_ops_labels_coarse_location">Coarse location</string>
+    <string name="app_ops_labels_delete_call_log">Delete your call log</string>
+    <string name="app_ops_labels_delete_contacts">Delete your contacts</string>
+    <string name="app_ops_labels_delete_mms">Delete your MMS messages</string>
+    <string name="app_ops_labels_delete_sms">Delete your SMS messages</string>
+    <string name="app_ops_labels_draw_on_top">Draw on top</string>
+    <string name="app_ops_labels_fine_location">Fine location</string>
+    <string name="app_ops_labels_get_accounts">Get accounts</string>
+    <string name="app_ops_labels_get_usage_stats">Get usage stats</string>
+    <string name="app_ops_labels_gps">GPS</string>
+    <string name="app_ops_labels_install_packages">Install packages</string>
+    <string name="app_ops_labels_keep_device_awake">Keep your device awake</string>
+    <string name="app_ops_labels_make_phone_call">Make a phone call</string>
+    <string name="app_ops_labels_manage_ipsec_tunnels">Manage ipsec tunnels</string>
+    <string name="app_ops_labels_mock_location">Mock location</string>
+    <string name="app_ops_labels_modify_calendar">Modify calendar</string>
+    <string name="app_ops_labels_modify_call_log">Modify call log</string>
+    <string name="app_ops_labels_modify_clipboard">Modify clipboard</string>
+    <string name="app_ops_labels_modify_contacts">Modify contacts</string>
+    <string name="app_ops_labels_modify_settings">Modify settings</string>
+    <string name="app_ops_labels_monitor_high_power_location">Monitor high power location</string>
+    <string name="app_ops_labels_monitor_location">Monitor location</string>
+    <string name="app_ops_labels_mute_unmute_microphone">Mute/unmute microphone</string>
+    <string name="app_ops_labels_neighboring_cells">Neighboring cells</string>
+    <string name="app_ops_labels_phone_calls">Answer phone calls</string>
+    <string name="app_ops_labels_picture_in_picture">Use picture in picture</string>
+    <string name="app_ops_labels_play_audio">Play audio</string>
+    <string name="app_ops_labels_post_notification">Post a notification</string>
+    <string name="app_ops_labels_project_media">Project media</string>
+    <string name="app_ops_labels_read_calendar">Read calendar</string>
+    <string name="app_ops_labels_read_call_log">Read call log</string>
+    <string name="app_ops_labels_read_cell_broadcasts">Read cell broadcasts</string>
+    <string name="app_ops_labels_read_clipboard">Read clipboard</string>
+    <string name="app_ops_labels_read_contacts">Read contacts</string>
+    <string name="app_ops_labels_read_external_storage">Read external storage</string>
+    <string name="app_ops_labels_read_mms">Read your MMS messages</string>
+    <string name="app_ops_labels_read_phone_numbers">Read phone numbers</string>
+    <string name="app_ops_labels_read_phone_state">Read phone state</string>
+    <string name="app_ops_labels_read_sms">Read SMS</string>
+    <string name="app_ops_labels_receive_emergency_broadcast">Receive an emergency broadcast message</string>
+    <string name="app_ops_labels_receive_sms">Receive SMS</string>
+    <string name="app_ops_labels_record_audio">Record audio</string>
+    <string name="app_ops_labels_request_delete_packages">Request delete packages</string>
+    <string name="app_ops_labels_run_any_in_background">Run any in background</string>
+    <string name="app_ops_labels_run_in_background">Run in background</string>
+    <string name="app_ops_labels_scan_wifi">Scan Wi-Fi networks</string>
+    <string name="app_ops_labels_send_mms">Send an MMS message</string>
+    <string name="app_ops_labels_send_sms">Send SMS</string>
+    <string name="app_ops_labels_start_at_bootup">Start at power up</string>
+    <string name="app_ops_labels_start_foreground">Start foreground</string>
+    <string name="app_ops_labels_su">Get root access</string>
+    <string name="app_ops_labels_toast_window">Display toasts</string>
+    <string name="app_ops_labels_toggle_bluetooth">Toggle Bluetooth</string>
+    <string name="app_ops_labels_toggle_mobile_data">Toggle cellular data</string>
+    <string name="app_ops_labels_toggle_nfc">Toggle NFC</string>
+    <string name="app_ops_labels_toggle_wifi">Toggle Wi-Fi</string>
+    <string name="app_ops_labels_turn_on_screen">Turn the screen on</string>
+    <string name="app_ops_labels_use_alarm_volume">Control alarm volume</string>
+    <string name="app_ops_labels_use_audio_focus">Control the audio focus</string>
+    <string name="app_ops_labels_use_bluetooth_volume">Control the Bluetooth volume</string>
+    <string name="app_ops_labels_use_body_sensors">Use body sensors</string>
+    <string name="app_ops_labels_use_fingerprint">Use fingerprint</string>
+    <string name="app_ops_labels_use_master_volume">Control the master volume</string>
+    <string name="app_ops_labels_use_media_buttons">Use the media buttons</string>
+    <string name="app_ops_labels_use_media_volume">Control the media volume</string>
+    <string name="app_ops_labels_use_notification_volume">Control the notification volume</string>
+    <string name="app_ops_labels_use_ring_volume">Control the ringtone volume</string>
+    <string name="app_ops_labels_use_vibrate">Use haptic feedback</string>
+    <string name="app_ops_labels_use_voice_volume">Control the voice call volume</string>
+    <string name="app_ops_labels_wifi_change">Change Wi-Fi state</string>
+    <string name="app_ops_labels_write_external_storage">Write to external storage</string>
+    <string name="app_ops_labels_write_mms">Write an MMS message</string>
+    <string name="app_ops_labels_write_sms">Write SMS</string>
+
+    <!-- Setting checkbox title for root access -->
+    <string name="root_access">Root access</string>
+    <string name="root_access_warning_title">Allow root access?</string>
+    <string name="root_access_warning_message">Allowing apps to request root access is very dangerous and could compromise the security of your system!</string>
+    <string name="root_access_none">Disabled</string>
+    <string name="root_access_apps">Apps only</string>
+    <string name="root_access_adb">ADB only</string>
+    <string name="root_access_all">Apps and ADB</string>
+
+    <!-- Preference link for root appops -->
+    <string name="root_appops_title">Manage root accesses</string>
+    <string name="root_appops_summary">View and control the root rules</string>
+
+</resources>
diff --git a/res/values/fairphone_strings.xml b/res/values/fairphone_strings.xml
new file mode 100644
index 0000000..d5823bf
--- /dev/null
+++ b/res/values/fairphone_strings.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018-2021 Fairphone B.V.
+
+     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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="crypt_keeper_unsupported_text">
+    Encrypting the phone is currently not supported on Android 9 on the FP2. For
+    now, to encrypt the phone please install Android 7, encrypt, and upgrade to
+    Android 9 again.
+    </string>
+
+    <!-- Maintenance settings --> <skip />
+    <!-- Preference title for maintenance settings -->
+    <string name="maintenance_preference_title">Maintenance</string>
+    <!-- Maintenance settings screen, the title for the item to take the user to Checkup. -->
+    <string name="checkup_title" translatable="false">Checkup</string>
+    <!-- Maintenance settings screen, the summary for the item to take the user to Checkup. -->
+    <string name="checkup_summary">Hardware diagnostics</string>
+    <!-- Maintenance settings screen, the title for the item to take the user to the Proximity Sensor app. -->
+    <string name="proximity_sensor_title">Proximity sensor</string>
+    <!-- Maintenance settings screen, the summary for the item to take the user to the Proximity Sensor app. -->
+    <string name="proximity_sensor_summary">Calibrate the proximity sensor</string>
+    <!-- Maintenance settings screen, the title for the item to take the user to the Hiccup settings. -->
+    <string name="hiccup_title" translatable="false">Hiccup</string>
+    <!-- Maintenance settings screen, the summary for the item to take the user to the Hiccup settings. -->
+    <string name="hiccup_summary">Stability reporting</string>
+    <!-- Maintenance settings screen, the title for the item to take the user to the OpenGL ES settings. -->
+    <string name="fairphone_setting_title">Enhanced hardware features</string>
+    <!-- Maintenance settings screen, the summary for the item to take the user to the OpenGL ES settings. -->
+    <string name="fairphone_settings_summary">Enable OpenGL ES 3.0 and hardware video playback</string>
+
+    <!-- About --> <skip />
+    <!-- About phone, status item label.  The hardware assembly number (set at the factory). -->
+    <string name="assembly_number">Assembly number</string>
+    <!-- About phone, status item label.  The device's processor. -->
+    <string name="processor_info">Processor</string>
+    <!-- About phone, status item label.  The installed receiver module. -->
+    <string name="receiver_module_info">Top module info</string>
+    <!-- About phone, status item value.  Original receiver module with OV2685 sensor. -->
+    <string name="receiver_module_ov2685">Front camera 2MP &#8211; OmniVision OV2685</string>
+    <!-- About phone, status item value.  2017 receiver module with OV5670 sensor. -->
+    <string name="receiver_module_ov5670">Front camera 5MP &#8211; OmniVision OV5670</string>
+    <!-- About phone, status item label.  The installed camera module. -->
+    <string name="camera_module_info">Camera module info</string>
+    <!-- About phone, status item value.  Original camera module with OV8865 sensor. -->
+    <string name="camera_module_ov8865">Main camera 8MP &#8211; OmniVision OV8865</string>
+    <!-- About phone, status item value.  2017 camera module with OV12870 sensor. -->
+    <string name="camera_module_ov12870">Main camera 12MP &#8211; OmniVision OV12870</string>
+    <!-- About phone, status item label.  The installed battery module. -->
+    <string name="battery_module_info">Battery info</string>
+    <!-- About phone, status item value.  Battery module info. -->
+    <string name="battery_module_summary" translatable="false"><xliff:g id="version"
+            example="FP2-BAT01">%1$s</xliff:g> &#8211; <xliff:g id="capacity"
+            example="2420">%2$d</xliff:g> mAh</string>
+</resources>
diff --git a/res/values/lineage_arrays.xml b/res/values/lineage_arrays.xml
new file mode 100644
index 0000000..9377953
--- /dev/null
+++ b/res/values/lineage_arrays.xml
@@ -0,0 +1,403 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2012-2015 The CyanogenMod Project
+     Copyright (C) 2018 The LinegeOS 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>
+    <!-- Arrays for root access capability -->
+    <string-array name="root_access_entries" translatable="false">
+        <item>@string/root_access_none</item>
+        <item>@string/root_access_apps</item>
+        <item>@string/root_access_adb</item>
+        <item>@string/root_access_all</item>
+    </string-array>
+
+    <string-array name="root_access_values" translatable="false">
+        <item>0</item>
+        <item>1</item>
+        <item>2</item>
+        <item>3</item>
+    </string-array>
+
+    <string-array name="root_access_entries_adb" translatable="false">
+        <item>@string/root_access_none</item>
+        <item>@string/root_access_adb</item>
+    </string-array>
+
+    <string-array name="root_access_values_adb" translatable="false">
+        <item>0</item>
+        <item>2</item>
+    </string-array>
+
+    <!-- Names of categories of app ops tabs - extension of AOSP -->
+    <string-array name="app_ops_categories_lineage" translatable="false">
+        <item>@string/app_ops_categories_location</item>
+        <item>@string/app_ops_categories_personal</item>
+        <item>@string/app_ops_categories_messaging</item>
+        <item>@string/app_ops_categories_media</item>
+        <item>@string/app_ops_categories_device</item>
+        <item>@string/app_ops_categories_run_in_background</item>
+        <item>@string/app_ops_categories_bootup</item>
+        <item>@string/app_ops_categories_su</item>
+        <item>@string/app_ops_categories_other</item>
+    </string-array>
+
+    <!-- User display names for app ops codes - extension of AOSP -->
+    <string-array name="app_ops_summaries_lineage" translatable="false">
+        <!-- OP_COARSE_LOCATION -->
+        <item>@string/app_ops_summaries_coarse_location</item>
+        <!-- OP_FINE_LOCATION -->
+        <item>@string/app_ops_summaries_fine_location</item>
+        <!-- OP_GPS -->
+        <item>@string/app_ops_summaries_gps</item>
+        <!-- OP_VIBRATE -->
+        <item>@string/app_ops_summaries_use_vibrate</item>
+        <!-- OP_READ_CONTACTS -->
+        <item>@string/app_ops_summaries_read_contacts</item>
+        <!-- OP_WRITE_CONTACTS -->
+        <item>@string/app_ops_summaries_modify_contacts</item>
+        <!-- OP_READ_CALL_LOG -->
+        <item>@string/app_ops_summaries_read_call_log</item>
+        <!-- OP_WRITE_CALL_LOG -->
+        <item>@string/app_ops_summaries_modify_call_log</item>
+        <!-- OP_READ_CALENDAR -->
+        <item>@string/app_ops_summaries_read_calendar</item>
+        <!-- OP_WRITE_CALENDAR -->
+        <item>@string/app_ops_summaries_modify_calendar</item>
+        <!-- OP_WIFI_SCAN -->
+        <item>@string/app_ops_summaries_scan_wifi</item>
+        <!-- OP_POST_NOTIFICATION -->
+        <item>@string/app_ops_summaries_post_notification</item>
+        <!-- OP_NEIGHBORING_CELLS -->
+        <item>@string/app_ops_summaries_neighboring_cells</item>
+        <!-- OP_CALL_PHONE -->
+        <item>@string/app_ops_summaries_make_phone_call</item>
+        <!-- OP_READ_SMS -->
+        <item>@string/app_ops_summaries_read_sms</item>
+        <!-- OP_WRITE_SMS -->
+        <item>@string/app_ops_summaries_write_sms</item>
+        <!-- OP_RECEIVE_SMS -->
+        <item>@string/app_ops_summaries_receive_sms</item>
+        <!-- OPSTR_RECEIVE_EMERGENCY_BROADCAST -->
+        <item>@string/app_ops_summaries_receive_emergency_broadcast</item>
+        <!-- OP_RECEIVE_MMS -->
+        <item>@string/app_ops_summaries_receive_sms</item>
+        <!-- OP_RECEIVE_WAP_PUSH -->
+        <item>@string/app_ops_summaries_receive_sms</item>
+        <!-- OP_SEND_SMS -->
+        <item>@string/app_ops_summaries_send_sms</item>
+        <!-- OP_READ_ICC_SMS -->
+        <item>@string/app_ops_summaries_read_sms</item>
+        <!-- OP_WRITE_ICC_SMS -->
+        <item>@string/app_ops_summaries_write_sms</item>
+        <!-- OP_WRITE_SETTINGS -->
+        <item>@string/app_ops_summaries_modify_settings</item>
+        <!-- OP_SYSTEM_ALERT_WINDOW -->
+        <item>@string/app_ops_summaries_draw_on_top</item>
+        <!-- OP_ACCESS_NOTIFICATIONS -->
+        <item>@string/app_ops_summaries_access_notifications</item>
+        <!-- OP_CAMERA -->
+        <item>@string/app_ops_summaries_access_camera</item>
+        <!-- OP_RECORD_AUDIO -->
+        <item>@string/app_ops_summaries_record_audio</item>
+        <!-- OP_PLAY_AUDIO -->
+        <item>@string/app_ops_summaries_play_audio</item>
+        <!-- OP_READ_CLIPBOARD -->
+        <item>@string/app_ops_summaries_read_clipboard</item>
+        <!-- OP_WRITE_CLIPBOARD -->
+        <item>@string/app_ops_summaries_modify_clipboard</item>
+        <!-- OP_TAKE_MEDIA_BUTTONS -->
+        <item>@string/app_ops_summaries_use_media_buttons</item>
+        <!-- OP_TAKE_AUDIO_FOCUS -->
+        <item>@string/app_ops_summaries_use_audio_focus</item>
+        <!-- OP_AUDIO_MASTER_VOLUME -->
+        <item>@string/app_ops_summaries_use_master_volume</item>
+        <!-- OP_AUDIO_VOICE_VOLUME -->
+        <item>@string/app_ops_summaries_use_voice_volume</item>
+        <!-- OP_AUDIO_RING_VOLUME -->
+        <item>@string/app_ops_summaries_use_ring_volume</item>
+        <!-- OP_AUDIO_MEDIA_VOLUME -->
+        <item>@string/app_ops_summaries_use_media_volume</item>
+        <!-- OP_AUDIO_ALARM_VOLUME -->
+        <item>@string/app_ops_summaries_use_alarm_volume</item>
+        <!-- OP_AUDIO_NOTIFICATION_VOLUME -->
+        <item>@string/app_ops_summaries_use_notification_volume</item>
+        <!-- OP_AUDIO_BLUETOOTH_VOLUME -->
+        <item>@string/app_ops_summaries_use_bluetooth_volume</item>
+        <!-- OP_WAKE_LOCK -->
+        <item>@string/app_ops_summaries_keep_device_awake</item>
+        <!-- OP_MONITOR_LOCATION -->
+        <item>@string/app_ops_summaries_monitor_location</item>
+        <!-- OP_MONITOR_HIGH_POWER_LOCATION -->
+        <item>@string/app_ops_summaries_monitor_high_power_location</item>
+        <!-- OP_GET_USAGE_STATS -->
+        <item>@string/app_ops_summaries_get_usage_stats</item>
+        <!-- OP_MUTE_MICROPHONE -->
+        <item>@string/app_ops_summaries_mute_unmute_microphone</item>
+        <!-- OP_TOAST_WINDOW -->
+        <item>@string/app_ops_summaries_toast_window</item>
+        <!-- OP_PROJECT_MEDIA -->
+        <item>@string/app_ops_summaries_project_media</item>
+        <!-- OP_ACTIVATE_VPN -->
+        <item>@string/app_ops_summaries_activate_vpn</item>
+        <!-- OP_WRITE_WALLPAPER -->
+        <item>@string/app_ops_summaries_change_wallpaper</item>
+        <!-- OP_ASSIST_STRUCTURE -->
+        <item>@string/app_ops_summaries_assist_structure</item>
+        <!-- OP_ASSIST_SCREENSHOT -->
+        <item>@string/app_ops_summaries_assist_screenshot</item>
+        <!-- OP_READ_PHONE_STATE -->
+        <item>@string/app_ops_summaries_read_phone_state</item>
+        <!-- OP_ADD_VOICEMAIL -->
+        <item>@string/app_ops_summaries_add_voicemail</item>
+        <!-- OP_USE_SIP -->
+        <item>@string/app_ops_summaries_make_phone_call</item>
+        <!-- OP_PROCESS_OUTGOING_CALLS -->
+        <item>@string/app_ops_summaries_make_phone_call</item>
+        <!-- OP_USE_FINGERPRINT -->
+        <item>@string/app_ops_summaries_use_fingerprint</item>
+        <!-- OP_BODY_SENSORS -->
+        <item>@string/app_ops_summaries_use_body_sensors</item>
+        <!-- OP_READ_CELL_BROADCASTS -->
+        <item>@string/app_ops_summaries_read_cell_broadcasts</item>
+        <!-- OP_MOCK_LOCATION -->
+        <item>@string/app_ops_summaries_mock_location</item>
+        <!-- OP_READ_EXTERNAL_STORAGE -->
+        <item>@string/app_ops_summaries_read_external_storage</item>
+        <!-- OP_WRITE_EXTERNAL_STORAGE -->
+        <item>@string/app_ops_summaries_write_external_storage</item>
+        <!-- OP_TURN_SCREEN_ON -->
+        <item>@string/app_ops_summaries_turn_on_screen</item>
+        <!-- OP_GET_ACCOUNTS -->
+        <item>@string/app_ops_summaries_get_accounts</item>
+        <!-- OP_RUN_IN_BACKGROUND -->
+        <item>@string/app_ops_summaries_run_in_background</item>
+        <!-- OP_AUDIO_ACCESSIBILITY_VOLUME -->
+        <item>@string/app_ops_summaries_audio_accessibility_volume</item>
+        <!-- OP_READ_PHONE_NUMBERS -->
+        <item>@string/app_ops_summaries_read_phone_numbers</item>
+        <!-- OP_REQUEST_INSTALL_PACKAGES -->
+        <item>@string/app_ops_summaries_install_packages</item>
+        <!-- OP_PICTURE_IN_PICTURE -->
+        <item>@string/app_ops_summaries_picture_in_picture</item>
+        <!-- OP_INSTANT_APP_START_FOREGROUND -->
+        <item>@string/app_ops_summaries_app_start_foreground</item>
+        <!-- OP_ANSWER_PHONE_CALLS -->
+        <item>@string/app_ops_summaries_phone_calls</item>
+        <!-- OP_RUN_ANY_IN_BACKGROUND -->
+        <item>@string/app_ops_summaries_run_any_in_background</item>
+        <!-- OP_CHANGE_WIFI_STATE -->
+        <item>@string/app_ops_summaries_wifi_change</item>
+        <!-- OP_REQUEST_DELETE_PACKAGES -->
+        <item>@string/app_ops_summaries_request_delete_packages</item>
+        <!-- OP_BIND_ACCESSIBILITY_SERVICE -->
+        <item>@string/app_ops_summaries_bind_accessibility_service</item>
+        <!-- OP_ACCEPT_HANDOVER -->
+        <item>@string/app_ops_summaries_accept_handover</item>
+        <!-- OP_MANAGE_IPSEC_TUNNELS -->
+        <item>@string/app_ops_summaries_manage_ipsec_tunnels</item>
+        <!-- OP_START_FOREGROUND -->
+        <item>@string/app_ops_summaries_start_foreground</item>
+        <!-- OP_BLUETOOTH_SCAN -->
+        <item>@string/app_ops_summaries_bluetooth_scan</item>
+        <!-- OP_BLUETOOTH_CHANGE -->
+        <item>@string/app_ops_summaries_toggle_bluetooth</item>
+        <!-- OP_BOOT_COMPLETED -->
+        <item>@string/app_ops_summaries_start_at_bootup</item>
+        <!-- OP_NFC_CHANGE -->
+        <item>@string/app_ops_summaries_toggle_nfc</item>
+        <!-- OP_DATA_CONNECT_CHANGE -->
+        <item>@string/app_ops_summaries_toggle_mobile_data</item>
+        <!-- OP_SU -->
+        <item>@string/app_ops_summaries_su</item>
+    </string-array>
+
+    <!-- User display names for app ops codes - extension of AOSP -->
+    <string-array name="app_ops_labels_lineage" translatable="false">
+        <!-- OP_COARSE_LOCATION -->
+        <item>@string/app_ops_labels_coarse_location</item>
+        <!-- OP_FINE_LOCATION -->
+        <item>@string/app_ops_labels_fine_location</item>
+        <!-- OP_GPS -->
+        <item>@string/app_ops_labels_gps</item>
+        <!-- OP_VIBRATE -->
+        <item>@string/app_ops_labels_use_vibrate</item>
+        <!-- OP_READ_CONTACTS -->
+        <item>@string/app_ops_labels_read_contacts</item>
+        <!-- OP_WRITE_CONTACTS -->
+        <item>@string/app_ops_labels_modify_contacts</item>
+        <!-- OP_READ_CALL_LOG -->
+        <item>@string/app_ops_labels_read_call_log</item>
+        <!-- OP_WRITE_CALL_LOG -->
+        <item>@string/app_ops_labels_modify_call_log</item>
+        <!-- OP_READ_CALENDAR -->
+        <item>@string/app_ops_labels_read_calendar</item>
+        <!-- OP_WRITE_CALENDAR -->
+        <item>@string/app_ops_labels_modify_calendar</item>
+        <!-- OP_WIFI_SCAN -->
+        <item>@string/app_ops_labels_scan_wifi</item>
+        <!-- OP_POST_NOTIFICATION -->
+        <item>@string/app_ops_labels_post_notification</item>
+        <!-- OP_NEIGHBORING_CELLS -->
+        <item>@string/app_ops_labels_neighboring_cells</item>
+        <!-- OP_CALL_PHONE -->
+        <item>@string/app_ops_labels_make_phone_call</item>
+        <!-- OP_READ_SMS -->
+        <item>@string/app_ops_labels_read_sms</item>
+        <!-- OP_WRITE_SMS -->
+        <item>@string/app_ops_labels_write_sms</item>
+        '<!-- OP_RECEIVE_SMS -->
+        <item>@string/app_ops_labels_receive_sms</item>
+        <!-- OPSTR_RECEIVE_EMERGENCY_BROADCAST -->
+        <item>@string/app_ops_labels_receive_emergency_broadcast</item>
+        <!-- OP_RECEIVE_MMS -->
+        <item>@string/app_ops_labels_receive_sms</item>
+        <!-- OP_RECEIVE_WAP_PUSH -->
+        <item>@string/app_ops_labels_receive_sms</item>
+        <!-- OP_SEND_SMS -->
+        <item>@string/app_ops_labels_send_sms</item>
+        <!-- OP_READ_ICC_SMS -->
+        <item>@string/app_ops_labels_read_sms</item>
+        <!-- OP_WRITE_ICC_SMS -->
+        <item>@string/app_ops_labels_write_sms</item>
+        <!-- OP_WRITE_SETTINGS -->
+        <item>@string/app_ops_labels_modify_settings</item>
+        <!-- OP_SYSTEM_ALERT_WINDOW -->
+        <item>@string/app_ops_labels_draw_on_top</item>
+        <!-- OP_ACCESS_NOTIFICATIONS -->
+        <item>@string/app_ops_labels_access_notifications</item>
+        <!-- OP_CAMERA -->
+        <item>@string/app_ops_labels_access_camera</item>
+        <!-- OP_RECORD_AUDIO -->
+        <item>@string/app_ops_labels_record_audio</item>
+        <!-- OP_PLAY_AUDIO -->
+        <item>@string/app_ops_labels_play_audio</item>
+        <!-- OP_READ_CLIPBOARD -->
+        <item>@string/app_ops_labels_read_clipboard</item>
+        <!-- OP_WRITE_CLIPBOARD -->
+        <item>@string/app_ops_labels_modify_clipboard</item>
+        <!-- OP_TAKE_MEDIA_BUTTONS -->
+        <item>@string/app_ops_labels_use_media_buttons</item>
+        <!-- OP_TAKE_AUDIO_FOCUS -->
+        <item>@string/app_ops_labels_use_audio_focus</item>
+        <!-- OP_AUDIO_MASTER_VOLUME -->
+        <item>@string/app_ops_labels_use_master_volume</item>
+        <!-- OP_AUDIO_VOICE_VOLUME -->
+        <item>@string/app_ops_labels_use_voice_volume</item>
+        <!-- OP_AUDIO_RING_VOLUME -->
+        <item>@string/app_ops_labels_use_ring_volume</item>
+        <!-- OP_AUDIO_MEDIA_VOLUME -->
+        <item>@string/app_ops_labels_use_media_volume</item>
+        <!-- OP_AUDIO_ALARM_VOLUME -->
+        <item>@string/app_ops_labels_use_alarm_volume</item>
+        <!-- OP_AUDIO_NOTIFICATION_VOLUME -->
+        <item>@string/app_ops_labels_use_notification_volume</item>
+        <!-- OP_AUDIO_BLUETOOTH_VOLUME -->
+        <item>@string/app_ops_labels_use_bluetooth_volume</item>
+        <!-- OP_WAKE_LOCK -->
+        <item>@string/app_ops_labels_keep_device_awake</item>
+        <!-- OP_MONITOR_LOCATION -->
+        <item>@string/app_ops_labels_monitor_location</item>
+        <!-- OP_MONITOR_HIGH_POWER_LOCATION -->
+        <item>@string/app_ops_labels_monitor_high_power_location</item>
+        <!-- OP_GET_USAGE_STATS -->
+        <item>@string/app_ops_labels_get_usage_stats</item>
+        <!-- OP_MUTE_MICROPHONE -->
+        <item>@string/app_ops_labels_mute_unmute_microphone</item>
+        <!-- OP_TOAST_WINDOW -->
+        <item>@string/app_ops_labels_toast_window</item>
+        <!-- OP_PROJECT_MEDIA -->
+        <item>@string/app_ops_labels_project_media</item>
+        <!-- OP_ACTIVATE_VPN -->
+        <item>@string/app_ops_labels_activate_vpn</item>
+        <!-- OP_WRITE_WALLPAPER -->
+        <item>@string/app_ops_labels_change_wallpaper</item>
+        <!-- OP_ASSIST_STRUCTURE -->
+        <item>@string/app_ops_labels_assist_structure</item>
+        <!-- OP_ASSIST_SCREENSHOT -->
+        <item>@string/app_ops_labels_assist_screenshot</item>
+        <!-- OP_READ_PHONE_STATE -->
+        <item>@string/app_ops_labels_read_phone_state</item>
+        <!-- OP_ADD_VOICEMAIL -->
+        <item>@string/app_ops_labels_add_voicemail</item>
+        <!-- OP_USE_SIP -->
+        <item>@string/app_ops_labels_make_phone_call</item>
+        <!-- OP_PROCESS_OUTGOING_CALLS -->
+        <item>@string/app_ops_labels_make_phone_call</item>
+        <!-- OP_USE_FINGERPRINT -->
+        <item>@string/app_ops_labels_use_fingerprint</item>
+        <!-- OP_BODY_SENSORS -->
+        <item>@string/app_ops_labels_use_body_sensors</item>
+        <!-- OP_READ_CELL_BROADCASTS -->
+        <item>@string/app_ops_labels_read_cell_broadcasts</item>
+        <!-- OP_MOCK_LOCATION -->
+        <item>@string/app_ops_labels_mock_location</item>
+        <!-- OP_READ_EXTERNAL_STORAGE -->
+        <item>@string/app_ops_labels_read_external_storage</item>
+        <!-- OP_WRITE_EXTERNAL_STORAGE -->
+        <item>@string/app_ops_labels_write_external_storage</item>
+        <!-- OP_TURN_SCREEN_ON -->
+        <item>@string/app_ops_labels_turn_on_screen</item>
+        <!-- OP_GET_ACCOUNTS -->
+        <item>@string/app_ops_labels_get_accounts</item>
+        <!-- OP_RUN_IN_BACKGROUND -->
+        <item>@string/app_ops_labels_run_in_background</item>
+        <!-- OP_AUDIO_ACCESSIBILITY_VOLUME -->
+        <item>@string/app_ops_labels_audio_accessibility_volume</item>
+        <!-- OP_READ_PHONE_NUMBERS -->
+        <item>@string/app_ops_labels_read_phone_numbers</item>
+        <!-- OP_REQUEST_INSTALL_PACKAGES -->
+        <item>@string/app_ops_labels_install_packages</item>
+        <!-- OP_PICTURE_IN_PICTURE -->
+        <item>@string/app_ops_labels_picture_in_picture</item>
+        <!-- OP_INSTANT_APP_START_FOREGROUND -->
+        <item>@string/app_ops_labels_app_start_foreground</item>
+        <!-- OP_ANSWER_PHONE_CALLS -->
+        <item>@string/app_ops_labels_phone_calls</item>
+        <!-- OP_RUN_ANY_IN_BACKGROUND -->
+        <item>@string/app_ops_labels_run_any_in_background</item>
+        <!-- OP_CHANGE_WIFI_STATE -->
+        <item>@string/app_ops_labels_wifi_change</item>
+        <!-- OP_REQUEST_DELETE_PACKAGES -->
+        <item>@string/app_ops_labels_request_delete_packages</item>
+        <!-- OP_BIND_ACCESSIBILITY_SERVICE -->
+        <item>@string/app_ops_labels_bind_accessibility_service</item>
+        <!-- OP_ACCEPT_HANDOVER -->
+        <item>@string/app_ops_labels_accept_handover</item>
+        <!-- OP_MANAGE_IPSEC_TUNNELS -->
+        <item>@string/app_ops_labels_manage_ipsec_tunnels</item>
+        <!-- OP_START_FOREGROUND -->
+        <item>@string/app_ops_labels_start_foreground</item>
+        <!-- OP_BLUETOOTH_SCAN -->
+        <item>@string/app_ops_labels_bluetooth_scan</item>
+        <!-- OP_BLUETOOTH_CHANGE -->
+        <item>@string/app_ops_labels_toggle_bluetooth</item>
+        <!-- OP_BOOT_COMPLETED -->
+        <item>@string/app_ops_labels_start_at_bootup</item>
+        <!-- OP_NFC_CHANGE -->
+        <item>@string/app_ops_labels_toggle_nfc</item>
+        <!-- OP_DATA_CONNECT_CHANGE -->
+        <item>@string/app_ops_labels_toggle_mobile_data</item>
+        <!-- OP_SU -->
+        <item>@string/app_ops_labels_su</item>
+    </string-array>
+
+    <!-- App ops permissions -->
+    <string-array name="app_ops_permissions">
+        <item>@string/app_ops_permissions_allowed</item>
+        <item>@string/app_ops_permissions_ignored</item>
+        <item>@string/app_ops_permissions_always_ask</item>
+    </string-array>
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index cc6d65c..56acccf 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10093,4 +10093,7 @@
     <string name="bluetooth_phonebook_access_dialog_title">Allow access to contacts and call log?</string>
     <!-- Bluetooth phonebook permission alert for dialog content [CHAR LIMIT=none] -->
     <string name="bluetooth_phonebook_access_dialog_content">An untrusted Bluetooth device, <xliff:g id="device_name" example="My device">%1$s</xliff:g>, wants to access your contacts and call log. This includes data about incoming and outgoing calls.\n\nYou haven\u2019t connected to <xliff:g id="device_name" example="My device">%2$s</xliff:g> before.</string>
+
+    <!-- Privacy Guard -->
+    <string name="privacy_guard_manager_title">Privacy Guard</string>
 </resources>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 74f29b3..e1dd978 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -119,6 +119,16 @@
             android:key="quick_settings_tiles"
             android:title="@string/quick_settings_developer_tiles"
             android:fragment="com.android.settings.development.qstile.DevelopmentTileConfigFragment" />
+
+        <ListPreference
+            android:key="root_access"
+            android:title="@string/root_access"
+            android:persistent="false" />
+
+        <Preference
+            android:key="root_appops"
+            android:title="@string/root_appops_title"
+            android:summary="@string/root_appops_summary" />
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/res/xml/maintenance.xml b/res/xml/maintenance.xml
new file mode 100644
index 0000000..ebe93e4
--- /dev/null
+++ b/res/xml/maintenance.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018-2020 Fairphone B.V.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:key="maintenance_settings_screen"
+    android:title="@string/maintenance_preference_title">
+
+    <Preference
+        android:key="checkup"
+        android:title="@string/checkup_title"
+        android:summary="@string/checkup_summary">
+
+        <intent android:action="android.intent.action.MAIN"
+            android:targetPackage="com.fairphone.checkup"
+            android:targetClass="com.fairphone.checkup.MainActivity" />
+
+    </Preference>
+
+    <Preference
+        android:key="proximity_sensor"
+        android:title="@string/proximity_sensor_title"
+        android:summary="@string/proximity_sensor_summary">
+
+        <intent android:action="android.intent.action.MAIN"
+            android:targetPackage="com.fairphone.psensor"
+            android:targetClass="com.fairphone.psensor.CalibrationActivity" />
+
+    </Preference>
+
+    <Preference
+        android:key="hiccup"
+        android:title="@string/hiccup_title"
+        android:summary="@string/hiccup_summary">
+
+        <intent android:action="android.intent.action.MAIN"
+            android:targetPackage="com.fairphone.hiccup.app"
+            android:targetClass="com.fairphone.hiccup.app.HiccupSettings" />
+
+    </Preference>
+
+    <Preference
+        android:key="opengles3"
+        android:title="@string/fairphone_setting_title"
+        android:summary="@string/fairphone_settings_summary">
+
+        <intent android:action="android.intent.action.MAIN"
+            android:targetPackage="com.fairphone.fp2.settings"
+            android:targetClass="com.fairphone.fp2.settings.ui.FairphoneSettingsActivity" />
+
+    </Preference>
+
+</PreferenceScreen>
diff --git a/res/xml/process_stats_summary.xml b/res/xml/process_stats_summary.xml
index 3b3271d..0e62f5c 100644
--- a/res/xml/process_stats_summary.xml
+++ b/res/xml/process_stats_summary.xml
@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2015-2016 The CyanogenMod Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -60,4 +62,8 @@
         android:key="apps_list"
         android:title="@string/memory_usage_apps" />
 
+    <Preference
+        android:key="apps_startup"
+        android:title="@string/memory_startup_apps_title" />
+
 </PreferenceScreen>
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
new file mode 100644
index 0000000..878167f
--- /dev/null
+++ b/res/xml/security_settings_misc.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:lineage="http://schemas.android.com/apk/res/lineageos.platform"
+        android:title="@string/security_settings_title">
+
+    <PreferenceCategory android:title="@string/security_passwords_title"
+            android:persistent="false">
+
+        <Preference
+            android:key="location"
+            android:title="@string/location_settings_title"
+            android:fragment="com.android.settings.location.LocationSettings">
+        </Preference>
+
+        <SwitchPreference
+            android:key="show_password"
+            android:title="@string/show_password"
+            android:summary="@string/show_password_summary"/>
+
+    </PreferenceCategory>
+
+    <PreferenceCategory>
+
+        <Preference android:key="manage_device_admin"
+                android:title="@string/manage_device_admin"
+                android:persistent="false"
+                android:fragment="com.android.settings.DeviceAdminSettings"/>
+
+        <Preference android:key="enterprise_privacy"
+                android:title="@string/enterprise_privacy_settings"
+                android:persistent="false"
+                android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"/>
+
+    </PreferenceCategory>
+
+    <Preference android:key="sim_lock_settings"
+        android:title="@string/sim_lock_settings_category"
+        android:persistent="false">
+
+        <intent android:action="android.intent.action.MAIN"
+            android:targetPackage="com.android.settings"
+            android:targetClass="com.android.settings.Settings$IccLockSettingsActivity"/>
+
+    </Preference>
+
+    <Preference
+        android:key="encryption_and_credential"
+        android:title="@string/encryption_and_credential_settings_title"
+        android:summary="@string/encryption_and_credential_settings_summary"
+        android:fragment="com.android.settings.EncryptionAndCredential"/>
+
+    <Preference android:key="manage_trust_agents"
+        android:title="@string/manage_trust_agents"
+        android:persistent="false"
+        android:fragment="com.android.settings.TrustAgentSettings"/>
+
+    <Preference
+        android:key="screen_pinning_settings"
+        android:title="@string/screen_pinning_title"
+        android:summary="@string/switch_off_text"
+        android:fragment="com.android.settings.ScreenPinningSettings"/>
+
+    <Preference android:key="usage_access"
+        android:title="@string/usage_access_title"
+        android:fragment="com.android.settings.applications.ManageApplications">
+        <extra
+            android:name="classname"
+            android:value="com.android.settings.Settings$UsageAccessSettingsActivity" />
+    </Preference>
+
+</PreferenceScreen>
diff --git a/res/xml/system_dashboard_fragment.xml b/res/xml/system_dashboard_fragment.xml
index 1ca86ab..e86c8f0 100644
--- a/res/xml/system_dashboard_fragment.xml
+++ b/res/xml/system_dashboard_fragment.xml
@@ -19,7 +19,7 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="system_dashboard_screen"
     android:title="@string/header_category_system"
-    settings:initialExpandedChildrenCount="4">
+    settings:initialExpandedChildrenCount="5">
 
     <Preference
         android:key="gesture_settings"
@@ -29,6 +29,13 @@
         android:fragment="com.android.settings.gestures.GestureSettings"
         settings:controller="com.android.settings.gestures.GesturesSettingPreferenceController"/>
 
+    <Preference
+        android:key="maintenance_settings"
+        android:title="@string/maintenance_preference_title"
+        android:icon="@drawable/ic_settings_maintenance"
+        android:order="-240"
+        android:fragment="com.android.settings.MaintenanceSettings"/>
+
     <!-- Backup -->
     <Preference
         android:key="backup_settings"
@@ -58,7 +65,9 @@
         android:order="-30"
         settings:keywords="@string/keywords_system_update_settings"
         settings:controller="com.android.settings.system.SystemUpdatePreferenceController">
-        <intent android:action="android.settings.SYSTEM_UPDATE_SETTINGS" />
+        <intent android:action="android.intent.action.MAIN"
+                android:targetPackage="com.fairphone.updater"
+                android:targetClass="com.fairphone.updater.UpdaterActivity" />
     </Preference>
 
     <Preference
diff --git a/src/com/android/settings/MaintenanceSettings.java b/src/com/android/settings/MaintenanceSettings.java
new file mode 100644
index 0000000..46a9f84
--- /dev/null
+++ b/src/com/android/settings/MaintenanceSettings.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018-2020 Fairphone B.V.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+
+public class MaintenanceSettings extends DashboardFragment {
+
+    private static final String TAG = "MaintenanceSettings";
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.FP_MAINTENANCE;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.maintenance;
+    }
+}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 0ad964b..95d42ed 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -18,6 +18,7 @@
 
 import android.os.Bundle;
 
+import com.android.settings.applications.appops.AppOpsSummary;
 import com.android.settings.enterprise.EnterprisePrivacySettings;
 
 /**
@@ -56,6 +57,15 @@
     public static class ManageApplicationsActivity extends SettingsActivity { /* empty */ }
     public static class ManageAssistActivity extends SettingsActivity { /* empty */ }
     public static class HighPowerApplicationsActivity extends SettingsActivity { /* empty */ }
+    public static class AppOpsSummaryActivity extends SettingsActivity {
+        @Override
+        public boolean isValidFragment(String className) {
+            if (AppOpsSummary.class.getName().equals(className)) {
+                return true;
+            }
+            return super.isValidFragment(className);
+        }
+    }
     public static class BackgroundCheckSummaryActivity extends SettingsActivity { /* empty */ }
     public static class StorageUseActivity extends SettingsActivity { /* empty */ }
     public static class DevelopmentSettingsDashboardActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/applications/ProcessStatsSummary.java b/src/com/android/settings/applications/ProcessStatsSummary.java
index 53da04c..de091d0 100644
--- a/src/com/android/settings/applications/ProcessStatsSummary.java
+++ b/src/com/android/settings/applications/ProcessStatsSummary.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The CyanogenMod Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +18,7 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.content.Intent;
 import android.os.Bundle;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.Preference.OnPreferenceClickListener;
@@ -25,12 +27,15 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
+import com.android.settings.Settings.AppOpsSummaryActivity;
 import com.android.settings.SummaryPreference;
 import com.android.settings.Utils;
 import com.android.settings.applications.ProcStatsData.MemInfo;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.dashboard.SummaryLoader;
 
+import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS;
+
 public class ProcessStatsSummary extends ProcessStatsBase implements OnPreferenceClickListener {
 
     private static final String KEY_STATUS_HEADER = "status_header";
@@ -40,6 +45,7 @@
     private static final String KEY_AVERAGY_USED = "average_used";
     private static final String KEY_FREE = "free";
     private static final String KEY_APP_LIST = "apps_list";
+    private static final String KEY_APP_STARTUP = "apps_startup";
 
     private SummaryPreference mSummaryPref;
 
@@ -48,6 +54,7 @@
     private Preference mAverageUsed;
     private Preference mFree;
     private Preference mAppListPreference;
+    private Preference mAppStartupPreference;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -61,6 +68,8 @@
         mFree = findPreference(KEY_FREE);
         mAppListPreference = findPreference(KEY_APP_LIST);
         mAppListPreference.setOnPreferenceClickListener(this);
+        mAppStartupPreference = findPreference(KEY_APP_STARTUP);
+        mAppStartupPreference.setOnPreferenceClickListener(this);
     }
 
     @Override
@@ -123,6 +132,14 @@
                     .setSourceMetricsCategory(getMetricsCategory())
                     .launch();
             return true;
+        } else if (preference == mAppStartupPreference) {
+            Intent intent = new Intent(Intent.ACTION_MAIN);
+            Bundle args = new Bundle();
+            args.putString("appops_tab", getString(R.string.app_ops_categories_bootup));
+            intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
+            intent.setClass(getContext(), AppOpsSummaryActivity.class);
+            startActivity(intent);
+            return true;
         }
         return false;
     }
diff --git a/src/com/android/settings/applications/appops/AppOpsCategory.java b/src/com/android/settings/applications/appops/AppOpsCategory.java
index b506ce0..aa2f878 100644
--- a/src/com/android/settings/applications/appops/AppOpsCategory.java
+++ b/src/com/android/settings/applications/appops/AppOpsCategory.java
@@ -38,25 +38,40 @@
 import android.widget.Switch;
 import android.widget.TextView;
 
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.applications.appops.AppOpsState.AppOpEntry;
+import com.android.settings.core.SubSettingLauncher;
 
 import java.util.List;
 
 public class AppOpsCategory extends ListFragment implements
         LoaderManager.LoaderCallbacks<List<AppOpEntry>> {
 
+    private static final String LOG_TAG = "SettingsActivity";
+
+    private static final int RESULT_APP_DETAILS = 1;
+
     AppOpsState mState;
+    boolean mUserControlled;
 
     // This is the Adapter being used to display the list's data.
     AppListAdapter mAdapter;
 
+    String mCurrentPkgName;
+
     public AppOpsCategory() {
     }
 
     public AppOpsCategory(AppOpsState.OpsTemplate template) {
+        this(template, false);
+    }
+
+    public AppOpsCategory(AppOpsState.OpsTemplate template, boolean userControlled) {
         Bundle args = new Bundle();
         args.putParcelable("template", template);
+        args.putBoolean("userControlled", userControlled);
         setArguments(args);
     }
 
@@ -114,18 +129,22 @@
         final InterestingConfigChanges mLastConfig = new InterestingConfigChanges();
         final AppOpsState mState;
         final AppOpsState.OpsTemplate mTemplate;
+        final boolean mUserControlled;
 
         List<AppOpEntry> mApps;
         PackageIntentReceiver mPackageObserver;
 
-        public AppListLoader(Context context, AppOpsState state, AppOpsState.OpsTemplate template) {
+        public AppListLoader(Context context, AppOpsState state, AppOpsState.OpsTemplate template,
+                boolean userControlled) {
             super(context);
             mState = state;
             mTemplate = template;
+            mUserControlled = userControlled;
         }
 
         @Override public List<AppOpEntry> loadInBackground() {
-            return mState.buildState(mTemplate, 0, null, AppOpsState.LABEL_COMPARATOR);
+            return mState.buildState(mTemplate, 0, null, mUserControlled ?
+                    AppOpsState.LABEL_COMPARATOR : AppOpsState.RECENCY_COMPARATOR);
         }
 
         /**
@@ -244,13 +263,15 @@
         private final Resources mResources;
         private final LayoutInflater mInflater;
         private final AppOpsState mState;
+        private final boolean mUserControlled;
 
         List<AppOpEntry> mList;
 
-        public AppListAdapter(Context context, AppOpsState state) {
+        public AppListAdapter(Context context, AppOpsState state, boolean userControlled) {
             mResources = context.getResources();
             mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             mState = state;
+            mUserControlled = userControlled;
         }
 
         public void setData(List<AppOpEntry> data) {
@@ -290,11 +311,18 @@
             ((ImageView) view.findViewById(R.id.app_icon)).setImageDrawable(
                     item.getAppEntry().getIcon());
             ((TextView) view.findViewById(R.id.app_name)).setText(item.getAppEntry().getLabel());
-            ((TextView) view.findViewById(R.id.op_name)).setText(
-                    item.getTimeText(mResources, false));
-            view.findViewById(R.id.op_time).setVisibility(View.GONE);
-            ((Switch) view.findViewById(R.id.op_switch)).setChecked(
-                    item.getPrimaryOpMode() == AppOpsManager.MODE_ALLOWED);
+            if (mUserControlled) {
+                ((TextView) view.findViewById(R.id.op_name)).setText(
+                        item.getTimeText(mResources, false));
+                view.findViewById(R.id.op_time).setVisibility(View.GONE);
+                ((Switch) view.findViewById(R.id.op_switch)).setChecked(
+                        item.getPrimaryOpMode() == AppOpsManager.MODE_ALLOWED);
+            } else {
+                ((TextView) view.findViewById(R.id.op_name)).setText(item.getSummaryText(mState));
+                ((TextView) view.findViewById(R.id.op_time)).setText(
+                        item.getTimeText(mResources, false));
+                view.findViewById(R.id.op_switch).setVisibility(View.GONE);
+            }
 
             return view;
         }
@@ -304,6 +332,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mState = new AppOpsState(getActivity());
+        mUserControlled = getArguments().getBoolean("userControlled");
     }
 
     @Override public void onActivityCreated(Bundle savedInstanceState) {
@@ -317,7 +346,7 @@
         setHasOptionsMenu(true);
 
         // Create an empty adapter we will use to display the loaded data.
-        mAdapter = new AppListAdapter(getActivity(), mState);
+        mAdapter = new AppListAdapter(getActivity(), mState, mUserControlled);
         setListAdapter(mAdapter);
 
         // Start out with a progress indicator.
@@ -327,20 +356,40 @@
         getLoaderManager().initLoader(0, null, this);
     }
 
+    // utility method used to start sub activity
+    private void startApplicationDetailsActivity() {
+        // start new fragment to display extended information
+        final Bundle args = new Bundle();
+        args.putString(AppOpsDetails.ARG_PACKAGE_NAME, mCurrentPkgName);
+
+        new SubSettingLauncher(getContext())
+                .setDestination(AppOpsDetails.class.getName())
+                .setTitle(R.string.privacy_guard_manager_title)
+                .setArguments(args)
+                .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN)
+                .setResultListener(this, RESULT_APP_DETAILS)
+                .launch();
+    }
+
     @Override public void onListItemClick(ListView l, View v, int position, long id) {
         AppOpEntry entry = mAdapter.getItem(position);
         if (entry != null) {
-            // We treat this as tapping on the check box, toggling the app op state.
-            Switch sw = v.findViewById(R.id.op_switch);
-            boolean checked = !sw.isChecked();
-            sw.setChecked(checked);
-            AppOpsManager.OpEntry op = entry.getOpEntry(0);
-            int mode = checked ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
-            mState.getAppOpsManager().setMode(op.getOp(),
-                    entry.getAppEntry().getApplicationInfo().uid,
-                    entry.getAppEntry().getApplicationInfo().packageName,
-                    mode);
-            entry.overridePrimaryOpMode(mode);
+            if (mUserControlled) {
+                // We treat this as tapping on the check box, toggling the app op state.
+                Switch sw = ((Switch) v.findViewById(R.id.op_switch));
+                boolean checked = !sw.isChecked();
+                sw.setChecked(checked);
+                AppOpsManager.OpEntry op = entry.getOpEntry(0);
+                int mode = checked ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
+                mState.getAppOpsManager().setMode(op.getOp(),
+                        entry.getAppEntry().getApplicationInfo().uid,
+                        entry.getAppEntry().getApplicationInfo().packageName,
+                        mode);
+                entry.overridePrimaryOpMode(mode);
+            } else {
+                mCurrentPkgName = entry.getAppEntry().getApplicationInfo().packageName;
+                startApplicationDetailsActivity();
+            }
         }
     }
 
@@ -348,9 +397,9 @@
         Bundle fargs = getArguments();
         AppOpsState.OpsTemplate template = null;
         if (fargs != null) {
-            template = fargs.getParcelable("template");
+            template = (AppOpsState.OpsTemplate) fargs.getParcelable("template");
         }
-        return new AppListLoader(getActivity(), mState, template);
+        return new AppListLoader(getActivity(), mState, template, mUserControlled);
     }
 
     @Override public void onLoadFinished(Loader<List<AppOpEntry>> loader, List<AppOpEntry> data) {
diff --git a/src/com/android/settings/applications/appops/AppOpsDetails.java b/src/com/android/settings/applications/appops/AppOpsDetails.java
new file mode 100644
index 0000000..72bc38f
--- /dev/null
+++ b/src/com/android/settings/applications/appops/AppOpsDetails.java
@@ -0,0 +1,406 @@
+/**
+ * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2017-2018 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.settings.applications.appops;
+
+import android.app.Activity;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.applications.manageapplications.ManageApplications;
+import com.android.settings.SettingsActivity;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.Utils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringJoiner;
+
+public class AppOpsDetails extends SettingsPreferenceFragment {
+    static final String TAG = "AppOpsDetails";
+
+    public static final String ARG_PACKAGE_NAME = "package";
+    private static final String KEY_HEADER = "header";
+
+    private AppOpsState mState;
+    private PackageManager mPm;
+    private AppOpsManager mAppOps;
+    private PackageInfo mPackageInfo;
+    private PreferenceScreen mPreferenceScreen;
+
+    private final int MODE_ALLOWED = 0;
+    private final int MODE_IGNORED = 1;
+    private final int MODE_ASK     = 2;
+
+    private final String[] MODE_ENTRIES = {
+            String.valueOf(MODE_ALLOWED),
+            String.valueOf(MODE_IGNORED),
+            String.valueOf(MODE_ASK)
+    };
+
+    private int modeToPosition(int mode) {
+        switch (mode) {
+            case AppOpsManager.MODE_ALLOWED:
+                return MODE_ALLOWED;
+            case AppOpsManager.MODE_IGNORED:
+                return MODE_IGNORED;
+            case AppOpsManager.MODE_ASK:
+                return MODE_ASK;
+            default:
+                return MODE_IGNORED;
+        }
+    }
+
+    private int positionToMode(int position) {
+        switch (position) {
+            case MODE_ALLOWED:
+                return AppOpsManager.MODE_ALLOWED;
+            case MODE_IGNORED:
+                return AppOpsManager.MODE_IGNORED;
+            case MODE_ASK:
+                return AppOpsManager.MODE_ASK;
+            default:
+                return AppOpsManager.MODE_IGNORED;
+        }
+    }
+
+    private static HashMap<Integer, Integer> OP_ICONS = new HashMap<>();
+
+    static {
+        OP_ICONS.put(AppOpsManager.OP_ACTIVATE_VPN, R.drawable.ic_perm_vpn);
+        OP_ICONS.put(AppOpsManager.OP_AUDIO_ALARM_VOLUME, R.drawable.ic_perm_alarm);
+        OP_ICONS.put(AppOpsManager.OP_AUDIO_MEDIA_VOLUME, R.drawable.ic_perm_audio);
+        OP_ICONS.put(AppOpsManager.OP_BLUETOOTH_CHANGE, R.drawable.ic_perm_bluetooth);
+        OP_ICONS.put(AppOpsManager.OP_BOOT_COMPLETED, R.drawable.ic_perm_boot);
+        OP_ICONS.put(AppOpsManager.OP_CHANGE_WIFI_STATE, R.drawable.ic_perm_wifi);
+        OP_ICONS.put(AppOpsManager.OP_DATA_CONNECT_CHANGE, R.drawable.ic_perm_data);
+        OP_ICONS.put(AppOpsManager.OP_GET_USAGE_STATS, R.drawable.ic_perm_data);
+        OP_ICONS.put(AppOpsManager.OP_GPS, R.drawable.ic_perm_location);
+        OP_ICONS.put(AppOpsManager.OP_MUTE_MICROPHONE, R.drawable.ic_perm_microphone);
+        OP_ICONS.put(AppOpsManager.OP_NFC_CHANGE, R.drawable.ic_perm_nfc);
+        OP_ICONS.put(AppOpsManager.OP_POST_NOTIFICATION, R.drawable.ic_perm_notifications);
+        OP_ICONS.put(AppOpsManager.OP_READ_CLIPBOARD, R.drawable.ic_perm_clipboard);
+        OP_ICONS.put(AppOpsManager.OP_RUN_IN_BACKGROUND, R.drawable.ic_perm_background);
+        OP_ICONS.put(AppOpsManager.OP_SU, R.drawable.ic_perm_su);
+        OP_ICONS.put(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, R.drawable.ic_perm_drawontop);
+        OP_ICONS.put(AppOpsManager.OP_TAKE_AUDIO_FOCUS, R.drawable.ic_perm_audio);
+        OP_ICONS.put(AppOpsManager.OP_TOAST_WINDOW, R.drawable.ic_perm_notifications);
+        OP_ICONS.put(AppOpsManager.OP_TURN_SCREEN_ON, R.drawable.ic_perm_turnscreenon);
+        OP_ICONS.put(AppOpsManager.OP_VIBRATE, R.drawable.ic_perm_vibrate);
+        OP_ICONS.put(AppOpsManager.OP_WAKE_LOCK, R.drawable.ic_perm_nosleep);
+        OP_ICONS.put(AppOpsManager.OP_WIFI_SCAN, R.drawable.ic_perm_wifi);
+        OP_ICONS.put(AppOpsManager.OP_WRITE_CLIPBOARD, R.drawable.ic_perm_clipboard);
+        OP_ICONS.put(AppOpsManager.OP_WRITE_SETTINGS, R.drawable.ic_perm_settings);
+        OP_ICONS.put(AppOpsManager.OP_WRITE_SMS , R.drawable.ic_perm_sms);
+    }
+
+    private boolean isPlatformSigned() {
+        final int match = mPm.checkSignatures("android", mPackageInfo.packageName);
+        return match >= PackageManager.SIGNATURE_MATCH;
+    }
+
+    // Utility method to set application label and icon.
+    private void setAppHeader(PackageInfo pkgInfo) {
+        ApplicationInfo appInfo = pkgInfo.applicationInfo;
+        String appLabel = mPm.getApplicationLabel(appInfo).toString();
+        String label;
+        try {
+            label = appInfo.loadLabel(mPm).toString();
+        } catch (Throwable t) {
+            Log.e(TAG, "Error loading application label for " + appLabel, t);
+            label = appLabel;
+        }
+
+        final Activity activity = getActivity();
+        final Preference pref = EntityHeaderController
+                .newInstance(getActivity(), this /* fragment */, null /* header */)
+                .setIcon(mPm.getApplicationIcon(appInfo))
+                .setLabel(label)
+                .setPackageName(appInfo.packageName)
+                .setUid(appInfo.uid)
+                .setHasAppInfoLink(true)
+                .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
+                        EntityHeaderController.ActionType.ACTION_NONE)
+                .done(getActivity(), getPrefContext());
+        pref.setKey(KEY_HEADER);
+        getPreferenceScreen().addPreference(pref);
+    }
+
+    private String retrieveAppEntry() {
+        final Bundle args = getArguments();
+        String packageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null;
+        if (packageName == null) {
+            Intent intent = (args == null) ?
+                    getActivity().getIntent() : (Intent) args.getParcelable("intent");
+            if (intent != null) {
+                packageName = intent.getData().getSchemeSpecificPart();
+            }
+        }
+        try {
+            mPackageInfo = mPm.getPackageInfo(packageName,
+                    PackageManager.MATCH_DISABLED_COMPONENTS |
+                    PackageManager.MATCH_ANY_USER);
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "Exception when retrieving package:" + packageName, e);
+            mPackageInfo = null;
+        }
+
+        return packageName;
+    }
+
+    private boolean refreshUi() {
+        if (mPackageInfo == null) {
+            return false;
+        }
+
+        mPreferenceScreen.removeAll();
+        setAppHeader(mPackageInfo);
+
+        AppOpsState.OpsTemplate[] allTemplates = getTemplates();
+        for (AppOpsState.OpsTemplate tpl : allTemplates) {
+            List<AppOpsState.AppOpEntry> entries = mState.buildState(tpl,
+                    mPackageInfo.applicationInfo.uid, mPackageInfo.packageName, true);
+            for (final AppOpsState.AppOpEntry entry : entries) {
+                String perm = null;
+                int op = -1;
+                // Find the first permission with a known name
+                for (int i = 0; i < entry.getNumOpEntry() && perm == null; i++) {
+                    op = entry.getOpEntry(i).getOp();
+                    perm = AppOpsManager.opToPermission(op);
+                }
+                Drawable icon = getIconByPermission(perm);
+                if (icon == null && op != -1 && OP_ICONS.containsKey(op)) {
+                    icon = getActivity().getDrawable(OP_ICONS.get(op));
+                }
+                if (icon == null) {
+                    Log.e(TAG, "Failed to retrieve icon for permission: " + perm);
+                } else {
+                    icon.setTint(Utils.getColorAttr(getActivity(),
+                            android.R.attr.colorControlNormal));
+                }
+
+                final AppOpsManager.OpEntry firstOp = entry.getOpEntry(0);
+                final int switchOp = AppOpsManager.opToSwitch(firstOp.getOp());
+
+                // ListPreference for 3 states: ask, allow, deny
+                if (AppOpsManager.isStrictOp(switchOp)) {
+                    ListPreference listPref = getListPrefForEntry(entry, icon);
+                    mPreferenceScreen.addPreference(listPref);
+                } else {
+                    SwitchPreference switchPref = getSwitchPrefForEntry(entry, icon);
+                    mPreferenceScreen.addPreference(switchPref);
+                }
+            }
+        }
+
+        if (mPreferenceScreen.getPreferenceCount() == 0) {
+            Preference noBlockablePermissionsPref = getNoBlockablePermissionsPref();
+            mPreferenceScreen.addPreference(noBlockablePermissionsPref);
+        }
+
+        return true;
+    }
+
+    private AppOpsState.OpsTemplate[] getTemplates() {
+        /* If we are platform signed, only show the root switch, this
+         * one is safe to toggle while other permission-based ones could
+         * certainly cause system-wide problems
+         */
+        if (isPlatformSigned()) {
+            return new AppOpsState.OpsTemplate[]{ AppOpsState.SU_TEMPLATE };
+        }
+
+        int length = AppOpsState.ALL_PERMS_TEMPLATES.length;
+        AppOpsState.OpsTemplate[] allTemplates = new AppOpsState.OpsTemplate[length];
+        // Loop all existing templates and set the visibility of each perm to true
+        for (int i = 0; i < length; i++) {
+            AppOpsState.OpsTemplate tpl = AppOpsState.ALL_PERMS_TEMPLATES[i];
+            for (int j = 0; j < tpl.ops.length; j++) {
+                // we only want to use the template's orderings, not the visibility
+                tpl.showPerms[j] = true;
+            }
+
+            allTemplates[i] = tpl;
+        }
+
+        return allTemplates;
+    }
+
+    private Drawable getIconByPermission(String perm) {
+        Drawable icon = null;
+        if (perm != null) {
+            try {
+                PermissionInfo pi = mPm.getPermissionInfo(perm, 0);
+                if (pi.group != null) {
+                    PermissionGroupInfo pgi = mPm.getPermissionGroupInfo(pi.group, 0);
+                    if (pgi.icon != 0) {
+                        icon = pgi.loadIcon(mPm);
+                    }
+                }
+            } catch (NameNotFoundException e) {
+            }
+        }
+        return icon;
+    }
+
+    private ListPreference getListPrefForEntry(final AppOpsState.AppOpEntry entry, Drawable icon) {
+        final Resources res = getActivity().getResources();
+
+        final AppOpsManager.OpEntry firstOp = entry.getOpEntry(0);
+        final AppOpsManager.PackageOps pkgOps = entry.getPackageOps();
+        final int uid = pkgOps.getUid();
+        final String pkgName = pkgOps.getPackageName();
+        final int switchOp = AppOpsManager.opToSwitch(firstOp.getOp());
+        final int mode = mAppOps.checkOpNoThrow(switchOp, uid, pkgName);
+        final CharSequence opName = entry.getSwitchText(mState);
+
+        ListPreference listPref = new ListPreference(getActivity());
+        listPref.setLayoutResource(R.layout.preference_appops);
+        listPref.setIcon(icon);
+        listPref.setTitle(opName);
+        listPref.setDialogTitle(opName);
+        listPref.setEntries(R.array.app_ops_permissions);
+        listPref.setEntryValues(MODE_ENTRIES);
+        listPref.setValueIndex(modeToPosition(mode));
+        String summary = getSummary(listPref.getEntry(), entry.getCountsText(res),
+                entry.getTimeText(res, true));
+        listPref.setSummary(summary);
+        listPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+            @Override
+            public boolean onPreferenceChange(Preference preference, Object newValue) {
+                ListPreference listPref = (ListPreference) preference;
+                String value = newValue.toString();
+                int selectedIndex = listPref.findIndexOfValue(value);
+                mAppOps.setMode(switchOp, uid, pkgName, positionToMode(selectedIndex));
+                String summary = getSummary(listPref.getEntries()[selectedIndex],
+                        entry.getCountsText(res), entry.getTimeText(res, true));
+                listPref.setSummary(summary);
+                return true;
+            }
+        });
+
+        return listPref;
+    }
+
+    private SwitchPreference getSwitchPrefForEntry(final AppOpsState.AppOpEntry entry,
+                                                   Drawable icon) {
+        final Resources res = getActivity().getResources();
+
+        final AppOpsManager.OpEntry firstOp = entry.getOpEntry(0);
+        final AppOpsManager.PackageOps pkgOps = entry.getPackageOps();
+        final int uid = pkgOps.getUid();
+        final String pkgName = pkgOps.getPackageName();
+        final int switchOp = AppOpsManager.opToSwitch(firstOp.getOp());
+        final int mode = mAppOps.checkOpNoThrow(switchOp, uid, pkgName);
+        final CharSequence opName = entry.getSwitchText(mState);
+
+        SwitchPreference switchPref = new SwitchPreference(getActivity());
+        switchPref.setLayoutResource(R.layout.preference_appops);
+        switchPref.setIcon(icon);
+        switchPref.setTitle(opName);
+        String summary = getSummary(entry.getCountsText(res), entry.getTimeText(res, true));
+        switchPref.setSummary(summary);
+        switchPref.setChecked(mode == AppOpsManager.MODE_ALLOWED);
+        switchPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+            @Override
+            public boolean onPreferenceChange(Preference preference,
+                                              Object newValue) {
+                Boolean isChecked = (Boolean) newValue;
+                mAppOps.setMode(switchOp, uid, pkgName,
+                        isChecked ? AppOpsManager.MODE_ALLOWED
+                                : AppOpsManager.MODE_IGNORED);
+                return true;
+            }
+        });
+
+        return switchPref;
+    }
+
+    private Preference getNoBlockablePermissionsPref() {
+        Preference emptyPref = new Preference(getActivity());
+        emptyPref.setTitle(R.string.app_ops_no_blockable_permissions);
+        emptyPref.setSelectable(false);
+        emptyPref.setEnabled(false);
+        return emptyPref;
+    }
+
+
+    private void setIntentAndFinish(boolean finish, boolean appChanged) {
+        Intent intent = new Intent();
+        intent.putExtra(ManageApplications.APP_CHG, appChanged);
+        SettingsActivity sa = (SettingsActivity)getActivity();
+        sa.finishPreferencePanel(Activity.RESULT_OK, intent);
+    }
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mState = new AppOpsState(getActivity());
+        mPm = getActivity().getPackageManager();
+        mAppOps = (AppOpsManager)getActivity().getSystemService(Context.APP_OPS_SERVICE);
+        mPreferenceScreen = getPreferenceManager().createPreferenceScreen(getActivity());
+        retrieveAppEntry();
+
+        setPreferenceScreen(mPreferenceScreen);
+        setHasOptionsMenu(true);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsEvent.APP_OPS_DETAILS;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (!refreshUi()) {
+            setIntentAndFinish(true, true);
+        }
+    }
+
+    private String getSummary(CharSequence... lines) {
+        StringJoiner sj = new StringJoiner("\n");
+        for (CharSequence line : lines) {
+            if (!TextUtils.isEmpty(line)) {
+                sj.add(line);
+            }
+        }
+        return sj.toString();
+    }
+}
diff --git a/src/com/android/settings/applications/appops/AppOpsDetailsTop.java b/src/com/android/settings/applications/appops/AppOpsDetailsTop.java
new file mode 100644
index 0000000..0353bb3
--- /dev/null
+++ b/src/com/android/settings/applications/appops/AppOpsDetailsTop.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2015 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.settings.applications.appops;
+
+import android.content.Intent;
+import android.preference.PreferenceActivity;
+
+public class AppOpsDetailsTop extends PreferenceActivity {
+
+    @Override
+    public Intent getIntent() {
+        Intent modIntent = new Intent(super.getIntent());
+        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, AppOpsDetails.class.getName());
+        modIntent.putExtra(EXTRA_NO_HEADERS, true);
+        return modIntent;
+    }
+
+    @Override
+    protected boolean isValidFragment(String fragmentName) {
+        if (AppOpsDetails.class.getName().equals(fragmentName)) return true;
+        return false;
+    }
+}
diff --git a/src/com/android/settings/applications/appops/AppOpsState.java b/src/com/android/settings/applications/appops/AppOpsState.java
index 2686b8c..7684c46 100644
--- a/src/com/android/settings/applications/appops/AppOpsState.java
+++ b/src/com/android/settings/applications/appops/AppOpsState.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2018 The LineageOS Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +17,7 @@
 
 package com.android.settings.applications.appops;
 
+import android.app.Activity;
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -23,6 +25,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
+import android.content.SharedPreferences;
 import android.graphics.drawable.Drawable;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -38,7 +41,9 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 public class AppOpsState {
     static final String TAG = "AppOpsState";
@@ -50,12 +55,17 @@
     final CharSequence[] mOpSummaries;
     final CharSequence[] mOpLabels;
 
+    List<AppOpEntry> mApps;
+
+    private SharedPreferences mPreferences;
+
     public AppOpsState(Context context) {
         mContext = context;
         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
         mPm = context.getPackageManager();
-        mOpSummaries = context.getResources().getTextArray(R.array.app_ops_summaries);
-        mOpLabels = context.getResources().getTextArray(R.array.app_ops_labels);
+        mOpSummaries = context.getResources().getTextArray(R.array.app_ops_summaries_lineage);
+        mOpLabels = context.getResources().getTextArray(R.array.app_ops_labels_lineage);
+        mPreferences = context.getSharedPreferences("appops_manager", Activity.MODE_PRIVATE);
     }
 
     public static class OpsTemplate implements Parcelable {
@@ -180,6 +190,7 @@
                     false,
                     false,
                     false,
+                    false,
                     false }
             );
 
@@ -193,7 +204,11 @@
                     AppOpsManager.OP_PROJECT_MEDIA,
                     AppOpsManager.OP_ACTIVATE_VPN,
                     AppOpsManager.OP_ASSIST_STRUCTURE,
-                    AppOpsManager.OP_ASSIST_SCREENSHOT},
+                    AppOpsManager.OP_ASSIST_SCREENSHOT,
+                    AppOpsManager.OP_CHANGE_WIFI_STATE,
+                    AppOpsManager.OP_BLUETOOTH_CHANGE,
+                    AppOpsManager.OP_NFC_CHANGE,
+                    AppOpsManager.OP_DATA_CONNECT_CHANGE },
             new boolean[] { false,
                     true,
                     true,
@@ -203,7 +218,11 @@
                     false,
                     false,
                     false,
-                    false }
+                    false,
+                    true,
+                    true,
+                    true,
+                    true }
             );
 
     public static final OpsTemplate RUN_IN_BACKGROUND_TEMPLATE = new OpsTemplate(
@@ -211,9 +230,62 @@
             new boolean[] { false }
             );
 
+    public static final OpsTemplate BOOTUP_TEMPLATE = new OpsTemplate(
+            new int[] { AppOpsManager.OP_BOOT_COMPLETED },
+            new boolean[] { true }
+            );
+
+    public static final OpsTemplate SU_TEMPLATE = new OpsTemplate(
+            new int[] { AppOpsManager.OP_SU },
+            new boolean[] { false }
+            );
+
+    // this template should contain all ops which are not part of any other template in
+    // ALL_TEMPLATES
+    public static final OpsTemplate REMAINING_TEMPLATE = new OpsTemplate(
+            new int[] { AppOpsManager.OP_GET_USAGE_STATS,
+                    AppOpsManager.OP_TOAST_WINDOW,
+                    AppOpsManager.OP_WRITE_WALLPAPER,
+                    AppOpsManager.OP_READ_PHONE_STATE,
+                    AppOpsManager.OP_ADD_VOICEMAIL,
+                    AppOpsManager.OP_USE_SIP,
+                    AppOpsManager.OP_PROCESS_OUTGOING_CALLS,
+                    AppOpsManager.OP_USE_FINGERPRINT,
+                    AppOpsManager.OP_BODY_SENSORS,
+                    AppOpsManager.OP_READ_CELL_BROADCASTS,
+                    AppOpsManager.OP_MOCK_LOCATION,
+                    AppOpsManager.OP_READ_EXTERNAL_STORAGE,
+                    AppOpsManager.OP_WRITE_EXTERNAL_STORAGE,
+                    AppOpsManager.OP_TURN_SCREEN_ON,
+                    AppOpsManager.OP_GET_ACCOUNTS },
+            new boolean[] { true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true,
+                    true }
+    );
+
     public static final OpsTemplate[] ALL_TEMPLATES = new OpsTemplate[] {
             LOCATION_TEMPLATE, PERSONAL_TEMPLATE, MESSAGING_TEMPLATE,
-            MEDIA_TEMPLATE, DEVICE_TEMPLATE, RUN_IN_BACKGROUND_TEMPLATE
+            MEDIA_TEMPLATE, DEVICE_TEMPLATE, RUN_IN_BACKGROUND_TEMPLATE,
+            BOOTUP_TEMPLATE, SU_TEMPLATE
+    };
+
+    // this template contains all permissions grouped by templates
+    public static final OpsTemplate[] ALL_PERMS_TEMPLATES = new OpsTemplate[] {
+            LOCATION_TEMPLATE, PERSONAL_TEMPLATE, MESSAGING_TEMPLATE,
+            MEDIA_TEMPLATE, DEVICE_TEMPLATE, RUN_IN_BACKGROUND_TEMPLATE,
+            BOOTUP_TEMPLATE, SU_TEMPLATE, REMAINING_TEMPLATE
     };
 
     /**
@@ -378,30 +450,59 @@
         }
 
         private CharSequence getCombinedText(ArrayList<AppOpsManager.OpEntry> ops,
-                CharSequence[] items) {
-            if (ops.size() == 1) {
-                return items[ops.get(0).getOp()];
-            } else {
-                StringBuilder builder = new StringBuilder();
-                for (int i=0; i<ops.size(); i++) {
-                    if (i > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append(items[ops.get(i).getOp()]);
+                CharSequence[] items, Resources res, boolean withTerseCounts) {
+            StringBuilder builder = new StringBuilder();
+            for (int i=0; i<ops.size(); i++) {
+                if (i > 0) {
+                    builder.append(", ");
                 }
-                return builder.toString();
+                AppOpsManager.OpEntry op = ops.get(i);
+                int count = op.getAllowedCount() + op.getIgnoredCount();
+
+                if (withTerseCounts && count > 0) {
+                    String quantity = res.getQuantityString(R.plurals.app_ops_count,
+                            count, count);
+                    builder.append(res.getString(R.string.app_ops_entry_summary,
+                            items[op.getOp()], quantity));
+                } else {
+                    builder.append(items[op.getOp()]);
+                }
             }
+            return builder.toString();
+        }
+
+        public CharSequence getCountsText(Resources res) {
+            AppOpsManager.OpEntry op = mOps.get(0);
+            int allowed = op.getAllowedCount();
+            int denied = op.getIgnoredCount();
+
+            if (allowed == 0 && denied == 0) {
+                return null;
+            }
+
+            CharSequence allowedQuantity = res.getQuantityString(R.plurals.app_ops_count,
+                    allowed, allowed);
+            CharSequence deniedQuantity = res.getQuantityString(R.plurals.app_ops_count,
+                    denied, denied);
+
+            if (denied == 0) {
+                return res.getString(R.string.app_ops_allowed_count, allowedQuantity);
+            } else if (allowed == 0) {
+                return res.getString(R.string.app_ops_ignored_count, deniedQuantity);
+            }
+            return res.getString(R.string.app_ops_both_count, allowedQuantity, deniedQuantity);
         }
 
         public CharSequence getSummaryText(AppOpsState state) {
-            return getCombinedText(mOps, state.mOpSummaries);
+            return getCombinedText(mOps, state.mOpSummaries, state.mContext.getResources(), true);
         }
 
         public CharSequence getSwitchText(AppOpsState state) {
+            final Resources res = state.mContext.getResources();
             if (mSwitchOps.size() > 0) {
-                return getCombinedText(mSwitchOps, state.mOpLabels);
+                return getCombinedText(mSwitchOps, state.mOpLabels, res, false);
             } else {
-                return getCombinedText(mOps, state.mOpLabels);
+                return getCombinedText(mOps, state.mOpLabels, res, false);
             }
         }
 
@@ -501,19 +602,34 @@
     }
 
     private AppEntry getAppEntry(final Context context, final HashMap<String, AppEntry> appEntries,
-            final String packageName, ApplicationInfo appInfo) {
+            final String packageName, ApplicationInfo appInfo, boolean applyFilters) {
+
+        if (appInfo == null) {
+            try {
+                appInfo = mPm.getApplicationInfo(packageName,
+                        PackageManager.GET_DISABLED_COMPONENTS
+                        | PackageManager.GET_UNINSTALLED_PACKAGES);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "Unable to find info for package " + packageName);
+                return null;
+            }
+        }
+
+        if (applyFilters) {
+            // Hide user apps if needed
+            if (!shouldShowUserApps() &&
+                    (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                return null;
+            }
+            // Hide system apps if needed
+            if (!shouldShowSystemApps() &&
+                     (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                return null;
+            }
+        }
+
         AppEntry appEntry = appEntries.get(packageName);
         if (appEntry == null) {
-            if (appInfo == null) {
-                try {
-                    appInfo = mPm.getApplicationInfo(packageName,
-                            PackageManager.MATCH_DISABLED_COMPONENTS
-                            | PackageManager.MATCH_ANY_USER);
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.w(TAG, "Unable to find info for package " + packageName);
-                    return null;
-                }
-            }
             appEntry = new AppEntry(this, appInfo);
             appEntry.loadLabel(context);
             appEntries.put(packageName, appEntry);
@@ -521,12 +637,35 @@
         return appEntry;
     }
 
-    public List<AppOpEntry> buildState(OpsTemplate tpl, int uid, String packageName) {
-        return buildState(tpl, uid, packageName, RECENCY_COMPARATOR);
+    private boolean shouldShowUserApps() {
+        return mPreferences.getBoolean("show_user_apps", true);
+    }
+
+    private boolean shouldShowSystemApps() {
+        return mPreferences.getBoolean("show_system_apps", true);
+    }
+
+    public List<AppOpEntry> buildState(OpsTemplate tpl, int uid, String packageName,
+            boolean privacyGuard) {
+        return buildState(tpl, uid, packageName, RECENCY_COMPARATOR, privacyGuard);
     }
 
     public List<AppOpEntry> buildState(OpsTemplate tpl, int uid, String packageName,
             Comparator<AppOpEntry> comparator) {
+        return buildState(tpl, uid, packageName, comparator, false);
+    }
+
+    private boolean isPrivacyGuardOp(int op) {
+        for (int privacyGuardOp : AppOpsManager.PRIVACY_GUARD_OP_STATES) {
+            if (privacyGuardOp == op) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public List<AppOpEntry> buildState(OpsTemplate tpl, int uid, String packageName,
+            Comparator<AppOpEntry> comparator, boolean privacyGuard) {
         final Context context = mContext;
 
         final HashMap<String, AppEntry> appEntries = new HashMap<String, AppEntry>();
@@ -535,7 +674,25 @@
         final ArrayList<String> perms = new ArrayList<String>();
         final ArrayList<Integer> permOps = new ArrayList<Integer>();
         final int[] opToOrder = new int[AppOpsManager._NUM_OP];
+
+        final Set<Integer> privacyGuardOps = new HashSet<>();
+
         for (int i=0; i<tpl.ops.length; i++) {
+            if (privacyGuard && isPrivacyGuardOp(tpl.ops[i])) {
+                // If there's a permission for this Privacy Guard OP, then
+                // we don't have to treat it in a special way. The application
+                // should have the permission declared if it uses it, so we
+                // will add this later when we query PackageManager
+                String perm = AppOpsManager.opToPermission(tpl.ops[i]);
+                if (perm != null) {
+                    if (DEBUG) Log.d(TAG, "Adding " + AppOpsManager.opToName(tpl.ops[i])
+                            + " (" + tpl.ops[i] + ") to privacyGuardOps");
+                    privacyGuardOps.add(tpl.ops[i]);
+                } else {
+                    if (DEBUG) Log.d(TAG, "Not adding " + AppOpsManager.opToName(tpl.ops[i])
+                            + " (" + tpl.ops[i] + ") with perm " + perm + " to privacyGuardOps");
+                }
+            }
             if (tpl.showPerms[i]) {
                 String perm = AppOpsManager.opToPermission(tpl.ops[i]);
                 if (perm != null && !perms.contains(perm)) {
@@ -546,6 +703,9 @@
             }
         }
 
+        // Whether to apply hide user / system app filters
+        final boolean applyFilters = (packageName == null);
+
         List<AppOpsManager.PackageOps> pkgs;
         if (packageName != null) {
             pkgs = mAppOps.getOpsForPackage(uid, packageName, tpl.ops);
@@ -556,12 +716,21 @@
         if (pkgs != null) {
             for (int i=0; i<pkgs.size(); i++) {
                 AppOpsManager.PackageOps pkgOps = pkgs.get(i);
-                AppEntry appEntry = getAppEntry(context, appEntries, pkgOps.getPackageName(), null);
+                AppEntry appEntry = getAppEntry(context, appEntries, pkgOps.getPackageName(), null,
+                        applyFilters);
                 if (appEntry == null) {
                     continue;
                 }
                 for (int j=0; j<pkgOps.getOps().size(); j++) {
                     AppOpsManager.OpEntry opEntry = pkgOps.getOps().get(j);
+                    if (privacyGuard && privacyGuardOps.contains(opEntry.getOp())) {
+                        // This OP is here because the user enabled Privacy Guard
+                        // for this application.
+                        if (DEBUG) Log.d(TAG, "Not adding "
+                                + AppOpsManager.opToName(opEntry.getOp())
+                                + " (" + opEntry.getOp() + ")");
+                        continue;
+                    }
                     addOp(entries, pkgOps, appEntry, opEntry, packageName == null,
                             packageName == null ? 0 : opToOrder[opEntry.getOp()]);
                 }
@@ -584,7 +753,7 @@
         for (int i=0; i<apps.size(); i++) {
             PackageInfo appInfo = apps.get(i);
             AppEntry appEntry = getAppEntry(context, appEntries, appInfo.packageName,
-                    appInfo.applicationInfo);
+                    appInfo.applicationInfo, applyFilters);
             if (appEntry == null) {
                 continue;
             }
@@ -593,7 +762,7 @@
             if (appInfo.requestedPermissions != null) {
                 for (int j=0; j<appInfo.requestedPermissions.length; j++) {
                     if (appInfo.requestedPermissionsFlags != null) {
-                        if ((appInfo.requestedPermissionsFlags[j]
+                        if (!privacyGuard && (appInfo.requestedPermissionsFlags[j]
                                 & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
                             if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + " perm "
                                     + appInfo.requestedPermissions[j] + " not granted; skipping");
@@ -618,7 +787,7 @@
 
                         }
                         AppOpsManager.OpEntry opEntry = new AppOpsManager.OpEntry(
-                                permOps.get(k), AppOpsManager.MODE_ALLOWED, 0, 0, 0, -1, null);
+                                permOps.get(k), AppOpsManager.MODE_ALLOWED, 0, 0, 0, -1, null, 0, 0);
                         dummyOps.add(opEntry);
                         addOp(entries, pkgOps, appEntry, opEntry, packageName == null,
                                 packageName == null ? 0 : opToOrder[opEntry.getOp()]);
diff --git a/src/com/android/settings/applications/appops/AppOpsSummary.java b/src/com/android/settings/applications/appops/AppOpsSummary.java
new file mode 100644
index 0000000..be1e9d6
--- /dev/null
+++ b/src/com/android/settings/applications/appops/AppOpsSummary.java
@@ -0,0 +1,272 @@
+/**
+ * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2016 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.settings.applications.appops;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.AppOpsManager;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceFrameLayout;
+import android.support.v13.app.FragmentPagerAdapter;
+import android.support.v4.view.PagerTabStrip;
+import android.support.v4.view.ViewPager;
+import android.util.Pair;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.InstrumentedPreferenceFragment;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.android.settings.development.RootAccessPreferenceController;
+import com.android.settings.R;
+
+public class AppOpsSummary extends InstrumentedPreferenceFragment {
+    // layout inflater object used to inflate views
+    private LayoutInflater mInflater;
+
+    private ViewGroup mContentContainer;
+    private View mRootView;
+    private ViewPager mViewPager;
+
+    private MyPagerAdapter mAdapter;
+
+    private Activity mActivity;
+    private SharedPreferences mPreferences;
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsEvent.APP_OPS_SUMMARY;
+    }
+
+    static class MyPagerAdapter extends FragmentPagerAdapter
+            implements ViewPager.OnPageChangeListener {
+        private List<Pair<CharSequence, AppOpsState.OpsTemplate>> mPageData;
+        private int mCurPos;
+
+        public MyPagerAdapter(FragmentManager fm,
+                List<Pair<CharSequence, AppOpsState.OpsTemplate>> data) {
+            super(fm);
+            mPageData = data;
+        }
+
+        @Override
+        public Fragment getItem(int position) {
+            return new AppOpsCategory(mPageData.get(position).second);
+        }
+
+        @Override
+        public int getCount() {
+            return mPageData.size();
+        }
+
+        @Override
+        public CharSequence getPageTitle(int position) {
+            return mPageData.get(position).first;
+        }
+
+        @Override
+        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+        }
+
+        @Override
+        public void onPageSelected(int position) {
+            mCurPos = position;
+        }
+
+        public int getCurrentPage() {
+            return mCurPos;
+        }
+
+        @Override
+        public void onPageScrollStateChanged(int state) {
+            if (state == ViewPager.SCROLL_STATE_IDLE) {
+                //updateCurrentTab(mCurPos);
+            }
+        }
+    }
+
+    private void resetAdapter() {
+        // trigger adapter load, preserving the selected page
+        int curPos = mAdapter.getCurrentPage();
+        mViewPager.setAdapter(mAdapter);
+        mViewPager.setOnPageChangeListener(mAdapter);
+        mViewPager.setCurrentItem(curPos);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        // initialize the inflater
+        mInflater = inflater;
+
+        View rootView = mInflater.inflate(R.layout.app_ops_summary,
+                container, false);
+        mContentContainer = container;
+        mRootView = rootView;
+
+        CharSequence[] pageNames = getResources().getTextArray(R.array.app_ops_categories_lineage);
+        AppOpsState.OpsTemplate[] templates = AppOpsState.ALL_PERMS_TEMPLATES;
+        assert(pageNames.length == templates.length);
+
+        int specificTab = -1;
+        Bundle bundle = getArguments();
+        if (bundle != null) {
+            specificTab = Arrays.asList(pageNames).indexOf(bundle.getString("appops_tab", ""));
+        }
+
+        List<Pair<CharSequence, AppOpsState.OpsTemplate>> pageData = new ArrayList<>();
+        for (int i = 0; i < pageNames.length; i++) {
+            pageData.add(Pair.create(pageNames[i], templates[i]));
+        }
+        filterPageData(pageData, specificTab);
+
+        mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
+        mAdapter = new MyPagerAdapter(getChildFragmentManager(), pageData);
+        mViewPager.setAdapter(mAdapter);
+        mViewPager.setOnPageChangeListener(mAdapter);
+        PagerTabStrip tabs = (PagerTabStrip) rootView.findViewById(R.id.tabs);
+
+        // HACK - https://code.google.com/p/android/issues/detail?id=213359
+        ((ViewPager.LayoutParams) tabs.getLayoutParams()).isDecor = true;
+
+        Resources.Theme theme = tabs.getContext().getTheme();
+        TypedValue typedValue = new TypedValue();
+        theme.resolveAttribute(android.R.attr.colorAccent, typedValue, true);
+        final int colorAccent = getContext().getColor(typedValue.resourceId);
+        tabs.setTabIndicatorColor(colorAccent);
+
+        // We have to do this now because PreferenceFrameLayout looks at it
+        // only when the view is added.
+        if (container instanceof PreferenceFrameLayout) {
+            ((PreferenceFrameLayout.LayoutParams) rootView.getLayoutParams()).removeBorders = true;
+        }
+
+        mActivity = getActivity();
+
+        return rootView;
+    }
+
+    private void filterPageData(List<Pair<CharSequence, AppOpsState.OpsTemplate>> data, int tab) {
+        if (tab >= 0 && tab < data.size()) {
+            Pair<CharSequence, AppOpsState.OpsTemplate> item = data.get(tab);
+            data.clear();
+            data.add(item);
+        } else if (!RootAccessPreferenceController.isRootForAppsEnabled()) {
+            for (Pair<CharSequence, AppOpsState.OpsTemplate> item : data) {
+                if (item.second == AppOpsState.SU_TEMPLATE) {
+                    data.remove(item);
+                    return;
+                }
+            }
+        }
+    }
+
+    private boolean shouldShowUserApps() {
+        return mPreferences.getBoolean("show_user_apps", true);
+    }
+
+    private boolean shouldShowSystemApps() {
+        return mPreferences.getBoolean("show_system_apps", true);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        // get shared preferences
+        mPreferences = mActivity.getSharedPreferences("appops_manager", Activity.MODE_PRIVATE);
+
+        setHasOptionsMenu(true);
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.appops_manager, menu);
+        menu.findItem(R.id.show_user_apps).setChecked(shouldShowUserApps());
+        menu.findItem(R.id.show_system_apps).setChecked(shouldShowSystemApps());
+    }
+
+    private void resetCounters() {
+        final AppOpsManager appOps =
+                (AppOpsManager) mActivity.getSystemService(Context.APP_OPS_SERVICE);
+        if (appOps == null) {
+            return;
+        }
+        appOps.resetCounters();
+        // reload content
+        resetAdapter();
+    }
+
+    private void resetCountersConfirm() {
+        new AlertDialog.Builder(getActivity())
+            .setIcon(android.R.drawable.ic_dialog_alert)
+            .setTitle(R.string.app_ops_reset_confirm_title)
+            .setMessage(R.string.app_ops_reset_confirm_mesg)
+            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
+                {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        resetCounters();
+                    }
+                })
+            .setNegativeButton(android.R.string.cancel, null)
+            .show();
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.show_user_apps:
+                final String prefNameUserApps = "show_user_apps";
+                // set the menu checkbox and save it in shared preference
+                item.setChecked(!item.isChecked());
+                mPreferences.edit().putBoolean(prefNameUserApps, item.isChecked()).commit();
+                // reload content
+                resetAdapter();
+                return true;
+            case R.id.show_system_apps:
+                final String prefNameSysApps = "show_system_apps";
+                // set the menu checkbox and save it in shared preference
+                item.setChecked(!item.isChecked());
+                mPreferences.edit().putBoolean(prefNameSysApps, item.isChecked()).commit();
+                // reload view content
+                resetAdapter();
+                return true;
+            case R.id.reset_counters:
+                resetCountersConfirm();
+                return true;
+            default:
+                return super.onContextItemSelected(item);
+        }
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/usb/UsbBackend.java b/src/com/android/settings/connecteddevice/usb/UsbBackend.java
index 54811c8..9b0dcec 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbBackend.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbBackend.java
@@ -153,6 +153,30 @@
                 .isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
     }
 
+    public boolean isSingleDataRoleSupported() {
+        return mPort != null && mPortStatus != null
+                && ((!mPortStatus
+                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST)
+                && !mPortStatus
+                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST))
+                || (!mPortStatus
+                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE)
+                && !mPortStatus
+                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE)));
+    }
+
+    public boolean isSinglePowerRoleSupported() {
+        return mPort != null && mPortStatus != null
+                && ((!mPortStatus
+                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE)
+                && !mPortStatus
+                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST))
+                || (!mPortStatus
+                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE)
+                && !mPortStatus
+                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST)));
+    }
+
     public static String usbFunctionsToString(long functions) {
         // TODO replace with UsbManager.usbFunctionsToString once supported by Roboelectric
         return Long.toBinaryString(functions);
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsDataRoleController.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsDataRoleController.java
index 93ff19e..6474419 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbDetailsDataRoleController.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsDataRoleController.java
@@ -109,7 +109,8 @@
 
     @Override
     public boolean isAvailable() {
-        return !Utils.isMonkeyRunning();
+        return !Utils.isMonkeyRunning()
+                && !mUsbBackend.isSingleDataRoleSupported();
     }
 
     @Override
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsPowerRoleController.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsPowerRoleController.java
index 77a7eb4..ae57129 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbDetailsPowerRoleController.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsPowerRoleController.java
@@ -118,7 +118,8 @@
 
     @Override
     public boolean isAvailable() {
-        return !Utils.isMonkeyRunning();
+        return !Utils.isMonkeyRunning()
+                && !mUsbBackend.isSinglePowerRoleSupported();
     }
 
     @Override
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 20a80d1..75acb64 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -57,7 +57,8 @@
 public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment
         implements SwitchBar.OnSwitchChangeListener, OemUnlockDialogHost, AdbDialogHost,
         AdbClearKeysDialogHost, LogPersistDialogHost,
-        BluetoothA2dpHwOffloadRebootDialog.OnA2dpHwDialogConfirmedListener {
+        BluetoothA2dpHwOffloadRebootDialog.OnA2dpHwDialogConfirmedListener,
+        RootAccessDialogHost {
 
     private static final String TAG = "DevSettingsDashboard";
 
@@ -278,6 +279,20 @@
     }
 
     @Override
+    public void onRootAccessDialogConfirmed() {
+        final RootAccessPreferenceController controller =
+                getDevelopmentOptionsController(RootAccessPreferenceController.class);
+        controller.onRootAccessDialogConfirmed();
+    }
+
+    @Override
+    public void onRootAccessDialogDismissed() {
+        final RootAccessPreferenceController controller =
+                getDevelopmentOptionsController(RootAccessPreferenceController.class);
+        controller.onRootAccessDialogDismissed();
+    }
+
+    @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         boolean handledResult = false;
         for (AbstractPreferenceController controller : mPreferenceControllers) {
@@ -455,6 +470,8 @@
         controllers.add(new FreeformWindowsPreferenceController(context));
         controllers.add(new ShortcutManagerThrottlingPreferenceController(context));
         controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context));
+        controllers.add(new RootAccessPreferenceController(context, fragment));
+        controllers.add(new RootAppOpsPreferenceController(context));
         controllers.add(new DefaultLaunchPreferenceController(context, "running_apps"));
         controllers.add(new DefaultLaunchPreferenceController(context, "demo_mode"));
         controllers.add(new DefaultLaunchPreferenceController(context, "quick_settings_tiles"));
diff --git a/src/com/android/settings/development/RootAccessDialogHost.java b/src/com/android/settings/development/RootAccessDialogHost.java
new file mode 100644
index 0000000..4a31ae8
--- /dev/null
+++ b/src/com/android/settings/development/RootAccessDialogHost.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+/**
+ * Interface for RootAccessWarningDialogFragment callbacks.
+ */
+public interface RootAccessDialogHost {
+
+    /**
+     * Called when the user presses ok on the warning dialog.
+     */
+    void onRootAccessDialogConfirmed();
+
+    /**
+     * Called when the user dismisses or cancels the warning dialog.
+     */
+    void onRootAccessDialogDismissed();
+}
diff --git a/src/com/android/settings/development/RootAccessPreferenceController.java b/src/com/android/settings/development/RootAccessPreferenceController.java
new file mode 100644
index 0000000..84e53d8
--- /dev/null
+++ b/src/com/android/settings/development/RootAccessPreferenceController.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import android.content.Context;
+import android.os.Build;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+import java.io.File;
+
+public class RootAccessPreferenceController extends DeveloperOptionsPreferenceController
+        implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
+
+    private static final String TAG = "RootAccessPreferenceController";
+    private static final String PREF_KEY = "root_access";
+
+    private static final String ROOT_ACCESS_PROPERTY = "persist.sys.root_access";
+
+    private final DevelopmentSettingsDashboardFragment mFragment;
+    private Object mPendingRootAccessValue;
+
+    public RootAccessPreferenceController(Context context,
+            DevelopmentSettingsDashboardFragment fragment) {
+        super(context);
+
+        mFragment = fragment;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        // User builds don't get root, and eng always gets root
+        return Build.IS_DEBUGGABLE || "eng".equals(Build.TYPE);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return PREF_KEY;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        File file = new File("/system/xbin/su");
+
+        if (file.exists()) {
+            ((ListPreference) mPreference).setEntries(R.array.root_access_entries);
+            ((ListPreference) mPreference).setEntryValues(R.array.root_access_values);
+        } else {
+            ((ListPreference) mPreference).setEntries(R.array.root_access_entries_adb);
+            ((ListPreference) mPreference).setEntryValues(R.array.root_access_values_adb);
+        }
+
+        updatePreference();
+
+        if (!isAdminUser()) {
+            mPreference.setEnabled(false);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if ("0".equals(newValue.toString())) {
+            writeRootAccessOptions(newValue);
+        } else {
+            mPendingRootAccessValue = newValue;
+            RootAccessWarningDialog.show(mFragment);
+        }
+        return true;
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        if (isAdminUser()) {
+            mPreference.setEnabled(true);
+        }
+    }
+
+    public void onRootAccessDialogConfirmed() {
+        writeRootAccessOptions(mPendingRootAccessValue);
+    }
+
+    public void onRootAccessDialogDismissed() {
+        updatePreference();
+    }
+
+    public static boolean isRootForAppsEnabled() {
+        int value = SystemProperties.getInt(ROOT_ACCESS_PROPERTY, 0);
+        boolean daemonState =
+                SystemProperties.get("init.svc.su_daemon", "absent").equals("running");
+        return daemonState && (value == 1 || value == 3);
+    }
+
+    private void writeRootAccessOptions(Object newValue) {
+        String oldValue = SystemProperties.get(ROOT_ACCESS_PROPERTY, "0");
+        SystemProperties.set(ROOT_ACCESS_PROPERTY, newValue.toString());
+        if (Integer.valueOf(newValue.toString()) < 2 && !oldValue.equals(newValue)
+                && SystemProperties.getInt("service.adb.root", 0) == 1) {
+            SystemProperties.set("service.adb.root", "0");
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.ADB_ENABLED, 0);
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.ADB_ENABLED, 1);
+        }
+        updatePreference();
+    }
+
+    private void updatePreference() {
+        String value = SystemProperties.get(ROOT_ACCESS_PROPERTY, "0");
+        ((ListPreference) mPreference).setValue(value);
+        ((ListPreference) mPreference).setSummary(mContext.getResources()
+                .getStringArray(R.array.root_access_entries)[Integer.valueOf(value)]);
+    }
+
+    @VisibleForTesting
+    boolean isAdminUser() {
+        return ((UserManager) mContext.getSystemService(Context.USER_SERVICE)).isAdminUser();
+    }
+}
diff --git a/src/com/android/settings/development/RootAccessWarningDialog.java b/src/com/android/settings/development/RootAccessWarningDialog.java
new file mode 100644
index 0000000..a102c98
--- /dev/null
+++ b/src/com/android/settings/development/RootAccessWarningDialog.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class RootAccessWarningDialog extends InstrumentedDialogFragment implements
+        DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+
+    public static final String TAG = "RootAccessWarningDialog";
+
+    public static void show(Fragment host) {
+        final FragmentManager manager = host.getActivity().getFragmentManager();
+        if (manager.findFragmentByTag(TAG) == null) {
+            final RootAccessWarningDialog dialog =
+                    new RootAccessWarningDialog();
+            dialog.setTargetFragment(host, 0 /* requestCode */);
+            dialog.show(manager, TAG);
+        }
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.TYPE_UNKNOWN;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        return new AlertDialog.Builder(getActivity())
+                .setTitle(R.string.root_access_warning_title)
+                .setMessage(R.string.root_access_warning_message)
+                .setPositiveButton(android.R.string.ok, this /* onClickListener */)
+                .setNegativeButton(android.R.string.cancel, this /* onClickListener */)
+                .create();
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        final RootAccessDialogHost host = (RootAccessDialogHost) getTargetFragment();
+        if (host == null) {
+            return;
+        }
+        if (which == DialogInterface.BUTTON_POSITIVE) {
+            host.onRootAccessDialogConfirmed();
+        } else {
+            host.onRootAccessDialogDismissed();
+        }
+    }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        super.onDismiss(dialog);
+        final RootAccessDialogHost host = (RootAccessDialogHost) getTargetFragment();
+        if (host == null) {
+            return;
+        }
+        host.onRootAccessDialogDismissed();
+    }
+}
diff --git a/src/com/android/settings/development/RootAppOpsPreferenceController.java b/src/com/android/settings/development/RootAppOpsPreferenceController.java
new file mode 100644
index 0000000..7a6b0f1
--- /dev/null
+++ b/src/com/android/settings/development/RootAppOpsPreferenceController.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.ServiceManager;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.Settings.AppOpsSummaryActivity;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS;
+
+public class RootAppOpsPreferenceController extends DeveloperOptionsPreferenceController
+        implements Preference.OnPreferenceClickListener, PreferenceControllerMixin {
+
+    private static final String TAG = "RootAppOpsPreferenceController";
+    private static final String PREF_KEY = "root_appops";
+
+    public RootAppOpsPreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        // User builds don't get root, and eng always gets root
+        return Build.IS_DEBUGGABLE || "eng".equals(Build.TYPE);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return PREF_KEY;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        mPreference.setOnPreferenceClickListener(this);
+
+        if (!RootAccessPreferenceController.isRootForAppsEnabled() || !isAdminUser()) {
+            mPreference.setEnabled(false);
+        }
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        if (isAdminUser()) {
+            mPreference.setEnabled(true);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceClick(Preference preference) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        Bundle args = new Bundle();
+        args.putString("appops_tab",
+                mContext.getResources().getString(R.string.app_ops_categories_su));
+        intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
+        intent.setClass(mContext, AppOpsSummaryActivity.class);
+        mContext.startActivity(intent);
+        return true;
+    }
+
+    @VisibleForTesting
+    boolean isAdminUser() {
+        return ((UserManager) mContext.getSystemService(Context.USER_SERVICE)).isAdminUser();
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java b/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java
index 6169b44..c6d399b 100644
--- a/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java
+++ b/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 Fairphone B.V.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,6 +24,7 @@
 import android.os.SystemProperties;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.TextView;
@@ -31,10 +33,33 @@
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 
+import com.fairphone.common.modules.BatteryModule;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 public class HardwareInfoDialogFragment extends InstrumentedDialogFragment {
 
     public static final String TAG = "HardwareInfo";
 
+    private static final String ASSEMBLY_NUMBER_FILE = "/persist/phoneid.bin";
+    private static final String FILENAME_PROC_CPUINFO = "/proc/cpuinfo";
+    private static final String KEY_RECEIVER_MODULE_INFO = "receiver_module_info";
+    private static final String PROPERTY_FRONT_CAMERA_SENSOR = "fp2.cam.front.sensor";
+    private static final String VALUE_FRONT_CAMERA_SENSOR_OV2685 = "ov2685";
+    private static final String VALUE_FRONT_CAMERA_SENSOR_OV5670 = "ov5670";
+    private static final String KEY_CAMERA_MODULE_INFO = "camera_module_info";
+    private static final String PROPERTY_MAIN_CAMERA_SENSOR = "fp2.cam.main.sensor";
+    private static final String VALUE_MAIN_CAMERA_SENSOR_OV8865 = "ov8865_q8v18a";
+    private static final String VALUE_MAIN_CAMERA_SENSOR_OV12870 = "ov12870";
+    private static final String KEY_BATTERY_MODULE_INFO = "battery_module_info";
+
     @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.DIALOG_SETTINGS_HARDWARE_INFO;
@@ -63,6 +88,24 @@
         setText(content, R.id.hardware_rev_label, R.id.hardware_rev_value,
                 SystemProperties.get("ro.boot.hardware.revision"));
 
+        // Assembly number
+        setText(content, R.id.assembly_number_label, R.id.assembly_number_value,
+                getAssemblyNumber());
+
+        // Processor
+        setText(content, R.id.processor_label, R.id.processor_value, getProcessorInfo());
+
+        // Receiver module
+        setText(content, R.id.receiver_module_label, R.id.receiver_module_value,
+                getReceiverModuleInfo());
+
+        // Camera module
+        setText(content, R.id.camera_module_label, R.id.camera_module_value, getCameraModuleInfo());
+
+        // Battery module
+        setText(content, R.id.battery_module_label, R.id.battery_module_value,
+                getBatteryModuleInfo());
+
         return builder.setView(content).create();
     }
 
@@ -87,4 +130,118 @@
     String getSerialNumber() {
         return Build.getSerial();
     }
+
+    private static String getAssemblyNumber() {
+        String assemblyNumber = null;
+        FileInputStream input = null;
+
+        try {
+            input = new FileInputStream(new File(ASSEMBLY_NUMBER_FILE));
+            final byte[] bytes = new byte[input.available()];
+
+            input.read(bytes);
+            assemblyNumber = new String(bytes, "ASCII");
+        } catch (FileNotFoundException e) {
+            Log.wtf(TAG, "Assembly number file not found", e);
+        } catch(IOException e) {
+            Log.wtf(TAG, "Could not read the assembly number file", e);
+        } finally {
+            try {
+                if (input != null) {
+                    input.close();
+                }
+            } catch (Exception e) {
+                Log.wtf(TAG, e);
+            }
+        }
+
+        return assemblyNumber;
+    }
+
+    /**
+     * Returns the Hardware value in /proc/cpuinfo, else returns "Unknown".
+     * @return a string that describes the processor
+     */
+    private static String getProcessorInfo() {
+        // Hardware : XYZ
+        final String PROC_HARDWARE_REGEX = "Hardware\\s*:\\s*(.*)$"; /* hardware string */
+
+        try {
+            BufferedReader reader = new BufferedReader(new FileReader(FILENAME_PROC_CPUINFO));
+            String cpuinfo;
+
+            try {
+                while (null != (cpuinfo = reader.readLine())) {
+                    if (cpuinfo.startsWith("Hardware")) {
+                        Matcher m = Pattern.compile(PROC_HARDWARE_REGEX).matcher(cpuinfo);
+                        if (m.matches()) {
+                            return m.group(1);
+                        }
+                    }
+                }
+                return "Unknown";
+            } finally {
+                reader.close();
+            }
+        } catch (IOException e) {
+            Log.e(TAG,
+                "IO Exception when getting cpuinfo for Device Info screen",
+                e);
+
+            return "Unknown";
+        }
+    }
+
+    private String getReceiverModuleInfo() {
+        final String frontCameraSensor = SystemProperties.get(PROPERTY_FRONT_CAMERA_SENSOR);
+        String info;
+
+        if (VALUE_FRONT_CAMERA_SENSOR_OV2685.equals(frontCameraSensor)) {
+            info = getResources().getString(R.string.receiver_module_ov2685);
+        } else if (VALUE_FRONT_CAMERA_SENSOR_OV5670.equals(frontCameraSensor)) {
+            info = getResources().getString(R.string.receiver_module_ov5670);
+        } else {
+            // Unexpected property value, or missing
+            info = getResources().getString(R.string.device_info_default);
+            Log.w(TAG, "Property " + PROPERTY_FRONT_CAMERA_SENSOR
+                    + " has an unknown value of " + frontCameraSensor);
+        }
+
+        return info;
+    }
+
+    private String getCameraModuleInfo() {
+        final String mainCameraSensor = SystemProperties.get(PROPERTY_MAIN_CAMERA_SENSOR);
+        String info;
+
+        if (VALUE_MAIN_CAMERA_SENSOR_OV8865.equals(mainCameraSensor)) {
+            info = getResources().getString(R.string.camera_module_ov8865);
+        } else if (VALUE_MAIN_CAMERA_SENSOR_OV12870.equals(mainCameraSensor)) {
+            info = getResources().getString(R.string.camera_module_ov12870);
+        } else {
+            // Unexpected property value, or missing
+            info = getResources().getString(R.string.device_info_default);
+            Log.w(TAG, "Property " + PROPERTY_MAIN_CAMERA_SENSOR
+                    + " has an unknown value of " + mainCameraSensor);
+        }
+
+        return info;
+    }
+
+    private String getBatteryModuleInfo() {
+       final BatteryModule module = BatteryModule.getModule(getContext());
+       String info;
+
+       if (module != null) {
+           info = getResources().getString(R.string.battery_module_summary,
+                   module.getVersionId(), module.getDesignCapacity());
+       } else {
+           info = getResources().getString(R.string.device_info_default);
+
+           Log.w(TAG, "Unknown battery module, property " + KEY_BATTERY_MODULE_INFO
+                   + " set to default value");
+       }
+
+       return info;
+   }
 }
diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
index f9555e2..d745115 100644
--- a/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
+++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoDialogController.java
@@ -89,7 +89,8 @@
 
     private void updateDialogForCdmaPhone() {
         final Resources res = mDialog.getContext().getResources();
-        mDialog.setText(ID_MEID_NUMBER_VALUE, getMeid());
+        mDialog.setText(ID_MEID_NUMBER_VALUE,
+                mSubscriptionInfo != null ? getMeid() : "");
         mDialog.setText(ID_MIN_NUMBER_VALUE,
                 mSubscriptionInfo != null ? mTelephonyManager.getCdmaMin(
                         mSubscriptionInfo.getSubscriptionId()) : "");
@@ -114,9 +115,13 @@
     }
 
     private void updateDialogForGsmPhone() {
-        mDialog.setText(ID_IMEI_VALUE, getTextAsDigits(mTelephonyManager.getImei(mSlotId)));
+        mDialog.setText(ID_IMEI_VALUE,
+                mSubscriptionInfo != null ?
+                getTextAsDigits(mTelephonyManager.getImei(mSlotId)) : "");
         mDialog.setText(ID_IMEI_SV_VALUE,
-                getTextAsDigits(mTelephonyManager.getDeviceSoftwareVersion(mSlotId)));
+                mSubscriptionInfo != null ?
+                getTextAsDigits(mTelephonyManager.
+                        getDeviceSoftwareVersion(mSlotId)) : "");
         // device is not CDMA, do not display CDMA features
         mDialog.removeViewFromScreen(ID_CDMA_SETTINGS);
     }
@@ -127,8 +132,12 @@
         if (subscriptionInfoList == null) {
             return null;
         }
-
-        return subscriptionInfoList.get(slotId);
+        for (SubscriptionInfo info : subscriptionInfoList) {
+            if (slotId == info.getSimSlotIndex()) {
+                return info;
+            }
+        }
+        return null;
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
index 7cbf318..76daa62 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
@@ -409,11 +409,15 @@
     private SubscriptionInfo getPhoneSubscriptionInfo(int slotId) {
         final List<SubscriptionInfo> subscriptionInfoList = SubscriptionManager.from(
                 mContext).getActiveSubscriptionInfoList();
-        if (subscriptionInfoList != null && subscriptionInfoList.size() > slotId) {
-            return subscriptionInfoList.get(slotId);
-        } else {
+        if (subscriptionInfoList == null) {
             return null;
         }
+        for (SubscriptionInfo info : subscriptionInfoList) {
+            if (slotId == info.getSimSlotIndex()) {
+                return info;
+            }
+        }
+        return null;
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/security/CryptKeeperSettings.java b/src/com/android/settings/security/CryptKeeperSettings.java
index 64f5abb..f6b510a 100644
--- a/src/com/android/settings/security/CryptKeeperSettings.java
+++ b/src/com/android/settings/security/CryptKeeperSettings.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2020-2021 Fairphone B.V.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -58,6 +59,7 @@
     private Button mInitiateButton;
     private View mPowerWarning;
     private View mBatteryWarning;
+    private View mUnsupportedMesssage;
     private IntentFilter mIntentFilter;
 
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -76,9 +78,12 @@
                      invalidCharger == 0;
 
                 // Update UI elements based on power/battery status
-                mInitiateButton.setEnabled(levelOk && pluggedOk);
-                mPowerWarning.setVisibility(pluggedOk ? View.GONE : View.VISIBLE );
-                mBatteryWarning.setVisibility(levelOk ? View.GONE : View.VISIBLE);
+                // mInitiateButton.setEnabled(levelOk && pluggedOk);
+                // mPowerWarning.setVisibility(pluggedOk ? View.GONE : View.VISIBLE );
+                // mBatteryWarning.setVisibility(levelOk ? View.GONE : View.VISIBLE);
+
+                // Encryption is disabled in the current version of Fairphone OS.
+                mInitiateButton.setEnabled(false);
             }
         }
     };
@@ -116,6 +121,7 @@
 
         mPowerWarning = mContentView.findViewById(R.id.warning_unplugged);
         mBatteryWarning = mContentView.findViewById(R.id.warning_low_charge);
+        mUnsupportedMesssage = mContentView.findViewById(R.id.message_unsupported);
 
         return mContentView;
     }
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index 853f80d..4b68430 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -40,6 +40,8 @@
 import android.widget.Toast;
 
 import com.android.settings.R;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -96,6 +98,7 @@
                     PhoneAccountHandle phoneAccountHandle =
                             subscriptionIdToPhoneAccountHandle(subId);
                     setDefaultDataSubId(context, subId);
+                    setPreferredNetworkMode(context, subId);
                     setDefaultSmsSubId(context, subId);
                     setUserSelectedOutgoingPhoneAccount(phoneAccountHandle);
                     finish();
@@ -115,6 +118,41 @@
         }
     }
 
+    private void setPreferredNetworkMode(Context context,int subId) {
+        final Phone[] phones = (Phone[])PhoneFactory.getPhones();
+        final Phone mPhone1, mPhone2;
+
+        // As we have only 2 slot
+        mPhone1 = phones[0];
+        mPhone2 = phones[1];
+
+        if (mPhone1.getSubId() == subId ) {
+            android.provider.Settings.Global.putInt(
+                context.getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mPhone2.getSubId(),
+                Phone.NT_MODE_GSM_ONLY);
+            mPhone2.setPreferredNetworkType(Phone.NT_MODE_GSM_ONLY, null);
+
+            android.provider.Settings.Global.putInt(
+                context.getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mPhone1.getSubId(),
+                Phone.NT_MODE_LTE_GSM_WCDMA);
+            mPhone1.setPreferredNetworkType(Phone.NT_MODE_LTE_GSM_WCDMA, null);
+          } else {
+            android.provider.Settings.Global.putInt(
+                context.getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mPhone1.getSubId(),
+                Phone.NT_MODE_GSM_ONLY);
+            mPhone1.setPreferredNetworkType(Phone.NT_MODE_GSM_ONLY, null);
+
+            android.provider.Settings.Global.putInt(
+                context.getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mPhone2.getSubId(),
+                Phone.NT_MODE_LTE_GSM_WCDMA);
+            mPhone2.setPreferredNetworkType(Phone.NT_MODE_LTE_GSM_WCDMA, null);
+          }
+    }
+
     private static void setDefaultDataSubId(final Context context, final int subId) {
         final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
         subscriptionManager.setDefaultDataSubId(subId);
@@ -166,6 +204,7 @@
                             case DATA_PICK:
                                 sir = subInfoList.get(value);
                                 setDefaultDataSubId(context, sir.getSubscriptionId());
+                                setPreferredNetworkMode(context, sir.getSubscriptionId());
                                 break;
                             case CALLS_PICK:
                                 final TelecomManager telecomManager =