summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Mortimer <sam@mortimer.me.uk>2014-11-14 23:15:15 -0800
committerRoman Birg <roman@cyngn.com>2015-11-03 12:21:35 -0800
commitdb521697716ce627bb9dd574de86e60b756ca2fa (patch)
tree2eb2f067129e8d059f66a1d9fa0b7d75f7993527
parent45b8df16fd9f45f5bb4f4ecb72dbd567e829dcbd (diff)
downloadpackages_apps_Settings-db521697716ce627bb9dd574de86e60b756ca2fa.zip
packages_apps_Settings-db521697716ce627bb9dd574de86e60b756ca2fa.tar.gz
packages_apps_Settings-db521697716ce627bb9dd574de86e60b756ca2fa.tar.bz2
[2/2] Settings: Privacy Guard
PS2: * add ic_privacy_guard*.png from frameworks/base * rebase PS3: * enable AppOpsSummaryActivity * use SubSettings on longclick PS4: * move privacyguard settings category to just below security PS5: * rebase Pulled together mostly (if not all) from: Author: Steve Kondik <shade@chemlab.org> Date: Tue Feb 25 14:02:16 2014 +0100 settings: Relocate Privacy Guard icons to framework * So we can use them in the permission dialog for MODE_ASK Change-Id: Ia9bac7dff0bbe91ae48db5d4b0d8f46feb9fdf86 Author: DvTonder <david.vantonder@gmail.com> Date: Thu Jan 16 19:01:23 2014 -0500 Settings: Fix up top level "Privacy" section Change-Id: Id4dbda10a891c793bc6eb3c42807cc0e3f6092cc Author: Danny Baumann <dannybaumann@web.de> Date: Fri Nov 8 13:37:07 2013 +0100 Add back privacy guard manager. Change-Id: Ic9fbbae137bb8425fe72a6cdb2f17117351b5709 Author: Chirayu Desai <cdesai@cyanogenmod.org> Date: Sat Dec 28 18:51:46 2013 +0530 PrivacyGuard: Specify a default value in Settings.getInt method call * While privacy guard is enabled by default, the default value specified here is returned only when the setting is not defined or not an integer. Change-Id: Iaedffcc76a23a310aa7915f6a42ccce83ba5d2a6 Author: Matt Mower <mowerm@gmail.com> Date: Wed Feb 5 19:40:37 2014 -0600 PrivacyGuard: confirm permissions reset The button to reset all application permissions to enabled looks suspiciously like a refresh button. Prompt the user with a confirmation dialog to make sure they know what they've pressed. Change-Id: I0444c5bf8e9533feccf890055d34d3200609c6f6 Change-Id: I2e10cb4d395e2e7e5141d2fadada9e9b21cd7fbf
-rw-r--r--AndroidManifest.xml4
-rw-r--r--proguard.flags3
-rw-r--r--res/drawable-hdpi/ic_privacy_guard.pngbin0 -> 1523 bytes
-rw-r--r--res/drawable-hdpi/ic_privacy_guard_off.pngbin0 -> 1810 bytes
-rw-r--r--res/drawable-hdpi/ic_settings_privacy.pngbin0 -> 722 bytes
-rw-r--r--res/drawable-mdpi/ic_privacy_guard.pngbin0 -> 1250 bytes
-rw-r--r--res/drawable-mdpi/ic_privacy_guard_off.pngbin0 -> 1507 bytes
-rw-r--r--res/drawable-mdpi/ic_settings_privacy.pngbin0 -> 515 bytes
-rw-r--r--res/drawable-xhdpi/ic_privacy_guard.pngbin0 -> 1579 bytes
-rw-r--r--res/drawable-xhdpi/ic_privacy_guard_off.pngbin0 -> 1642 bytes
-rw-r--r--res/drawable-xhdpi/ic_settings_privacy.pngbin0 -> 1069 bytes
-rw-r--r--res/drawable-xxhdpi/ic_privacy_guard.pngbin0 -> 1694 bytes
-rw-r--r--res/drawable-xxhdpi/ic_privacy_guard_off.pngbin0 -> 1743 bytes
-rw-r--r--res/drawable-xxhdpi/ic_settings_privacy.pngbin0 -> 1611 bytes
-rw-r--r--res/layout/privacy_guard_manager.xml46
-rw-r--r--res/layout/privacy_guard_manager_list_row.xml49
-rw-r--r--res/menu/privacy_guard_manager.xml29
-rw-r--r--res/values/arrays.xml72
-rw-r--r--res/values/cm_strings.xml21
-rw-r--r--res/xml/dashboard_categories.xml9
-rw-r--r--res/xml/privacy_guard_prefs.xml26
-rw-r--r--res/xml/privacy_settings_cyanogenmod.xml26
-rw-r--r--src/com/android/settings/SettingsActivity.java7
-rw-r--r--src/com/android/settings/applications/AppOpsState.java3
-rw-r--r--src/com/android/settings/cyanogenmod/PrivacySettings.java48
-rw-r--r--src/com/android/settings/privacyguard/PrivacyGuardAppListAdapter.java185
-rw-r--r--src/com/android/settings/privacyguard/PrivacyGuardManager.java423
-rw-r--r--src/com/android/settings/privacyguard/PrivacyGuardPrefs.java89
28 files changed, 982 insertions, 58 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2c4c9aa..4798382 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1123,7 +1123,7 @@
<activity android:name="Settings$AppOpsSummaryActivity"
android:label="@string/app_ops_settings"
android:taskAffinity=""
- android:enabled="false">
+ android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.APP_OPS_SETTINGS" />
@@ -2524,6 +2524,8 @@
<activity android:name=".notificationlight.NotificationLightSettings" />
<activity android:name=".notificationlight.BatteryLightSettings" />
+ <activity android:name=".cyanogenmod.PrivacySettings" />
+
<receiver android:name=".widget.SettingsAppWidgetProvider"
android:label="@string/gadget_title"
android:exported="false"
diff --git a/proguard.flags b/proguard.flags
index 991c31c..22d7de6 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -18,6 +18,9 @@
-keep class com.android.settings.notification.*
-keep class com.android.settings.cyanogenmod.*
+-keep class com.android.settings.cyanogenmod.*Settings
+-keep class com.android.settings.privacyguard.*
+
# Keep click responders
-keepclassmembers class com.android.settings.inputmethod.UserDictionaryAddWordActivity {
*** onClick*(...);
diff --git a/res/drawable-hdpi/ic_privacy_guard.png b/res/drawable-hdpi/ic_privacy_guard.png
new file mode 100644
index 0000000..0f58fce
--- /dev/null
+++ b/res/drawable-hdpi/ic_privacy_guard.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_privacy_guard_off.png b/res/drawable-hdpi/ic_privacy_guard_off.png
new file mode 100644
index 0000000..f5dce61
--- /dev/null
+++ b/res/drawable-hdpi/ic_privacy_guard_off.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_settings_privacy.png b/res/drawable-hdpi/ic_settings_privacy.png
new file mode 100644
index 0000000..60ceeb8
--- /dev/null
+++ b/res/drawable-hdpi/ic_settings_privacy.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_privacy_guard.png b/res/drawable-mdpi/ic_privacy_guard.png
new file mode 100644
index 0000000..a749b20
--- /dev/null
+++ b/res/drawable-mdpi/ic_privacy_guard.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_privacy_guard_off.png b/res/drawable-mdpi/ic_privacy_guard_off.png
new file mode 100644
index 0000000..8d9db2e
--- /dev/null
+++ b/res/drawable-mdpi/ic_privacy_guard_off.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_settings_privacy.png b/res/drawable-mdpi/ic_settings_privacy.png
new file mode 100644
index 0000000..6fcb431
--- /dev/null
+++ b/res/drawable-mdpi/ic_settings_privacy.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_privacy_guard.png b/res/drawable-xhdpi/ic_privacy_guard.png
new file mode 100644
index 0000000..f7b4a4c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_privacy_guard.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_privacy_guard_off.png b/res/drawable-xhdpi/ic_privacy_guard_off.png
new file mode 100644
index 0000000..6425549
--- /dev/null
+++ b/res/drawable-xhdpi/ic_privacy_guard_off.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_settings_privacy.png b/res/drawable-xhdpi/ic_settings_privacy.png
new file mode 100644
index 0000000..2faa6d5
--- /dev/null
+++ b/res/drawable-xhdpi/ic_settings_privacy.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_privacy_guard.png b/res/drawable-xxhdpi/ic_privacy_guard.png
new file mode 100644
index 0000000..b432ed4
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_privacy_guard.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_privacy_guard_off.png b/res/drawable-xxhdpi/ic_privacy_guard_off.png
new file mode 100644
index 0000000..c1964f4
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_privacy_guard_off.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_settings_privacy.png b/res/drawable-xxhdpi/ic_settings_privacy.png
new file mode 100644
index 0000000..52206b1
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_settings_privacy.png
Binary files differ
diff --git a/res/layout/privacy_guard_manager.xml b/res/layout/privacy_guard_manager.xml
new file mode 100644
index 0000000..98d9ae4
--- /dev/null
+++ b/res/layout/privacy_guard_manager.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 Slimroms 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:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <fragment
+ android:id="@+id/privacy_guard_prefs"
+ android:name="com.android.settings.privacyguard.PrivacyGuardPrefs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <TextView
+ android:id="@+id/error"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="20dip"
+ android:layout_gravity="center"
+ android:gravity="center_horizontal"
+ android:textColor="@android:color/white"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:visibility="gone" />
+ <ListView android:id="@+id/apps_list"
+ android:drawSelectorOnTop="false"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:scrollbarStyle="@*android:integer/preference_fragment_scrollbarStyle" />
+</LinearLayout>
diff --git a/res/layout/privacy_guard_manager_list_row.xml b/res/layout/privacy_guard_manager_list_row.xml
new file mode 100644
index 0000000..eb6a327
--- /dev/null
+++ b/res/layout/privacy_guard_manager_list_row.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 Slimroms 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.
+-->
+
+<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip" >
+ <ImageView
+ android:id="@+id/app_icon"
+ android:layout_width="36dip"
+ android:layout_height="36dip"
+ android:layout_marginEnd="8dip"
+ android:layout_gravity="center_vertical"
+ android:scaleType="centerInside"
+ android:contentDescription="@null" />
+ <TextView
+ android:id="@+id/app_title"
+ android:layout_width="0dip"
+ android:layout_gravity="fill_horizontal|center_vertical"
+ android:layout_marginTop="2dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textAlignment="viewStart" />
+ <ImageView
+ android:id="@+id/app_privacy_guard_icon"
+ android:layout_width="@android:dimen/app_icon_size"
+ android:layout_height="@android:dimen/app_icon_size"
+ android:layout_gravity="center_vertical"
+ android:scaleType="centerInside"
+ android:contentDescription="@null" />
+</GridLayout>
diff --git a/res/menu/privacy_guard_manager.xml b/res/menu/privacy_guard_manager.xml
new file mode 100644
index 0000000..5e41e46
--- /dev/null
+++ b/res/menu/privacy_guard_manager.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 Slimroms 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/reset"
+ android:showAsAction="always"
+ android:icon="@drawable/ic_settings_backup"
+ android:title="@string/privacy_guard_reset_title" />
+ <item android:id="@+id/show_system_apps"
+ android:title="@string/privacy_guard_manager_show_system_apps"
+ android:checkable="true" />
+ <item android:id="@+id/advanced"
+ android:title="@string/privacy_guard_advanced_settings_title" />
+ <item android:id="@+id/help"
+ android:title="@string/privacy_guard_help_title" />
+</menu>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index e5f1988..581427e 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -688,60 +688,24 @@
<item>write wallpaper</item>
<item>assist structure</item>
<item>assist screenshot</item>
- </string-array>
-
- <!-- User display names for app ops codes -->
- <string-array name="app_ops_labels">
- <item>Location</item>
- <item>Location</item>
- <item>Location</item>
- <item>Vibrate</item>
- <item>Read contacts</item>
- <item>Modify contacts</item>
- <item>Read call log</item>
- <item>Modify call log</item>
- <item>Read calendar</item>
- <item>Modify calendar</item>
- <item>Location</item>
- <item>Post notification</item>
- <item>Location</item>
- <item>Call phone</item>
- <item>Read SMS/MMS</item>
- <item>Write SMS/MMS</item>
- <item>Receive SMS/MMS</item>
- <item>Receive SMS/MMS</item>
- <item>Receive SMS/MMS</item>
- <item>Receive SMS/MMS</item>
- <item>Send SMS/MMS</item>
- <item>Read SMS/MMS</item>
- <item>Write SMS/MMS</item>
- <item>Modify settings</item>
- <item>Draw on top</item>
- <item>Access notifications</item>
- <item>Camera</item>
- <item>Record audio</item>
- <item>Play audio</item>
- <item>Read clipboard</item>
- <item>Modify clipboard</item>
- <item>Media buttons</item>
- <item>Audio focus</item>
- <item>Master volume</item>
- <item>Voice volume</item>
- <item>Ring volume</item>
- <item>Media volume</item>
- <item>Alarm volume</item>
- <item>Notification volume</item>
- <item>Bluetooth volume</item>
- <item>Keep awake</item>
- <item>Location</item>
- <item>Location</item>
- <item>Get usage stats</item>
- <item>Mute/unmute microphone</item>
- <item>Project media</item>
- <item>Activate VPN</item>
- <item>Write wallpaper</item>
- <item>Assist structure</item>
- <item>Assist screenshot</item>
+ <item>read phone state</item>
+ <item>add voicemail</item>
+ <item>use sip</item>
+ <item>make call</item>
+ <item>use fingerprint</item>
+ <item>use body sensors</item>
+ <item>read cell broadcast</item>
+ <item>mock location</item>
+ <item>read external storage</item>
+ <item>write external storage</item>
+ <item>turn screen on</item>
+ <item>get accounts</item>
+ <item>change wifi</item>
+ <item>toggle bluetooth</item>
+ <item>start at boot</item>
+ <item>toggle nfc</item>
+ <item>change mobile data</item>
+ <item>superuser</item>
</string-array>
<!-- Titles for the list of long press timeout options. -->
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index a65dbd5..281f8e9 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -620,4 +620,25 @@
<string name="keep_screen_on_never">Never</string>
<string name="keep_screen_on_debugging">While USB debugging</string>
<string name="keep_screen_on_charging">While charging</string>
+
+ <!-- Privacy Settings Header item -->
+ <string name="privacy_settings_cyanogenmod_title">Privacy</string>
+ <string name="privacy_settings_cyanogenmod_category" translatable="false">CyanogenMod</string>
+
+ <!-- Privacy Guard -->
+ <string name="privacy_guard_switch_label">Enable Privacy Guard</string>
+ <string name="privacy_guard_dlg_title">Enable Privacy Guard?</string>
+ <string name="privacy_guard_dlg_text">When Privacy Guard is enabled, the app will not be able to access personal data such as contacts, messages or call logs.</string>
+ <string name="privacy_guard_dlg_system_app_text">When enabling Privacy Guard for a built-in app, the app will not be able to access or provide personal data. This may cause other apps to misbehave.</string>
+ <string name="privacy_guard_default_title">Enabled by default</string>
+ <string name="privacy_guard_default_summary">Enable by default for newly-installed apps</string>
+ <string name="privacy_guard_manager_title">Privacy Guard</string>
+ <string name="privacy_guard_manager_summary">Manage which apps have access to your personal data</string>
+ <string name="privacy_guard_no_user_apps">No apps are installed</string>
+ <string name="privacy_guard_help_title">Help</string>
+ <string name="privacy_guard_reset_title">Reset</string>
+ <string name="privacy_guard_reset_text">Reset permissions?</string>
+ <string name="privacy_guard_help_text">In this screen you can choose which apps Privacy Guard should be active for by simply tapping on them. Selected apps will not be able to access your personal data such as contacts, messages or call logs. Long pressing an app\'s entry opens its app details screen.\n\nBuilt-in apps are not shown by default but can be revealed by selecting the respective menu option.</string>
+ <string name="privacy_guard_manager_show_system_apps">Show built-in apps</string>
+ <string name="privacy_guard_advanced_settings_title">Advanced</string>
</resources>
diff --git a/res/xml/dashboard_categories.xml b/res/xml/dashboard_categories.xml
index b730c16..db62950 100644
--- a/res/xml/dashboard_categories.xml
+++ b/res/xml/dashboard_categories.xml
@@ -227,6 +227,15 @@
android:icon="@drawable/ic_settings_security"
/>
+ <!-- CyanogenMod Privacy Settings -->
+ <!-- This is the 'real' Privacy items and includes Privacy Guard, Blacklist & WhisperPush -->
+ <dashboard-tile
+ android:id="@+id/privacy_settings_cyanogenmod"
+ android:title="@string/privacy_settings_cyanogenmod_title"
+ android:fragment="com.android.settings.cyanogenmod.PrivacySettings"
+ android:icon="@drawable/ic_settings_privacy"
+ />
+
<!-- Account -->
<dashboard-tile
android:id="@+id/account_settings"
diff --git a/res/xml/privacy_guard_prefs.xml b/res/xml/privacy_guard_prefs.xml
new file mode 100644
index 0000000..2cc82c1
--- /dev/null
+++ b/res/xml/privacy_guard_prefs.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 Slimroms 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">
+
+ <CheckBoxPreference
+ android:key="privacy_guard_default"
+ android:title="@string/privacy_guard_default_title"
+ android:summary="@string/privacy_guard_default_summary"
+ android:persistent="false" />
+
+</PreferenceScreen>
diff --git a/res/xml/privacy_settings_cyanogenmod.xml b/res/xml/privacy_settings_cyanogenmod.xml
new file mode 100644
index 0000000..b9a361d
--- /dev/null
+++ b/res/xml/privacy_settings_cyanogenmod.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009-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"
+ android:title="@string/privacy_settings_title">
+
+ <Preference
+ android:fragment="com.android.settings.privacyguard.PrivacyGuardManager"
+ android:key="privacy_guard_manager"
+ android:summary="@string/privacy_guard_manager_summary"
+ android:title="@string/privacy_guard_manager_title" />
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 7f48cc4..bb289a2 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -120,6 +120,7 @@ import com.android.settings.print.PrintJobSettingsFragment;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.search.DynamicIndexableContentMonitor;
import com.android.settings.search.Index;
+import com.android.settings.privacyguard.PrivacyGuardPrefs;
import com.android.settings.sim.SimSettings;
import com.android.settings.tts.TextToSpeechSettings;
import com.android.settings.users.UserSettings;
@@ -286,7 +287,8 @@ public class SettingsActivity extends Activity
R.id.print_settings,
R.id.nfc_payment_settings,
R.id.home_settings,
- R.id.dashboard
+ R.id.dashboard,
+ R.id.privacy_settings_cyanogenmod
};
private static final String[] ENTRY_FRAGMENTS = {
@@ -362,7 +364,8 @@ public class SettingsActivity extends Activity
ProcessStatsSummary.class.getName(),
DrawOverlayDetails.class.getName(),
WriteSettingsDetails.class.getName(),
- LiveDisplay.class.getName()
+ LiveDisplay.class.getName(),
+ com.android.settings.cyanogenmod.PrivacySettings.class.getName()
};
diff --git a/src/com/android/settings/applications/AppOpsState.java b/src/com/android/settings/applications/AppOpsState.java
index 07e955d..9176815 100644
--- a/src/com/android/settings/applications/AppOpsState.java
+++ b/src/com/android/settings/applications/AppOpsState.java
@@ -57,7 +57,7 @@ public class AppOpsState {
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);
+ mOpLabels = context.getResources().getTextArray(com.android.internal.R.array.app_ops_labels);
}
public static class OpsTemplate implements Parcelable {
@@ -180,6 +180,7 @@ public class AppOpsState {
false,
false,
false,
+ false,
false }
);
diff --git a/src/com/android/settings/cyanogenmod/PrivacySettings.java b/src/com/android/settings/cyanogenmod/PrivacySettings.java
new file mode 100644
index 0000000..4c1cc25
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/PrivacySettings.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.cyanogenmod;
+
+//import android.content.pm.PackageManager;
+import android.os.Bundle;
+//import android.preference.PreferenceScreen;
+//import com.android.settings.Utils;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
+/**
+ * Privacy settings
+ */
+public class PrivacySettings extends SettingsPreferenceFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.privacy_settings_cyanogenmod);
+ }
+
+ @Override
+ protected int getMetricsCategory() {
+ return MetricsLogger.DONT_TRACK_ME_BRO;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+}
diff --git a/src/com/android/settings/privacyguard/PrivacyGuardAppListAdapter.java b/src/com/android/settings/privacyguard/PrivacyGuardAppListAdapter.java
new file mode 100644
index 0000000..49555a9
--- /dev/null
+++ b/src/com/android/settings/privacyguard/PrivacyGuardAppListAdapter.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2013 SlimRoms 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.privacyguard;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.SectionIndexer;
+import android.widget.TextView;
+
+import com.android.settings.R;
+import com.android.settings.privacyguard.PrivacyGuardManager.AppInfo;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class PrivacyGuardAppListAdapter extends BaseAdapter implements SectionIndexer {
+
+ private LayoutInflater mInflater;
+ private PackageManager mPm;
+
+ private List<AppInfo> mApps;
+ private String[] mSections;
+ private int[] mPositions;
+ private ConcurrentHashMap<String, Drawable> mIcons;
+ private Drawable mDefaultImg;
+
+ private Context mContext;
+
+ //constructor
+ public PrivacyGuardAppListAdapter(Context context, List<AppInfo> apps,
+ List<String> sections, List<Integer> positions) {
+ mContext = context;
+ mInflater = LayoutInflater.from(mContext);
+ mPm = context.getPackageManager();
+
+ mApps = apps;
+ mSections = sections.toArray(new String[sections.size()]);
+ mPositions = new int[positions.size()];
+ for (int i = 0; i < positions.size(); i++) {
+ mPositions[i] = positions.get(i);
+ }
+
+ // set the default icon till the actual app icon is loaded in async task
+ mDefaultImg = mContext.getResources().getDrawable(android.R.mipmap.sym_def_app_icon);
+ mIcons = new ConcurrentHashMap<String, Drawable>();
+
+ new LoadIconsTask().execute(apps.toArray(new PrivacyGuardManager.AppInfo[]{}));
+ }
+
+ @Override
+ public int getCount() {
+ return mApps.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mApps.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ PrivacyGuardAppViewHolder appHolder;
+
+ if (convertView == null) {
+ convertView = mInflater.inflate(R.layout.privacy_guard_manager_list_row, null);
+
+ // creates a ViewHolder and children references
+ appHolder = new PrivacyGuardAppViewHolder();
+ appHolder.title = (TextView) convertView.findViewById(R.id.app_title);
+ appHolder.icon = (ImageView) convertView.findViewById(R.id.app_icon);
+ appHolder.privacyGuardIcon = (ImageView) convertView.findViewById(R.id.app_privacy_guard_icon);
+ convertView.setTag(appHolder);
+ } else {
+ appHolder = (PrivacyGuardAppViewHolder) convertView.getTag();
+ }
+
+ PrivacyGuardManager.AppInfo app = mApps.get(position);
+
+ appHolder.title.setText(app.title);
+
+ Drawable icon = mIcons.get(app.packageName);
+ appHolder.icon.setImageDrawable(icon != null ? icon : mDefaultImg);
+
+ int privacyGuardDrawableResId = app.privacyGuardEnabled
+ ? R.drawable.ic_privacy_guard :
+ R.drawable.ic_privacy_guard_off;
+ appHolder.privacyGuardIcon.setImageResource(privacyGuardDrawableResId);
+
+ return convertView;
+ }
+
+ @Override
+ public int getPositionForSection(int section) {
+ if (section < 0 || section >= mSections.length) {
+ return -1;
+ }
+
+ return mPositions[section];
+ }
+
+ @Override
+ public int getSectionForPosition(int position) {
+ if (position < 0 || position >= getCount()) {
+ return -1;
+ }
+
+ int index = Arrays.binarySearch(mPositions, position);
+
+ /*
+ * Consider this example: section positions are 0, 3, 5; the supplied
+ * position is 4. The section corresponding to position 4 starts at
+ * position 3, so the expected return value is 1. Binary search will not
+ * find 4 in the array and thus will return -insertPosition-1, i.e. -3.
+ * To get from that number to the expected value of 1 we need to negate
+ * and subtract 2.
+ */
+ return index >= 0 ? index : -index - 2;
+ }
+
+ @Override
+ public Object[] getSections() {
+ return mSections;
+ }
+
+ /**
+ * An asynchronous task to load the icons of the installed applications.
+ */
+ private class LoadIconsTask extends AsyncTask<PrivacyGuardManager.AppInfo, Void, Void> {
+ @Override
+ protected Void doInBackground(PrivacyGuardManager.AppInfo... apps) {
+ for (PrivacyGuardManager.AppInfo app : apps) {
+ try {
+ Drawable icon = mPm.getApplicationIcon(app.packageName);
+ mIcons.put(app.packageName, icon);
+ publishProgress();
+ } catch (PackageManager.NameNotFoundException e) {
+ // ignored; app will show up with default image
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... progress) {
+ notifyDataSetChanged();
+ }
+ }
+
+ /**
+ * App view holder used to reuse the views inside the list.
+ */
+ public static class PrivacyGuardAppViewHolder {
+ TextView title;
+ ImageView icon;
+ ImageView privacyGuardIcon;
+ }
+}
diff --git a/src/com/android/settings/privacyguard/PrivacyGuardManager.java b/src/com/android/settings/privacyguard/PrivacyGuardManager.java
new file mode 100644
index 0000000..9fb8c9d
--- /dev/null
+++ b/src/com/android/settings/privacyguard/PrivacyGuardManager.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2013 SlimRoms 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.privacyguard;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.AppOpsManager;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.settings.R;
+import com.android.settings.Settings.AppOpsSummaryActivity;
+import com.android.settings.SubSettings;
+import com.android.settings.applications.AppOpsDetails;
+import com.android.settings.applications.AppOpsState;
+import com.android.settings.applications.AppOpsState.OpsTemplate;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class PrivacyGuardManager extends Fragment
+ implements OnItemClickListener, OnItemLongClickListener {
+
+ private static final String TAG = "PrivacyGuardManager";
+
+ private TextView mNoUserAppsInstalled;
+ private ListView mAppsList;
+ private PrivacyGuardAppListAdapter mAdapter;
+ private List<AppInfo> mApps;
+
+ private PackageManager mPm;
+ private Activity mActivity;
+
+ private SharedPreferences mPreferences;
+ private AppOpsManager mAppOps;
+
+ private int mSavedFirstVisiblePosition = AdapterView.INVALID_POSITION;
+ private int mSavedFirstItemOffset;
+
+ // keys for extras and icicles
+ private final static String LAST_LIST_POS = "last_list_pos";
+ private final static String LAST_LIST_OFFSET = "last_list_offset";
+
+ // holder for package data passed into the adapter
+ public static final class AppInfo {
+ String title;
+ String packageName;
+ boolean enabled;
+ boolean privacyGuardEnabled;
+ int uid;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ mActivity = getActivity();
+ mPm = mActivity.getPackageManager();
+ mAppOps = (AppOpsManager)getActivity().getSystemService(Context.APP_OPS_SERVICE);
+
+ return inflater.inflate(R.layout.privacy_guard_manager, container, false);
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ FragmentManager fm = getFragmentManager();
+ Fragment f = fm.findFragmentById(R.id.privacy_guard_prefs);
+ if (f != null && !fm.isDestroyed()) {
+ fm.beginTransaction().remove(f).commit();
+ }
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ mNoUserAppsInstalled = (TextView) mActivity.findViewById(R.id.error);
+
+ mAppsList = (ListView) mActivity.findViewById(R.id.apps_list);
+ mAppsList.setOnItemClickListener(this);
+ mAppsList.setOnItemLongClickListener(this);
+
+ // get shared preference
+ mPreferences = mActivity.getSharedPreferences("privacy_guard_manager", Activity.MODE_PRIVATE);
+ if (!mPreferences.getBoolean("first_help_shown", false)) {
+ showHelp();
+ }
+
+ if (savedInstanceState != null) {
+ mSavedFirstVisiblePosition = savedInstanceState.getInt(LAST_LIST_POS,
+ AdapterView.INVALID_POSITION);
+ mSavedFirstItemOffset = savedInstanceState.getInt(LAST_LIST_OFFSET, 0);
+ } else {
+ mSavedFirstVisiblePosition = AdapterView.INVALID_POSITION;
+ mSavedFirstItemOffset = 0;
+ }
+
+ // load apps and construct the list
+ loadApps();
+
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onViewStateRestored(Bundle savedInstanceState) {
+ super.onViewStateRestored(savedInstanceState);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putInt(LAST_LIST_POS, mSavedFirstVisiblePosition);
+ outState.putInt(LAST_LIST_OFFSET, mSavedFirstItemOffset);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ // Remember where the list is scrolled to so we can restore the scroll position
+ // when we come back to this activity and *after* we complete querying for the
+ // conversations.
+ mSavedFirstVisiblePosition = mAppsList.getFirstVisiblePosition();
+ View firstChild = mAppsList.getChildAt(0);
+ mSavedFirstItemOffset = (firstChild == null) ? 0 : firstChild.getTop();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ // rebuild the list; the user might have changed settings inbetween
+ loadApps();
+
+ if (mSavedFirstVisiblePosition != AdapterView.INVALID_POSITION) {
+ mAppsList.setSelectionFromTop(mSavedFirstVisiblePosition, mSavedFirstItemOffset);
+ mSavedFirstVisiblePosition = AdapterView.INVALID_POSITION;
+ }
+ }
+
+ private void loadApps() {
+ mApps = loadInstalledApps();
+
+ // if app list is empty inform the user
+ // else go ahead and construct the list
+ if (mApps == null || mApps.isEmpty()) {
+ mNoUserAppsInstalled.setText(R.string.privacy_guard_no_user_apps);
+ mNoUserAppsInstalled.setVisibility(View.VISIBLE);
+ mAppsList.setVisibility(View.GONE);
+ mAppsList.setAdapter(null);
+ } else {
+ mNoUserAppsInstalled.setVisibility(View.GONE);
+ mAppsList.setVisibility(View.VISIBLE);
+ mAdapter = createAdapter();
+ mAppsList.setAdapter(mAdapter);
+ mAppsList.setFastScrollEnabled(true);
+ }
+ }
+
+ private PrivacyGuardAppListAdapter createAdapter() {
+ String lastSectionIndex = null;
+ ArrayList<String> sections = new ArrayList<String>();
+ ArrayList<Integer> positions = new ArrayList<Integer>();
+ int count = mApps.size(), offset = 0;
+
+ for (int i = 0; i < count; i++) {
+ AppInfo app = mApps.get(i);
+ String sectionIndex;
+
+ if (!app.enabled) {
+ sectionIndex = "--"; //XXX
+ } else if (app.title.isEmpty()) {
+ sectionIndex = "";
+ } else {
+ sectionIndex = app.title.substring(0, 1).toUpperCase();
+ }
+ if (lastSectionIndex == null) {
+ lastSectionIndex = sectionIndex;
+ }
+
+ if (!TextUtils.equals(sectionIndex, lastSectionIndex)) {
+ sections.add(sectionIndex);
+ positions.add(offset);
+ lastSectionIndex = sectionIndex;
+ }
+ offset++;
+ }
+
+ return new PrivacyGuardAppListAdapter(mActivity, mApps, sections, positions);
+ }
+
+ private void resetPrivacyGuard() {
+ if (mApps == null || mApps.isEmpty()) {
+ return;
+ }
+ showResetDialog();
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ // on click change the privacy guard status for this item
+ final AppInfo app = (AppInfo) parent.getItemAtPosition(position);
+
+ app.privacyGuardEnabled = !app.privacyGuardEnabled;
+ mAppOps.setPrivacyGuardSettingForPackage(app.uid, app.packageName, app.privacyGuardEnabled);
+
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+ // on long click open app details window
+ final AppInfo app = (AppInfo) parent.getItemAtPosition(position);
+
+ Bundle args = new Bundle();
+ args.putString(AppOpsDetails.ARG_PACKAGE_NAME, app.packageName);
+
+ SubSettings ssa = (SubSettings) getActivity();
+ ssa.startPreferencePanel(AppOpsDetails.class.getName(), args,
+ R.string.app_ops_settings, null, this, 2);
+ return true;
+ }
+
+ /**
+ * Uses the package manager to query for all currently installed apps
+ * for the list.
+ *
+ * @return the complete List off installed applications (@code PrivacyGuardAppInfo)
+ */
+ private List<AppInfo> loadInstalledApps() {
+ List<AppInfo> apps = new ArrayList<AppInfo>();
+ List<PackageInfo> packages = mPm.getInstalledPackages(
+ PackageManager.GET_PERMISSIONS | PackageManager.GET_SIGNATURES);
+ boolean showSystemApps = shouldShowSystemApps();
+ Signature platformCert;
+
+ try {
+ PackageInfo sysInfo = mPm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
+ platformCert = sysInfo.signatures[0];
+ } catch (PackageManager.NameNotFoundException e) {
+ platformCert = null;
+ }
+
+ for (PackageInfo info : packages) {
+ final ApplicationInfo appInfo = info.applicationInfo;
+
+ // hide apps signed with the platform certificate to avoid the user
+ // shooting himself in the foot
+ if (platformCert != null && info.signatures != null
+ && platformCert.equals(info.signatures[0])) {
+ continue;
+ }
+
+ // skip all system apps if they shall not be included
+ if (!showSystemApps && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ continue;
+ }
+
+ AppInfo app = new AppInfo();
+ app.title = appInfo.loadLabel(mPm).toString();
+ app.packageName = info.packageName;
+ app.enabled = appInfo.enabled;
+ app.uid = info.applicationInfo.uid;
+ app.privacyGuardEnabled = mAppOps.getPrivacyGuardSettingForPackage(
+ app.uid, app.packageName);
+ apps.add(app);
+ }
+
+ // sort the apps by their enabled state, then by title
+ Collections.sort(apps, new Comparator<AppInfo>() {
+ @Override
+ public int compare(AppInfo lhs, AppInfo rhs) {
+ if (lhs.enabled != rhs.enabled) {
+ return lhs.enabled ? -1 : 1;
+ }
+ return lhs.title.compareToIgnoreCase(rhs.title);
+ }
+ });
+
+ return apps;
+ }
+
+ private boolean shouldShowSystemApps() {
+ return mPreferences.getBoolean("show_system_apps", false);
+ }
+
+ private class HelpDialogFragment extends DialogFragment {
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.privacy_guard_help_title)
+ .setMessage(R.string.privacy_guard_help_text)
+ .setNegativeButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ })
+ .create();
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ mPreferences.edit().putBoolean("first_help_shown", true).commit();
+ }
+ }
+
+ private void showHelp() {
+ HelpDialogFragment fragment = new HelpDialogFragment();
+ fragment.show(getFragmentManager(), "help_dialog");
+ }
+
+ private class ResetDialogFragment extends DialogFragment {
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.privacy_guard_reset_title)
+ .setMessage(R.string.privacy_guard_reset_text)
+ .setPositiveButton(R.string.dlg_ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // turn off privacy guard for all apps shown in the current list
+ for (AppInfo app : mApps) {
+ app.privacyGuardEnabled = false;
+ }
+ mAppOps.resetAllModes();
+ mAdapter.notifyDataSetChanged();
+ }
+ })
+ .setNegativeButton(R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // Do nothing
+ }
+ })
+ .create();
+ }
+ }
+
+ private void showResetDialog() {
+ ResetDialogFragment dialog = new ResetDialogFragment();
+ dialog.show(getFragmentManager(), "reset_dialog");
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.privacy_guard_manager, menu);
+ menu.findItem(R.id.show_system_apps).setChecked(shouldShowSystemApps());
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.help:
+ showHelp();
+ return true;
+ case R.id.reset:
+ resetPrivacyGuard();
+ return true;
+ case R.id.show_system_apps:
+ final String prefName = "show_system_apps";
+ // set the menu checkbox and save it in
+ // shared preference and rebuild the list
+ item.setChecked(!item.isChecked());
+ mPreferences.edit().putBoolean(prefName, item.isChecked()).commit();
+ loadApps();
+ return true;
+ case R.id.advanced:
+ Intent i = new Intent(Intent.ACTION_MAIN);
+ i.setClass(mActivity, AppOpsSummaryActivity.class);
+ mActivity.startActivity(i);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+}
diff --git a/src/com/android/settings/privacyguard/PrivacyGuardPrefs.java b/src/com/android/settings/privacyguard/PrivacyGuardPrefs.java
new file mode 100644
index 0000000..0f45d98
--- /dev/null
+++ b/src/com/android/settings/privacyguard/PrivacyGuardPrefs.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 Slimroms
+ *
+ * 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.privacyguard;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.Utils;
+import cyanogenmod.providers.CMSettings;
+
+public class PrivacyGuardPrefs extends SettingsPreferenceFragment implements
+ OnPreferenceChangeListener {
+
+ private static final String TAG = "PrivacyGuardPrefs";
+
+ private static final String KEY_PRIVACY_GUARD_DEFAULT = "privacy_guard_default";
+
+ private CheckBoxPreference mPrivacyGuardDefault;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.privacy_guard_prefs);
+ PreferenceScreen prefSet = getPreferenceScreen();
+
+ mPrivacyGuardDefault = (CheckBoxPreference) findPreference(KEY_PRIVACY_GUARD_DEFAULT);
+ mPrivacyGuardDefault.setOnPreferenceChangeListener(this);
+
+ mPrivacyGuardDefault.setChecked(Settings.Secure.getInt(getContentResolver(),
+ CMSettings.Secure.PRIVACY_GUARD_DEFAULT, 0) == 1);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ final View view = super.onCreateView(inflater, container, savedInstanceState);
+ final ListView list = (ListView) view.findViewById(android.R.id.list);
+ // our container already takes care of the padding
+ int paddingTop = list.getPaddingTop();
+ int paddingBottom = list.getPaddingBottom();
+ list.setPadding(0, paddingTop, 0, paddingBottom);
+ return view;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mPrivacyGuardDefault) {
+ boolean value = (Boolean) newValue;
+ Settings.Secure.putInt(getContentResolver(),
+ CMSettings.Secure.PRIVACY_GUARD_DEFAULT, value ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected int getMetricsCategory() {
+ return MetricsLogger.DONT_TRACK_ME_BRO;
+ }
+}