@@ -231,6 +231,9 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
231231
232232 private static final String INACTIVE_APPS_KEY = "inactive_apps" ;
233233
234+ private static final String ROOT_ACCESS_KEY = "root_access" ;
235+ private static final String ROOT_ACCESS_PROPERTY = "persist.sys.root_access" ;
236+
234237 private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY
235238 = "immediately_destroy_activities" ;
236239 private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit" ;
@@ -354,6 +357,8 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
354357 private SwitchPreference mColorTemperaturePreference ;
355358
356359 private PreferenceScreen mDevelopmentTools ;
360+ private ListPreference mRootAccess ;
361+ private Object mSelectedRootValue ;
357362
358363 private final ArrayList <Preference > mAllPrefs = new ArrayList <>();
359364
@@ -367,6 +372,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment
367372 private Dialog mAdbTcpDialog ;
368373 private Dialog mAdbKeysDialog ;
369374 private boolean mUnavailable ;
375+ private Dialog mRootDialog ;
370376
371377 private boolean mLogpersistCleared ;
372378 private Dialog mLogpersistClearDialog ;
@@ -608,6 +614,11 @@ public void onCreate(Bundle icicle) {
608614 mDevelopmentTools = (PreferenceScreen ) findPreference (DEVELOPMENT_TOOLS );
609615 mAllPrefs .add (mDevelopmentTools );
610616
617+ mRootAccess = (ListPreference ) findPreference (ROOT_ACCESS_KEY );
618+ mRootAccess .setOnPreferenceChangeListener (this );
619+ if (!removeRootOptionsIfRequired ()) {
620+ mAllPrefs .add (mRootAccess );
621+ }
611622 addDashboardCategoryPreferences ();
612623 }
613624
@@ -648,6 +659,18 @@ private SwitchPreference findAndInitSwitchPref(String key) {
648659 return pref ;
649660 }
650661
662+ private boolean removeRootOptionsIfRequired () {
663+ // user builds don't get root, and eng always gets root
664+ if (!(Build .IS_DEBUGGABLE || "eng" .equals (Build .TYPE ))) {
665+ if (mRootAccess != null ) {
666+ getPreferenceScreen ().removePreference (mRootAccess );
667+ return true ;
668+ }
669+ }
670+
671+ return false ;
672+ }
673+
651674 @ Override
652675 public void onActivityCreated (Bundle savedInstanceState ) {
653676 super .onActivityCreated (savedInstanceState );
@@ -874,6 +897,7 @@ private void updateAllOptions() {
874897 updateBluetoothEnableInbandRingingOptions ();
875898 updateBluetoothA2dpConfigurationValues ();
876899 updateAdbOverNetwork ();
900+ updateRootAccessOptions ();
877901 }
878902
879903 private void updateAdbOverNetwork () {
@@ -921,6 +945,7 @@ private void resetDangerousOptions() {
921945 mEnableAdbController .resetPreference ();
922946 resetDebuggerOptions ();
923947 resetAdbNotifyOptions ();
948+ resetRootAccessOptions ();
924949 writeLogpersistOption (null , true );
925950 writeLogdSizeOption (null );
926951 writeAnimationScaleOption (0 , mWindowAnimationScale , null );
@@ -943,6 +968,47 @@ private void resetAdbNotifyOptions() {
943968 LineageSettings .Secure .ADB_NOTIFY , 1 );
944969 }
945970
971+ private void updateRootAccessOptions () {
972+ String value = SystemProperties .get (ROOT_ACCESS_PROPERTY , "0" );
973+ mRootAccess .setValue (value );
974+ mRootAccess .setSummary (getResources ()
975+ .getStringArray (R .array .root_access_entries )[Integer .valueOf (value )]);
976+ }
977+
978+ public static boolean isRootForAppsEnabled () {
979+ int value = SystemProperties .getInt (ROOT_ACCESS_PROPERTY , 0 );
980+ boolean daemonState =
981+ SystemProperties .get ("init.svc.su_daemon" , "absent" ).equals ("running" );
982+ return daemonState && (value == 1 || value == 3 );
983+ }
984+
985+ private void writeRootAccessOptions (Object newValue ) {
986+ String oldValue = SystemProperties .get (ROOT_ACCESS_PROPERTY , "0" );
987+ SystemProperties .set (ROOT_ACCESS_PROPERTY , newValue .toString ());
988+ if (Integer .valueOf (newValue .toString ()) < 2 && !oldValue .equals (newValue )
989+ && "1" .equals (SystemProperties .get ("service.adb.root" , "0" ))) {
990+ SystemProperties .set ("service.adb.root" , "0" );
991+ Settings .Secure .putInt (getActivity ().getContentResolver (),
992+ Settings .Secure .ADB_ENABLED , 0 );
993+ Settings .Secure .putInt (getActivity ().getContentResolver (),
994+ Settings .Secure .ADB_ENABLED , 1 );
995+ }
996+ updateRootAccessOptions ();
997+ }
998+
999+ private void resetRootAccessOptions () {
1000+ String oldValue = SystemProperties .get (ROOT_ACCESS_PROPERTY , "0" );
1001+ SystemProperties .set (ROOT_ACCESS_PROPERTY , "0" );
1002+ if (!oldValue .equals ("0" ) && "1" .equals (SystemProperties .get ("service.adb.root" , "0" ))) {
1003+ SystemProperties .set ("service.adb.root" , "0" );
1004+ Settings .Secure .putInt (getActivity ().getContentResolver (),
1005+ Settings .Secure .ADB_ENABLED , 0 );
1006+ Settings .Secure .putInt (getActivity ().getContentResolver (),
1007+ Settings .Secure .ADB_ENABLED , 1 );
1008+ }
1009+ updateRootAccessOptions ();
1010+ }
1011+
9461012 private void updateHdcpValues () {
9471013 ListPreference hdcpChecking = (ListPreference ) findPreference (HDCP_CHECKING_KEY );
9481014 if (hdcpChecking != null ) {
@@ -2718,6 +2784,24 @@ public boolean onPreferenceChange(Preference preference, Object newValue) {
27182784 } else if (preference == mSimulateColorSpace ) {
27192785 writeSimulateColorSpace (newValue );
27202786 return true ;
2787+ } else if (preference == mRootAccess ) {
2788+ if ("0" .equals (SystemProperties .get (ROOT_ACCESS_PROPERTY , "0" ))
2789+ && !"0" .equals (newValue )) {
2790+ mSelectedRootValue = newValue ;
2791+ mDialogClicked = false ;
2792+ if (mRootDialog != null ) {
2793+ dismissDialogs ();
2794+ }
2795+ mRootDialog = new AlertDialog .Builder (getActivity ())
2796+ .setMessage (getResources ().getString (R .string .root_access_warning_message ))
2797+ .setTitle (R .string .root_access_warning_title )
2798+ .setPositiveButton (android .R .string .yes , this )
2799+ .setNegativeButton (android .R .string .no , this ).show ();
2800+ mRootDialog .setOnDismissListener (this );
2801+ } else {
2802+ writeRootAccessOptions (newValue );
2803+ }
2804+ return true ;
27212805 }
27222806 return false ;
27232807 }
@@ -2740,6 +2824,10 @@ private void dismissDialogs() {
27402824 mAdbTcpDialog .dismiss ();
27412825 mAdbTcpDialog = null ;
27422826 }
2827+ if (mRootDialog != null ) {
2828+ mRootDialog .dismiss ();
2829+ mRootDialog = null ;
2830+ }
27432831 }
27442832
27452833 public void onClick (DialogInterface dialog , int which ) {
@@ -2773,6 +2861,13 @@ public void onClick(DialogInterface dialog, int which) {
27732861 LineageSettings .Secure .putInt (getActivity ().getContentResolver (),
27742862 LineageSettings .Secure .ADB_PORT , 5555 );
27752863 }
2864+ } else if (dialog == mRootDialog ) {
2865+ if (which == DialogInterface .BUTTON_POSITIVE ) {
2866+ writeRootAccessOptions (mSelectedRootValue );
2867+ } else {
2868+ // Reset the option
2869+ writeRootAccessOptions ("0" );
2870+ }
27762871 }
27772872 }
27782873
@@ -2788,6 +2883,9 @@ public void onDismiss(DialogInterface dialog) {
27882883 } else if (dialog == mAdbTcpDialog ) {
27892884 updateAdbOverNetwork ();
27902885 mAdbTcpDialog = null ;
2886+ } else if (dialog == mRootDialog ) {
2887+ updateRootAccessOptions ();
2888+ mRootDialog = null ;
27912889 }
27922890 }
27932891
0 commit comments