IMS中Binder案例

news2025/2/26 0:32:27

IMS中Binder案例

  • 1、FWK层中AIDL形式
    • 1.1 服务端实现Stub
    • 1.2 客户端获取proxy
  • 2、Native层中AIDL形式
    • 2.1 服务端对应Bn端
    • 2.2 客户端对应Bp端

android12-release


1、FWK层中AIDL形式

Android 接口定义语言 (AIDL)、Android 应用层 到 HAL 层

AIDL形式是Android中binder机制的具体实现。按照规范aidl/hidl文件自动生成相应代码文件:
客户端获取proxyasInterface(android.os.IBinder obj)
服务端实现Stub:class Stub extends android.os.Binder

1.1 服务端实现Stub

InputManagerService继承IInputManager.StubSystemServer.java中服务初始化添加到ServiceManager
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

frameworks/base/core/java/android/hardware/input/IInputManager.aidl

/** @hide */
interface IInputManager {
    // Gets input device information.
    InputDevice getInputDevice(int deviceId);
    int[] getInputDeviceIds();

    // Enable/disable input device.
    boolean isInputDeviceEnabled(int deviceId);
    void enableInputDevice(int deviceId);
    void disableInputDevice(int deviceId);

    // Reports whether the hardware supports the given keys; returns true if successful
    boolean hasKeys(int deviceId, int sourceMask, in int[] keyCodes, out boolean[] keyExists);

    // Temporarily changes the pointer speed.
    void tryPointerSpeed(int speed);

    // Injects an input event into the system.  To inject into windows owned by other
    // applications, the caller must have the INJECT_EVENTS permission.
    @UnsupportedAppUsage
    boolean injectInputEvent(in InputEvent ev, int mode);

    VerifiedInputEvent verifyInputEvent(in InputEvent ev);

    // Calibrate input device position
    TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor, int rotation);
    void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int rotation,
            in TouchCalibration calibration);

    // Keyboard layouts configuration.
    KeyboardLayout[] getKeyboardLayouts();
    KeyboardLayout[] getKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier);
    KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor);
    String getCurrentKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier);
    void setCurrentKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
            String keyboardLayoutDescriptor);
    String[] getEnabledKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier);
    void addKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
            String keyboardLayoutDescriptor);
    void removeKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
            String keyboardLayoutDescriptor);

    // Registers an input devices changed listener.
    void registerInputDevicesChangedListener(IInputDevicesChangedListener listener);

    // Queries whether the device is currently in tablet mode
    int isInTabletMode();
    // Registers a tablet mode change listener
    void registerTabletModeChangedListener(ITabletModeChangedListener listener);

    // Queries whether the device's microphone is muted by switch
    int isMicMuted();

    // Input device vibrator control.
    void vibrate(int deviceId, in VibrationEffect effect, IBinder token);
    void vibrateCombined(int deviceId, in CombinedVibration vibration, IBinder token);
    void cancelVibrate(int deviceId, IBinder token);
    int[] getVibratorIds(int deviceId);
    boolean isVibrating(int deviceId);
    boolean registerVibratorStateListener(int deviceId, in IVibratorStateListener listener);
    boolean unregisterVibratorStateListener(int deviceId, in IVibratorStateListener listener);

    // Input device battery query.
    int getBatteryStatus(int deviceId);
    int getBatteryCapacity(int deviceId);

    void setPointerIconType(int typeId);
    void setCustomPointerIcon(in PointerIcon icon);

    oneway void requestPointerCapture(IBinder inputChannelToken, boolean enabled);

    /** Create an input monitor for gestures. */
    InputMonitor monitorGestureInput(String name, int displayId);

    // Add a runtime association between the input port and the display port. This overrides any
    // static associations.
    void addPortAssociation(in String inputPort, int displayPort);
    // Remove the runtime association between the input port and the display port. Any existing
    // static association for the cleared input port will be restored.
    void removePortAssociation(in String inputPort);

    // Add a runtime association between the input device and display.
    void addUniqueIdAssociation(in String inputDeviceName, in String displayUniqueId);
    // Remove the runtime association between the input device and display.
    void removeUniqueIdAssociation(in String inputDeviceName);

    InputSensorInfo[] getSensorList(int deviceId);

    boolean registerSensorListener(IInputSensorEventListener listener);

    void unregisterSensorListener(IInputSensorEventListener listener);

    boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs,
                int maxBatchReportLatencyUs);

    void disableSensor(int deviceId, int sensorType);

    boolean flushSensor(int deviceId, int sensorType);

    List<Light> getLights(int deviceId);

    LightState getLightState(int deviceId, int lightId);

    void setLightStates(int deviceId, in int[] lightIds, in LightState[] states, in IBinder token);

    void openLightSession(int deviceId, String opPkg, in IBinder token);

    void closeLightSession(int deviceId, in IBinder token);
}

frameworks/base/services/java/com/android/server/SystemServer.java

t.traceBegin("StartInputManagerService");
inputManager = new InputManagerService(context);
t.traceEnd();

t.traceBegin("DeviceStateManagerService");
mSystemServiceManager.startService(DeviceStateManagerService.class);
t.traceEnd();

if (!disableCameraService) {
    t.traceBegin("StartCameraServiceProxy");
    mSystemServiceManager.startService(CameraServiceProxy.class);
    t.traceEnd();
}

t.traceBegin("StartWindowManagerService");
// WMS needs sensor service ready
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
        new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
t.traceEnd();

1.2 客户端获取proxy

应用端获取服务getSystemService(Context.INPUT_SERVICE)),这里获取InputManager初始化InputManager.getInstance()(即是 IInputManager.Stub.asInterface(ServiceManager.getServiceOrThrow(Context.INPUT_SERVICE))
frameworks/base/core/java/android/app/SystemServiceRegistry.java
在这里插入图片描述

frameworks/base/core/java/android/hardware/input/InputManager.java

/**
 * Gets an instance of the input manager.
 *
 * @return The input manager instance.
 *
 * @hide
 */
@UnsupportedAppUsage
public static InputManager getInstance() {
    synchronized (InputManager.class) {
        if (sInstance == null) {
            try {
                sInstance = new InputManager(IInputManager.Stub
                        .asInterface(ServiceManager.getServiceOrThrow(Context.INPUT_SERVICE)));
            } catch (ServiceNotFoundException e) {
                throw new IllegalStateException(e);
            }
        }
        return sInstance;
    }
}

2、Native层中AIDL形式

Android 接口定义语言 (AIDL)、Android 应用层 到 HAL 层

AIDL形式是Android中binder机制的具体实现。按照规范aidl/hidl文件自动生成相应代码文件:
C++中客户端对应Bp端,服务端对应Bn端

2.1 服务端对应Bn端

JNI调用到Native层,ServiceManager中添加"inputflinger"对应InputManager,InputManager继承BnInputFlinger端,对应方法实现返回binder::Status

frameworks/native/libs/input/Android.bp
frameworks/native/libs/input/android/os/IInputFlinger.aidl

package android.os;

import android.FocusRequest;
import android.InputChannel;
import android.InputWindowInfo;
import android.os.ISetInputWindowsListener;

/** @hide */
interface IInputFlinger
{
    // SurfaceFlinger is the caller of this method, it uses the listener callback to ensure the
    // ordering when needed.
    // SurfaceFlinger calls this only every VSync, so overflow of binder's oneway buffer
    // shouldn't be a concern.
    oneway void setInputWindows(in InputWindowInfo[] inputHandles,
            in @nullable ISetInputWindowsListener setInputWindowsListener);
    InputChannel createInputChannel(in @utf8InCpp String name);
    void removeInputChannel(in IBinder connectionToken);
    /**
     * Sets focus to the window identified by the token. This must be called
     * after updating any input window handles.
     */
    oneway void setFocusedWindow(in FocusRequest request);
}

frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) {
    JNIEnv* env = jniEnv();

    mServiceObj = env->NewGlobalRef(serviceObj);

    {
        AutoMutex _l(mLock);
        mLocked.systemUiLightsOut = false;
        mLocked.pointerSpeed = 0;
        mLocked.pointerGesturesEnabled = true;
        mLocked.showTouches = false;
        mLocked.pointerCapture = false;
        mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
    }
    mInteractive = true;

    InputManager* im = new InputManager(this, this);
    mInputManager = im;
    defaultServiceManager()->addService(String16("inputflinger"), im);
}

frameworks/native/services/inputflinger/InputManager.cpp
frameworks/native/services/inputflinger/InputManager.h

binder::Status setInputWindows(
        const std::vector<InputWindowInfo>& handles,
        const sp<ISetInputWindowsListener>& setInputWindowsListener) override;

binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
binder::Status removeInputChannel(const sp<IBinder>& connectionToken) override;
binder::Status setFocusedWindow(const FocusRequest&) override;

2.2 客户端对应Bp端

系统中查看在SurfaceFlinger::bootFinished()中有获取"inputflinger"服务使用。

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::bootFinished() {
    if (mBootFinished == true) {
        ALOGE("Extra call to bootFinished");
        return;
    }
    mBootFinished = true;
    if (mStartPropertySetThread->join() != NO_ERROR) {
        ALOGE("Join StartPropertySetThread failed!");
    }

    if (mRenderEnginePrimeCacheFuture.valid()) {
        mRenderEnginePrimeCacheFuture.get();
    }
    const nsecs_t now = systemTime();
    const nsecs_t duration = now - mBootTime;
    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );

    mFrameTracer->initialize();
    mFrameTimeline->onBootFinished();

    // wait patiently for the window manager death
    const String16 name("window");
    mWindowManager = defaultServiceManager()->getService(name);
    if (mWindowManager != 0) {
        mWindowManager->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
    }

    // stop boot animation
    // formerly we would just kill the process, but we now ask it to exit so it
    // can choose where to stop the animation.
    property_set("service.bootanim.exit", "1");

    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));

    sp<IBinder> input(defaultServiceManager()->getService(String16("inputflinger")));

    static_cast<void>(schedule([=] {
        if (input == nullptr) {
            ALOGE("Failed to link to input service");
        } else {
            mInputFlinger = interface_cast<os::IInputFlinger>(input);
        }

        readPersistentProperties();
        mPowerAdvisor.onBootFinished();
        mBootStage = BootStage::FINISHED;

        if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) {
            enableRefreshRateOverlay(true);
        }
    }));
}
void SurfaceFlinger::updateInputFlinger() {
    ATRACE_CALL();
    if (!mInputFlinger) {
        return;
    }

    if (mVisibleRegionsDirty || mInputInfoChanged) {
        mInputInfoChanged = false;
        updateInputWindowInfo();
    } else if (mInputWindowCommands.syncInputWindows) {
        // If the caller requested to sync input windows, but there are no
        // changes to input windows, notify immediately.
        setInputWindowsFinished();
    }

    for (const auto& focusRequest : mInputWindowCommands.focusRequests) {
        mInputFlinger->setFocusedWindow(focusRequest);
    }
    mInputWindowCommands.clear();
}
void SurfaceFlinger::updateInputWindowInfo() {
    std::vector<InputWindowInfo> inputInfos;

    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
        if (!layer->needsInputInfo()) return;
        sp<DisplayDevice> display;
        if (enablePerWindowInputRotation()) {
            for (const auto& pair : ON_MAIN_THREAD(mDisplays)) {
                const auto& displayDevice = pair.second;
                if (!displayDevice->getCompositionDisplay()
                             ->belongsInOutput(layer->getLayerStack(),
                                               layer->getPrimaryDisplayOnly())) {
                    continue;
                }
                display = displayDevice;
            }
        }
        // When calculating the screen bounds we ignore the transparent region since it may
        // result in an unwanted offset.
        inputInfos.push_back(layer->fillInputInfo(display));
    });

    mInputFlinger->setInputWindows(inputInfos,
                               mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener
                                                                     : nullptr);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/923730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python自动化】pytest系列(中)

书接上文&#xff1a;【python自动化】pytest系列&#xff08;上&#xff09; 本篇为中篇&#xff0c;后面还有两篇&#xff0c;从本篇开始&#xff0c;知识点会增加&#xff0c;难度会一丢丢的一次递增。 本章知识点 文章目录 1、上节内容知识点回顾2、Pytest的前置后置操作…

C语言:算数转换

一、什么是算数转换 已知&#xff1a;char 和 short 这两种字节长度小于 int 类型参与算术运算时&#xff0c;会进行整型提升。 而当字节长度大于 int 类型的数据参与运算时&#xff0c;如果某个操作符的两个操作数是不同类型&#xff0c;其中一个操作数需要按级别&#xff08;…

便携式水污染物监测设备有哪些参数要求

便携式水污染物监测设备应用范围有&#xff1a; 1、饮用水检测&#xff1a;生活用水&#xff08;自来水&#xff09;、&#xff08;瓶、桶装&#xff09;矿泉水、天然矿泉水等&#xff1b; 2、工业用水检测&#xff1a;工业循环冷却水、工业锅炉水等&#xff1b; 3、其他检测&a…

c语言实现队列

文章目录 前言一、队列的特征二、队列的实现1、队列的设计2、队列的初始化3、元素的入队和出队4、返回队头的数据和队尾的数据5、返回队列的长度6、队列的销毁 三、循环队列四、队列和栈综合练习 前言 栈的特点是元素后进先出(Last In First Out)&#xff0c;而对应的还有一种…

十、pikachu之php反序列化

文章目录 1、php反序列化概述2、实战3、关于Magic function4、__wakeup()和destruct() 1、php反序列化概述 在理解这个漏洞前&#xff0c;首先搞清楚php中serialize()&#xff0c;unserialize()这两个函数。 &#xff08;1&#xff09;序列化serialize()&#xff1a;就是把一个…

一款打工人必备的电脑端自律软件!!冲鸭打工人!!

你&#xff01;有没有渴望进步&#xff01;&#xff01; 你&#xff01;有没有渴望变强&#xff01;&#xff01;&#xff01; 成为大佬&#xff01;&#xff01;&#xff01;超越巨佬&#xff01;&#xff01;&#xff01; 这就是一款为这样的你量身定做的程序&#xff1a;输入…

宝塔 杀死 java服务 netstat -tlnp | grep :7003 kill 2205698

7003 是端口 netstat -tlnp | grep :7003 kill 2205698

基于鸽群算法优化的BP神经网络(预测应用) - 附代码

基于鸽群算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于鸽群算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.鸽群优化BP神经网络2.1 BP神经网络参数设置2.2 鸽群算法应用 4.测试结果&#xff1a;5.Matlab代码 摘要…

遥感影像的缨帽(K-T)变换Python实现

&#xff08;1&#xff09;介绍 缨帽变换&#xff08;Kirchhoff Transform&#xff0c;K-T变换&#xff09; 是一种在遥感图像处理中常用的技术&#xff0c;它可以有效地提取地物的空间特征和频谱信息。本文将对遥感缨帽变换的提出者、原理方法、公式、现在的发展、作用进行详…

Mybatis (3)-----分页的运用

目录 一、分页查询 二&#xff0c;特殊的字符处理 三、总结 前言&#xff1a;在我们上篇已经学的动态sql的基础上&#xff0c;今天继续讲解关于maybatis的分页&#xff0c;特殊的字符处理。希望这篇博客可以帮助到大家哦&#xff01; 一、分页查询 为什么要重写mybatis的分…

ATFX汇市:美国PMI数据不及预期,非农基数又遭下修,经济前景堪忧

环球汇市行情摘要—— 昨日&#xff0c;美元指数下跌0.22%&#xff0c;收盘在103.38点&#xff0c; 欧元升值0.17%&#xff0c;收盘价1.0864点&#xff1b; 日元升值0.7%&#xff0c;收盘价144.85点&#xff1b; 英镑贬值0.06%&#xff0c;收盘价1.2725点&#xff1b; 瑞郎…

基于Visual studio创建API项目

API&#xff08;英文全称&#xff1a;Application Programming Interface,中文&#xff1a;应用程序编程接口&#xff09; 为什么要 通过API接口可以与其他软件实现数据相互通信&#xff0c;API这项技术能够提高开发效率。 本文是基于vs2017 .net平台搭建API。希望可以帮助到学…

Python Opencv实践 - 图像直方图自适应均衡化

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/cat.jpg", cv.IMREAD_GRAYSCALE) print(img.shape)#整幅图像做普通的直方图均衡化 img_hist_equalized cv.equalizeHist(img)#图像直方图自适应均衡化 #1. 创…

一、MQ的基本概念

1、初识MQ MQ全称是Message Queue&#xff0c;消息队列&#xff0c;多用于系统之间进行异步通信。队列的概念数据结构中有详细介绍过&#xff0c;先进先出&#xff0c;消息队列就是存储消息的数据结构。 同步调用和异步调用两者之间的区别&#xff1a; 同步调用&#xff1a;发…

使用yapi生成漂亮接口文档

YApi-教程 1. 进入yapi 的菜单 2. 从微服务中导出swagger的json 从浏览器页面访问http://localhost:端口/服务/swagger-ui.html&#xff0c;然后打开浏览器的控制台&#xff0c;查看network&#xff0c;刷新下页面&#xff0c;找到XHR中的api-docs&#xff0c;然后查看res…

【代码】Java中的动态代理实战

文章目录 1. JDK 动态代理2、CGLIB 动态代理 动态代理允许你在运行时创建代理对象&#xff0c;来代替原始对象执行某些操作。这在AOP&#xff08;面向切面编程&#xff09;中非常有用&#xff0c;用于实现日志记录、性能监控、事务管理等功能。 Java提供了两种主要的动态代理实…

缓存的设计方式

问题情况&#xff1a; 当有大量的请求到内部系统时&#xff0c;若每一个请求都需要我们操作数据库&#xff0c;例如查询操作&#xff0c;那么对于那种数据基本不怎么变动的数据来说&#xff0c;每一次都去数据库里面查询&#xff0c;是很消耗我们的性能 尤其是对于在海量数据…

【0基础入门Python Web笔记】一、python 之基础语法、基础数据类型、复合数据类型及基本操作

一、python 之基础语法、基础数据类型、复合数据类型及基本操作 基础语法规则基础数据类型数字类型&#xff08;Numbers&#xff09;字符串类型&#xff08;String&#xff09;布尔类型&#xff08;Boolean&#xff09; 复合数据类型List&#xff08;列表&#xff09;Tuple&…

【C++代码】有序数组的平方,长度最小的子数组,螺旋矩阵 II--代码随想录

题目&#xff1a;有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 题解 数组其实是有序的&#xff0c; 只不过负数平方之后可能成为最大数了。那么数组平方的最大值就在数组的…

shell 编写一个带有进度条的程序安装脚本

需求 使用 shell 写一个 软件安装脚本&#xff0c;带有进度条 示例 #!/bin/bash# 模拟软件安装的步骤列表 steps("解压文件" "安装依赖" "配置设置" "复制文件" "")# 计算总步骤数 total_steps${#steps[]}# 安装进度的初…