Allow reregistering callback
Callbacks would have to be allowed being reregistered to handle frameworks restarts. Bug: 35758079 Test: adb shell stop; adb shell start; and see if USB notifications happen. Change-Id: I256b4e714340f48c1dd8377e660cb28ebd716b8a
This commit is contained in:
parent
393f3907ec
commit
6e718f9e4c
2 changed files with 48 additions and 6 deletions
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
@ -34,6 +35,9 @@ namespace usb {
|
|||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
|
||||
// Set by the signal handler to destroy the thread
|
||||
volatile bool destroyThread;
|
||||
|
||||
int32_t readFile(std::string filename, std::string& contents) {
|
||||
std::ifstream file(filename);
|
||||
|
||||
|
@ -374,7 +378,7 @@ void* work(void* param) {
|
|||
goto error;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
while (!destroyThread) {
|
||||
struct epoll_event events[64];
|
||||
|
||||
nevents = epoll_wait(epoll_fd, events, 64, -1);
|
||||
|
@ -392,6 +396,7 @@ void* work(void* param) {
|
|||
}
|
||||
}
|
||||
|
||||
ALOGI("exiting worker thread");
|
||||
error:
|
||||
close(uevent_fd);
|
||||
|
||||
|
@ -401,26 +406,61 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void sighandler(int sig)
|
||||
{
|
||||
if (sig == SIGUSR1) {
|
||||
destroyThread = true;
|
||||
ALOGI("destroy set");
|
||||
return;
|
||||
}
|
||||
signal(SIGUSR1, sighandler);
|
||||
}
|
||||
|
||||
Return<void> Usb::setCallback(const sp<IUsbCallback>& callback) {
|
||||
|
||||
if (mCallback != NULL) {
|
||||
ALOGE("Callback already registered");
|
||||
pthread_mutex_lock(&mLock);
|
||||
if ((mCallback == NULL && callback == NULL) ||
|
||||
(mCallback != NULL && callback != NULL)) {
|
||||
mCallback = callback;
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return Void();
|
||||
}
|
||||
|
||||
mCallback = callback;
|
||||
ALOGI("registering callback");
|
||||
|
||||
if (pthread_create(&mPoll, NULL, work, this)) {
|
||||
ALOGE("pthread creation failed %d", errno);
|
||||
mCallback = NULL;
|
||||
if (mCallback == NULL) {
|
||||
if (!pthread_kill(mPoll, SIGUSR1)) {
|
||||
pthread_join(mPoll, NULL);
|
||||
ALOGI("pthread destroyed");
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return Void();
|
||||
}
|
||||
|
||||
destroyThread = false;
|
||||
signal(SIGUSR1, sighandler);
|
||||
|
||||
if (pthread_create(&mPoll, NULL, work, this)) {
|
||||
ALOGE("pthread creation failed %d", errno);
|
||||
mCallback = NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return Void();
|
||||
}
|
||||
|
||||
// Protects *usb assignment
|
||||
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
Usb *usb;
|
||||
|
||||
Usb::Usb() {
|
||||
pthread_mutex_lock(&lock);
|
||||
// Make this a singleton class
|
||||
assert(usb == NULL);
|
||||
usb = this;
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace usb
|
||||
|
|
|
@ -32,6 +32,7 @@ using ::android::hardware::Void;
|
|||
using ::android::sp;
|
||||
|
||||
struct Usb : public IUsb {
|
||||
Usb();
|
||||
Return<void> switchRole(const hidl_string& portName, const PortRole& role) override;
|
||||
Return<void> setCallback(const sp<IUsbCallback>& callback) override;
|
||||
Return<void> queryPortStatus() override;
|
||||
|
@ -39,6 +40,7 @@ struct Usb : public IUsb {
|
|||
sp<IUsbCallback> mCallback;
|
||||
private:
|
||||
pthread_t mPoll;
|
||||
pthread_mutex_t mLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
|
|
Loading…
Reference in a new issue