Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e718f9e authored by Badhri Jagan Sridharan's avatar Badhri Jagan Sridharan Committed by Badhri Jagan Sridharan
Browse files

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
parent 393f3907
Loading
Loading
Loading
Loading
+45 −5
Original line number Diff line number Diff line
@@ -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,24 +406,59 @@ 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 (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();
}

    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
+2 −0
Original line number Diff line number Diff line
@@ -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