• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "InputManager"
18 
19 //#define LOG_NDEBUG 0
20 
21 #include "InputManager.h"
22 #include "InputDispatcherFactory.h"
23 #include "InputReaderFactory.h"
24 #include "UnwantedInteractionBlocker.h"
25 
26 #include <android/sysprop/InputProperties.sysprop.h>
27 #include <binder/IPCThreadState.h>
28 
29 #include <log/log.h>
30 #include <unordered_map>
31 
32 #include <private/android_filesystem_config.h>
33 
34 namespace android {
35 
36 static const bool ENABLE_INPUT_DEVICE_USAGE_METRICS =
37         sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true);
38 
39 using gui::FocusRequest;
40 
exceptionCodeFromStatusT(status_t status)41 static int32_t exceptionCodeFromStatusT(status_t status) {
42     switch (status) {
43         case OK:
44             return binder::Status::EX_NONE;
45         case INVALID_OPERATION:
46             return binder::Status::EX_UNSUPPORTED_OPERATION;
47         case BAD_VALUE:
48         case BAD_TYPE:
49         case NAME_NOT_FOUND:
50             return binder::Status::EX_ILLEGAL_ARGUMENT;
51         case NO_INIT:
52             return binder::Status::EX_ILLEGAL_STATE;
53         case PERMISSION_DENIED:
54             return binder::Status::EX_SECURITY;
55         default:
56             return binder::Status::EX_TRANSACTION_FAILED;
57     }
58 }
59 
60 /**
61  * The event flow is via the "InputListener" interface, as follows:
62  *   InputReader
63  *     -> UnwantedInteractionBlocker
64  *     -> InputProcessor
65  *     -> InputDeviceMetricsCollector
66  *     -> InputDispatcher
67  */
InputManager(const sp<InputReaderPolicyInterface> & readerPolicy,InputDispatcherPolicyInterface & dispatcherPolicy)68 InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,
69                            InputDispatcherPolicyInterface& dispatcherPolicy) {
70     mDispatcher = createInputDispatcher(dispatcherPolicy);
71 
72     if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
73         mCollector = std::make_unique<InputDeviceMetricsCollector>(*mDispatcher);
74     }
75 
76     mProcessor = ENABLE_INPUT_DEVICE_USAGE_METRICS ? std::make_unique<InputProcessor>(*mCollector)
77                                                    : std::make_unique<InputProcessor>(*mDispatcher);
78     mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mProcessor);
79     mReader = createInputReader(readerPolicy, *mBlocker);
80 }
81 
~InputManager()82 InputManager::~InputManager() {
83     stop();
84 }
85 
start()86 status_t InputManager::start() {
87     status_t result = mDispatcher->start();
88     if (result) {
89         ALOGE("Could not start InputDispatcher thread due to error %d.", result);
90         return result;
91     }
92 
93     result = mReader->start();
94     if (result) {
95         ALOGE("Could not start InputReader due to error %d.", result);
96 
97         mDispatcher->stop();
98         return result;
99     }
100 
101     return OK;
102 }
103 
stop()104 status_t InputManager::stop() {
105     status_t status = OK;
106 
107     status_t result = mReader->stop();
108     if (result) {
109         ALOGW("Could not stop InputReader due to error %d.", result);
110         status = result;
111     }
112 
113     result = mDispatcher->stop();
114     if (result) {
115         ALOGW("Could not stop InputDispatcher thread due to error %d.", result);
116         status = result;
117     }
118 
119     return status;
120 }
121 
getReader()122 InputReaderInterface& InputManager::getReader() {
123     return *mReader;
124 }
125 
getProcessor()126 InputProcessorInterface& InputManager::getProcessor() {
127     return *mProcessor;
128 }
129 
getMetricsCollector()130 InputDeviceMetricsCollectorInterface& InputManager::getMetricsCollector() {
131     return *mCollector;
132 }
133 
getDispatcher()134 InputDispatcherInterface& InputManager::getDispatcher() {
135     return *mDispatcher;
136 }
137 
monitor()138 void InputManager::monitor() {
139     mReader->monitor();
140     mBlocker->monitor();
141     mProcessor->monitor();
142     mDispatcher->monitor();
143 }
144 
dump(std::string & dump)145 void InputManager::dump(std::string& dump) {
146     mReader->dump(dump);
147     dump += '\n';
148     mBlocker->dump(dump);
149     dump += '\n';
150     mProcessor->dump(dump);
151     dump += '\n';
152     if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
153         mCollector->dump(dump);
154         dump += '\n';
155     }
156     mDispatcher->dump(dump);
157     dump += '\n';
158 }
159 
160 // Used by tests only.
createInputChannel(const std::string & name,InputChannel * outChannel)161 binder::Status InputManager::createInputChannel(const std::string& name, InputChannel* outChannel) {
162     IPCThreadState* ipc = IPCThreadState::self();
163     const int uid = ipc->getCallingUid();
164     if (uid != AID_SHELL && uid != AID_ROOT) {
165         ALOGE("Invalid attempt to register input channel over IPC"
166                 "from non shell/root entity (PID: %d)", ipc->getCallingPid());
167         return binder::Status::ok();
168     }
169 
170     base::Result<std::unique_ptr<InputChannel>> channel = mDispatcher->createInputChannel(name);
171     if (!channel.ok()) {
172         return binder::Status::fromExceptionCode(exceptionCodeFromStatusT(channel.error().code()),
173                                                  channel.error().message().c_str());
174     }
175     (*channel)->copyTo(*outChannel);
176     return binder::Status::ok();
177 }
178 
removeInputChannel(const sp<IBinder> & connectionToken)179 binder::Status InputManager::removeInputChannel(const sp<IBinder>& connectionToken) {
180     mDispatcher->removeInputChannel(connectionToken);
181     return binder::Status::ok();
182 }
183 
dump(int fd,const Vector<String16> & args)184 status_t InputManager::dump(int fd, const Vector<String16>& args) {
185     std::string dump;
186 
187     dump += " InputFlinger dump\n";
188 
189     ::write(fd, dump.c_str(), dump.size());
190     return NO_ERROR;
191 }
192 
setFocusedWindow(const FocusRequest & request)193 binder::Status InputManager::setFocusedWindow(const FocusRequest& request) {
194     mDispatcher->setFocusedWindow(request);
195     return binder::Status::ok();
196 }
197 
198 } // namespace android
199