Android input系统
1.Input相关服务启动的起点在SystemServer.startOtherServices:
/** * Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized. */ private void startOtherServices(@NonNull TimingsTraceAndSlog t) { t.traceBegin("startOtherServices"); final Context context = mSystemContext; ...... InputManagerService inputManager = null; ...... try { ...... t.traceBegin("StartInputManagerService"); inputManager = new InputManagerService(context); t.traceEnd(); ...... t.traceBegin("StartInputManager"); inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback()); inputManager.start(); t.traceEnd(); .... } }
1)、创建了一个InputManagerService对象inputManager。
2)、调用了InputManagerService.start方法。
frameworks\base\services\core\java\com\android\server\input\InputManagerService.java
public InputManagerService(Context context) { this.mContext = context; this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper()); mStaticAssociations = loadStaticInputPortAssociations(); mUseDevInputEventForAudioJack = context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack=" + mUseDevInputEventForAudioJack); mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue()); String doubleTouchGestureEnablePath = context.getResources().getString( R.string.config_doubleTouchGestureEnableFile); mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null : new File(doubleTouchGestureEnablePath); LocalServices.addService(InputManagerInternal.class, new LocalService()); }
public void start() { Slog.i(TAG, "Starting input manager"); nativeStart(mPtr); // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); registerPointerSpeedSettingObserver(); registerShowTouchesSettingObserver(); registerAccessibilityLargePointerSettingObserver(); registerLongPressTimeoutObserver(); registerMaximumObscuringOpacityForTouchSettingObserver(); registerBlockUntrustedTouchesModeSettingObserver(); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); updateAccessibilityLargePointerFromSettings(); updateDeepPressStatusFromSettings("user switched"); } }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); updateAccessibilityLargePointerFromSettings(); updateDeepPressStatusFromSettings("just booted"); updateMaximumObscuringOpacityForTouchFromSettings(); updateBlockUntrustedTouchesModeFromSettings(); }
static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == nullptr) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper()); im->incStrong(0); return reinterpret_cast<jlong>(im); }
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); status_t result = im->getInputManager()->start(); if (result) { jniThrowRuntimeException(env, "Input manager could not be started."); } }
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.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
InputManager::InputManager( const sp<InputReaderPolicyInterface>& readerPolicy, const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) { mDispatcher = createInputDispatcher(dispatcherPolicy); mClassifier = new InputClassifier(mDispatcher); mReader = createInputReader(readerPolicy, mClassifier); }
status_t InputManager::start() { status_t result = mDispatcher->start(); if (result) { ALOGE("Could not start InputDispatcher thread due to error %d.", result); return result; } ALOGE("longjiang InputReader start"); result = mReader->start(); if (result) { ALOGE("Could not start InputReader due to error %d.", result); mDispatcher->stop(); return result; } return OK; }
frameworks\native\services\inputflinger\dispatcher\InputDispatcherFactory.cpp
sp<InputDispatcherInterface> createInputDispatcher( const sp<InputDispatcherPolicyInterface>& policy) { return new android::inputdispatcher::InputDispatcher(policy); }
frameworks\native\services\inputflinger\reader\InputReaderFactory.cpp
sp<InputReaderInterface> createInputReader(const sp<InputReaderPolicyInterface>& policy, const sp<InputListenerInterface>& listener) { return new InputReader(std::make_unique<EventHub>(), policy, listener); }
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub, const sp<InputReaderPolicyInterface>& policy, const sp<InputListenerInterface>& listener) : mContext(this), mEventHub(eventHub), mPolicy(policy), mGlobalMetaState(0), mLedMetaState(AMETA_NUM_LOCK_ON), mGeneration(1), mNextInputDeviceId(END_RESERVED_ID), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX), mConfigurationChangesToRefresh(0) { mQueuedListener = new QueuedInputListener(listener); { // acquire lock std::scoped_lock _l(mLock); refreshConfigurationLocked(0); updateGlobalMetaStateLocked(); } // release lock }
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) : mPolicy(policy), mPendingEvent(nullptr), mLastDropReason(DropReason::NOT_DROPPED), mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX), mNextUnblockedEvent(nullptr), mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false), // mInTouchMode will be initialized by the WindowManager to the default device config. // To avoid leaking stack in case that call never comes, and for tests, // initialize it here anyways. mInTouchMode(true), mMaximumObscuringOpacityForTouch(1.0f), mFocusedDisplayId(ADISPLAY_ID_DEFAULT), mWindowTokenWithPointerCapture(nullptr), mLatencyAggregator(), mLatencyTracker(&mLatencyAggregator), mCompatService(getCompatService()) { mLooper = new Looper(false); mReporter = createInputReporter(); mKeyRepeatState.lastKeyEntry = nullptr; policy->getDispatcherConfiguration(&mConfig); }