Запись cpu0/cpufreq/cpuinfo_min_freq: ошибка открытия: EACCES (отказано в доступе)

Я пытаюсь программно установить минимальную/максимальную тактовую частоту на рутированном телефоне. Следуя предложению, сделанному в ответ на этот вопрос, Я нашел некоторая документация, которая предполагает, что я записываю данные в:

/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq

а также

/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq

у меня уже есть

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

в моем манифесте. Также я могу успешно читать оба файла. При попытке записи в файлы получил open failed: EACCES (Permission denied). Итак, я попытался...

Runtime.getRuntime().exec("su -c \"chmod 777 /sys/devices/system/cpu/cpu0/cpufreq/*\"");

... который выполнялся без ошибок, но это не имело значения. Ошибка возникает, когда я выполняю вторую из этих двух строк:

File file = new File("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq");
BufferedWriter bw = new BufferedWriter(new FileWriter(file));  

Я не уверен, что я могу попробовать дальше.

EDIT: Следуя совету mrPjer, я запустил оболочку adb. Я набрал su и перешел к /sys/devices/system/cpu/cpu0/cpufreq. Затем я набрал

chmod 777 scaling_max_freq

и подтвердил, что разрешения были приняты, набрав

ls -l scaling_max_freq

и, конечно же, он был указан как -rwxrwxrwx. Затем я набрал

echo 124200 > scaling_max_freq

а потом

cat scaling_max_freq

к сожалению, это сообщило, что файл не изменился как «1512000».

РЕДАКТИРОВАТЬ: Этот вопрос теперь несколько отклонился от первоначального названия, поэтому я опубликую последнее редактирование как совсем новый вопрос.


person Mick    schedule 13.11.2014    source источник


Ответы (1)


Вместо того, чтобы изменять права доступа к системным файлам на глобальные для чтения/записи (чего вам действительно не следует делать), попробуйте записать файлы напрямую, используя root-доступ.

Вы можете легко сделать это, используя echo вместо chmod в вашем вызове su. Например.

Runtime.getRuntime().exec("su -c \"echo 1234 > /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq\"");

Вызов exec также должен возвращать объект Process, для которого вы можете вызвать функцию waitFor(), которая даст вам код возврата вызова. Если это отличается от нуля, что-то пошло не так.

Наконец, подтвердите, что вы действительно получаете root-доступ — при выполнении запроса su появляется ли диалоговое окно с просьбой разрешить действие?

Кроме того, поскольку вы пишете приложения с поддержкой root, взгляните на библиотеку RootTools: https://code.google.com/p/roottools/wiki/Usage.

person mrPjer    schedule 13.11.2014
comment
Звучит как хороший совет. Я попробовал Runtime.getRuntime().exec(su -c \echo 594000 › /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq\); и это было выполнено без каких-либо исключений ... но, к сожалению, когда я прочитал файл через несколько мгновений, чтобы проверить, что он сработал, это было 384000. Возможно, ваш ответ дает правильный способ записи файла, но почему-то этого недостаточно, чтобы навсегда установить минимальная частота процессора :-( - person Mick; 13.11.2014
comment
Телефон рутирован (100% уверен). Означает ли это автоматически, что мое приложение имеет root-доступ или нет, я менее уверен. - person Mick; 13.11.2014
comment
Можете ли вы подтвердить, что приложение имеет root-доступ? Кроме того, можете ли вы подтвердить код возврата, полученный при выполнении этой команды? Прошло некоторое время с тех пор, как я делал что-то подобное, но проверьте, нужно ли вам делать что-то еще, если ваш процессор имеет несколько ядер. Кроме того, чтобы упростить отладку, я бы посоветовал вам сначала попробовать получить команду, которая работает, используя оболочку adb. Это даст вам стандартную оболочку, в которой вы сможете опробовать команды, которые позже вы сможете добавить в вызов exec(). - person mrPjer; 13.11.2014
comment
Я не понимаю, как получить код возврата от exec(). Что касается проверки, нужно ли вам делать что-то дополнительно, если ваш процессор многоядерный - я понятия не имею, как это выяснить. Я искал во многих местах без везения. Буду играть с adb shell. - person Mick; 13.11.2014
comment
Я не могу проверить это сейчас, но возвращаемый тип вызова exec должен быть объектом Process. Допустим, вы назначаете его с помощью Process p = Runtime.getRuntime().exec(...). Вы можете получить код возврата из этого объекта процесса, вызвав int returnCode = p.waitFor();. Проверьте, отличается ли он от 0. Кроме того, при запуске в оболочке ADB вы можете проверить код возврата последней команды, запустив echo $?. Кроме того, файл cpuinfo_min_freq может быть доступен только для чтения. Посмотрите, есть ли у вас масштабирование_min_freq в том же каталоге. - person mrPjer; 13.11.2014
comment
Подтвердите, что вы действительно можете запустить как su, так и echo с оболочкой adb. В зависимости от того, как настроена ваша система, вам может потребоваться указать полный путь к двоичным файлам (что-то вроде /system/xbin/su). Однако это не будет работать на всех устройствах. Более надежный способ можно найти на su.chainfire.eu. - person mrPjer; 13.11.2014
comment
См. редактирование ОП. И эхо, и su выполняются без ошибок, даже когда я нахожусь в каталоге cpufreq. - person Mick; 13.11.2014
comment
Давайте продолжим обсуждение в чате. - person mrPjer; 13.11.2014