Home | History | Annotate | Download | only in host
      1 /*
      2  * Copyright (C) 2015 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 #include <functional>
     18 #include <stdint.h>
     19 #include <sys/types.h>
     20 #include <unordered_map>
     21 #include <vector>
     22 
     23 #define LOG_TAG "InputDriver"
     24 
     25 #define LOG_NDEBUG 0
     26 
     27 #include "InputDriver.h"
     28 #include "InputHost.h"
     29 
     30 #include <hardware/input.h>
     31 #include <input/InputDevice.h>
     32 #include <utils/Log.h>
     33 #include <utils/PropertyMap.h>
     34 #include <utils/String8.h>
     35 
     36 #define INDENT2 "    "
     37 
     38 struct input_property_map {
     39     android::PropertyMap* propertyMap;
     40 };
     41 
     42 struct input_property {
     43     android::String8 key;
     44     android::String8 value;
     45 };
     46 
     47 struct input_device_identifier {
     48     const char* name;
     49     const char* uniqueId;
     50     input_bus_t bus;
     51     int32_t     vendorId;
     52     int32_t     productId;
     53     int32_t     version;
     54 };
     55 
     56 struct input_device_definition {
     57     std::vector<input_report_definition*> reportDefs;
     58 };
     59 
     60 struct input_device_handle {
     61     input_device_identifier_t* id;
     62     input_device_definition_t* def;
     63 };
     64 
     65 struct input_int_usage {
     66     input_usage_t usage;
     67     int32_t min;
     68     int32_t max;
     69     float   resolution;
     70 };
     71 
     72 struct input_collection {
     73     int32_t arity;
     74     std::vector<input_int_usage> intUsages;
     75     std::vector<input_usage_t> boolUsages;
     76 };
     77 
     78 struct InputCollectionIdHasher {
     79     std::size_t operator()(const input_collection_id& id) const {
     80         return std::hash<int>()(static_cast<int>(id));
     81     }
     82 };
     83 
     84 struct input_report_definition {
     85     std::unordered_map<input_collection_id_t, input_collection, InputCollectionIdHasher> collections;
     86 };
     87 
     88 
     89 namespace android {
     90 
     91 static input_host_callbacks_t kCallbacks = {
     92     .create_device_identifier = create_device_identifier,
     93     .create_device_definition = create_device_definition,
     94     .create_input_report_definition = create_input_report_definition,
     95     .create_output_report_definition = create_output_report_definition,
     96     .free_report_definition = free_report_definition,
     97     .input_device_definition_add_report = input_device_definition_add_report,
     98     .input_report_definition_add_collection = input_report_definition_add_collection,
     99     .input_report_definition_declare_usage_int = input_report_definition_declare_usage_int,
    100     .input_report_definition_declare_usages_bool = input_report_definition_declare_usages_bool,
    101     .register_device = register_device,
    102     .input_allocate_report = input_allocate_report,
    103     .input_report_set_usage_int = input_report_set_usage_int,
    104     .input_report_set_usage_bool = input_report_set_usage_bool,
    105     .report_event = report_event,
    106     .input_get_device_property_map = input_get_device_property_map,
    107     .input_get_device_property = input_get_device_property,
    108     .input_get_property_key = input_get_property_key,
    109     .input_get_property_value = input_get_property_value,
    110     .input_free_device_property = input_free_device_property,
    111     .input_free_device_property_map = input_free_device_property_map,
    112 };
    113 
    114 InputDriver::InputDriver(const char* name) : mName(String8(name)) {
    115     const hw_module_t* module;
    116     int err = input_open(&module, name);
    117     LOG_ALWAYS_FATAL_IF(err != 0, "Input module %s not found", name);
    118     mHal = reinterpret_cast<const input_module_t*>(module);
    119 }
    120 
    121 void InputDriver::init() {
    122     mHal->init(mHal, static_cast<input_host_t*>(this), kCallbacks);
    123 }
    124 
    125 input_device_identifier_t* InputDriver::createDeviceIdentifier(
    126             const char* name, int32_t productId, int32_t vendorId,
    127             input_bus_t bus, const char* uniqueId) {
    128     auto identifier = new ::input_device_identifier {
    129         .name = name,
    130         .productId = productId,
    131         .vendorId = vendorId,
    132         .bus = bus,
    133         .uniqueId = uniqueId,
    134     };
    135     // TODO: store this identifier somewhere
    136     return identifier;
    137 }
    138 
    139 input_device_definition_t* InputDriver::createDeviceDefinition() {
    140     return new ::input_device_definition;
    141 }
    142 
    143 input_report_definition_t* InputDriver::createInputReportDefinition() {
    144     return new ::input_report_definition;
    145 }
    146 
    147 input_report_definition_t* InputDriver::createOutputReportDefinition() {
    148     return new ::input_report_definition;
    149 }
    150 
    151 void InputDriver::freeReportDefinition(input_report_definition_t* reportDef) {
    152     delete reportDef;
    153 }
    154 
    155 void InputDriver::inputDeviceDefinitionAddReport(input_device_definition_t* d,
    156         input_report_definition_t* r) {
    157     d->reportDefs.push_back(r);
    158 }
    159 
    160 void InputDriver::inputReportDefinitionAddCollection(input_report_definition_t* report,
    161         input_collection_id_t id, int32_t arity) {
    162     report->collections[id] = {.arity = arity};
    163 }
    164 
    165 void InputDriver::inputReportDefinitionDeclareUsageInt(input_report_definition_t* report,
    166         input_collection_id_t id, input_usage_t usage, int32_t min, int32_t max,
    167         float resolution) {
    168     if (report->collections.find(id) != report->collections.end()) {
    169         report->collections[id].intUsages.push_back({
    170                 .usage = usage, .min = min, .max = max, .resolution = resolution});
    171     }
    172 }
    173 
    174 void InputDriver::inputReportDefinitionDeclareUsagesBool(input_report_definition_t* report,
    175         input_collection_id_t id, input_usage_t* usage, size_t usageCount) {
    176     if (report->collections.find(id) != report->collections.end()) {
    177         for (size_t i = 0; i < usageCount; ++i) {
    178             report->collections[id].boolUsages.push_back(usage[i]);
    179         }
    180     }
    181 }
    182 
    183 input_device_handle_t* InputDriver::registerDevice(input_device_identifier_t* id,
    184         input_device_definition_t* d) {
    185     ALOGD("Registering device %s with %zu input reports", id->name, d->reportDefs.size());
    186     // TODO: save this device handle
    187     return new input_device_handle{ .id = id, .def = d };
    188 }
    189 
    190 void InputDriver::unregisterDevice(input_device_handle_t* handle) {
    191     delete handle;
    192 }
    193 
    194 input_report_t* InputDriver::inputAllocateReport(input_report_definition_t* r) {
    195     ALOGD("Allocating input report for definition %p", r);
    196     return nullptr;
    197 }
    198 
    199 void InputDriver::inputReportSetUsageInt(input_report_t* r, input_collection_id_t id,
    200         input_usage_t usage, int32_t value, int32_t arity_index) {
    201 }
    202 
    203 void InputDriver::inputReportSetUsageBool(input_report_t* r, input_collection_id_t id,
    204         input_usage_t usage, bool value, int32_t arity_index) {
    205 }
    206 
    207 void InputDriver::reportEvent(input_device_handle_t* d, input_report_t* report) {
    208     ALOGD("report_event %p for handle %p", report, d);
    209 }
    210 
    211 input_property_map_t* InputDriver::inputGetDevicePropertyMap(input_device_identifier_t* id) {
    212     InputDeviceIdentifier idi;
    213     idi.name = id->name;
    214     idi.uniqueId = id->uniqueId;
    215     idi.bus = id->bus;
    216     idi.vendor = id->vendorId;
    217     idi.product = id->productId;
    218     idi.version = id->version;
    219 
    220     String8 configFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
    221             idi, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
    222     if (configFile.isEmpty()) {
    223         ALOGD("No input device configuration file found for device '%s'.",
    224                 idi.name.string());
    225     } else {
    226         auto propMap = new input_property_map_t();
    227         status_t status = PropertyMap::load(configFile, &propMap->propertyMap);
    228         if (status) {
    229             ALOGE("Error loading input device configuration file for device '%s'. "
    230                     "Using default configuration.",
    231                     idi.name.string());
    232             delete propMap;
    233             return nullptr;
    234         }
    235         return propMap;
    236     }
    237     return nullptr;
    238 }
    239 
    240 input_property_t* InputDriver::inputGetDeviceProperty(input_property_map_t* map,
    241         const char* key) {
    242     String8 keyString(key);
    243     if (map != nullptr) {
    244         if (map->propertyMap->hasProperty(keyString)) {
    245             auto prop = new input_property_t();
    246             if (!map->propertyMap->tryGetProperty(keyString, prop->value)) {
    247                 delete prop;
    248                 return nullptr;
    249             }
    250             prop->key = keyString;
    251             return prop;
    252         }
    253     }
    254     return nullptr;
    255 }
    256 
    257 const char* InputDriver::inputGetPropertyKey(input_property_t* property) {
    258     if (property != nullptr) {
    259         return property->key.string();
    260     }
    261     return nullptr;
    262 }
    263 
    264 const char* InputDriver::inputGetPropertyValue(input_property_t* property) {
    265     if (property != nullptr) {
    266         return property->value.string();
    267     }
    268     return nullptr;
    269 }
    270 
    271 void InputDriver::inputFreeDeviceProperty(input_property_t* property) {
    272     if (property != nullptr) {
    273         delete property;
    274     }
    275 }
    276 
    277 void InputDriver::inputFreeDevicePropertyMap(input_property_map_t* map) {
    278     if (map != nullptr) {
    279         delete map->propertyMap;
    280         delete map;
    281     }
    282 }
    283 
    284 void InputDriver::dump(String8& result) {
    285     result.appendFormat(INDENT2 "HAL Input Driver (%s)\n", mName.string());
    286 }
    287 
    288 } // namespace android
    289 
    290 // HAL wrapper functions
    291 
    292 namespace android {
    293 
    294 ::input_device_identifier_t* create_device_identifier(input_host_t* host,
    295         const char* name, int32_t product_id, int32_t vendor_id,
    296         input_bus_t bus, const char* unique_id) {
    297     auto driver = static_cast<InputDriverInterface*>(host);
    298     return driver->createDeviceIdentifier(name, product_id, vendor_id, bus, unique_id);
    299 }
    300 
    301 input_device_definition_t* create_device_definition(input_host_t* host) {
    302     auto driver = static_cast<InputDriverInterface*>(host);
    303     return driver->createDeviceDefinition();
    304 }
    305 
    306 input_report_definition_t* create_input_report_definition(input_host_t* host) {
    307     auto driver = static_cast<InputDriverInterface*>(host);
    308     return driver->createInputReportDefinition();
    309 }
    310 
    311 input_report_definition_t* create_output_report_definition(input_host_t* host) {
    312     auto driver = static_cast<InputDriverInterface*>(host);
    313     return driver->createOutputReportDefinition();
    314 }
    315 
    316 void free_report_definition(input_host_t* host, input_report_definition_t* report_def) {
    317     auto driver = static_cast<InputDriverInterface*>(host);
    318     driver->freeReportDefinition(report_def);
    319 }
    320 
    321 void input_device_definition_add_report(input_host_t* host,
    322         input_device_definition_t* d, input_report_definition_t* r) {
    323     auto driver = static_cast<InputDriverInterface*>(host);
    324     driver->inputDeviceDefinitionAddReport(d, r);
    325 }
    326 
    327 void input_report_definition_add_collection(input_host_t* host,
    328         input_report_definition_t* report, input_collection_id_t id, int32_t arity) {
    329     auto driver = static_cast<InputDriverInterface*>(host);
    330     driver->inputReportDefinitionAddCollection(report, id, arity);
    331 }
    332 
    333 void input_report_definition_declare_usage_int(input_host_t* host,
    334         input_report_definition_t* report, input_collection_id_t id,
    335         input_usage_t usage, int32_t min, int32_t max, float resolution) {
    336     auto driver = static_cast<InputDriverInterface*>(host);
    337     driver->inputReportDefinitionDeclareUsageInt(report, id, usage, min, max, resolution);
    338 }
    339 
    340 void input_report_definition_declare_usages_bool(input_host_t* host,
    341         input_report_definition_t* report, input_collection_id_t id,
    342         input_usage_t* usage, size_t usage_count) {
    343     auto driver = static_cast<InputDriverInterface*>(host);
    344     driver->inputReportDefinitionDeclareUsagesBool(report, id, usage, usage_count);
    345 }
    346 
    347 input_device_handle_t* register_device(input_host_t* host,
    348         input_device_identifier_t* id, input_device_definition_t* d) {
    349     auto driver = static_cast<InputDriverInterface*>(host);
    350     return driver->registerDevice(id, d);
    351 }
    352 
    353 void unregister_device(input_host_t* host, input_device_handle_t* handle) {
    354     auto driver = static_cast<InputDriverInterface*>(host);
    355     driver->unregisterDevice(handle);
    356 }
    357 
    358 input_report_t* input_allocate_report(input_host_t* host, input_report_definition_t* r) {
    359     auto driver = static_cast<InputDriverInterface*>(host);
    360     return driver->inputAllocateReport(r);
    361 }
    362 
    363 void input_report_set_usage_int(input_host_t* host, input_report_t* r,
    364         input_collection_id_t id, input_usage_t usage, int32_t value, int32_t arity_index) {
    365     auto driver = static_cast<InputDriverInterface*>(host);
    366     driver->inputReportSetUsageInt(r, id, usage, value, arity_index);
    367 }
    368 
    369 void input_report_set_usage_bool(input_host_t* host, input_report_t* r,
    370         input_collection_id_t id, input_usage_t usage, bool value, int32_t arity_index) {
    371     auto driver = static_cast<InputDriverInterface*>(host);
    372     driver->inputReportSetUsageBool(r, id, usage, value, arity_index);
    373 }
    374 
    375 void report_event(input_host_t* host, input_device_handle_t* d, input_report_t* report) {
    376     auto driver = static_cast<InputDriverInterface*>(host);
    377     driver->reportEvent(d, report);
    378 }
    379 
    380 input_property_map_t* input_get_device_property_map(input_host_t* host,
    381         input_device_identifier_t* id) {
    382     auto driver = static_cast<InputDriverInterface*>(host);
    383     return driver->inputGetDevicePropertyMap(id);
    384 }
    385 
    386 input_property_t* input_get_device_property(input_host_t* host, input_property_map_t* map,
    387         const char* key) {
    388     auto driver = static_cast<InputDriverInterface*>(host);
    389     return driver->inputGetDeviceProperty(map, key);
    390 }
    391 
    392 const char* input_get_property_key(input_host_t* host, input_property_t* property) {
    393     auto driver = static_cast<InputDriverInterface*>(host);
    394     return driver->inputGetPropertyKey(property);
    395 }
    396 
    397 const char* input_get_property_value(input_host_t* host, input_property_t* property) {
    398     auto driver = static_cast<InputDriverInterface*>(host);
    399     return driver->inputGetPropertyValue(property);
    400 }
    401 
    402 void input_free_device_property(input_host_t* host, input_property_t* property) {
    403     auto driver = static_cast<InputDriverInterface*>(host);
    404     driver->inputFreeDeviceProperty(property);
    405 }
    406 
    407 void input_free_device_property_map(input_host_t* host, input_property_map_t* map) {
    408     auto driver = static_cast<InputDriverInterface*>(host);
    409     driver->inputFreeDevicePropertyMap(map);
    410 }
    411 
    412 } // namespace android
    413