18b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol/*
28b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Copyright (c) 2014 Intel Corporation 
38b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
48b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Licensed under the Apache License, Version 2.0 (the "License");
58b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// you may not use this file except in compliance with the License.
68b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// You may obtain a copy of the License at
78b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
88b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//      http://www.apache.org/licenses/LICENSE-2.0
98b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Unless required by applicable law or agreed to in writing, software
118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// distributed under the License is distributed on an "AS IS" BASIS,
128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// See the License for the specific language governing permissions and
148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// limitations under the License.
158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol*/
168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <poll.h>
178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <sys/socket.h>
188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <sys/un.h>
198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <sys/queue.h>
208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <linux/netlink.h>
218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <sys/types.h>
228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <unistd.h>
238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <DrmConfig.h>
248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <HwcTrace.h>
258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <UeventObserver.h>
268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace android {
288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace intel {
298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolUeventObserver::UeventObserver()
318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    : mUeventFd(-1),
328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mExitRDFd(-1),
338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mExitWDFd(-1),
348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mListeners()
358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolUeventObserver::~UeventObserver()
398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    deinitialize();
418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool UeventObserver::initialize()
448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mListeners.clear();
468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mUeventFd != -1) {
488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return true;
498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mThread = new UeventObserverThread(this);
528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mThread.get()) {
538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to create uevent observer thread");
548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // init uevent socket
588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    struct sockaddr_nl addr;
598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // set the socket receive buffer to 64K
608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // NOTE: this is only called for once
618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int sz = 64 * 1024;
628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    memset(&addr, 0, sizeof(addr));
648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    addr.nl_family = AF_NETLINK;
658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    addr.nl_pid =  pthread_self() | getpid();
668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    addr.nl_groups = 0xffffffff;
678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mUeventFd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mUeventFd < 0) {
708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        DEINIT_AND_RETURN_FALSE("failed to create uevent socket");
718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (setsockopt(mUeventFd, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz))) {
748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        WTRACE("setsockopt() failed");
758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        //return false;
768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (bind(mUeventFd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        DEINIT_AND_RETURN_FALSE("failed to bind scoket");
808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    memset(mUeventMessage, 0, UEVENT_MSG_LEN);
848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int exitFds[2];
868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (pipe(exitFds) < 0) {
878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to make pipe");
888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        deinitialize();
898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mExitRDFd = exitFds[0];
928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mExitWDFd = exitFds[1];
938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid UeventObserver::deinitialize()
988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mUeventFd != -1) {
1008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (mExitWDFd != -1) {
1018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            close(mExitWDFd);
1028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            mExitWDFd = -1;
1038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
1048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        close(mUeventFd);
1058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mUeventFd = -1;
1068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mThread.get()) {
1098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mThread->requestExitAndWait();
1108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mThread = NULL;
1118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    while (!mListeners.isEmpty()) {
1148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        UeventListener *listener = mListeners.valueAt(0);
1158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mListeners.removeItemsAt(0);
1168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        delete listener;
1178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid UeventObserver::start()
1218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mThread.get()) {
1238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mThread->run("UeventObserver", PRIORITY_URGENT_DISPLAY);
1248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid UeventObserver::registerListener(const char *event, UeventListenerFunc func, void *data)
1298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!event || !func) {
1318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("invalid event string or listener to register");
1328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return;
1338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    String8 key(event);
1368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mListeners.indexOfKey(key) >= 0) {
1378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("listener for uevent %s exists", event);
1388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return;
1398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    UeventListener *listener = new UeventListener;
1428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!listener) {
1438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to create Uevent Listener");
1448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return;
1458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    listener->func = func;
1478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    listener->data = data;
1488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mListeners.add(key, listener);
1508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool UeventObserver::threadLoop()
1538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mUeventFd == -1) {
1558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("invalid uEvent file descriptor");
1568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
1578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    struct pollfd fds[2];
1608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int nr;
1618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    fds[0].fd = mUeventFd;
1638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    fds[0].events = POLLIN;
1648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    fds[0].revents = 0;
1658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    fds[1].fd = mExitRDFd;
1668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    fds[1].events = POLLIN;
1678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    fds[1].revents = 0;
1688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    nr = poll(fds, 2, -1);
1698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (nr > 0 && fds[0].revents == POLLIN) {
1718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        int count = recv(mUeventFd, mUeventMessage, UEVENT_MSG_LEN - 2, 0);
1728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (count > 0) {
1738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            onUevent();
1748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
1758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    } else if (fds[1].revents) {
1768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        close(mExitRDFd);
1778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mExitRDFd = -1;
1788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ITRACE("exiting wait");
1798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
1808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // always looping
1828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
1838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid UeventObserver::onUevent()
1868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    char *msg = mUeventMessage;
1888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    const char *envelope = DrmConfig::getUeventEnvelope();
1898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (strncmp(msg, envelope, strlen(envelope)) != 0)
1908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return;
1918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    msg += strlen(msg) + 1;
1938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    UeventListener *listener;
1958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    String8 key;
1968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    while (*msg) {
1978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        key = String8(msg);
1988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (mListeners.indexOfKey(key) >= 0) {
1998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            DTRACE("received Uevent: %s", msg);
2008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            listener = mListeners.valueFor(key);
2018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            if (listener) {
2028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol                listener->func(listener->data);
2038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            } else {
2048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol                ETRACE("no listener for uevent %s", msg);
2058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            }
2068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
2078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        msg += strlen(msg) + 1;
2088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
2098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
2108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace intel
2128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace android
2138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
214