Merge "Create PrivacyControls page in settings"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a5a5501..7f26c8d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -13045,6 +13045,11 @@
<!-- Summary for the top level Privacy Settings [CHAR LIMIT=NONE]-->
<string name="privacy_dashboard_summary">Permissions, account activity, personal data</string>
+
+ <!-- Title for the privacy controls page [CHAR LIMIT=30]-->
+ <string name="privacy_controls_title">Controls</string>
+
+
<!-- Label for button in contextual card for users to remove the card [CHAR LIMIT=30] -->
<string name="contextual_card_dismiss_remove">Remove</string>
<!-- Label for button in contextual card for users to keep the card [CHAR LIMIT=30] -->
@@ -13592,8 +13597,10 @@
<string name="camera_toggle_title">Camera access</string>
<!-- Label for the camera use toggle [CHAR LIMIT=40] -->
<string name="mic_toggle_title">Microphone access</string>
- <!-- Describes what is affected by the camera toggle [CHAR LIMIT=NONE] -->
- <string name="cam_toggle_description">For apps and services</string>
+ <!-- Label for the location use toggle [CHAR LIMIT=40] -->
+ <string name="location_toggle_title">Location access</string>
+ <!-- Describes what is affected by a permission toggle [CHAR LIMIT=NONE] -->
+ <string name="perm_toggle_description">For apps and services</string>
<!-- Describes what is affected by the mic toggle [CHAR LIMIT=NONE] -->
<string name="mic_toggle_description">For apps and services. If this setting is off, microphone data may still be shared when you call an emergency number.</string>
diff --git a/res/xml/location_settings_personal.xml b/res/xml/location_settings_personal.xml
index bae1ac1..f8b21b9 100644
--- a/res/xml/location_settings_personal.xml
+++ b/res/xml/location_settings_personal.xml
@@ -42,7 +42,7 @@
android:title="@string/location_app_level_permissions"
settings:controller="com.android.settings.location.AppLocationPermissionPreferenceController">
<intent android:action="android.intent.action.MANAGE_PERMISSION_APPS">
- <extra android:name="android.intent.extra.PERMISSION_NAME"
+ <extra android:name="android.intent.extra.PERMISSION_GROUP_NAME"
android:value="android.permission-group.LOCATION"/>
</intent>
</Preference>
diff --git a/res/xml/location_settings_workprofile.xml b/res/xml/location_settings_workprofile.xml
index 51d8761..bcac084 100644
--- a/res/xml/location_settings_workprofile.xml
+++ b/res/xml/location_settings_workprofile.xml
@@ -50,7 +50,7 @@
android:title="@string/location_app_level_permissions"
settings:controller="com.android.settings.location.AppLocationPermissionPreferenceController">
<intent android:action="android.intent.action.MANAGE_PERMISSION_APPS">
- <extra android:name="android.intent.extra.PERMISSION_NAME"
+ <extra android:name="android.intent.extra.PERMISSION_GROUP_NAME"
android:value="android.permission-group.LOCATION"/>
</intent>
</Preference>
diff --git a/res/xml/privacy_controls_settings.xml b/res/xml/privacy_controls_settings.xml
new file mode 100644
index 0000000..a477dc2
--- /dev/null
+++ b/res/xml/privacy_controls_settings.xml
@@ -0,0 +1,50 @@
+<!--
+ ~ Copyright (C) 2022 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:settings="http://schemas.android.com/apk/res-auto"
+ android:key="privacy_controls_page"
+ android:title="@string/privacy_controls_title">
+
+ <!-- Camera toggle -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="privacy_camera_toggle"
+ android:title="@string/camera_toggle_title"
+ android:summary="@string/perm_toggle_description"
+ settings:controller="com.android.settings.privacy.CameraToggleController"/>
+
+ <!-- Microphone toggle -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="privacy_mic_toggle"
+ android:title="@string/mic_toggle_title"
+ android:summary="@string/mic_toggle_description"
+ settings:controller="com.android.settings.privacy.MicToggleController"/>
+
+ <!-- Location toggle -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="privacy_location_toggle"
+ android:title="@string/location_toggle_title"
+ android:summary="@string/perm_toggle_description"/>
+
+ <!-- Clipboard access notifications -->
+ <SwitchPreference
+ android:key="show_clip_access_notification"
+ android:title="@string/show_clip_access_notification"
+ android:summary="@string/show_clip_access_notification_summary"
+ settings:controller="com.android.settings.privacy.ShowClipAccessNotificationPreferenceController"/>
+
+</PreferenceScreen>
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index 7e1d5ce..0a7cab5 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -65,7 +65,7 @@
<com.android.settingslib.RestrictedSwitchPreference
android:key="privacy_camera_toggle"
android:title="@string/camera_toggle_title"
- android:summary="@string/cam_toggle_description"
+ android:summary="@string/perm_toggle_description"
settings:controller="com.android.settings.privacy.CameraToggleController"/>
<!-- Microphone toggle -->
diff --git a/src/com/android/settings/location/LocationEnabler.java b/src/com/android/settings/location/LocationEnabler.java
index ab59b8e..cbe1c77 100644
--- a/src/com/android/settings/location/LocationEnabler.java
+++ b/src/com/android/settings/location/LocationEnabler.java
@@ -92,7 +92,10 @@
mContext.unregisterReceiver(mReceiver);
}
- void refreshLocationMode() {
+ /**
+ * Get the current location enable state, and update listeners
+ */
+ public void refreshLocationMode() {
final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
if (Log.isLoggable(TAG, Log.INFO)) {
@@ -103,7 +106,10 @@
}
}
- void setLocationEnabled(boolean enabled) {
+ /**
+ * Set the device's location enable state
+ */
+ public void setLocationEnabled(boolean enabled) {
final int currentMode = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
@@ -123,7 +129,10 @@
refreshLocationMode();
}
- boolean isEnabled(int mode) {
+ /**
+ * Checks if location is enabled, based on mode and restrictions.
+ */
+ public boolean isEnabled(int mode) {
return mode != Settings.Secure.LOCATION_MODE_OFF && !isRestricted();
}
@@ -132,13 +141,16 @@
*
* @return true if device policy has put a location access lock-down on the managed profile
*/
- boolean isManagedProfileRestrictedByBase() {
+ public boolean isManagedProfileRestrictedByBase() {
final UserHandle managedProfile = Utils.getManagedProfile(mUserManager);
return managedProfile != null
&& hasShareLocationRestriction(managedProfile.getIdentifier());
}
- RestrictedLockUtils.EnforcedAdmin getShareLocationEnforcedAdmin(int userId) {
+ /**
+ * Gets the admin enforcement for location for the current user
+ */
+ public RestrictedLockUtils.EnforcedAdmin getShareLocationEnforcedAdmin(int userId) {
RestrictedLockUtils.EnforcedAdmin admin = checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
@@ -149,7 +161,10 @@
return admin;
}
- boolean hasShareLocationRestriction(int userId) {
+ /**
+ * Check if the current user has a location restriction
+ */
+ public boolean hasShareLocationRestriction(int userId) {
return RestrictedLockUtilsInternal.hasBaseUserRestriction(
mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
}
diff --git a/src/com/android/settings/privacy/LocationToggleController.java b/src/com/android/settings/privacy/LocationToggleController.java
new file mode 100644
index 0000000..7d388bd
--- /dev/null
+++ b/src/com/android/settings/privacy/LocationToggleController.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.privacy;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.location.LocationEnabler;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+/**
+ * Controller for location toggle
+ */
+public class LocationToggleController extends TogglePreferenceController
+ implements LocationEnabler.LocationModeChangeListener {
+
+ private final LocationEnabler mLocationEnabler;
+ private RestrictedSwitchPreference mPreference;
+
+ private boolean mIsLocationEnabled = true;
+
+ public LocationToggleController(Context context, String preferenceKey, Lifecycle lifecycle) {
+ super(context, preferenceKey);
+ mLocationEnabler = new LocationEnabler(context, this, lifecycle);
+ mLocationEnabler.refreshLocationMode();
+ }
+ @Override
+ public void onLocationModeChanged(int mode, boolean restricted) {
+ if (mPreference == null) {
+ return;
+ }
+
+ mIsLocationEnabled = mLocationEnabler.isEnabled(mode);
+ final int userId = UserHandle.myUserId();
+ final RestrictedLockUtils.EnforcedAdmin admin =
+ mLocationEnabler.getShareLocationEnforcedAdmin(userId);
+ final boolean hasBaseUserRestriction =
+ mLocationEnabler.hasShareLocationRestriction(userId);
+ // Disable the whole switch bar instead of the switch itself. If we disabled the switch
+ // only, it would be re-enabled again if the switch bar is not disabled.
+ if (!hasBaseUserRestriction && admin != null) {
+ mPreference.setDisabledByAdmin(admin);
+ } else {
+ mPreference.setEnabled(!restricted);
+ }
+ updateState(mPreference);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public boolean isChecked() {
+ return mIsLocationEnabled;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ mLocationEnabler.setLocationEnabled(isChecked);
+ return true;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ mLocationEnabler.refreshLocationMode();
+ }
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return 0;
+ }
+}
diff --git a/src/com/android/settings/privacy/PrivacyControlsFragment.java b/src/com/android/settings/privacy/PrivacyControlsFragment.java
new file mode 100644
index 0000000..7b33364
--- /dev/null
+++ b/src/com/android/settings/privacy/PrivacyControlsFragment.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.privacy;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Fragment that shows several privacy toggle controls
+ */
+public class PrivacyControlsFragment extends DashboardFragment {
+ private static final String TAG = "PrivacyDashboardFrag";
+ private static final String CAMERA_KEY = "privacy_camera_toggle";
+ private static final String MIC_KEY = "privacy_mic_toggle";
+ private static final String LOCATION_KEY = "privacy_location_toggle";
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new CameraToggleController(context, CAMERA_KEY));
+ controllers.add(new MicToggleController(context, MIC_KEY));
+ controllers.add(new LocationToggleController(context, LOCATION_KEY,
+ getSettingsLifecycle()));
+ controllers.add(new ShowClipAccessNotificationPreferenceController(context));
+ return controllers;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.TOP_LEVEL_PRIVACY;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.privacy_controls_settings;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+}