当前位置: 首页 > news >正文

【Android】【root remount】【2】如何判断设备是否remount

前言

高版本的android设备,在remount之后,如果再进行ota升级,会产生异常,从而无法升级成功。

如何判断设备是否remount

当前已android 10 平台为例
当我们执行 adb remount 时,系统调用会调用到system/core/adb/daemon/remount_service.cpp

/** Copyright (C) 2008 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string>#include "adb.h"
#include "adb_io.h"
#include "adb_unique_fd.h"static constexpr char kRemountCmd[] = "/system/bin/remount";static bool do_remount(int fd, const std::string& cmd) {if (getuid() != 0) {WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n");return false;}auto pid = fork();if (pid < 0) {WriteFdFmt(fd, "Failed to fork to %s: %s\n", kRemountCmd, strerror(errno));return false;}if (pid == 0) {// child side of the forkdup2(fd, STDIN_FILENO);dup2(fd, STDOUT_FILENO);dup2(fd, STDERR_FILENO);execl(kRemountCmd, kRemountCmd, cmd.empty() ? nullptr : cmd.c_str(), nullptr);_exit(errno);}int wstatus = 0;auto ret = waitpid(pid, &wstatus, 0);if (ret == -1) {WriteFdFmt(fd, "Failed to wait for %s: %s\n", kRemountCmd, strerror(errno));return false;} else if (ret != pid) {WriteFdFmt(fd, "pid %d and waitpid return %d do not match for %s\n",static_cast<int>(pid), static_cast<int>(ret), kRemountCmd);return false;}if (WIFSIGNALED(wstatus)) {WriteFdFmt(fd, "%s terminated with signal %s\n", kRemountCmd,strsignal(WTERMSIG(wstatus)));return false;}if (!WIFEXITED(wstatus)) {WriteFdFmt(fd, "%s stopped with status 0x%x\n", kRemountCmd, wstatus);return false;}if (WEXITSTATUS(wstatus)) {WriteFdFmt(fd, "%s exited with status %d\n", kRemountCmd, WEXITSTATUS(wstatus));return false;}return true;
}void remount_service(unique_fd fd, const std::string& cmd) {const char* success = do_remount(fd.get(), cmd) ? "succeeded" : "failed";WriteFdFmt(fd.get(), "remount %s\n", success);
}

当前的思路时,再执行do_remount 函数时,添加一个persist变量来判断记录已经remount了,并记录remount次数。
具体修改如下:

#include <unistd.h>
//add 
#include <android-base/properties.h>
//add 
#include <string>
......static bool do_remount(int fd, const std::string& cmd) {......//add std::string prop = android::base::GetProperty("persist.sys.remount.count", "0");int count  = std::stoi(prop) + 1;android::base::SetProperty("persist.sys.remount.count", std::to_string(count));// addreturn true;
}

获取状态remount状态

java

import android.os.SystemProperties;public static final String PROP_REMOUNT_COUNT = "persist.sys.remount.count";/*** NULL* @return device remount status*/public static boolean isRemounted(){return getRemountCount() >0;}/*** NULL* @return get remount count Since first power up*/public static int getRemountCount(){return SystemProperties.getInt(PROP_ROOT_COUNT,0);}

相关文章:

  • 接口自动化测试(python+pytest+requests)
  • 工业视觉AI应用总结记录
  • AI日报:GPT-4-Turbo正式版自带读图能力;Gemini1.5Pro开放API;SD3将于4月中旬发布;抖音宫崎骏AI特效爆火
  • String类(1)
  • 动手学习深度学习(李沐)
  • Java项目:基于SSM+vue框架实现的人力资源管理系统设计与实现(源码+数据库+毕业论文+任务书)
  • 前端使用minio传输文件
  • Java Set基础篇
  • Linux(CentOS7)安装 Docker 以及 Docker 基本使用教程
  • 在unbuntu服务器上使用nginx+uwsgi部署django项目
  • 领鸡蛋游戏养鸡游戏淘宝客源码广告联盟
  • 活动预告|NineData 创始人CEO叶正盛将参加QCon全球软件开发大会,共话AI大模型技术在数据库DevOps的实践
  • docker 安装redis报错:can not init background jbos
  • Golang | Leetcode Golang题解之第18题四数之和
  • 计算机服务器中了devicdata勒索病毒怎么办,devicdata勒索病毒解密数据恢复
  • 【知识碎片】第三方登录弹窗效果
  • 07.Android之多媒体问题
  • 2017 年终总结 —— 在路上
  • 5、React组件事件详解
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • docker-consul
  • emacs初体验
  • ES6语法详解(一)
  • Flannel解读
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Median of Two Sorted Arrays
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Redux系列x:源码分析
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • 大数据与云计算学习:数据分析(二)
  • 关于使用markdown的方法(引自CSDN教程)
  • 检测对象或数组
  • 前嗅ForeSpider教程:创建模板
  • 异步
  • 用Python写一份独特的元宵节祝福
  • raise 与 raise ... from 的区别
  • 阿里云服务器如何修改远程端口?
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • #define,static,const,三种常量的区别
  • $().each和$.each的区别
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (NSDate) 时间 (time )比较
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (七)c52学习之旅-中断
  • (区间dp) (经典例题) 石子合并
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)LINQ之路
  • (转)setTimeout 和 setInterval 的区别
  • (转)Unity3DUnity3D在android下调试
  • (转)为C# Windows服务添加安装程序
  • (转载)深入super,看Python如何解决钻石继承难题
  • ****Linux下Mysql的安装和配置
  • ***详解账号泄露:全球约1亿用户已泄露