DivestOS/Patches/LineageOS-18.1/android_packages_apps_Settings/0002-Sensors.patch
Tad 84c7d230ab Permission for sensors access patches from @MSe1969
Signed-off-by: Tad <tad@spotco.us>
2021-09-24 23:35:33 -04:00

261 lines
12 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From a0087ffdd73ca128dc9f27118fc9eb4fd43c798b Mon Sep 17 00:00:00 2001
From: MSe1969 <mse1969@posteo.de>
Date: Sat, 14 Nov 2020 15:17:37 +0100
Subject: [PATCH] Special Access: Add an option to administer Sensor access
Accesses the added AppOp for OP_OTHER_SENSORS
Change-Id: I79c0ed4ab97494434edc6c308a8a54bd123c02ee
---
res/values-de/strings.xml | 3 +
res/values-fr/strings.xml | 3 +
res/values/strings.xml | 5 +
res/xml/special_access.xml | 7 +
.../specialaccess/sensor/SensorAccess.java | 178 ++++++++++++++++++
5 files changed, 196 insertions(+)
create mode 100644 src/com/android/settings/applications/specialaccess/sensor/SensorAccess.java
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index b2acb11e61..f5815df4a8 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -4969,4 +4969,7 @@
<string name="bluetooth_phonebook_access_notification_content" msgid="4280361621526852063">"Ein nicht vertrauenswürdiges Gerät fordert Zugriff auf deine Kontakte und deine Anrufliste an. Weitere Informationen."</string>
<string name="bluetooth_phonebook_access_dialog_title" msgid="7624607995928968721">"Möchtest du den Zugriff auf Kontakte und Anrufliste zulassen?"</string>
<string name="bluetooth_phonebook_access_dialog_content" msgid="4766700015848574532">"Ein nicht vertrauenswürdiges Bluetooth-Gerät (<xliff:g id="DEVICE_NAME_0">%1$s</xliff:g>) möchte auf deine Kontakte und deine Anrufliste zugreifen. Dazu gehören auch Daten über ein- und ausgehende Anrufe.\n\nDu warst bisher noch nicht mit <xliff:g id="DEVICE_NAME_1">%2$s</xliff:g> verbunden."</string>
+ <string name="sensor_access_summary">Sensorzugriff von Benutzer-Apps kontrollieren</string>
+ <string name="sensor_access_title">Zugriff auf Sensoren</string>
+ <string name="sensor_access_title_empty_text">Keine installierte App hat Sensorzugriff angefordert.</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 42545707e6..d65e050664 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -4968,4 +4968,7 @@
<string name="bluetooth_phonebook_access_notification_content" msgid="4280361621526852063">"Un appareil non vérifié souhaite accéder à vos contacts et à votre journal d\'appels. Appuyez ici pour plus de détails."</string>
<string name="bluetooth_phonebook_access_dialog_title" msgid="7624607995928968721">"Autoriser l\'accès aux contacts et au journal d\'appels ?"</string>
<string name="bluetooth_phonebook_access_dialog_content" msgid="4766700015848574532">"Un appareil Bluetooth non vérifié, <xliff:g id="DEVICE_NAME_0">%1$s</xliff:g>, souhaite accéder à vos contacts et à votre journal d\'appels. Ceci inclut des données concernant les appels entrants et sortants.\n\nVous ne vous êtes jamais connecté à <xliff:g id="DEVICE_NAME_1">%2$s</xliff:g> auparavant."</string>
+ <string name="sensor_access_summary">Contrôler l\'accès des applications utilisateurs aux capteurs</string>
+ <string name="sensor_access_title">Access aux Capteurs</string>
+ <string name="sensor_access_title_empty_text">Aucune app installée n\'a demandé de l\'accès aux capteurs.</string>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index adf837a034..e4e0c9d129 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12227,4 +12227,9 @@
<string name="bluetooth_connect_access_dialog_negative">Don\u2019t connect</string>
<!-- Strings for Dialog connect button -->
<string name="bluetooth_connect_access_dialog_positive">Connect</string>
+
+ <!-- Sensor AppOps -->
+ <string name="sensor_access_summary">Control sensor access for user apps</string>
+ <string name="sensor_access_title">Access to Sensors</string>
+ <string name="sensor_access_title_empty_text">No installed apps have requested sensors access.</string>
</resources>
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index 6ee87f4664..f65ee68f7e 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -154,6 +154,13 @@
android:value="com.android.settings.Settings$ChangeWifiStateActivity" />
</Preference>
+ <Preference
+ android:key="sensor_access"
+ android:title="@string/sensor_access_title"
+ android:summary="@string/sensor_access_summary"
+ android:fragment="com.android.settings.applications.specialaccess.sensor.SensorAccess">
+ </Preference>
+
<Preference
android:key="special_access_more"
android:title="@string/special_access_more"
diff --git a/src/com/android/settings/applications/specialaccess/sensor/SensorAccess.java b/src/com/android/settings/applications/specialaccess/sensor/SensorAccess.java
new file mode 100644
index 0000000000..2c29f3abfd
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/sensor/SensorAccess.java
@@ -0,0 +1,178 @@
+package com.android.settings.applications.specialaccess.sensor;
+
+import android.annotation.Nullable;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.SettingsPreferenceFragment;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class SensorAccess extends SettingsPreferenceFragment {
+
+ private final SettingObserver mObserver = new SettingObserver();
+
+ static final String TAG = "SensorAccess";
+
+ private Context mContext;
+ private PackageManager mPackageManager;
+ private AppOpsManager mAppOpsManager;
+ private TextView mEmpty;
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.VIEW_UNKNOWN;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mContext = getActivity();
+ mPackageManager = mContext.getPackageManager();
+ mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+ setPreferenceScreen(getPreferenceManager().createPreferenceScreen(mContext));
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ mEmpty = new TextView(getContext());
+ mEmpty.setGravity(Gravity.CENTER);
+ mEmpty.setText(R.string.sensor_access_title_empty_text);
+ TypedValue value = new TypedValue();
+ getContext().getTheme().resolveAttribute(android.R.attr.textAppearanceMedium, value, true);
+ mEmpty.setTextAppearance(value.resourceId);
+ ((ViewGroup) view.findViewById(android.R.id.list_container)).addView(mEmpty,
+ new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ setEmptyView(mEmpty);
+ reloadList();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ getActivity().getActionBar().setTitle(R.string.sensor_access_title);
+ reloadList();
+ }
+
+ private void reloadList() {
+ final PreferenceScreen screen = getPreferenceScreen();
+ screen.removeAll();
+
+ final ArrayList<ApplicationInfo> apps = new ArrayList<>();
+ final List<ApplicationInfo> installed = mPackageManager.getInstalledApplications(0);
+ if (installed != null) {
+ for (ApplicationInfo app : installed) {
+ // Skip system apps
+ if (isUserApp(app.packageName)) {
+ // Only apps effectively having the Op OTHER_SENSORS
+ if (mAppOpsManager.getOpsForPackage(getPackageUid(app.packageName),
+ app.packageName, new int[]{AppOpsManager.OP_OTHER_SENSORS}) != null)
+ apps.add(app);
+ }
+ }
+ }
+ Collections.sort(apps, new PackageItemInfo.DisplayNameComparator(mPackageManager));
+ for (ApplicationInfo app : apps) {
+ final String pkg = app.packageName;
+ final CharSequence label = app.loadLabel(mPackageManager);
+ final SwitchPreference pref = new SwitchPreference(getPrefContext());
+ pref.setPersistent(false);
+ pref.setIcon(app.loadIcon(mPackageManager));
+ pref.setTitle(label);
+ updateState(pref, pkg);
+ pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ boolean switchOn = (Boolean) newValue;
+ mAppOpsManager.setMode(AppOpsManager.OP_OTHER_SENSORS, getPackageUid(pkg), pkg,
+ switchOn ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
+ pref.setChecked(switchOn);
+ return false;
+ }
+ });
+ screen.addPreference(pref);
+ }
+ }
+
+ public void updateState(SwitchPreference preference, String pkg) {
+ final int mode = mAppOpsManager
+ .checkOpNoThrow(AppOpsManager.OP_OTHER_SENSORS, getPackageUid(pkg), pkg);
+ if (mode == AppOpsManager.MODE_ERRORED) {
+ preference.setChecked(false);
+ } else {
+ final boolean checked = mode != AppOpsManager.MODE_IGNORED;
+ preference.setChecked(checked);
+ }
+ }
+
+ private boolean isUserApp(String pkg) {
+ ApplicationInfo appInfo;
+ try {
+ appInfo = mPackageManager.getApplicationInfo(pkg,
+ PackageManager.GET_DISABLED_COMPONENTS
+ | PackageManager.GET_UNINSTALLED_PACKAGES);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Unable to find info for package " + pkg);
+ return false;
+ }
+ return ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0);
+ }
+
+ private int getPackageUid(String pkg) {
+ int uid;
+ try {
+ uid = mPackageManager.getPackageUid(pkg, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ // We shouldn't hit this, ever. What can we even do after this?
+ uid = -1;
+ }
+ return uid;
+ }
+
+ private final class SettingObserver extends ContentObserver {
+ public SettingObserver() {
+ super(new Handler(Looper.getMainLooper()));
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ reloadList();
+ }
+ }
+}
--
2.31.1