Does anyone know just where in the Android stack the "Restrict Background Data" setting is enforced and how it is enforced? (I.e. apps in the background are not allowed to use the phone data network while running in the background - WIFI not affected.)
Thanks much,
Dawg
Android uses iptables rules as on any linux box to restrict data-access to certain users (every user downloaded app on android runs under its own unique user id).
If you wish to remove restriction for your app, you can remove the rule from a root shell.
iptables -F penalty_box -j REJECT
or on newer devices, as below:
iptables -F bw_penalty_box -j REJECT
However on a restart, Android will re-enforce the rule to iptables automatically. To prevent this, you need to remove <uid-policy ...> from "/data/system/netpolicy.xml". Global Restrict Background Data settings can be removed by setting "restrictBackgroundData" atribute to "false" on <policy-list ...> node.
Along with the netpolicy.xml changes, you must perform a reboot for your changes to take effect.
Note: Any of these operations may require to be run as root.
Related
Background: I am developing for a signage device which is to be remotely operated. I need an application that can
Fetch and install new packages
Reboot the device (for troubleshooting)
I have an unrooted Android device. I also have files which I am told are the platform keys.
I have developed an application which attempts to kick off the su process.
Process p = Runtime.getRuntime().exec("su");
Before I signed the application with the platform keys this was throwing an IOException, with the message being Permission Denied.
I signed the application with these platform keys, and I am still getting the Permission Denied exception.
Here are three contradictory statements. Which one of these statements (if any) is correct?
Statment 1: This should work. The application, even though is is stored in /data/app, should be able to run su. Either I have the wrong keys, or there's some other entry I need to add to the manifest to get it to work.
Statement 2: This shouldn't work. Even though it is signed with the platform key, the application is in /data/app, so it's a data application, not a system application. Data applications cannot run su on an unrooted devices. If this application was installed into /system/app, then it would be able to run su. (And I can't get it into /system/app because it's unrooted, so I'm stuck).
Statment 3: This will never work. If the device is not rooted, then NOTHING can run su, even if it is a signed system app.
Android shouldn't even have a su binary if you didn't flash some sort of root method to the device, such as Magisk or SuperSU.
Even if it does have a su binary, I wouldn't expect it to work, for one of two reasons. Assuming that your device comes with a preinstalled su binary, who's managing it? If it's unmanaged, it should just deny all requests. If you flash a root method, then it's up to that manager to decide if your app gets access to su, regardless of whether you have signature-level permissions or nor (the root manager uses a different signature, after all).
And why would you even need access to su as a signature app? You have total access to the device anyway. If you need to run a command, you should have no problems no matter what you run, as long as it's done from your platform-signed package. But since you have full access, the native APIs should let you do everything you need.
As for the IOException returned when you try to execute su in a Process, that's just a weird Android quirk. If there's no su binary installed, it'll sometimes return command not found and other times permission denied, depending on the device.
The point I think I'm making is that, unless your app is the root manager, you could be part of the system_server and still have the same access to su as everyone else. For which statement I agree with, I think #3, although I don't fully agree with it, because chances are su just doesn't exist, or it's a dud binary.
I've explained why #1 shouldn't be true, but #2 is just incorrect. If you look at the platform manifest, every permission that requires a privileged app can also be granted to signature apps. So even if you did move your app to /system/priv-app/ (/system/app/ won't make it privileged), it wouldn't make a difference. Basically, if your app is signed by the platform signature, it doesn't matter where it's installed.
EDIT:
You can easily reboot by just running reboot as a command, since you have signature-level access to the system, but it's a little more elegant to use the proper API for this. If you use the API, you get the shutdown animation, but you also let the system shut down gracefully, stopping services and sending the ACTION_REBOOT broadcast to any apps that might be listening for that.
To use the API, first add the following permission to your AndroidManifest:
<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
Now, where you need to call the reboot action, use the following code:
IStatusBarService bar = IStatusBarService.Stub.asInterface(ServiceManager.getService(Context.STATUS_BAR_SERVICE));
bar.reboot(false); //using true here will reboot to Safe Mode
This method is a hidden method, so if you're using Android Studio to edit and compile, it'll error out. You can use reflection, or use Android Hidden API to access it directly.
This is how System UI implements it in the power menu: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
This is the class that implements IStatusBar service: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/services/core/java/com/android/server/statusbar/StatusBarManagerService.java#L969
I'd go with Statement 3. This will never work on an unrooted Android device. At least, not on recent Android OS versions (I have no idea if this might work on really old Android devices).
"su" is an application -- there has to be an "su" binary on disk in order to execute it, and Android does not by default provide an "su" binary for security purposes. When you use thirdparty rootkits, they install their own "su" binary to provide a mechanism for the user to elevate themselves to root privileges.
If your app is signed with a special key and granted elevated privileges from startup, why would you need to execute "su" anyway?
At work, we have an Android-based infotainment system that we're constantly deploying new versions to, on a half-dozen different test benches. The deployment script does the moral equivalent of:
for apk in ${apk_files}; do
adb install -r ${apk]
done
After this, we need to manually execute the following steps:
Set the home app to be one of our just-installed applications (Always, not Just Once)
Become a developer, and enable the Stay Awake option
Select the Google TTS engine for text-to-speech functionality rather than Pico
Executing these steps after each deploy is a giant PITA. People often forget one or more steps, and leave the test bench in a non-working state. This results in a bunch of 'bogus' bug reports that waste everbody's time.
Is there some way (using adb, perhaps) that we can automate these steps?
You can disable other home apps with adb shell pm disable .... I don't think there's a command line option to set apps as default. I remember looking into this before and there was a "preferred application" XML file where this was stored. If you want to look into it, the magic happens in PackageManagerService.addPreferredActivityInternal(). Looks like it writes the data to a file on disk: package-restrictions.xml. I suppose it's possible you could figure out the format thereof and write the file (you'd need root).
This is controlled by a system settings, "stay_on_while_plugged_in". You can set it using adb shell settings system put ....
The TTS engine is stored in a secure setting, "tts_default_synth". You can see the value like,
$ adb shell settings get secure tts_default_synth com.svox.pico
com.svox.pico
And you can set it with adb shell settings put secure "tts_default_synth" <the value>.
I noticed that if the value was not been previously set, when you get the value using the settings command you get null and it's not listed in settings list, even though there is a default value. As of Android 6 (I think), settings are no longer in a DB but rather are stored in XML files in /data/system/users/0/settings_*.xml. You can see the values therein.
I am trying to set the Settings.Global.PACKAGE_VERIFIER_ENABLE value in Android by using
Settings.Global.putInt(mContext.getContentResolver(),key,value);
However, what ever value I set , I was not getting the value when do following adb command.
adb shell settings get global package_verifier_enable
Thanks InAdvance
in the official android documentation is described that
Applications can read these but are not allowed to write; like the "Secure" settings, these are for preferences that the user must explicitly modify through the system UI or specialized APIs for those values.
This means that unless your app is running as system you're not allowed to write to those settings.
If you have the right signing certificate for the android operating system that you're using, you can sign your app to run with system privileges. As long as you're just running as a "normal" app there is no way to modify these settings.
You can however (which is bad practice) use su to set this setting via
su -c 'settings set global package_verifier_enable 0'
Is it possible to disable the "grant/deny" popup dialog when my app needs to perform tasks that require root access? I have full control of the device the app will run on (internal project), the device is rooted and it has supersu 2.x app.
This tells me that I need to declare the android.permission.ACCESS_SUPERUSER permission for my app to disable the popup, but it has no effect.
Is there a simple way to solve this (without changing the option i supersu app settings)?
Remove the SuperSU APK (usually either /system/app/Superuser.apk or /data/app/eu.chainfire.supersu*.apk or /system/app/SuperSU/SuperSU.apk) and rm -rf the /data/data/eu.chainfire.supersu directory, and the su command will always grant access without showing the prompt.
If you're making a custom firmware image for your project, just exclude the APK.
Note that pm path eu.chainfire.supersu from an adb shell will give you the exact path for the APK.
You can't decide in you app to disable the prompt. That's a security measure which no app can change.
If your device is rooted and you have supersu, you can still get rid of the dialog. You have to change a setting in supersu: Settings --> Access --> Default access --> Grant
This is not possible, you can't interfere with the logic of another app, i.e. the one showing the popup when su is accessed (for example Superuser).
I have a list of apps which consume high battery.
when I select one app, I want to "Restrict background data (Settings > Data usage > select app > Restrict background data)" for the selected app.
How Can I do this ?
Same question is asked at below link
Programatically toggle "Restrict Background Data"
And it says it can not be done.
You can run this command in the command line
svc data disable or svc data enable
You obviously need root to do that, like this:
Runtime.getRuntime().exec("echo svc data disable | su");
This should bring up root dialog if your device is rooted.
And it says it can not be done.
There is nothing in the Android SDK for this. Therefore, it is usually assumed to be impossible until proven otherwise. In this case, there is also a security aspect -- one app should not be able to control this setting for other apps, except perhaps on rooted devices.
You may try Reflection.I am not sure of it.