1. 程式人生 > >如何在android framework裡建立執行緒Thread

如何在android framework裡建立執行緒Thread

android 執行緒Thread介紹:

https://blog.csdn.net/qq_33670826/article/details/81483520

下面在安卓display裡建立執行緒為例:

diff --git a/display/display/DisplayManager.cpp b/display/display/DisplayManager.cpp
index 07cb1be..f671326 100644
--- a/display/display/DisplayManager.cpp
+++ b/display/display/DisplayManager.cpp
@@ -18,6 +18,8 @@
 #include <dirent.h>
 #include <cutils/log.h>
 #include <cutils/properties.h>
+#include <sys/epoll.h>
+#include <sys/inotify.h>
 
 #include "FbDisplay.h"
 #include "KmsDisplay.h"
@@ -65,6 +67,10 @@ DisplayManager::DisplayManager()
     mDrmMode = false;
     mDriverReady = true;
     enumKmsDisplays();
+    if (!mDriverReady) {
+        mPollFileThread = new PollFileThread(this);
+    }
+
     if (!mDrmMode) {
         enumFbDisplays();
     }
@@ -91,6 +97,9 @@ DisplayManager::~DisplayManager()
     if (mHotplugThread != NULL) {
         mHotplugThread->requestExit();
     }
+    if (mPollFileThread != NULL) {
+        mPollFileThread->requestExit();
+    }
 
     Display* display = getPhysicalDisplay(DISPLAY_PRIMARY);
     display->setVsyncEnabled(false);
@@ -210,6 +219,12 @@ void DisplayManager::setCallback(EventListener* callback)
     display->setCallback(callback);
 }
 
+EventListener* DisplayManager::getCallback()
+{
+    Mutex::Autolock _l(mLock);
+    return mListener;
+}
+
 bool DisplayManager::isOverlay(int fb)
 {
     char fb_path[HWC_PATH_LENGTH];
@@ -512,13 +527,6 @@ void DisplayManager::handleKmsHotplug()
             callback = mListener;
         }
 
-        if (!mDriverReady) {
-            enumKmsDisplays();
-            if (callback != NULL) {
-                callback->onRefresh(i);
-            }
-        }
-
         bool connected = display->connected();
         display->readConnection();
         if (display->connected() == connected) {
@@ -602,4 +610,98 @@ bool DisplayManager::HotplugThread::threadLoop()
     return true;
 }
 
+DisplayManager::PollFileThread::PollFileThread(DisplayManager *ctx)
+   : Thread(false), mCtx(ctx), mINotifyFd(-1), mINotifyWd(-1), mEpollFd(-1)
+{
+}
+
+void DisplayManager::PollFileThread::onFirstRef()
+{
+    run("HWC-Poll-Thread", android::PRIORITY_URGENT_DISPLAY);
+}
+
+int32_t DisplayManager::PollFileThread::readyToRun()
+{
+    mINotifyFd = inotify_init();
+    if (mINotifyFd < 0) {
+        ALOGE("Fail to initialize inotify fd, error:%s",strerror(errno));
+        return -1;
+    }
+
+    mINotifyWd = inotify_add_watch(mINotifyFd, DRM_DRI_PATH, IN_CREATE);
+    if (mINotifyWd < 0) {
+        ALOGE("Fail to add watch for %s,error:%s",DRM_DRI_PATH,strerror(errno));
+        close(mINotifyFd);
+        return -1;
+    }
+
+    mEpollFd = epoll_create(1);
+    if (mEpollFd == -1) {
+        ALOGE("Fail to create epoll instance, error:%s",strerror(errno));
+        inotify_rm_watch(mINotifyFd,mINotifyWd);
+        close(mINotifyFd);
+        return -1;
+    }
+    epoll_event eventItem;
+    memset(&eventItem, 0, sizeof(epoll_event));
+    eventItem.events = EPOLLIN;
+    eventItem.data.fd = mINotifyFd;
+    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
+    if (result == -1) {
+        ALOGE("Fail to add inotify to epoll instance, error:%s",strerror(errno));
+        inotify_rm_watch(mINotifyFd,mINotifyWd);
+        close(mINotifyFd);
+        close(mEpollFd);
+        return -1;
+    }
+    return 0;
+}
+
+bool DisplayManager::PollFileThread::threadLoop()
+{
+    int numEpollEvent = 0;
+    epoll_event epollItems[EPOLL_MAX_EVENTS];
+    numEpollEvent = epoll_wait(mEpollFd, epollItems, EPOLL_MAX_EVENTS, -1);
+    if (numEpollEvent <= 0) {
+        ALOGE("Fail to wait requested events,numEpollEvent:%d,error:%s",numEpollEvent,strerror(errno));
+        return true;
+    }
+
+    for (int i=0; i<numEpollEvent; i++) {
+        if (epollItems[i].events & (EPOLLERR|EPOLLHUP)) {
+            continue;
+        }
+        if (epollItems[i].events & EPOLLIN) {
+            char buf[BUFFER_SIZE];
+            int numINotifyItem = read(mINotifyFd,buf,BUFFER_SIZE);
+            if (numINotifyItem < 0) {
+                ALOGE("Fail to read from INotifyFd,error:%s",strerror(errno));
+                continue;
+            }
+
+            //Each successful read returns a buffer containing one or more of struct inotify_event
+            //The length of each inotify_event structure is sizeof(struct inotify_event)+len.
+            for (char *inotifyItemBuf = buf;inotifyItemBuf < buf+numINotifyItem;) {
+                struct inotify_event *inotifyItem = (struct inotify_event *)inotifyItemBuf;
+                if (strstr(inotifyItem->name,"card")) {
+                    //detect /dev/dri/card%d has been created
+                    mCtx->enumKmsDisplays();
+                    EventListener* callback = NULL;
+                    callback = mCtx->getCallback();
+                    if (callback != NULL) {
+                        callback->onRefresh(0);
+                    }
+                    inotify_rm_watch(mINotifyFd,mINotifyWd);
+                    close(mEpollFd);
+                    close(mINotifyFd);
+                    return false;
+                }
+                inotifyItemBuf += sizeof(struct inotify_event) + inotifyItem->len;
+            }
+        }
+    }
+
+    return true;
+}
+
 }
diff --git a/display/display/DisplayManager.h b/display/display/DisplayManager.h
index b39e1fb..26cebf8 100644
--- a/display/display/DisplayManager.h
+++ b/display/display/DisplayManager.h
@@ -22,6 +22,10 @@
 
 #include "VirtualDisplay.h"
 
+#define BUFFER_SIZE 512
+#define DRM_DRI_PATH "/dev/dri/"
+#define EPOLL_MAX_EVENTS 8
+
 #define MAX_PHYSICAL_DISPLAY 10
 #define MAX_VIRTUAL_DISPLAY  16
 
@@ -48,6 +52,7 @@ public:
     int enumFakeKmsDisplay();
     int enumKmsDisplays();
     void setCallback(EventListener* callback);
+    EventListener* getCallback();
     void handleHotplugEvent();
     void handleKmsHotplug();
 
@@ -69,6 +74,23 @@ private:
 
     sp<HotplugThread> mHotplugThread;
 
+    class PollFileThread : public Thread {
+    public:
+        PollFileThread(DisplayManager *ctx);
+
+    private:
+        virtual void onFirstRef();
+        virtual int32_t readyToRun();
+        virtual bool threadLoop();
+
+        DisplayManager *mCtx;
+        int mINotifyFd;
+        int mINotifyWd;
+        int mEpollFd;
+    };
+
+    sp<PollFileThread> mPollFileThread;
+
 private:
     static Mutex sLock;
     static DisplayManager* sInstance;