USB: HAL: update wahoo hal to V1_1

This CL adds support to notify frameworks when an audio
or debug accessory is attached.

Bug: 36604276
Test: Manually test inserting an Audio accessory.
Change-Id: I9ec0f88ed85ed593b31132ba58bfedb51a435cd8
This commit is contained in:
Badhri Jagan Sridharan
2017-04-18 17:41:35 -07:00
committed by Thierry Strudel
parent 39ccb7186f
commit fc32e28be9
9 changed files with 130 additions and 87 deletions

View File

@@ -2,4 +2,5 @@ subdirs = [
"vr",
"vibrator",
"wifi_offload",
"usb",
]

View File

@@ -285,7 +285,7 @@ PRODUCT_COPY_FILES += \
device/google/wahoo/nfc/libnfc-brcm.conf:$(TARGET_COPY_OUT_VENDOR)/etc/libnfc-brcm.conf \
PRODUCT_PACKAGES += \
android.hardware.usb@1.0-service.device
android.hardware.usb@1.1-service.wahoo
PRODUCT_PACKAGES += \
libmm-omxcore \

View File

@@ -198,7 +198,7 @@
/vendor/bin/qmuxd u:object_r:qmuxd_exec:s0
/vendor/bin/cnd u:object_r:cnd_exec:s0
/vendor/bin/esed u:object_r:esed_exec:s0
/vendor/bin/hw/android\.hardware\.usb@1\.0-service.device u:object_r:hal_usb_default_exec:s0
/vendor/bin/hw/android\.hardware\.usb@1\.1-service.wahoo u:object_r:hal_usb_default_exec:s0
/vendor/bin/chre u:object_r:chre_exec:s0
/vendor/bin/folio_daemon u:object_r:folio_daemon_exec:s0
/vendor/bin/time_daemon u:object_r:time_daemon_exec:s0

32
usb/Android.bp Normal file
View File

@@ -0,0 +1,32 @@
//
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
cc_binary {
name: "android.hardware.usb@1.1-service.wahoo",
relative_install_path: "hw",
init_rc: ["android.hardware.usb@1.1-service.wahoo.rc"],
srcs: ["service.cpp", "Usb.cpp"],
shared_libs: [
"libbase",
"libhidlbase",
"libhidltransport",
"liblog",
"libutils",
"libhardware",
"android.hardware.usb@1.0",
"android.hardware.usb@1.1",
"libcutils",
],
proprietary: true,
}

View File

@@ -1,36 +0,0 @@
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE := android.hardware.usb@1.0-service.device
LOCAL_INIT_RC := android.hardware.usb@1.0-service.device.rc
LOCAL_SRC_FILES := \
service.cpp \
Usb.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhidlbase \
libhidltransport \
liblog \
libhwbinder \
libutils \
libhardware \
android.hardware.usb@1.0 \
include $(BUILD_EXECUTABLE)

View File

@@ -13,6 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.usb@1.1-service.wahoo"
#include <android-base/logging.h>
#include <assert.h>
#include <dirent.h>
#include <pthread.h>
@@ -31,7 +35,7 @@
namespace android {
namespace hardware {
namespace usb {
namespace V1_0 {
namespace V1_1 {
namespace implementation {
// Set by the signal handler to destroy the thread
@@ -85,8 +89,8 @@ std::string convertRoletoString(PortRole role) {
if (role.role == static_cast<uint32_t>(PortDataRole::DEVICE))
return "device";
} else if (role.type == PortRoleType::MODE) {
if (role.role == static_cast<uint32_t>(PortMode::UFP)) return "ufp";
if (role.role == static_cast<uint32_t>(PortMode::DFP)) return "dfp";
if (role.role == static_cast<uint32_t>(PortMode_1_1::UFP)) return "ufp";
if (role.role == static_cast<uint32_t>(PortMode_1_1::DFP)) return "dfp";
}
return "none";
}
@@ -155,10 +159,24 @@ Return<void> Usb::switchRole(const hidl_string &portName,
return Void();
}
Status getAccessoryConnected(std::string portName, std::string *accessory) {
std::string filename =
"/sys/class/typec/" + portName + "-partner/accessory_mode";
if (readFile(filename, accessory)) {
ALOGE("getAccessoryConnected: Failed to open filesystem node: %s",
filename.c_str());
return Status::ERROR;
}
return Status::SUCCESS;
}
Status getCurrentRoleHelper(std::string portName, bool connected,
PortRoleType type, uint32_t *currentRole) {
std::string filename;
std::string roleName;
std::string accessory;
// Mode
@@ -170,13 +188,26 @@ Status getCurrentRoleHelper(std::string portName, bool connected,
*currentRole = static_cast<uint32_t>(PortDataRole::NONE);
} else if (type == PortRoleType::MODE) {
filename = "/sys/class/typec/" + portName + "/current_data_role";
*currentRole = static_cast<uint32_t>(PortMode::NONE);
*currentRole = static_cast<uint32_t>(PortMode_1_1::NONE);
} else {
return Status::ERROR;
}
if (!connected) return Status::SUCCESS;
if (type == PortRoleType::MODE) {
if (getAccessoryConnected(portName, &accessory) != Status::SUCCESS) {
return Status::ERROR;
}
if (accessory == "Audio Adapter Accessory Mode") {
*currentRole = static_cast<uint32_t>(PortMode_1_1::AUDIO_ACCESSORY);
return Status::SUCCESS;
} else if (accessory == "Debug Accessory Mode") {
*currentRole = static_cast<uint32_t>(PortMode_1_1::DEBUG_ACCESSORY);
return Status::SUCCESS;
}
}
if (readFile(filename, &roleName)) {
ALOGE("getCurrentRole: Failed to open filesystem node: %s",
filename.c_str());
@@ -193,12 +224,12 @@ Status getCurrentRoleHelper(std::string portName, bool connected,
if (type == PortRoleType::DATA_ROLE)
*currentRole = static_cast<uint32_t>(PortDataRole::HOST);
else
*currentRole = static_cast<uint32_t>(PortMode::DFP);
*currentRole = static_cast<uint32_t>(PortMode_1_1::DFP);
} else if (roleName == "device") {
if (type == PortRoleType::DATA_ROLE)
*currentRole = static_cast<uint32_t>(PortDataRole::DEVICE);
else
*currentRole = static_cast<uint32_t>(PortMode::UFP);
*currentRole = static_cast<uint32_t>(PortMode_1_1::UFP);
} else if (roleName != "none") {
/* case for none has already been addressed.
* so we check if the role isnt none.
@@ -253,23 +284,23 @@ bool canSwitchRoleHelper(const std::string portName, PortRoleType /*type*/) {
return false;
}
Status getPortStatusHelper(hidl_vec<PortStatus> *currentPortStatus) {
Status getPortStatus_1_1Helper(hidl_vec<PortStatus_1_1> *currentPortStatus_1_1) {
std::unordered_map<std::string, bool> names;
Status result = getTypeCPortNamesHelper(&names);
int i = -1;
if (result == Status::SUCCESS) {
currentPortStatus->resize(names.size());
currentPortStatus_1_1->resize(names.size());
for (std::pair<std::string, bool> port : names) {
i++;
ALOGI("%s", port.first.c_str());
(*currentPortStatus)[i].portName = port.first;
(*currentPortStatus_1_1)[i].status.portName = port.first;
uint32_t currentRole;
if (getCurrentRoleHelper(port.first, port.second,
PortRoleType::POWER_ROLE,
&currentRole) == Status::SUCCESS) {
(*currentPortStatus)[i].currentPowerRole =
(*currentPortStatus_1_1)[i].status.currentPowerRole =
static_cast<PortPowerRole>(currentRole);
} else {
ALOGE("Error while retreiving portNames");
@@ -278,7 +309,7 @@ Status getPortStatusHelper(hidl_vec<PortStatus> *currentPortStatus) {
if (getCurrentRoleHelper(port.first, port.second, PortRoleType::DATA_ROLE,
&currentRole) == Status::SUCCESS) {
(*currentPortStatus)[i].currentDataRole =
(*currentPortStatus_1_1)[i].status.currentDataRole =
static_cast<PortDataRole>(currentRole);
} else {
ALOGE("Error while retreiving current port role");
@@ -287,28 +318,31 @@ Status getPortStatusHelper(hidl_vec<PortStatus> *currentPortStatus) {
if (getCurrentRoleHelper(port.first, port.second, PortRoleType::MODE,
&currentRole) == Status::SUCCESS) {
(*currentPortStatus)[i].currentMode =
static_cast<PortMode>(currentRole);
(*currentPortStatus_1_1)[i].currentMode =
static_cast<PortMode_1_1>(currentRole);
} else {
ALOGE("Error while retreiving current data role");
goto done;
}
(*currentPortStatus)[i].canChangeMode = false;
(*currentPortStatus)[i].canChangeDataRole =
(*currentPortStatus_1_1)[i].status.canChangeMode = false;
(*currentPortStatus_1_1)[i].status.canChangeDataRole =
port.second ? canSwitchRoleHelper(port.first, PortRoleType::DATA_ROLE)
: false;
(*currentPortStatus)[i].canChangePowerRole =
(*currentPortStatus_1_1)[i].status.canChangePowerRole =
port.second
? canSwitchRoleHelper(port.first, PortRoleType::POWER_ROLE)
: false;
ALOGI("connected:%d canChangeMode: %d canChagedata: %d canChangePower:%d",
port.second, (*currentPortStatus)[i].canChangeMode,
(*currentPortStatus)[i].canChangeDataRole,
(*currentPortStatus)[i].canChangePowerRole);
port.second, (*currentPortStatus_1_1)[i].status.canChangeMode,
(*currentPortStatus_1_1)[i].status.canChangeDataRole,
(*currentPortStatus_1_1)[i].status.canChangePowerRole);
(*currentPortStatus)[i].supportedModes = PortMode::DRP;
(*currentPortStatus_1_1)[i].supportedModes = PortMode_1_1::UFP | PortMode_1_1::DFP;
(*currentPortStatus_1_1)[i].status.supportedModes = V1_0::PortMode::NONE;
(*currentPortStatus_1_1)[i].status.currentMode = V1_0::PortMode::NONE;
}
return Status::SUCCESS;
}
@@ -317,17 +351,17 @@ done:
}
Return<void> Usb::queryPortStatus() {
hidl_vec<PortStatus> currentPortStatus;
hidl_vec<PortStatus_1_1> currentPortStatus_1_1;
Status status;
status = getPortStatusHelper(&currentPortStatus);
status = getPortStatus_1_1Helper(&currentPortStatus_1_1);
pthread_mutex_lock(&mLock);
if (mCallback != NULL) {
Return<void> ret =
mCallback->notifyPortStatusChange(currentPortStatus, status);
mCallback->notifyPortStatusChange_1_1(currentPortStatus_1_1, status);
if (!ret.isOk())
ALOGE("queryPortStatus error %s", ret.description().c_str());
ALOGE("queryPortStatus_1_1 error %s", ret.description().c_str());
} else {
ALOGI("Notifying userspace skipped. Callback is NULL");
}
@@ -337,7 +371,7 @@ Return<void> Usb::queryPortStatus() {
}
struct data {
int uevent_fd;
android::hardware::usb::V1_0::implementation::Usb *usb;
android::hardware::usb::V1_1::implementation::Usb *usb;
};
static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
@@ -359,10 +393,10 @@ static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
ALOGI("uevent received %s", cp);
pthread_mutex_lock(&payload->usb->mLock);
if (payload->usb->mCallback != NULL) {
hidl_vec<PortStatus> currentPortStatus;
Status status = getPortStatusHelper(&currentPortStatus);
Return<void> ret = payload->usb->mCallback->notifyPortStatusChange(
currentPortStatus, status);
hidl_vec<PortStatus_1_1> currentPortStatus_1_1;
Status status = getPortStatus_1_1Helper(&currentPortStatus_1_1);
Return<void> ret = payload->usb->mCallback->notifyPortStatusChange_1_1(
currentPortStatus_1_1, status);
if (!ret.isOk()) ALOGE("error %s", ret.description().c_str());
} else {
ALOGI("Notifying userspace skipped. Callback is NULL");
@@ -391,7 +425,7 @@ void *work(void *param) {
}
payload.uevent_fd = uevent_fd;
payload.usb = (android::hardware::usb::V1_0::implementation::Usb *)param;
payload.usb = (android::hardware::usb::V1_1::implementation::Usb *)param;
fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
@@ -444,7 +478,13 @@ void sighandler(int sig) {
signal(SIGUSR1, sighandler);
}
Return<void> Usb::setCallback(const sp<IUsbCallback> &callback) {
Return<void> Usb::setCallback(const sp<::android::hardware::usb::V1_0::IUsbCallback> &callback) {
sp<IUsbCallback> callback_V1_1 = IUsbCallback::castFrom(callback);
if (callback != NULL)
CHECK(callback_V1_1 != NULL);
pthread_mutex_lock(&mLock);
/*
* When both the old callback and new callback values are NULL,
@@ -455,12 +495,12 @@ Return<void> Usb::setCallback(const sp<IUsbCallback> &callback) {
*/
if ((mCallback == NULL && callback == NULL) ||
(mCallback != NULL && callback != NULL)) {
mCallback = callback;
mCallback = callback_V1_1;
pthread_mutex_unlock(&mLock);
return Void();
}
mCallback = callback;
mCallback = callback_V1_1;
ALOGI("registering callback");
// Kill the worker thread if the new callback is NULL.

View File

@@ -1,27 +1,30 @@
#ifndef ANDROID_HARDWARE_USB_V1_0_USB_H
#define ANDROID_HARDWARE_USB_V1_0_USB_H
#ifndef ANDROID_HARDWARE_USB_V1_1_USB_H
#define ANDROID_HARDWARE_USB_V1_1_USB_H
#include <android/hardware/usb/1.0/IUsb.h>
#include <hidl/MQDescriptor.h>
#include <android/hardware/usb/1.1/IUsb.h>
#include <android/hardware/usb/1.1/types.h>
#include <android/hardware/usb/1.1/IUsbCallback.h>
#include <hidl/Status.h>
#include <utils/Log.h>
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "android.hardware.usb@1.0-service.device"
#define UEVENT_MSG_LEN 2048
namespace android {
namespace hardware {
namespace usb {
namespace V1_0 {
namespace V1_1 {
namespace implementation {
using ::android::hardware::usb::V1_0::IUsb;
using ::android::hardware::usb::V1_0::IUsbCallback;
using ::android::hardware::usb::V1_0::PortRole;
using ::android::hardware::usb::V1_0::PortRoleType;
using ::android::hardware::usb::V1_0::PortDataRole;
using ::android::hardware::usb::V1_0::PortPowerRole;
using ::android::hardware::usb::V1_0::Status;
using ::android::hardware::usb::V1_0::IUsb;
using ::android::hardware::usb::V1_1::IUsbCallback;
using ::android::hardware::usb::V1_1::PortMode_1_1;
using ::android::hardware::usb::V1_1::PortStatus_1_1;
using ::android::hidl::base::V1_0::DebugInfo;
using ::android::hidl::base::V1_0::IBase;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
@@ -33,9 +36,10 @@ using ::android::sp;
struct Usb : public IUsb {
Return<void> switchRole(const hidl_string& portName, const PortRole& role) override;
Return<void> setCallback(const sp<IUsbCallback>& callback) override;
Return<void> setCallback(const sp<::android::hardware::usb::V1_0::IUsbCallback>& callback) override;
Return<void> queryPortStatus() override;
sp<IUsbCallback> mCallback;
pthread_mutex_t mLock = PTHREAD_MUTEX_INITIALIZER;
@@ -49,4 +53,4 @@ struct Usb : public IUsb {
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_USB_V1_0_USB_H
#endif // ANDROID_HARDWARE_USB_V1_1_USB_H

View File

@@ -1,4 +1,4 @@
service usb-hal-1-0 /vendor/bin/hw/android.hardware.usb@1.0-service.device
service usb-hal-1-1 /vendor/bin/hw/android.hardware.usb@1.1-service.wahoo
class hal
user system
group system

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
#define LOG_TAG "android.hardware.usb@1.1-service.wahoo"
#include <hidl/HidlTransportSupport.h>
#include "Usb.h"
@@ -25,7 +27,7 @@ using android::hardware::joinRpcThreadpool;
// Generated HIDL files
using android::hardware::usb::V1_0::IUsb;
using android::hardware::usb::V1_0::implementation::Usb;
using android::hardware::usb::V1_1::implementation::Usb;
using android::status_t;
using android::OK;