Перенос данных и кэша приложений ГУ Changan CS55 Plus
Основной вопрос, который волнует большинство пользователей приложений в ГУ на Changan CS55 Plus - это контроль свободного пространства в разделе /data
. Переполнение раздела /data
, где хранятся все пользовательские приложения, а так же кэш и данные приложений, может привести к не совсем приятным последствиям. Хотя на практике такого не наблюдалось, но потенциальный риск есть всегда.
Одним из выходов стало использование SD-карты видеорегистратора, где можно сохранить оффлайн-карты Я.Навигатора, треки Я.Музыки, кэш и треки Spotify, что значительно разгружает внутреннее хранилище ГУ. Единственным минусом такого варианта является тот факт, что не все приложения обладают такими возможностями.
Однако, еще год назад, при изучении нашего ГУ я обнаружил "скрытый потенциал" нашего ГУ, который не давал покоя. Сейчас я решил реализовать данный потенциал и постараться упростить хранение данных и кэша отдельных ресурсоёмких приложений.
Внутренние разделы ГУ
Если подключиться к нашему ГУ по ADB, то можно получить перечень разделов внутреннего хранилища:
adb root
adb remount
adb shell
# пароль "adb369875"
df -h
в итоге мы видим следующий вывод:
Помимо стандартных разделов data
, vendor
, mnt
есть два интересных раздела:
- раздел
/fota
, со свободным объемом 4 гб; - раздел
/resources
, объемом 12 Гб и свободным объемом 9,6 Гб; - раздел
/sdcard
, объемом 2 Гб, который является хранилищем для мультимедиа файлов, HDD в стоковом плеере ГУ;
По характеру заполнения видно, что раздел /fota
содержит несколько служебных файлов, и похоже используется в китайской версии ГУ для онлайн обновления прошивки, на него возможно загружается файлы обновления из сети. Но у нас в дилерских машинах РФ такой функции нет.
А вот раздел /resources
содержит ряд системных файлов, и также большую папку с логами, которые можно также наблюдать в инженерном меню. Возможно в китайской версии ГУ на данном разделе есть еще много интересного, но у нас данный раздел почти пустует, доступно 9,6 Гб свободного пространства. Появилась идея его использовать.
Изменение места хранения данных и кэша приложений
В Linux-based системах, и в том числе в Android широко используются два способа представления пути до файлов и папок, с фактическим размещением в другой точке хранения в системе:
- символьная ссылка на папки и файлы;
- bind mount;
В нашем случае, нам необходимо перенести папки с данными и кэшем приложений из раздела /data
в раздел /resources
, и сделать ссылки на фактические папки в раздел /resources обратно в раздел /data
, чтобы система нашла необходимые файлы там, где требуется. В итоге приложения будут фактически сохранять файлы в разделе /resources
, но думать, что сохраняют в разделе /data
.
Bind mount был бы отличным вариантом для нашего применения, но такой вид ссылок надо запускать системной службой, или скриптом при запуске ГУ, а с данным вопросом я еще не разобрался, есть ряд рисков, которые пока хочется избежать.
А вот символьными ссылками (symlink) всё гораздо проще, потому что они постоянны. Есть, зачастую, у них проблемы с правами доступа и записью в системные разделы, но мы все действия будем проводить под root, и выдавать нужные разрешения на каталоги.
Место хранение данных и кэша приложений
В нашей системе все приложения хранят свои текущие данные и кэш в следующих директориях:
/data/data/
: здесь свои данные хранят все приложения устройства, в том числе и системные приложения;/data/media/0/Android/data/
: здесь свои данные дополнительно хранят те пользовательские приложения, которые умеют так же работать с внешними хранилищами, что позволяет им разместить свои данные на SD-карте, так же в директории/Android/data/
. Здесь свои данные хранят, например, приложения Я.Навигатор и Я.музыка;
В связи с этим для каждого переносимого приложения нам необходимо создать символьные ссылки в директориях /data/data/
и /data/media/0/Android/data/
, вида /data/data/ru.yandex.yandexnavi
Shell скрипт переноса данных и кэша приложений
В ходе своих экспериментов я пришел к такому скрипту для выполнения функции переноса папок данных приложений:
#!/system/bin/sh
# Получение имени приложения из первого аргумента
app_name=$1
# Проверяем, был ли передан аргумент (имя пакета приложения)
if [ -z "$app_name" ]; then
echo "Не указан пакет приложения. Используйте команду вида: ./moveappfolder.sh com.example.app"
exit 1
fi
# Останавливаем текущее приложение, если запущено
am force-stop $app_name
# Путь к исходной папке приложения в /data/data
src_path="/data/data/$app_name"
# Путь к исходной папке приложения в /data/media/0/Android/data
src0_path="/data/media/0/Android/data/$app_name"
# Путь к новой папке в /resources/new_data
dest_path="/resources/new_data/$app_name"
# Путь к новой папке в /resources/new_a0_data
dest0_path="/resources/new_a0_data/$app_name"
# Проверяем, существует ли папка /resources/new_data
if [ ! -d "/resources/new_data" ]; then
# Если папки нет, создать её
mkdir -p /resources/new_data
# Устанавливаем права доступа 771 и владельца system:system
chmod 771 /resources/new_data
chown system:system /resources/new_data
fi
# Проверяем, существует ли папка /resources/new_a0_data
if [ ! -d "/resources/new_a0_data" ]; then
# Если папки нет, создать её
mkdir -p /resources/new_a0_data
# Устанавливаем права доступа 775 и владельца media_rw:media_rw
chmod 775 /resources/new_a0_data
chown media_rw:media_rw /resources/new_data
fi
# Проверяем существование исходного пути для /data/data
if [ -d "$src_path" ]; then
# Если существует, перемещаем его в новую директорию
mv $src_path $dest_path
else
# Если нет, создаем новый каталог
mkdir -p $dest_path
fi
# Устанавливаем права доступа 777 на новую папку и подпапки, если они существуют после перемещения
chmod -R 777 $dest_path
# Создаем символическую ссылку из нового каталога обратно в /data/data
ln -sf $dest_path $src_path
echo "Папка данных приложения успешно перенесена в раздел /resources (new_data)"
# Проверяем существование исходного пути для /data/media/0/Android/data
if [ -d "$src0_path" ]; then
# Если существует, перемещаем его в новую директорию
mv $src0_path $dest0_path
else
# Если нет, создаем новый каталог
mkdir -p $dest0_path
fi
# Устанавливаем права доступа 777 на новую папку и подпапки, если они существуют после перемещения
chmod -R 777 $dest0_path
# Создаем символическую ссылку из нового каталога обратно в /data/media/0/Android/data
ln -sf $dest0_path $src0_path
echo "Папка данных приложения успешно перенесена в раздел /resources (new_a0_data)"
Что делает shell скрипт?
Для запуска скрипта нам необходимо загрузить его на устройство, сделать его исполняемым, и запустить скрипт, передав ему в качестве аргумента название пакета требуемого приложения:
adb push moveappfolder.sh /data/local/tmp
adb root
adb remount
adb shell
# пароль "adb369875"
chmod +x /data/local/tmp/moveappfolder.sh
./data/local/tmp/moveappfolder.sh ru.yandex.yandexnavi
В ходе выполнения скрипт создаст в разделе /resources директории:
/new_data
, с правами доступа 771 и владельцем system:system;/new_a0_data
с правами доступа 775 и владельца media_rw:media_rw;
Затем перенесет или создаст папки приложения:
- из
/data/data/
в/resources/new_data/
; - из
/data/media/0/Android/data/
в/resources/new_a0_data
;
Перенесенным или созданным папкам будут присвоены права 777, на случай если папка создаётся вновь, так как у каждого приложения свой UID, и без его определения и присвоения каждой папки приложения работать не будет.
Затем скрипт делает символьную ссылку на папку из директории из /resources/new_data/
в директорию /data/data/
, и из /resources/new_a0_data d
в /data/media/0/Android/data/
;
В итоге, после выполнения скрипта, имеем следующую картину:
ls -l /resources/new_data
ls -l /resources/new_a0_data
ls -l /data/data
ls -l /data/media/0/Android/data
Как видим, символьные ссылки созданы, всё корректно.
А вот, что выдает df -h
после загрузки более 1 Гб оффлайн-карт в Я.навигатор:
Свободное место в разделе /resources
уменьшилось, а раздел /data
не изменяется!
Это всё интересно, но как мне просто перенести данные и кэш приложений в другой раздел всего в пару действий ?!
Batch скрипт для Windows для переноса данный приложений
Для тех пользователей, кто уже знаком с моих batch скриптом установки приложений, я подготовил дополнительный раздел меню, в котором можно выполнить перенос данных приложений в раздел /resources
На текущий момент я внес в скрипт несколько основных приложений для тестирования. Можете подать предложения, какие приложение еще стоит добавить, я внесу корректировку в скрипт. Принцип работы тот же, подключаемся к ГУ в режиме ADB, проверяем соединение, выбираем нужные пункты меню, ждем завершения выполнения.
Те, кто знаком с синтаксисом batch скрипта, могут добавить необходимые приложения самостоятельно, хотя это в этом случае проще уже сделать это в ADB shell вызовом ./data/local/tmp/moveappfolder.sh
с именем пакета приложения в качестве аргумента.
Архив с обновленным скриптом:
И ссылка на Я.Диск: adb_moveapps.zip
Что еще можно перенести на другие разделы?
Можно ли перенести вообще директории /data/data/ и /data/media/0/Android/data/ на другой раздел?
Думаю, что в случае с /data/media/0/Android/data
да, это разумно сделать, там сидят только пользовательские приложения. Чуть позже постараюсь это проверить и реализовать.
А вот с директорией /data/data/
сложнее, так как там еще живут все системные приложения, и я не совсем уверен в результате, если весь объем переместить и заменить символьной ссылкой. С ГУ на рабочем столе я бы еще провернул такой трюк, но с рабочим устройством в машине пока повременю.
Можно ли перенести пакеты самих приложений из /data/app ?
Да, в этом направлении я тоже веду работу, и у меня уже имеется готовый скрипт, но есть одна особенность. Как только я делаю символьную ссылку из папки /resources/new_app/ru.yandex.yandexnavi
в /data/app/ru.yandex.yandexnavi
, то при следующей перезагрузки устройства, все файлы в папке /resources/new_app/ru.yandex.yandexnavi
удаляются системой! Если же не делать символьную ссылку, то файлы в папке перенесенного приложения в /resources/new_app/ru.yandex.yandexnavi
продолжают там размещаться после перезагрузки.
Поэтому сейчас рассматриваю вариант с bind mount и загрузкой скрипта монтирования через службу в /system/etc/init
О результатах напишу в следующих статьях.
Прошу читателей протестировать скрипт переноса данных, и дать свои замечания, вместе постараемся улучшить.