Перенос данных и кэша приложений ГУ Changan CS55 Plus

CHANGAN CS55 PLUS 29 окт. 2024 г.

Основной вопрос, который волнует большинство пользователей приложений в ГУ на Changan CS55 Plus - это контроль свободного пространства в разделе /data. Переполнение раздела /data, где хранятся все пользовательские приложения, а так же кэш и данные приложений, может привести к не совсем приятным последствиям. Хотя на практике такого не наблюдалось, но потенциальный риск есть всегда.

Одним из выходов стало использование SD-карты видеорегистратора, где можно сохранить оффлайн-карты Я.Навигатора, треки Я.Музыки, кэш и треки Spotify, что значительно разгружает внутреннее хранилище ГУ. Единственным минусом такого варианта является тот факт, что не все приложения обладают такими возможностями.

Однако, еще год назад, при изучении нашего ГУ я обнаружил "скрытый потенциал" нашего ГУ, который не давал покоя. Сейчас я решил реализовать данный потенциал и постараться упростить хранение данных и кэша отдельных ресурсоёмких приложений.

Внутренние разделы ГУ

Если подключиться к нашему ГУ по ADB, то можно получить перечень разделов внутреннего хранилища:

adb root
adb remount
adb shell 
# пароль "adb369875"
df -h

в итоге мы видим следующий вывод:

вывод "df"

Помимо стандартных разделов 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

О результатах напишу в следующих статьях.

Прошу читателей протестировать скрипт переноса данных, и дать свои замечания, вместе постараемся улучшить.

Теги