android 源码分析surfaceFinger是如何通过设置属性启动bootanim

ruby 复制代码
//frameworks/base/cmds/boot/animationbootanim.rc


service bootanim /system/bin/bootanimation
   class core animation
   user graphics
   group graphics audio
   disabled #服务默认不启动,需手动 `start` 
   oneshot
   writepid /dev/stune/top-app/tasks

bootanim服务默认是不启动的

SurfaceFlinger 初始化完成 ‌(SurfaceFlinger::init())后,会启动一个 StartPropertySetThread 线程,代码在 frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

php 复制代码
void SurfaceFlinger::init() {

   // Inform native graphics APIs whether the present timestamp is supported:
   if (getHwComposer().hasCapability(
           HWC2::Capability::PresentFenceIsNotReliable)) {
       mStartPropertySetThread = new StartPropertySetThread(false);
   } else {
       mStartPropertySetThread = new StartPropertySetThread(true);
   }

   if (mStartPropertySetThread->Start() != NO_ERROR) {
       ALOGE("Run StartPropertySetThread failed!");
   }

}

线程执行 threadLoop() ‌,依次设置几个关键属性,代码在 frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp:

arduino 复制代码
bool StartPropertySetThread::threadLoop() {
    // Set property service.sf.present_timestamp, consumer need check its readiness
    property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");
    // Clear BootAnimation exit flag
    property_set("service.bootanim.exit", "0");
    // Start BootAnimation if not started
    property_set("ctl.start", "bootanim");
    // Exit immediately
    return false;//frameworks/base/cmds/boot/animationbootanim.rc
}

init 响应属性变化 ‌:init 监听属性 socket,收到 ctl.start 后调用 handle_property_set_fd() → HandleControlMessage() → 根据服务名 bootanim 找到服务并启动

scss 复制代码
void start_property_service() {
    property_set("ro.property_service.version", "2");

    property_set_fd = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
                                   false, 0666, 0, 0, nullptr, sehandle);
    if (property_set_fd == -1) {
        PLOG(ERROR) << "start_property_service socket creation failed";
        exit(1);
    }

    listen(property_set_fd, 8);
    //注册监听
    register_epoll_handler(property_set_fd, handle_property_set_fd);
}
c 复制代码
static void handle_property_set(SocketConnection& socket,
                                const std::string& name,
                                const std::string& value,
                                bool legacy_protocol) {
  const char* cmd_name = legacy_protocol ? "PROP_MSG_SETPROP" : "PROP_MSG_SETPROP2";
  if (!is_legal_property_name(name)) {
    LOG(ERROR) << "sys_prop(" << cmd_name << "): illegal property name "" << name << """;
    socket.SendUint32(PROP_ERROR_INVALID_NAME);
    return;
  }

  struct ucred cr = socket.cred();
  char* source_ctx = nullptr;
  getpeercon(socket.socket(), &source_ctx);
  
  if (android::base::StartsWith(name, "ctl.")) {
    if (check_control_mac_perms(value.c_str(), source_ctx, &cr)) {
      handle_control_message(name.c_str() + 4, value.c_str());
      if (!legacy_protocol) {
        socket.SendUint32(PROP_SUCCESS);
      }
    } else {
      LOG(ERROR) << "sys_prop(" << cmd_name << "): Unable to " << (name.c_str() + 4)
                 << " service ctl [" << value << "]"
                 << " uid:" << cr.uid
                 << " gid:" << cr.gid
                 << " pid:" << cr.pid;
      if (!legacy_protocol) {
        socket.SendUint32(PROP_ERROR_HANDLE_CONTROL_MESSAGE);
      }
    }
  } else {
    //...
  }

}
ini 复制代码
void handle_control_message(const std::string& msg, const std::string& name) {
    Service* svc = ServiceManager::GetInstance().FindServiceByName(name);
    if (svc == nullptr) {
        LOG(ERROR) << "no such service '" << name << "'";
        return;
    }

    if (msg == "start") {
        svc->Start();
    } else if (msg == "stop") {
        svc->Stop();
    } else if (msg == "restart") {
        svc->Restart();
    } else {
        LOG(ERROR) << "unknown control msg '" << msg << "'";
    }
}
相关推荐
JoyMonitor1 小时前
APK mmap 内存增长定位:pagemap 与 DEX 结构联合定位方法
android
有什么事1 小时前
永久虚拟免费云手机能实现吗,本地安卓容器与云端托管的技术边界
android·智能手机
妖星1 小时前
Android 源码 .rc 语法详解
android
JMchen1 小时前
实战项目一——实现一个高性能图片滤镜App
android·c++·性能优化
白帽攻防录2 小时前
SRC 挖洞:Android 蓝牙预认证 RCE 深度复盘,CVE-2026-55330 怎么在蓝牙范围内零交互攻破手机
android·网络安全·智能手机·src漏洞挖掘
vilya2 小时前
手机端 Agent 是怎么跑起来的:决策循环、四道护栏、两条红线
android·agent
2501_915921432 小时前
详细教程:使用Perfdog工具测量iOS应用的功耗性能与优化方法
android·macos·ios·小程序·uni-app·cocoa·iphone
hunterandroid3 小时前
android方案 : Multiplatform 跨平台开发实战:一套代码,多端运行
android·前端