【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 fork
        dup2(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));
    // add
    return 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);
    }

相关推荐

  1. 如何判断服务器是否被入侵了

    2024-04-11 23:36:03       59 阅读
  2. 企业如何判断定岗定编是否合理?

    2024-04-11 23:36:03       51 阅读
  3. JVM 如何判断对象是否可回收

    2024-04-11 23:36:03       35 阅读
  4. 如何判断服务器是否被攻击

    2024-04-11 23:36:03       25 阅读
  5. 如何判断服务器是否被攻击

    2024-04-11 23:36:03       29 阅读
  6. 如何用Python设置函数判断输入括号是否合规

    2024-04-11 23:36:03       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-11 23:36:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-11 23:36:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-11 23:36:03       87 阅读
  4. Python语言-面向对象

    2024-04-11 23:36:03       96 阅读

热门阅读

  1. 每日一题 第八十八期 洛谷 滑动窗口

    2024-04-11 23:36:03       44 阅读
  2. leetcode26--删除有序数组中的重复项

    2024-04-11 23:36:03       31 阅读
  3. IntersectionObserver实现图片懒加载

    2024-04-11 23:36:03       38 阅读
  4. 【前端】CSS常用选择器总结

    2024-04-11 23:36:03       37 阅读
  5. POSTGRESQL——存储过程调试

    2024-04-11 23:36:03       41 阅读
  6. spring基本框架搭建(思路分享)

    2024-04-11 23:36:03       39 阅读
  7. ELK日志

    ELK日志

    2024-04-11 23:36:03      35 阅读
  8. 安装hadoop,9000端口访问不了

    2024-04-11 23:36:03       38 阅读