• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

packages/apps/Settings


Commit MetaInfo

Revisioneb1cc8623e75a2704acf8ce7f51f1ec3707766a0 (tree)
Zeit2021-11-05 10:36:41
AutorSteve Kondik <steve@cyng...>
CommiterMauro Rossi

Log Message

Settings: Add developer setting for root access

Also includes following change:

Settings: Set root access options appropriately
It is possible to be running a user build with a debuggable boot image.
In this case, "su" will not be available. So only show none/adb.
Issue-Id: BACON-4461
Change-Id: Iaa7df8311b9ea81eabb1566ba6f9159fdc9fab34

Change-Id: If96219d893c0dfdcf4ad36e1cd8de3a413db0e8b

Ändern Zusammenfassung

Diff

--- /dev/null
+++ b/res/values/cm_strings.xml
@@ -0,0 +1,27 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!--
3+ Copyright (C) 2012-2016 The CyanogenMod Project
4+ Copyright (C) 2017 The LineageOS Project
5+
6+ Licensed under the Apache License, Version 2.0 (the "License");
7+ you may not use this file except in compliance with the License.
8+ You may obtain a copy of the License at
9+
10+ http://www.apache.org/licenses/LICENSE-2.0
11+
12+ Unless required by applicable law or agreed to in writing, software
13+ distributed under the License is distributed on an "AS IS" BASIS,
14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+ See the License for the specific language governing permissions and
16+ limitations under the License.
17+-->
18+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
19+ <!-- Setting checkbox title for root access -->
20+ <string name="root_access">Root access</string>
21+ <string name="root_access_warning_title">Allow root access?</string>
22+ <string name="root_access_warning_message">Allowing apps to request root access is very dangerous and could compromise the security of your system!</string>
23+ <string name="root_access_none">Disabled</string>
24+ <string name="root_access_apps">Apps only</string>
25+ <string name="root_access_adb">ADB only</string>
26+ <string name="root_access_all">Apps and ADB</string>
27+</resources>
--- /dev/null
+++ b/res/values/lineage_arrays.xml
@@ -0,0 +1,43 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!--
3+ Copyright (C) 2012-2015 The CyanogenMod Project
4+ Copyright (C) 2018 The LinegeOS Project
5+
6+ Licensed under the Apache License, Version 2.0 (the "License");
7+ you may not use this file except in compliance with the License.
8+ You may obtain a copy of the License at
9+
10+ http://www.apache.org/licenses/LICENSE-2.0
11+
12+ Unless required by applicable law or agreed to in writing, software
13+ distributed under the License is distributed on an "AS IS" BASIS,
14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+ See the License for the specific language governing permissions and
16+ limitations under the License.
17+-->
18+<resources>
19+ <!-- Arrays for root access capability -->
20+ <string-array name="root_access_entries" translatable="false">
21+ <item>@string/root_access_none</item>
22+ <item>@string/root_access_apps</item>
23+ <item>@string/root_access_adb</item>
24+ <item>@string/root_access_all</item>
25+ </string-array>
26+
27+ <string-array name="root_access_values" translatable="false">
28+ <item>0</item>
29+ <item>1</item>
30+ <item>2</item>
31+ <item>3</item>
32+ </string-array>
33+
34+ <string-array name="root_access_entries_adb" translatable="false">
35+ <item>@string/root_access_none</item>
36+ <item>@string/root_access_adb</item>
37+ </string-array>
38+
39+ <string-array name="root_access_values_adb" translatable="false">
40+ <item>0</item>
41+ <item>2</item>
42+ </string-array>
43+</resources>
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -128,6 +128,11 @@
128128 android:key="quick_settings_tiles"
129129 android:title="@string/quick_settings_developer_tiles"
130130 android:fragment="com.android.settings.development.qstile.DevelopmentTileConfigFragment" />
131+
132+ <ListPreference
133+ android:key="root_access"
134+ android:title="@string/root_access"
135+ android:persistent="false" />
131136 </PreferenceCategory>
132137
133138 <PreferenceCategory
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -78,7 +78,8 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
7878 implements SwitchBar.OnSwitchChangeListener, OemUnlockDialogHost, AdbDialogHost,
7979 AdbClearKeysDialogHost, LogPersistDialogHost,
8080 BluetoothA2dpHwOffloadRebootDialog.OnA2dpHwDialogConfirmedListener,
81- AbstractBluetoothPreferenceController.Callback {
81+ AbstractBluetoothPreferenceController.Callback,
82+ RootAccessDialogHost {
8283
8384 private static final String TAG = "DevSettingsDashboard";
8485
@@ -355,6 +356,20 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
355356 }
356357
357358 @Override
359+ public void onRootAccessDialogConfirmed() {
360+ final RootAccessPreferenceController controller =
361+ getDevelopmentOptionsController(RootAccessPreferenceController.class);
362+ controller.onRootAccessDialogConfirmed();
363+ }
364+
365+ @Override
366+ public void onRootAccessDialogDismissed() {
367+ final RootAccessPreferenceController controller =
368+ getDevelopmentOptionsController(RootAccessPreferenceController.class);
369+ controller.onRootAccessDialogDismissed();
370+ }
371+
372+ @Override
358373 public void onActivityResult(int requestCode, int resultCode, Intent data) {
359374 boolean handledResult = false;
360375 for (AbstractPreferenceController controller : mPreferenceControllers) {
@@ -552,6 +567,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
552567 controllers.add(new SizeCompatFreeformPreferenceController(context));
553568 controllers.add(new ShortcutManagerThrottlingPreferenceController(context));
554569 controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context));
570+ controllers.add(new RootAccessPreferenceController(context, fragment));
555571 controllers.add(new DefaultLaunchPreferenceController(context, "running_apps"));
556572 controllers.add(new DefaultLaunchPreferenceController(context, "demo_mode"));
557573 controllers.add(new DefaultLaunchPreferenceController(context, "quick_settings_tiles"));
--- /dev/null
+++ b/src/com/android/settings/development/RootAccessDialogHost.java
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2018 The LineageOS Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+package com.android.settings.development;
18+
19+/**
20+ * Interface for RootAccessWarningDialogFragment callbacks.
21+ */
22+public interface RootAccessDialogHost {
23+
24+ /**
25+ * Called when the user presses ok on the warning dialog.
26+ */
27+ void onRootAccessDialogConfirmed();
28+
29+ /**
30+ * Called when the user dismisses or cancels the warning dialog.
31+ */
32+ void onRootAccessDialogDismissed();
33+}
--- /dev/null
+++ b/src/com/android/settings/development/RootAccessPreferenceController.java
@@ -0,0 +1,136 @@
1+/*
2+ * Copyright (C) 2018 The LineageOS Project
3+ * Copyright (C) 2019 The Android-x86 Open Source Project
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ */
17+
18+package com.android.settings.development;
19+
20+import android.content.Context;
21+import android.os.Build;
22+import android.os.SystemProperties;
23+import android.os.UserManager;
24+import android.provider.Settings;
25+import androidx.annotation.VisibleForTesting;
26+import androidx.preference.ListPreference;
27+import androidx.preference.Preference;
28+import androidx.preference.PreferenceScreen;
29+
30+import com.android.settings.R;
31+import com.android.settings.core.PreferenceControllerMixin;
32+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
33+
34+import java.io.File;
35+
36+public class RootAccessPreferenceController extends DeveloperOptionsPreferenceController
37+ implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
38+
39+ private static final String TAG = "RootAccessPreferenceController";
40+ private static final String PREF_KEY = "root_access";
41+
42+ private static final String ROOT_ACCESS_PROPERTY = "persist.sys.root_access";
43+
44+ private final DevelopmentSettingsDashboardFragment mFragment;
45+ private Object mPendingRootAccessValue;
46+
47+ public RootAccessPreferenceController(Context context,
48+ DevelopmentSettingsDashboardFragment fragment) {
49+ super(context);
50+
51+ mFragment = fragment;
52+ }
53+
54+ @Override
55+ public boolean isAvailable() {
56+ // User builds don't get root, and eng always gets root
57+ return Build.IS_DEBUGGABLE || "eng".equals(Build.TYPE);
58+ }
59+
60+ @Override
61+ public String getPreferenceKey() {
62+ return PREF_KEY;
63+ }
64+
65+ @Override
66+ public void displayPreference(PreferenceScreen screen) {
67+ super.displayPreference(screen);
68+
69+ final File file = new File("/system/xbin/su");
70+ if (file.exists()) {
71+ ((ListPreference) mPreference).setEntries(R.array.root_access_entries);
72+ ((ListPreference) mPreference).setEntryValues(R.array.root_access_values);
73+ } else {
74+ ((ListPreference) mPreference).setEntries(R.array.root_access_entries_adb);
75+ ((ListPreference) mPreference).setEntryValues(R.array.root_access_values_adb);
76+ }
77+
78+ updatePreference();
79+
80+ if (!isAdminUser()) {
81+ mPreference.setEnabled(false);
82+ }
83+ }
84+
85+ @Override
86+ public boolean onPreferenceChange(Preference preference, Object newValue) {
87+ if ("0".equals(newValue.toString())) {
88+ writeRootAccessOptions(newValue);
89+ } else {
90+ mPendingRootAccessValue = newValue;
91+ RootAccessWarningDialog.show(mFragment, this);
92+ }
93+ return true;
94+ }
95+
96+ @Override
97+ protected void onDeveloperOptionsSwitchEnabled() {
98+ if (isAdminUser()) {
99+ mPreference.setEnabled(true);
100+ }
101+ }
102+
103+ public void onRootAccessDialogConfirmed() {
104+ writeRootAccessOptions(mPendingRootAccessValue);
105+ }
106+
107+ public void onRootAccessDialogDismissed() {
108+ updatePreference();
109+ }
110+
111+ private void writeRootAccessOptions(Object newValue) {
112+ String oldValue = SystemProperties.get(ROOT_ACCESS_PROPERTY, "0");
113+ SystemProperties.set(ROOT_ACCESS_PROPERTY, newValue.toString());
114+ if (Integer.valueOf(newValue.toString()) < 2 && !oldValue.equals(newValue)
115+ && SystemProperties.getInt("service.adb.root", 0) == 1) {
116+ SystemProperties.set("service.adb.root", "0");
117+ Settings.Secure.putInt(mContext.getContentResolver(),
118+ Settings.Secure.ADB_ENABLED, 0);
119+ Settings.Secure.putInt(mContext.getContentResolver(),
120+ Settings.Secure.ADB_ENABLED, 1);
121+ }
122+ updatePreference();
123+ }
124+
125+ private void updatePreference() {
126+ String value = SystemProperties.get(ROOT_ACCESS_PROPERTY, "0");
127+ ((ListPreference) mPreference).setValue(value);
128+ ((ListPreference) mPreference).setSummary(mContext.getResources()
129+ .getStringArray(R.array.root_access_entries)[Integer.valueOf(value)]);
130+ }
131+
132+ @VisibleForTesting
133+ boolean isAdminUser() {
134+ return ((UserManager) mContext.getSystemService(Context.USER_SERVICE)).isAdminUser();
135+ }
136+}
--- /dev/null
+++ b/src/com/android/settings/development/RootAccessWarningDialog.java
@@ -0,0 +1,81 @@
1+/*
2+ * Copyright (C) 2018 The LineageOS Project
3+ * Copyright (C) 2019 The Android-x86 Open Source Project
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ */
17+
18+package com.android.settings.development;
19+
20+import android.app.Dialog;
21+import android.content.DialogInterface;
22+import android.os.Bundle;
23+
24+import androidx.appcompat.app.AlertDialog;
25+import androidx.fragment.app.FragmentManager;
26+
27+import com.android.internal.logging.nano.MetricsProto;
28+import com.android.settings.R;
29+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
30+
31+public class RootAccessWarningDialog extends InstrumentedDialogFragment implements
32+ DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
33+
34+ public static final String TAG = "RootAccessWarningDialog";
35+
36+ public static void show(DevelopmentSettingsDashboardFragment host,
37+ RootAccessPreferenceController controller) {
38+ final FragmentManager manager = host.getActivity().getSupportFragmentManager();
39+ if (manager.findFragmentByTag(TAG) == null) {
40+ final RootAccessWarningDialog dialog = new RootAccessWarningDialog();
41+ dialog.setTargetFragment(host, 0 /* requestCode */);
42+ dialog.show(manager, TAG);
43+ }
44+ }
45+
46+ @Override
47+ public int getMetricsCategory() {
48+ return MetricsProto.MetricsEvent.TYPE_UNKNOWN;
49+ }
50+
51+ @Override
52+ public Dialog onCreateDialog(Bundle savedInstanceState) {
53+ return new AlertDialog.Builder(getActivity())
54+ .setTitle(R.string.root_access_warning_title)
55+ .setMessage(R.string.root_access_warning_message)
56+ .setPositiveButton(android.R.string.ok, this /* onClickListener */)
57+ .setNegativeButton(android.R.string.cancel, this /* onClickListener */)
58+ .create();
59+ }
60+
61+ @Override
62+ public void onClick(DialogInterface dialog, int which) {
63+ final RootAccessDialogHost host = (RootAccessDialogHost) getTargetFragment();
64+ if (host != null) {
65+ if (which == DialogInterface.BUTTON_POSITIVE) {
66+ host.onRootAccessDialogConfirmed();
67+ } else {
68+ host.onRootAccessDialogDismissed();
69+ }
70+ }
71+ }
72+
73+ @Override
74+ public void onDismiss(DialogInterface dialog) {
75+ super.onDismiss(dialog);
76+ final RootAccessDialogHost host = (RootAccessDialogHost) getTargetFragment();
77+ if (host != null) {
78+ host.onRootAccessDialogDismissed();
79+ }
80+ }
81+}