Changing Doze mode parameters programmatically - android

Question about changing the parameters of the transition to doze mode
I have a non-rooted Android 12 device
There are a number of parameters for changing the transition time in doze mode:
inactive_to
motion_inactive_to
light_after_inactive_to
If you change these parameters through the PC using ADB, then the parameters are set. For instance:
adb shell device_config put device_idle inactive_to 2592000000
The problem is that after a reboot, the settings are reset.
Tried to change them directly in the program
// val command = arrayOf("/system/bin/device_config", "put", "device_idle", "motion_inactive_to", "2592000000")
val command = arrayOf("/system/bin/settings", "put", "global", "device_idle_constants", "light_after_inactive_to", "2592000000")
Log.d("ADB", "Start ${command.joinToString(separator = " ")}")
val process = Runtime.getRuntime().exec(command)
val bufReader = BufferedReader(InputStreamReader(process.errorStream))
val log = StringBuilder()
var line: String?
line = bufReader.readLine()
while (line != null) {
log.append(line + "\n")
line = bufReader.readLine()
}
Log.d("ADB", "Command: $log")
But the first command is answered:
“cmd: Can't find service: "device_config"”
And the second command gives an error:
Permission Denial: getCurrentUser() from pid=28435, uid=10245 requires android.permission.INTERACT_ACROSS_USERS
After searching for information about the INTERACT_ACROSS_USERS permission, I understand that it is necessary for it to make the application system. And for this I need to root the device.
Is there any other way to change the parameters of doze mode or disable it altogether?
It's confusing that you can run a command with adb on a non-rooted device, but you can't directly in the program.

Is there any other way to change the parameters of doze mode or disable it altogether?
No. If there were, it would have been pointless to add Doze mode, as every developer would opt out of it.
It's confusing that you can run a command with adb on a non-rooted device, but you can't directly in the program.
Different users/processes having different privileges has been a common concept in operating systems for at least 30 years.

Related

Executing adb commands on Android 10 (API 29)

I'm trying to run adb commands programmatically from inside an Android priviledged app (apk file uploaded to priv-app folder, privapp-permissions-platform.xml file uploaded to /etc/permissions/.
private fun executeAdbCommand() {
val commandStart = "am start -n com.abc.bcd/com.abc.bcd.MainActivity"
val process = Runtime.getRuntime().exec(commandStart)
val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
val commandBattery = "dumpsys battery set level 20"
val processBattery = Runtime.getRuntime().exec(commandBattery)
val bufferedReaderBattery = BufferedReader(InputStreamReader(processBattery.inputStream))
val commandBack = "input keyevent ${KeyEvent.KEYCODE_BACK}"
val processBack = Runtime.getRuntime().exec(commandBack)
val bufferedReaderThree = BufferedReader(InputStreamReader(processBack.inputStream))
}
The first two commands produce no result. The third one is actually pressing the Back Button.
When I run the first two commands from a PowerShell windows they are both executed correctly:
adb shell am start -n com.abc.bcd/com.abc.bcd.MainActivity is starting the mentioned activity,
adb shell dumpsys battery set level 20 is setting the emulator's battery to 20%.
I am targeting Android 10 (API level 29) - is this the expected behaviour of the system? What is the particular reason the first two commands are getting discarded (no error log is generated) and the third one is getting executed? Is there any way of getting the first two commands running (might this be a missing permission or something similar)?

Can we programatically enable/disable USB debugging on Android devices? [duplicate]

This question already has answers here:
Enable USB debugging (under settings/applications/development) programmatically from within an app
(6 answers)
Closed 5 years ago.
Is there any way to turn USB debugging on/off programmatically on Android devices?
Hi this is my first post on here, and normally I wouldn't bother but I see no one wanted to give you the answer despite there being multiple ways to do so.
This is all from my app, I'm "idone" on xda-dev btw. Also some of this code maybe Samsung MSMxxxx specific
If you have root you can indeed. And here are 3 ways to do so despite other people saying otherwise
Method 1(broadcast secret code)
Method 2(set sys.usb.config)
Method 3(set settings global adb_enabled 1)
public String[] SET_DM_PORT_STATUS_LIST = new String[9];{
SET_DM_PORT_STATUS_LIST[0] = "setMTP";
SET_DM_PORT_STATUS_LIST[1] = "setMTPADB";
SET_DM_PORT_STATUS_LIST[2] = "setPTP";
SET_DM_PORT_STATUS_LIST[3] = "setPTPADB";
SET_DM_PORT_STATUS_LIST[4] = "setRNDISDMMODEM";
SET_DM_PORT_STATUS_LIST[5] = "setRMNETDMMODEM";
SET_DM_PORT_STATUS_LIST[6] = "setDMMODEMADB";
SET_DM_PORT_STATUS_LIST[7] = "setMASSSTORAGE";
SET_DM_PORT_STATUS_LIST[8] = "setMASSSTORAGEADB";}
public String[] SET_DM_PORT_CONFIG_LIST = new String[9];{
SET_DM_PORT_CONFIG_LIST[0] = "mtp";
SET_DM_PORT_CONFIG_LIST[1] = "mtp,adb";
SET_DM_PORT_CONFIG_LIST[2] = "ptp";
SET_DM_PORT_CONFIG_LIST[3] = "ptp,adb";
SET_DM_PORT_CONFIG_LIST[4] = "rndis,acm,diag";
SET_DM_PORT_CONFIG_LIST[5] = "rmnet,acm,diag";
SET_DM_PORT_CONFIG_LIST[6] = "diag,acm,adb";
SET_DM_PORT_CONFIG_LIST[7] = "mass_storage";
SET_DM_PORT_CONFIG_LIST[8] = "mass_storage,adb";}
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
outputStream.writeBytes("am broadcast -a android.provider.Telephony.SECRET_CODE -d android_secret_code://" + SET_DM_PORT_STATUS_LIST[paramInt]+"\n");
outputStream.writeBytes("setprop sys.usb.config " + SET_DM_PORT_CONFIG_LIST[paramInt]+"\n");
if(SET_DM_PORT_STATUS_LIST[paramInt].contains("adb")){
outputStream.writeBytes("settings put global adb_enabled 1\n");
}
I am in the process of reversing IOTHIDDENMENU.apk and recreating it's methods but without the internal and hidden api it uses.
On a regular device, with a regular app, you can't.
You need a rooted device, with an app in /system/app, then you can.
Anyway, you shouldn't configure such a thing by yourself, the user should be in full control in such a case.
This is not possible in android because for that you have to access Setting.System. For more info take a look here : How can I disable Android USB debugging programmatically
It's not possible without using your own custom firmware that grants access to the security settings. See thread here: http://groups.google.com/group/android-developers/browse_frm/thread/953c6f0eb0fa9bed#
usb debugging is another name for the Android Debug Bridge (ADB). The item you're looking for is here
http://developer.android.com/reference/android/provider/Settings.Secure.html#ADB_ENABLED
great answer :
https://stackoverflow.com/a/17029123/1136074
basicly its:
android.os.Debug.waitForDebugger(); also you can use the following to determine if the debugger is connected:
android.os.Debug.isDebuggerConnected(); //Determine if a debugger is currently att

Android : How to enable or disable ADB? [duplicate]

I'm trying to enable ADB (USB debugging) only when my application is running and disabling it when my application is not. I have full access to the phone and it is rooted, su available, etc., but I cannot find a way to do the toggling.
What I've tried so far:
Process proc = Runtime.getRuntime().exec(new String [] { "su", "-c", "setprop", "persist.service.adb.enable", "0"});
proc.waitFor();
Process proc2 = Runtime.getRuntime().exec(new String [] { "su", "-c", "stop", "adbd"});
proc2.waitFor();
This however causes the phone to enter a reboot loop instantaneously.
The code that works is easy:
Settings.Secure.putInt(getContentResolver(),Settings.Secure.ADB_ENABLED, 0); // 0 to disable, 1 to enable
Edit/Update:
Thanks to #MohanT for the following update:
Settings.Global.putInt(getContentResolver(),Settings.Global.ADB_ENABLED, 0); // 0 to disable, 1 to enable
However, the app needs to be a system app to be able to use this. To get out of having to sign it, build a custom rom, etc.. I did the following to get it to be a system app.
First, I installed it regularly using eclipse, then adb shell:
> su
# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
# cat /data/app/filename.apk > /system/app/filename.apk
# mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system
# reboot
You can achieve by following next steps:
Check whether ADB is currently enabled. To do that you can use a relevant global constant:
Settings.Global.ADB_ENABLED for API 17 and above.
Settings.Secure.ADB_ENABLED prior to API 17.
Use implicit Intent with Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS action to open developers options, where user can enable or disable ADB.
Code example:
Java
public static final int API = Build.VERSION.SDK_INT;
public static final int ENABLED=1, DISABLED=0;
public static boolean adbEnabled(Context context){
if(API>16)
return ENABLED == Settings.Global.getInt(context.getContentResolver(), Settings.Global.ADB_ENABLED,DISABLED);
else
return ENABLED == Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ADB_ENABLED,DISABLED);
}
public void checkAdb(Context context){
//if ADB disabled
if(!adbEnabled(context)){
//open developer options settings
Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
context.startActivity(intent);
}
}
Kotlin
val API = Build.VERSION.SDK_INT
val ENABLED = 1
val DISABLED = 0
fun adbEnabled(context: Context): Boolean {
return if (API > 16)
ENABLED == Settings.Global.getInt(context.contentResolver, Settings.Global.ADB_ENABLED, DISABLED)
else
ENABLED == Settings.Secure.getInt(context.contentResolver, Settings.Secure.ADB_ENABLED, DISABLED)
}
fun checkAdb(context: Context) {
//if ADB disabled
if (!adbEnabled(context)) {
//open developer options settings
val intent = Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
context.startActivity(intent)
}
}
Just for reference:
Prior to API 3 (probably no longer relevant) Settings.System.ADB_ENABLED was used.
Chris's answer is correct except the ADB_ENABLED field in Secure class has been depreciated and the string has been moved to Global class. So you can use below command -
Settings.Global.putInt(getContentResolver(),Settings.Global.ADB_ENABLED, 0); // 0 to disable, 1 to enable
From my experiences using setprop doesn't always work reliable, and might even conflict with the Settings > Applications > Development > USB Debugging option. Besides that it might be irritating for instance if USB debugging is enabled but adb doesn't work etc. Therefore using Settings.Secure.ADB_ENABLED is the prefered way... plus you always have the notification in the status panel.
If you don't want to go through the hassle to install your app on system partition when only trying to access Settings.Secure.ADB_ENABLED then you can instead rely on another app that is doing this work already:
This app is called ADB Toggle. You can find it in Google Play:
https://play.google.com/store/apps/details?id=com.ramdroid.adbtoggle
The library to access USB debug settings via ADB Toggle is available here:
https://github.com/ramdroid/AdbToggleAccessLib

Looking to enable and disable (toggle) ADB or USB debugging using command line or in app

I'm trying to enable ADB (USB debugging) only when my application is running and disabling it when my application is not. I have full access to the phone and it is rooted, su available, etc., but I cannot find a way to do the toggling.
What I've tried so far:
Process proc = Runtime.getRuntime().exec(new String [] { "su", "-c", "setprop", "persist.service.adb.enable", "0"});
proc.waitFor();
Process proc2 = Runtime.getRuntime().exec(new String [] { "su", "-c", "stop", "adbd"});
proc2.waitFor();
This however causes the phone to enter a reboot loop instantaneously.
The code that works is easy:
Settings.Secure.putInt(getContentResolver(),Settings.Secure.ADB_ENABLED, 0); // 0 to disable, 1 to enable
Edit/Update:
Thanks to #MohanT for the following update:
Settings.Global.putInt(getContentResolver(),Settings.Global.ADB_ENABLED, 0); // 0 to disable, 1 to enable
However, the app needs to be a system app to be able to use this. To get out of having to sign it, build a custom rom, etc.. I did the following to get it to be a system app.
First, I installed it regularly using eclipse, then adb shell:
> su
# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
# cat /data/app/filename.apk > /system/app/filename.apk
# mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system
# reboot
You can achieve by following next steps:
Check whether ADB is currently enabled. To do that you can use a relevant global constant:
Settings.Global.ADB_ENABLED for API 17 and above.
Settings.Secure.ADB_ENABLED prior to API 17.
Use implicit Intent with Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS action to open developers options, where user can enable or disable ADB.
Code example:
Java
public static final int API = Build.VERSION.SDK_INT;
public static final int ENABLED=1, DISABLED=0;
public static boolean adbEnabled(Context context){
if(API>16)
return ENABLED == Settings.Global.getInt(context.getContentResolver(), Settings.Global.ADB_ENABLED,DISABLED);
else
return ENABLED == Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ADB_ENABLED,DISABLED);
}
public void checkAdb(Context context){
//if ADB disabled
if(!adbEnabled(context)){
//open developer options settings
Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
context.startActivity(intent);
}
}
Kotlin
val API = Build.VERSION.SDK_INT
val ENABLED = 1
val DISABLED = 0
fun adbEnabled(context: Context): Boolean {
return if (API > 16)
ENABLED == Settings.Global.getInt(context.contentResolver, Settings.Global.ADB_ENABLED, DISABLED)
else
ENABLED == Settings.Secure.getInt(context.contentResolver, Settings.Secure.ADB_ENABLED, DISABLED)
}
fun checkAdb(context: Context) {
//if ADB disabled
if (!adbEnabled(context)) {
//open developer options settings
val intent = Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
context.startActivity(intent)
}
}
Just for reference:
Prior to API 3 (probably no longer relevant) Settings.System.ADB_ENABLED was used.
Chris's answer is correct except the ADB_ENABLED field in Secure class has been depreciated and the string has been moved to Global class. So you can use below command -
Settings.Global.putInt(getContentResolver(),Settings.Global.ADB_ENABLED, 0); // 0 to disable, 1 to enable
From my experiences using setprop doesn't always work reliable, and might even conflict with the Settings > Applications > Development > USB Debugging option. Besides that it might be irritating for instance if USB debugging is enabled but adb doesn't work etc. Therefore using Settings.Secure.ADB_ENABLED is the prefered way... plus you always have the notification in the status panel.
If you don't want to go through the hassle to install your app on system partition when only trying to access Settings.Secure.ADB_ENABLED then you can instead rely on another app that is doing this work already:
This app is called ADB Toggle. You can find it in Google Play:
https://play.google.com/store/apps/details?id=com.ramdroid.adbtoggle
The library to access USB debug settings via ADB Toggle is available here:
https://github.com/ramdroid/AdbToggleAccessLib

Manually starting 3G connection in Android, and keeping it on

How do you start the 3G data connection in Android at the same time WiFi is on? I tried
IConnectivityManager.setMobileDataEnabled(enabled); // via reflection
and it works in the emulator, but in my real phone (Droid 2), it briefly turns on then back off again.
From the shell (adb shell), ip link provides the details of the 3G connection:
15: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 3 link/ppp
However, it is only available when WiFi is off. When WiFi is on and I try to turn it on manually, it complains the ppp0 device doesn't exist.
bash-3.2# ip link set ppp0 up
ip link set ppp0 up
Cannot find device "ppp0"
When I try to list the device, I can't even find it
bash-3.2# ls /dev/ppp*
ls /dev/ppp*
/dev/ppp
As I understand it's not possible to get 3g and WiFi simultaneously connected without modifying Android platform source code (at least versions 2.3 and 4). The main problem is hardcoded priorities of connections defined in frameworks/base/core/res/res/values/config.xml:
<!-- This string array should be overridden by the device to present a list of network
attributes. This is used by the connectivity manager to decide which networks can coexist
based on the hardware -->
<!-- An Array of "[Connection name],[ConnectivityManager connection type],
[associated radio-type],[priority] -->
<!-- ^^^^^^^^^^---------- Connection priority -->
<string-array translatable="false" name="networkAttributes">
<item>"wifi,1,1,1"</item>
<item>"mobile,0,0,0"</item>
<item>"mobile_mms,2,0,2"</item>
<item>"mobile_supl,3,0,2"</item>
<item>"mobile_hipri,5,0,3"</item>
</string-array>
This config.xml is then read by ConnectivityService which is subscribed to connect/disconnect events. And in connect handler it decides what it should do with other connections:
private void handleConnect(NetworkInfo info) {
//------------8-<--------------------------
// if this is a default net and other default is running
// kill the one not preferred
if (mNetAttributes[type].isDefault()) {
if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
if ((type != mNetworkPreference &&
mNetAttributes[mActiveDefaultNetwork].mPriority >
// ^^^^^^^^^ --- From config.xml
mNetAttributes[type].mPriority) ||
// ^^^^^^^^^-------- From config.xml
mNetworkPreference == mActiveDefaultNetwork) {
// don't accept this one
if (DBG) Slog.v(TAG, "Not broadcasting CONNECT_ACTION " +
"to torn down network " + info.getTypeName());
teardown(thisNet);
return;
//------------8-<--------------------------
You could try keeping both active at the same time by modifying your connectivityservice,
but I'd advice against it, since it'll most likely destroy your battery life.
See here if you want to give it a try anyway (and make sure you have a backup, obviously)
If you're trying to connect to a specific machine you can try ConnectivityManager.requestRouteToHost.

Categories

Resources