精华内容
下载资源
问答
  • 奇瑞捷途X70悦行版车机升级包,版本V0.30.05,升级后支持Android11。从4S店复制的,保证好用。注意百度网盘上有人分享的V0.30.04版的不行,一定要这个05的
  • 最近按项目要求,需要做一个车机Android在线升级操作,但是cache内存太小了,最后只能寄存希望在 data/文件夹下,但是data/目录在6.0之后禁止recovery读取data文件.最后的解决方案是在/data/文件下创建一个系统app能够...

    最近按项目要求,需要做一个车机Android在线升级操作,但是cache内存太小了,最后只能寄存希望在 data/文件夹下,但是data/目录在6.0之后禁止recovery读取data文件.最后的解决方案是在/data/文件下创建一个系统app能够操作的文件夹,进行升级操作.
    1、升级流程
    Android自带升级流程 API RecoverySystem.java (framework/base/core/java/android/os/RecoverySystem.java)
    调用如下代码就可以进行升级操作,对你没看错,就是一句代码,将你下载好的压缩包路径传过去就行.

       private void excuteUpdateZip(String local_path) {
            // TODO Auto-generated method stub
            try {
                RecoverySystem.installPackage(this, new File(local_path));
                //RecoverySystem.installPackage(this, new File(local_path));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    

    但是 事情永远是比想象的麻烦, 因为我们的车机要求的是将压缩包放到 /data/目录下. 那放就放吧 先编译好一个全包 使用命令

    adb root 
    adb remount
    adb push  updata.zip /data/
    

    使用模拟升级命令进行升级操作

    adb shell "echo --update_package=/data/update.zip > /cache/recovery/command"
     
    adb shell sync
     
    adb reboot recovery
    

    就这样成功进行了升级,what?完成了? 这么简单,原来这才是跳坑的开始,看到生面测试成功了之后,迫不及待的在自己的程序中将路径填写成 /data/update.zip ,开始了升级操作,结果失败了.开始检查原因
    是不是AndroidManifest.xml中没有添加 如下权限
    android:sharedUserId=“android.uid.system”
    查看添加了,是不是没有对自己的apk进行系统签名?发现也签名了(如何给APK系统签名),没有放到system/app/文件夹下?也放了,.那原因出在哪里那?不想了,先去看看log

    Android机器中 /cache/recovery/的目录结构如下:

    cache/        
    └── recovery      
        ├── last_install
        ├── last_kmsg  #系统升级的时候的全log. 如果有last_kmsg.1 
                       #那last_kmsg 永远是最后一次升级的log,所以每
                       #次只查看last_kmsg就行
        ├── last_locale
        └── last_log   #升级过程中的简log,能看到为何升级失败
     
    

    在log中查看到的是 --update_package=@/cache/recovery/block.map 看到这个结果的时候,第一感觉就是apk没有安装成功,于是加了log 发现加的log 成功打印,吓了一跳,自己撞见鬼了?

    抱着程序员不明原因不放弃的心态,看了一下RecoverySystem.java 中的 installPackage 方法,原来是 installpackage在代码中做了限制, 要是设置的路径是以 /data/ 开头强制更改@/cache/recovery/block.map

      @SystemApi
        public static void installPackage(Context context, File packageFile, boolean processed)
                throws IOException {
            //省略代码......
           if (filename.startsWith("/data/")) {
                    if (processed) {
                       //省略代码......
                    } else {
                    //省略代码......
                    }
                    //TODO 重点就是这句话,将路径强制求改
                    filename = "@/cache/recovery/block.map";
                } 
                final String filenameArg = "--update_package=" + filename + "\n";
                final String localeArg = "--locale=" + Locale.getDefault().toString() + "\n";
                final String securityArg = "--security\n";
                String command = filenameArg + localeArg;
                //省略代码......
            }
        }
    

    看到这,挡了我的路,必定铲除,将代码很愉快的注掉了,重新编译进行测试.
    激动的等待中…
    又失败了?难道还有拦路虎? 我的心要崩溃了,为什么还是失败,还是查看log发现 --update_package=data/update.zip . 这么看来已经能写到重启文件中了.

    查看log提示是 --update_package=data/update.zip Permission Denied 看来是datarecover没有权限读取/data目录啊
    快速验证 是不是selinux问题 可以修改 BoardConfig.mk 添加如下代码 编译boot文件测试,如下代码是禁用selinux代码
    BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
    2.selinux权限问题
    经过一番调查 发现 data的 type属于 system_data_file类型的
    在file_contexts中可以查看到
    /data(/.*)? u:object_r:system_data_file:s0
    在recovery.te中发现了如下代码

    neverallow recovery data_file_type:file { no_w_file_perms no_x_file_perms };
    neverallow recovery data_file_type:dir no_w_dir_perms;
    

    也就是说明 recover.te何时都不能读取和操作/data/目录,那怎么办?当然是有办法的,我们可以新建一个文件夹 和自定义文件类型啊
    首先是开机的时候要有一个文件夹
    我们可以在init.rc 或者 init.qcom.rc中创建一个文件夹

    #Create directory for download
    mkdir /data/download 0771
    chown system system /data/download
    

    这样的话 我们已经创建了 文件夹,并且system app级别的应用可以读取.

    那既然存储好了之后是不是下面需要 recovery可以读取到文件那?系统不允许读取 recovery.te /data/路径.那我们就自己创建一个文件类型,在file_contexts 增加类型

    /data/download(/.*)?           u:object_r:download_data_file:s0  
    

    然后在file.te中定义download_data_file类型, 注意是只属于file_type类型的。
    type download_data_file, file_type;
    然后在recovery.te中增加对download_data_file的权限

    allow recovery download_data_file:dir { write search remove_name };
    allow recovery download_data_file:file { read getattr open unlink };
    

    因为data目录有可能需要进行加密处理,我们还需要在uncrypt.te中增加如下。

    allow uncrypt download_data_file:dir { search getattr };  
    allow uncrypt download_data_file:file { getattr read open };
    

    以上就是完成了添加,我本地全编译,测试成功.
    最后升级的过程中可能会看到Permission Denied 最后可以cat last_kmsg 查看 最后一样都会输出失败的权限原因
    比如 :

    avc:  denied  { open } for  pid=381 comm="recovery"
    path="/data/download/update.zip" dev="mmcblk0p51" ino=513074 
    scontext=u:r:recovery:s0 tcontext=u:object_r:download_data_file:s0 
    tclass=file permissive=0
    

    这种权限只能报错什么权限添加什么权限,我们可以遵循这个方法,从头开始寻找关键对象,然后调整一下顺序,生成一条语句,最后将该语句填写到.te中即可。
    denied { open } scontext=u:r:recovery:s0 tcontext=u:object_r:download_data_file:s0 tclass=file

             A                                    B                                                             C                                                  D
    
             B                                    C                                                             D                                                   A
    

    allow recovery download_data_file:tclass open;
    如果升级没有错误,APP操作文件夹中的文件无效时,可以在操作的时候执行如下命令,如果报了相关权限问题,加上即可,
    adb shell dmesg | grep denied

    其它版本的系统升级,升级包存储在/data/分区的情况可以参考这篇文章,大同小异的。

    展开全文
  • 汉腾X7车机系统1.96.rar

    2020-04-12 09:48:00
    汉腾X7车机系统1.96 原来黄色界面升级以后是最新版的蓝色界面,优化原来存在的bug。界面更加炫酷更有科技感。
  • 如果说小米是国内手机厂商系统维护的巨头,那么一加也不容忽视。...由于一加5和5T基本接近,后续5T手机也应该会有安卓10底层升级作为1款2017年发布的安卓手机,一加让其从安卓7.1一路升级迭代到了安卓10系统,这下...

    如果说小米是国内手机厂商系统维护的巨头,那么一加也不容忽视。近日,一加论坛发

    布了H2OS For OnePlus 5【Android 10.0 公测版】 第1版更新公告,带来了全新的UI设

    计,轻快流畅操作体验,系统更新至 Android 10版本。由于一加5和5T基本接近,后续

    5T手机也应该会有安卓10底层升级

    a196105b200b6044fedce08afa5a2350.png

    作为1款2017年发布的安卓手机,一加让其从安卓7.1一路升级迭代到了安卓10系统,这

    下使用一加5系列的机油有福了。从介绍来看,氢OS 10.0是一次里程碑式的升级。更加

    轻快流畅的底层优化,Smooth Battle 带来的逐帧优化、超 150项动效优化、更智能的

    相册、支持公交门禁的多功能 NFC、还有随你所想、随叫随到的车载语音助手。


    升级方式
    1、从指定地址下载OnePlus 5 公测ROM升级压缩包
    2、将ROM升级压缩包拷贝到手机根目录

    3、设置 -> 系统 -> 系统升级 -> 右上齿轮 -> 本地升级 -> 点击对应的安装包 -> 马上

    升级 -> 系统升级完成

    4、选择重启(或按电源键重新启动)
    5、成功升级公测版

    bed1129e809259f31f0ef5a876a99af7.png

    已知问题:
    1、目前相机应用暂不支持电子防抖功能,后续版本推送将会优化该功能

    2、系统多任务卡片界面正处于升级调整中,将于5月上旬可通过应用自升级完善

    展开全文
  • 诺威达车机车载导航睿志诚安卓rom刷机,9.1系统,稳定快速。必须是诺威达车机,车载导航睿志诚安卓rom刷机。刷机有风险,请谨慎操作,后果自行承担,
  • 最近按项目要求,需要做一个车机Android在线升级操作,但是cache内存太小了,最后只能寄存希望在 data/文件夹下,但是data/目录在6.0之后禁止recovery读取data文件.最后的解决方案是在/data/文件下创建一个系统app能够...

    最近按项目要求,需要做一个车机Android在线升级操作,但是cache内存太小了,最后只能寄存希望在 data/文件夹下,但是data/目录在6.0之后禁止recovery读取data文件.最后的解决方案是在/data/文件下创建一个系统app能够操作的文件夹,进行升级操作.

     

    1.升级流程

    Android自带升级流程 API  RecoverySystem.java  (framework/base/core/java/android/os/RecoverySystem.java) 

    调用如下代码就可以进行升级操作,对你没看错,就是一句代码,将你下载好的压缩包路径传过去就行.

       private void excuteUpdateZip(String local_path) {
            // TODO Auto-generated method stub
            try {
                RecoverySystem.installPackage(this, new File(local_path));
                //RecoverySystem.installPackage(this, new File(local_path));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    但是 事情永远是比想象的麻烦, 因为我们的车机要求的是将压缩包放到 /data/目录下. 那放就放吧  先编译好一个全包 使用命令

    adb root 
    adb remount
    adb push  updata.zip /data/

    使用模拟升级命令进行升级操作

    adb shell "echo --update_package=/data/update.zip > /cache/recovery/command"
    
    adb shell sync
    
    adb reboot recovery

    就这样成功进行了升级,what?完成了? 这么简单,原来这才是跳坑的开始,看到生面测试成功了之后,迫不及待的在自己的程序中将路径填写成  /data/update.zip ,开始了升级操作,结果失败了.开始检查原因

    是不是AndroidManifest.xml中没有添加 如下权限

    android:sharedUserId="android.uid.system"

    查看添加了,是不是没有对自己的apk进行系统签名?发现也签名了(如何给APK系统签名),没有放到system/app/文件夹下?也放了,.那原因出在哪里那?不想了,先去看看log

    Android机器中 /cache/recovery/的目录结构如下:

    cache/        
    └── recovery      
        ├── last_install
        ├── last_kmsg  #系统升级的时候的全log. 如果有last_kmsg.1 
                       #那last_kmsg 永远是最后一次升级的log,所以每
                       #次只查看last_kmsg就行
        ├── last_locale
        └── last_log   #升级过程中的简log,能看到为何升级失败
    
    

    在log中查看到的是  --update_package=@/cache/recovery/block.map 看到这个结果的时候,第一感觉就是apk没有安装成功,于是加了log 发现加的log 成功打印,吓了一跳,自己撞见鬼了? 

    抱着程序员不明原因不放弃的心态,看了一下RecoverySystem.java 中的 installPackage 方法,原来是 installpackage在代码中做了限制, 要是设置的路径是以 /data/ 开头强制更改@/cache/recovery/block.map  

      @SystemApi
        public static void installPackage(Context context, File packageFile, boolean processed)
                throws IOException {
            //省略代码......
           if (filename.startsWith("/data/")) {
                    if (processed) {
                       //省略代码......
                    } else {
                    //省略代码......
                    }
                    //TODO 重点就是这句话,将路径强制求改
                    filename = "@/cache/recovery/block.map";
                } 
                final String filenameArg = "--update_package=" + filename + "\n";
                final String localeArg = "--locale=" + Locale.getDefault().toString() + "\n";
                final String securityArg = "--security\n";
                String command = filenameArg + localeArg;
                //省略代码......
            }
        }
    

    看到这,挡了我的路,必定铲除,将代码很愉快的注掉了,重新编译进行测试.

    激动的等待中.........

    又失败了?难道还有拦路虎? 我的心要崩溃了,为什么还是失败,还是查看log发现 --update_package=data/update.zip . 这么看来已经能写到重启文件中了.

    查看log提示是  --update_package=data/update.zip  Permission Denied 看来是datarecover没有权限读取/data目录啊

     

    快速验证 是不是selinux问题 可以修改 BoardConfig.mk 添加如下代码 编译boot文件测试,如下代码是禁用selinux代码

    BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive

     

    2具体的recovery修改 

    bootable/recovery/Android.mk 修改 文件
    bootable/recovery/recovery.cpp  修改 文件
    bootable/recovery/usb.h 新增文件
    bootable/usb.cpp 新增文件

    bootable/recovery/Android.mk

    
    diff --git a/recovery/Android.mk b/recovery/Android.mk
    --- a/recovery/Android.mk
    +++ b/recovery/Android.mk
    @@ -41,6 +41,7 @@
         verifier.cpp \
         wear_ui.cpp \
         wear_touch.cpp \
    +    usb.cpp
     
     LOCAL_MODULE := recovery
     

        bootable/recovery/recovery.cpp

    diff --git a/recovery/recovery.cpp b/recovery/recovery.cpp
    --- a/recovery/recovery.cpp
    +++ b/recovery/recovery.cpp
    @@ -68,6 +68,7 @@
     #include "ui.h"
     #include "unique_fd.h"
     #include "screen_ui.h"
    +#include "usb.h"
     
     #include <stdio.h>
     #include <memory.h>
    @@ -1466,59 +1467,7 @@
         }
     }
     
    -static bool is_battery_ok() {
    -    struct healthd_config healthd_config = {
    -            .batteryStatusPath = android::String8(android::String8::kEmptyString),
    -            .batteryHealthPath = android::String8(android::String8::kEmptyString),
    -            .batteryPresentPath = android::String8(android::String8::kEmptyString),
    -            .batteryCapacityPath = android::String8(android::String8::kEmptyString),
    -            .batteryVoltagePath = android::String8(android::String8::kEmptyString),
    -            .batteryTemperaturePath = android::String8(android::String8::kEmptyString),
    -            .batteryTechnologyPath = android::String8(android::String8::kEmptyString),
    -            .batteryCurrentNowPath = android::String8(android::String8::kEmptyString),
    -            .batteryCurrentAvgPath = android::String8(android::String8::kEmptyString),
    -            .batteryChargeCounterPath = android::String8(android::String8::kEmptyString),
    -            .batteryFullChargePath = android::String8(android::String8::kEmptyString),
    -            .batteryCycleCountPath = android::String8(android::String8::kEmptyString),
    -            .energyCounter = NULL,
    -            .boot_min_cap = 0,
    -            .screen_on = NULL
    -    };
    -    healthd_board_init(&healthd_config);
     
    -    android::BatteryMonitor monitor;
    -    monitor.init(&healthd_config);
    -
    -    int wait_second = 0;
    -    while (true) {
    -        int charge_status = monitor.getChargeStatus();
    -        // Treat unknown status as charged.
    -        bool charged = (charge_status != android::BATTERY_STATUS_DISCHARGING &&
    -                        charge_status != android::BATTERY_STATUS_NOT_CHARGING);
    -        android::BatteryProperty capacity;
    -        android::status_t status = monitor.getProperty(android::BATTERY_PROP_CAPACITY, &capacity);
    -        ui_print("charge_status %d, charged %d, status %d, capacity %lld\n", charge_status,
    -                 charged, status, capacity.valueInt64);
    -        // At startup, the battery drivers in devices like N5X/N6P take some time to load
    -        // the battery profile. Before the load finishes, it reports value 50 as a fake
    -        // capacity. BATTERY_READ_TIMEOUT_IN_SEC is set that the battery drivers are expected
    -        // to finish loading the battery profile earlier than 10 seconds after kernel startup.
    -        if (status == 0 && capacity.valueInt64 == 50) {
    -            if (wait_second < BATTERY_READ_TIMEOUT_IN_SEC) {
    -                sleep(1);
    -                wait_second++;
    -                continue;
    -            }
    -        }
    -        // If we can't read battery percentage, it may be a device without battery. In this
    -        // situation, use 100 as a fake battery percentage.
    -        if (status != 0) {
    -            capacity.valueInt64 = 100;
    -        }
    -        return (charged && capacity.valueInt64 >= BATTERY_WITH_CHARGER_OK_PERCENTAGE) ||
    -                (!charged && capacity.valueInt64 >= BATTERY_OK_PERCENTAGE);
    -    }
    -}
     
     static void set_retry_bootloader_message(int retry_count, int argc, char** argv) {
         bootloader_message boot = {};
    @@ -1623,56 +1572,6 @@
         return __android_log_pmsg_file_write(logId, prio, name.c_str(), buf, len);
     }
     
    -
    -static void setLine(int fd, int flags, int speed)
    -{
    -        struct termios t;
    -        tcgetattr(fd, &t);
    -        t.c_cflag = flags | CREAD | HUPCL | CLOCAL;
    -        t.c_iflag = IGNBRK | IGNPAR;
    -        t.c_oflag = 0;
    -        t.c_lflag = 0;
    -        t.c_cc[VMIN] = 1;
    -        t.c_cc[VTIME] = 0;
    -        cfsetispeed(&t, speed);
    -        cfsetospeed(&t, speed);
    -        tcsetattr(fd, TCSANOW, &t);
    -}
    -
    -int tty_fd = -1;
    -void *heartbeatfun(void __unused *argv)
    -{
    -    char boot[] = {0x80};
    -    char heartbeat[] = {0x81};
    -    char run[] = {0x95,0x01};
    -
    -    write(tty_fd, boot, sizeof(boot));
    -        //usleep(100);
    -//        write(tty_fd, heartbeat, sizeof(heartbeat));
    -//        usleep(100);
    -//        write(tty_fd, run, sizeof(run));
    -    while(1)
    -    {
    -        write(tty_fd, heartbeat, sizeof(heartbeat));
    -        usleep(500000);
    -    }
    -
    -    return NULL;
    -}
    -
    -void start_heartbeat_thread(void)
    -{
    -        pthread_t timerid;
    -        int err = 0;
    -
    -        err = pthread_create(&timerid, NULL, heartbeatfun, NULL);
    -        if (err) {
    -                printf("can't creat heartbeatthread\n");
    -        }
    -}
    -
    -
    -
     int main(int argc, char **argv) {
         // Take last pmsg contents and rewrite it to the current pmsg session.
         static const char filter[] = "recovery/";
    @@ -1700,30 +1599,6 @@
     
         time_t start = time(NULL);
     
    -    tty_fd = open("/dev/ttyHSL1", O_RDWR, 0);
    -        while(tty_fd < 0) {
    -
    -                fprintf(stdout,"open error=%d %s\n", errno, strerror(errno));
    -		printf("deanji open ttyHSL1 failed \n");
    -                tty_fd = open("/dev/ttyHSL1", O_RDWR, 0);
    -                usleep(5000000);
    -        }
    -    fprintf(stdout, "update_package = 1  tty_fd=%d ...\n",tty_fd);
    -       
    -    if(tty_fd>0){
    -       int ldisc = N_BHDLC;
    -       int rc; 
    -       setLine(tty_fd, CS8, B115200);
    -       rc = ioctl(tty_fd, TIOCSETD, &ldisc);
    -        if(rc < 0) {
    -                fprintf(stdout,"#####set line discipline error=%d %s\n",
    -                       errno, strerror(errno));
    -                return rc;
    -        }
    -       fcntl(tty_fd, F_SETFL, fcntl(tty_fd, F_GETFL) & ~O_NONBLOCK);
    -       start_heartbeat_thread();
    -    }
    -
         // redirect_stdio should be called only in non-sideload mode. Otherwise
         // we may have two logger instances with different timestamps.
         redirect_stdio(TEMPORARY_LOG_FILE);
    @@ -1852,24 +1727,33 @@
                 else
                     printf("modified_path allocation failed\n");
             }
    -        if (!strncmp("/sdcard", update_package, 7)) {
    -            //If this is a UFS device lets mount the sdcard ourselves.Depending
    -            //on if the device is UFS or EMMC based the path to the sdcard
    -            //device changes so we cannot rely on the block dev path from
    -            //recovery.fstab
    -            if (is_ufs_dev()) {
    -                    if(do_sdcard_mount_for_ufs() != 0) {
    -                            status = INSTALL_ERROR;
    -                            goto error;
    -                    }
    -                    if (ensure_path_mounted("/cache") != 0 || ensure_path_mounted("/tmp") != 0) {
    -                            ui->Print("\nFailed to mount tmp/cache partition\n");
    -                            status = INSTALL_ERROR;
    -                            goto error;
    -                    }
    -                    mount_required = false;
    -            } else {
    -                    ui->Print("Update via sdcard on EMMC dev. Using path from fstab\n");
    +	else if (strncmp(update_package, "usb:", 4) == 0) {
    +                printf("recovery from udisk\n");
    +                char *absolutePath = (char*)malloc(PATH_MAX);
    +                memset(absolutePath, 0, PATH_MAX);
    +				
    +		char ota_name[128] = {'\0'};
    +		strcpy(ota_name, update_package+4);
    +                printf("ota_name=%s\n",ota_name);
    +                // wait 3s , make sure usb mounted
    +                sleep(3);
    +                if (!search_file_in_usb(ota_name, absolutePath)) {
    +                    update_package = absolutePath;
    +                    printf("find update.zip in usb success!\n");
    +                } else {
    +                    printf("find update.zip in usb failed!\n");
    +            }
    +        }
    +        else if (!strncmp("/data", update_package, 5)) {
    +			if (ensure_path_mounted(DATA_ROOT) != 0) {
    +                 ui->Print("\n-- Couldn't mount %s.\n", DATA_ROOT);
    +				 status = INSTALL_ERROR;
    +				 goto error;
    +            }
    +            if (ensure_path_mounted("/cache") != 0 || ensure_path_mounted("/tmp") != 0) {
    +                ui->Print("\nFailed to mount tmp/cache partition\n");
    +                status = INSTALL_ERROR;
    +                goto error;
                 }
             }
         }
    @@ -1884,14 +1768,7 @@
             // to log the update attempt since update_package is non-NULL.
             modified_flash = true;
     
    -        if (!is_battery_ok()) {
    -            ui->Print("battery capacity is not enough for installing package, needed is %d%%\n",
    -                      BATTERY_OK_PERCENTAGE);
    -            // Log the error code to last_install when installation skips due to
    -            // low battery.
    -            log_failure_code(kLowBattery, update_package);
    -            status = INSTALL_SKIPPED;
    -        } else if (bootreason_in_blacklist()) {
    +        if (bootreason_in_blacklist()) {
                 // Skip update-on-reboot when bootreason is kernel_panic or similar
                 ui->Print("bootreason is in the blacklist; skip OTA installation\n");
                 log_failure_code(kBootreasonInBlacklist, update_package);
    @@ -1933,42 +1810,21 @@
                     }
                 }
             }
    -    } else if (should_wipe_data) {
    +    }  if (should_wipe_data) {
             if (!wipe_data(false, device)) {
                 status = INSTALL_ERROR;
             }
    -    } else if (should_wipe_cache) {
    +    } if (should_wipe_cache) {
             if (!wipe_cache(false, device)) {
                 status = INSTALL_ERROR;
             }
    -    } else if (should_wipe_ab) {
    +    }  if (should_wipe_ab) {
             if (!wipe_ab_device(wipe_package_size)) {
                 status = INSTALL_ERROR;
             }
    -    } else if (sideload) {
    -        // 'adb reboot sideload' acts the same as user presses key combinations
    -        // to enter the sideload mode. When 'sideload-auto-reboot' is used, text
    -        // display will NOT be turned on by default. And it will reboot after
    -        // sideload finishes even if there are errors. Unless one turns on the
    -        // text display during the installation. This is to enable automated
    -        // testing.
    -        if (!sideload_auto_reboot) {
    -            ui->ShowText(true);
    -        }
    -        status = apply_from_adb(ui, &should_wipe_cache, TEMPORARY_INSTALL_FILE);
    -        if (status == INSTALL_SUCCESS) {
    -            ota_completed = true;
    -        }
    -        if (status == INSTALL_SUCCESS && should_wipe_cache) {
    -            if (!wipe_cache(false, device)) {
    -                status = INSTALL_ERROR;
    -            }
    -        }
    -        ui->Print("\nInstall from ADB complete (status: %d).\n", status);
    -        if (sideload_auto_reboot) {
    -            ui->Print("Rebooting automatically.\n");
    -        }
    -    } else if (!just_exit) {
    +    }
    +
    +    if (!just_exit) {
             status = INSTALL_NONE;  // No command specified
             ui->SetBackground(RecoveryUI::NO_COMMAND);
     
    @@ -1984,7 +1840,8 @@
             copy_logs();
             ui->SetBackground(RecoveryUI::ERROR);
         }
    -
    +    
    +    /*
         Device::BuiltinAction after = shutdown_after ? Device::SHUTDOWN : Device::REBOOT;
         if ((status != INSTALL_SUCCESS && status != INSTALL_SKIPPED && !sideload_auto_reboot) ||
                 ui->IsTextVisible()) {
    @@ -1993,10 +1850,16 @@
                 after = temp;
             }
         }
    +    */
     
         // Save logs and clean up before rebooting or shutting down.
         finish_recovery(send_intent);
     
    +    // no matter what result  reboot 
    +    sleep(1);
    +    property_set(ANDROID_RB_PROPERTY, "reboot,");
    +
    +    /*
         switch (after) {
             case Device::SHUTDOWN:
                 ui->Print("Shutting down...\n");
    @@ -2016,6 +1879,7 @@
         while (true) {
           pause();
         }
    +    */
         // Should be unreachable.
         return EXIT_SUCCESS;
     }

        bootable/recovery/usb.h

    diff --git a/recovery/usb.h b/recovery/usb.h
    --- /dev/null
    +++ b/recovery/usb.h
    @@ -0,0 +1,21 @@
    +#ifndef USB_H_
    +#define USB_H_
    +
    +#include "common.h"
    +
    +//return 0 if exists
    +int check_file_exists(const char *path);
    +
    +//return 0 if the usb mounted success
    +int ensure_dev_mounted(const char *devPath, const char *mountedPoint);
    +
    +//return 0 if the usb unmounted success
    +int ensure_dev_unmounted(const char *mountedPoint);
    +
    +//search file in usbs,return 0 if success, then save its absolute path arg2.
    +int search_file_in_usb(const char *file, char *absolutePath);
    +
    +int in_usb_device(const char *file);
    +
    +#endif  // USB_H_
    +

    bootable/usb.cpp

    diff --git a/recovery/usb.cpp b/recovery/usb.cpp
    --- /dev/null
    +++ b/recovery/usb.cpp
    @@ -0,0 +1,165 @@
    +#include <errno.h>
    +#include <stdlib.h>
    +#include <sys/mount.h>
    +#include <sys/stat.h>
    +#include <sys/types.h>
    +#include <unistd.h>
    +#include <sys/time.h>
    +#include <sys/wait.h>
    +#include <string>
    +#include <android/log.h> 
    +#include <log/logger.h>
    +#include <private/android_logger.h>
    +
    +#include "usb.h"
    +
    +#define MAX_DISK 4
    +#define MAX_PARTITION 8
    +#define PATH_MAX 256
    +#define TIME_OUT 6000000
    +
    +static const char *USB_ROOT = "/usb/";
    +struct timeval tpstart,tpend;
    +float timeuse = 0;
    +
    +#define MOUNT_EXFAT            "/system/bin/mount.exfat"
    +
    +void startTiming(){
    +    gettimeofday(&tpstart, NULL);
    +}
    +
    +void endTimming(){
    +    gettimeofday(&tpend, NULL);
    +    timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) +
    +        (tpend.tv_usec - tpstart.tv_usec);
    +    LOGD("spend Time %f\n", timeuse);
    +}
    +
    +int check_file_exists(const char * path){
    +    int ret = -1;
    +	if(path == NULL){
    +		return -1;
    +	}
    +    ret = access(path, F_OK);
    +	return ret;
    +}
    +
    +int ensure_dev_mounted(const char * devPath,const char * mountedPoint){
    +    int ret;
    +	if(devPath == NULL || mountedPoint == NULL){
    +		return -1;
    +	}
    +    mkdir(mountedPoint, 0755);  //in case it doesn't already exist
    +    startTiming();
    +    ret = mount(devPath, mountedPoint, "vfat",
    +        MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
    +    endTimming();
    +    if(ret == 0){
    +        LOGD("mount %s with fs 'vfat' success\n", devPath);
    +        return 0;
    +    }else{
    +        startTiming();
    +        ret = mount(devPath, mountedPoint, "ntfs",
    +            MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
    +        endTimming();
    +        if(ret == 0){
    +            LOGD("mount %s with fs 'ntfs' success\n", devPath);
    +            return 0;
    +        }else{
    +            startTiming();
    +            ret = mount(devPath, mountedPoint, "ext4",
    +                MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
    +            endTimming();
    +            if(ret == 0){
    +                LOGD("mount %s with fs 'ext4' success\n", devPath);
    +                return 0;
    +            }
    +        }
    +        LOGD("failed to mount %s (%s)\n", devPath, strerror(errno));
    +        return -1;
    +    }
    +}
    +
    +int search_file_in_dev(const char * file, char *absolutePath,
    +        const char *devPath, const char *devName){
    +    if(!check_file_exists(devPath)){
    +        LOGD("dev %s exists\n", devPath);
    +        char mountedPoint[32];
    +        sprintf(mountedPoint, "%s%s", USB_ROOT, devName);
    +        //if the dev exists, try to mount it
    +        if(!ensure_dev_mounted(devPath, mountedPoint)){
    +            LOGD("dev %s mounted in %s\n", devPath, mountedPoint);
    +            char desFile[PATH_MAX];
    +            sprintf(desFile, "%s/%s", mountedPoint, file);
    +            //if mount success.search des file in it
    +            if(!check_file_exists(desFile)){
    +                //if find the file,return its absolute path
    +                LOGD("file %s exist\n", desFile);
    +                sprintf(absolutePath, "%s", desFile);
    +                return 0;
    +            }else{
    +                ensure_dev_unmounted(mountedPoint);
    +            }
    +        }
    +    }
    +    return -1;
    +}
    +
    +int search_file_in_usb(const char * file,char * absolutePath){
    +    timeval now;
    +    gettimeofday(&now, NULL);
    +    int i = 0;
    +    int j = 0;
    +    timeval workTime;
    +    long spends;
    +    mkdir(USB_ROOT, 0755);  //in case dir USB_ROOT doesn't already exist
    +    //do main work here
    +    do{
    +        LOGD("begin....\n");
    +        for(i = 0; i < MAX_DISK; i++){
    +            char devDisk[32];
    +            char devPartition[32];
    +            char devName[8];
    +            char parName[8];
    +            sprintf(devName, "sd%c", 'a' + i);
    +            sprintf(devDisk, "/dev/block/%s", devName);
    +            LOGD("check disk %s\n", devDisk);
    +            if(check_file_exists(devDisk)){
    +                LOGD("dev %s does not exists (%s),waiting ...\n", devDisk, strerror(errno));
    +                continue;
    +            }
    +            for(j = 1; j <= MAX_PARTITION; j++){
    +                sprintf(parName, "%s%d", devName, j);
    +                sprintf(devPartition, "%s%d" ,devDisk, j);
    +                if(!search_file_in_dev(file, absolutePath, devPartition, parName)){
    +                    return 0;
    +                }
    +            }
    +            if(j > MAX_PARTITION){
    +                if(!search_file_in_dev(file, absolutePath, devDisk, devName)){
    +                    return 0;
    +                }
    +            }
    +        }
    +        usleep(500000);
    +        gettimeofday(&workTime, NULL);
    +        spends = (workTime.tv_sec - now.tv_sec)*1000000 + (workTime.tv_usec - now.tv_usec);
    +    }while(spends < TIME_OUT);
    +    LOGD("Time to search %s is %ld\n", file, spends);
    +    return -1;
    +}
    +
    +
    +
    +int ensure_dev_unmounted(const char * mountedPoint){
    +    int ret = umount(mountedPoint);
    +    return ret;
    +}
    +
    +int in_usb_device(const char * file){
    +    int len = strlen(USB_ROOT);
    +    if (strncmp(file, USB_ROOT, len) == 0){
    +        return 0;
    +    }
    +    return -1;
    +}
    

     

    3.selinux权限问题

    经过一番调查 发现 data的 type属于 system_data_file类型的

    在file_contexts中可以查看到

    /data(/.*)?		u:object_r:system_data_file:s0

    在recovery.te中发现了如下代码

    neverallow recovery data_file_type:file { no_w_file_perms no_x_file_perms };
    neverallow recovery data_file_type:dir no_w_dir_perms;
    allow recovery rootfs:dir rw_dir_perms;

    也就是说明 recover.te何时都不能读取和操作/data/目录,那怎么办?当然是有办法的,我们可以新建一个文件夹 和自定义文件类型啊

    首先是开机的时候要有一个文件夹

    我们可以在init.rc 或者 init.qcom.rc中创建一个文件夹

    #Create directory for download
    mkdir /data/download 0771
    chown system system /data/download

    创建完成之后需要app可以读取因此 需要在 system_app.te 中增加对应的权限

    # allow system_app to access /data/download
    allow system_app download_data_file:dir { search write add_name getattr remove_name };
    allow system_app download_data_file:file { create read write open getattr unlink rename };

    这样的话 我们已经创建了 文件夹,并且system app级别的应用可以读取.

    那既然存储好了之后是不是下面需要 recovery可以读取到文件那?系统不允许读取 recovery.te /data/路径.那我们就自己创建一个文件类型,在file_contexts 增加类型

    /data/download(/.*)?           u:object_r:download_data_file:s0  

    然后在file.te中定义download_data_file类型, 注意是只属于file_type类型的。

    type download_data_file, file_type;   

    然后在recovery.te中增加对download_data_file的权限

    allow recovery download_data_file:dir { write search remove_name };
    allow recovery download_data_file:file { read getattr open unlink };

    因为data目录有可能需要进行加密处理,我们还需要在uncrypt.te中增加如下。

    allow uncrypt download_data_file:dir { search getattr };  
    allow uncrypt download_data_file:file { getattr read open };

    以上就是完成了添加,我本地全编译,测试成功.

     

    最后升级的过程中可能会看到Permission Denied 最后可以cat   last_kmsg 查看 最后一样都会输出失败的权限原因

    比如 :

    avc:  denied  { open } for  pid=381 comm="recovery"
    path="/data/download/update.zip" dev="mmcblk0p51" ino=513074 
    scontext=u:r:recovery:s0 tcontext=u:object_r:download_data_file:s0 
    tclass=file permissive=0

    这种权限只能报错什么权限添加什么权限,我们可以遵循这个方法,从头开始寻找关键对象,然后调整一下顺序,生成一条语句,最后将该语句填写到.te中即可。

    denied { open }            scontext=u:r:recovery:s0          tcontext=u:object_r:download_data_file:s0        tclass=file               

                 A                                    B                                                             C                                                  D
     
                 B                                    C                                                             D                                                   A

    allow recovery  download_data_file:tclass   open;

    如果升级没有错误,APP操作文件夹中的文件无效时,可以在操作的时候执行如下命令,如果报了相关权限问题,加上即可,

    adb shell dmesg | grep denied

     

    展开全文
  • 欧蓝德V1.3.0&V2.1.0软件升级注意事项 更新功能:此次更新加入安卓9.0支持和倒车引导线关闭选项 升级注意事项: 将U盘格式化为FAT32格式,U盘中切勿同时存储其它文件 整机升级过程全自动进行,无需操作,升级完成后...
  • 车载导航升级

    2013-01-26 19:13:40
    凯立德移动导航系统 下载地址
  • 掌讯大屏导航升级安卓8.1 V006-V008
  • 掌讯8227 横屏 1024X600 升级安卓5.1 自带root权限
  • 天之眼车机(wince6.0)刷机包 本软件适用天之眼车机卓越版、普通版、精英版、V02精英版一体。 普通版: 收音模块为 6621 、 收星模块为 3328 、 ...如当系统卡在开机动画界面进不去系统就要刷BSP,请下载BSP升级包
  • carlife车机端安装包下载

    千次阅读 2021-06-03 11:05:02
    carlife车机版由百度联网官方打造,支持车载互联、语音娱乐和智能地图导航等功能,也是国内目前兼容性最好的车载平台之一,海量车主的共同选择,欢迎前来体验更多优质服务!carlife软件介绍carlife完美内置百度...

    carlife车机版由百度车联网官方打造,支持车载互联、语音娱乐和智能地图导航等功能,也是国内目前兼容性最好的车载平台之一,海量车主的共同选择,欢迎前来体验更多优质服务!

    carlife软件介绍

    carlife完美内置百度地图,全面准确的海量地点信息;实时路况智能播报,告别拥堵和罚单.。可以非常好的支持android和ios智能操作系统,能够覆盖到95%以上的智能手机用户。

    450944ddc1b6cd10e7c0d615aad1597e.png

    软件功能

    车规级的界面和服务、风度的应用群和流量。

    室内外无缝导航、handsfree人机对话系统。

    实时停车位查询、停车定位记录、电子狗、实时路况。

    最好的互联网导航体验,将通过软件面向所有车主群体。

    软件特色

    来电去电轻松操作,一目了然。

    养护、停车、加油、美食等服务陆续开启。

    可共享到车载系统直接播放,奏出环绕最强音。

    carlife车机端安装教程

    要准备材料:tf卡、usb线、手机、车钥匙

    首先在当易网下载carlife车机端安装包

    下载后到车把图卡拿回来就tf卡最那个卡

    弄个usb读卡器把图卡装插到电脑

    然后点击安装等提示完成就,可以把卡拿走

    相关介绍

    carlife是全球范围内兼容性最强大的车联网标准之一,也是国内第一款跨平台的车联网解决方案。目前合作品牌已达70+,覆盖top 10销量品牌。超过400款合作车型正在陆续加入carlife+大家庭,2020年将为你带来更多精彩,敬请期待。

    更新日志

    v6.5.1

    1.提升投屏分辨率,支持投屏分辨率设置;

    2.新增恶劣天气及限行提醒;

    v6.4.4

    bugs修复。

    包名:

    MD5:

    展开全文
  • 仅支持16款17款wince车机升级后支持安卓10,音质提升,收音关闭
  • 安卓刷机工具支持各种软件版本,刷机 安卓驱动安装
  • 安卓车机大屏rom,鼎微ts8横屏版,可以root
  • 鼎微 T3固件 安卓5.1.2 MCU版本:T5.3.19-46-13-E57201-170220 系统版本:v6.4.3_20200916.100915_TW6-X 解压到U盘插到车机USB口上 点设置 系统升级 选择U盘 就会自动升级
  • 本人车机中的用户手册打开后,有部分视频无法找到资源了,应该是车机内存中的某些文件夹没了,我也不知道哪个文件夹是用户手册的,会复制的车友能提供一下吗(方法是,打开鲸鱼文件管理,除amapauto8、android、...
  • 五月份的时候韩国现代汽车宣布其部分车型的车主可以使用一种完全 DIY 的方式来升级车机手机互联系统,以增加 Apple CarPlay 和 Android Audio 支持。并且接下来会逐步增加更多的车型支持。目前支持列表里包含四款...
  • CX70豪华版、精英版影音系统升级程序。现在官网已经下架了,希望大家能在这里下载!好不容易自己收藏的,与大家一起分享!
  • 折腾了两三天,总算是给升级成功…欢喜 折腾前,为了避免失误,一定需要注意的是:MCU 需要区分是否带 360,而 SPD 则为通用 ...总之,SPD 在远景 SUV 中就是中控操作系统,而要升级到目前最新的 2.1.9276 ...
  • OTA升级客户指导-Android 7.0
  • 适合科沃兹中配,也就是欣悦版的都可以,但是目前除了顶配车型不可以用,预装或后装 Mylink车机的都可以升级。MU8217_CA7054160906V16.BIN
  • 纽曼车机刷机软件

    2016-03-02 21:24:01
    纽曼Pad2的Win6刷机软件,非安卓系统
  • 作者2017年6月入手的2015款全新途胜智能款,在前段时间更新了现代途胜的中控,也有人称之为“多媒体系统”,本文统一称为“中控系统”,感受到了版本升级带来的巨大变化。同时,最近入手了一个Hicar转换模块,手握...
  • 固件基于掌讯3560的Android8.1Go官方精简完成,仅集成最新4.1.2版同行者,嘟嘟桌面。...把固件压缩包复制到U盘根目录,进入车机设置>系统信息>Android升级即可,全程不要断电!!!(U盘需FAT32格式,16G以下)
  • 起亚K2刷机系统.rar

    2021-05-13 15:03:22
    起亚K2导航刷机系统
  • 首先我们来了解安卓的刷机分区,从安卓5.0开始,刷机里的system分区,不再以文件夹格式展现,从原本散落的文件夹格式,变成了dat文件,dat文件包含着system文件夹里的全部文件。那么对于打包压缩...
  • 1.51路畅导航系统固件升级刷机是一款路畅导航系统固件升级下载,路畅导航使用中发现有开机缓慢,不能保存电台,蓝牙通话不畅,使用时间长了,要优化刷机了,又是速度杠杠的。
  • carlife车机端是一款由百度打造的手机车机智能互联产品,carlife安卓版只需在车内连接手机,即可将carlife汇集的生活服务分享到车载屏幕上,享受驾驶中更安全便捷的车载体验。软件介绍百度CarLife是百度联网推出...
  • 居于mtk芯片安卓车机系统具体流程

    万次阅读 2017-10-25 15:52:52
    一:车机系统框架 MCU 功能  电源控制  Radio 控制(RDS)  按键检测(Panel/Remote/SW)  常见信号检查(倒车/大灯/刹车)  CAN 模块通讯  ARM-MCU 通讯  进出碟控制  翻转马达系统  ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,674
精华内容 3,069
关键字:

安卓车机系统升级包