IMS中Binder案例

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

  • defaultServiceManager()->addService(String16("inputflinger"), im); 添加"inputflinger"服务
  • class InputManager : public InputManagerInterface, public BnInputFlinger 对应Bn端

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"服务使用。

  • defaultServiceManager()->getService(String16("inputflinger")) 获取"inputflinger"服务
  • mInputFlinger = interface_cast<os::IInputFlinger>(input) 转化Bp端,查看 Binder系列2-ServiceManager模板interface_cast => 模板::android::sp<Bp##INTERFACE>::make(obj)

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);
}

猜你喜欢

转载自blog.csdn.net/qq_23452385/article/details/132400593