2016年7月25日 星期一

nelenkov blog

https://nelenkov.blogspot.tw/

Programming sample code

http://www.programcreek.com/
http://www.programcreek.com/java-api-examples/index.php

[轉] Binder的機制和原理

http://book.51cto.com/art/201105/265319.htm


http://wycwang.blogspot.tw/2012/09/android-surface.html

01 static sp<ISurfaceComposer> getComposerService()
02 {
03     sp<ISurfaceComposer> sc;
04     Mutex::Autolock _l(gLock);
05     if (gSurfaceManager != 0) {
06         sc = gSurfaceManager;
07     } else {
08         // release the lock while we're waiting...
09         gLock.unlock();
10 
11         sp<IBinder> binder;
12         sp<IServiceManager> sm = defaultServiceManager();
13         do {
14             binder = sm->getService(String16("SurfaceFlinger"));
15             if (binder == 0) {
16                 LOGW("SurfaceFlinger not published, waiting...");
17                 usleep(500000); // 0.5 s
18             }
19         } while(binder == 0);
20 
21         // grab the lock again for updating gSurfaceManager
22         gLock.lock();
23         if (gSurfaceManager == 0) {
24             sc = interface_cast<ISurfaceComposer>(binder);
25             gSurfaceManager = sc;
26         } else {
27             sc = gSurfaceManager;
28         }
29     }
30     return sc;
31 }
sp<IServiceManager> defaultServiceManager()Android 圖形系統使用的是 client-server 的架構, client  server 位在不同的 process,彼此之間透過 binder 通信除了 client  server, Android 另外有一個全域的 service manager 用來管理各種 service.  defaultServiceManager() 函式的功能就在獲得和 service manager 的通信管道程式代碼如下:

01 sp<IServiceManager> defaultServiceManager()
02 {
03     if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
04     {
05         AutoMutex _l(gDefaultServiceManagerLock);
06         if (gDefaultServiceManager == NULL) {
07             gDefaultServiceManager = interface_cast<IServiceManager>(
08                 ProcessState::self()->getContextObject(NULL));
09         }
10     }
11     return gDefaultServiceManager;
12 }
看來每個 process, gDefaultServiceManager 只會有一份instance. 若是 gDefaultServiceManager 尚未建立則以下程式代碼會被執行:

gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));

ProcessState::self() 函式程式代碼如下
\frameworks\base\libs\binder\ProcessState.cpp

01 sp<ProcessState> ProcessState::self()
02 {
03     if (gProcess != NULL) return gProcess;
04    
05     AutoMutex _l(gProcessMutex);
06     if (gProcess == NULL) gProcess = new ProcessState;
07     return gProcess;
08 }
 gDefaultServiceManager 一樣一個 process , gProcess 也只有一份instance, ProcessState 的建構式負責開啟binder 驅動 (/dev/binder), 並且將 binder 的記憶體空間 mapping  virtual memory space.
讀者可以自行跟一下 ProcessState 的建構式代碼.
回到
gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));

其中 調用getContextObject(NULL); 得到和 services manager 之間的 binder(此處為 BpBinder), 這裡的interface_cast 蠻關鍵的, interface_cast 是一個 template,定義如下:

01 template<typename INTERFACE>
02 inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
03 {
04     return INTERFACE::asInterface(obj);
05 }
由以上 interface_cast 的定義下面這一段程式碼

gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));

等同於
gDefaultServiceManager = IServiceManager::asInterface( const sp<IBinder>& obj);

現在關鍵來到IServiceManager:: asInterface(). 但是在 IServiceManager 這個 class 中找不到 asInterface () 函式的定義和宣告.  IServiceManager 的父類別是 IInterface, IServiceManager.h 中引用了 IInterface.h ,  IInterface.h找到了以下兩個巨集定義巨集定義中的符號 “##” 連接的意思:

01 #define DECLARE_META_INTERFACE(INTERFACE)              \
02     static const String16 descriptor;       \
03     static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \
04     virtual const String16& getInterfaceDescriptor() const;     \
05     I##INTERFACE();          \
06     virtual ~I##INTERFACE();         \

01 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                      \
02     const String16 I##INTERFACE::descriptor(NAME);                     \
03     const String16& I##INTERFACE::getInterfaceDescriptor() const {     \
04         return I##INTERFACE::descriptor;                               \
05     }                                                                  \
06     sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \ 
07     {                                                                  \
08         sp<I##INTERFACE> intr;                                         \
09         if (obj != NULL) {                                             \
10             intr = static_cast<I##INTERFACE*>(                         \
11                 obj->queryLocalInterface(                              \
12                         I##INTERFACE::descriptor).get());              \
13             if (intr == NULL) {                                        \
14                 intr = new Bp##INTERFACE(obj);                         \
15             }                                                          \
16         }                                                              \
17         return intr;                                                   \
18     }                                                                  \
19     I##INTERFACE::I##INTERFACE() { }                                   \
20     I##INTERFACE::~I##INTERFACE() { }                                  \

 IServiceManager.h , 使用到的是DECLARE_META_INTERFACE巨集如下

01 DECLARE_META_INTERFACE(ServiceManager);

巨集展開後的程式代碼:    

01 static const String16 descriptor;                              
02     static sp<IServiceManager > asInterface(const sp<IBinder>& obj);     
03     virtual const String16& getInterfaceDescriptor() const;               
04     IServiceManager ();                                          
05     virtual ~ IServiceManager ();     
 IServiceManager.cpp 則是使用到IMPLEMENT_META_INTERFACE巨集:
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
巨集展開後程式代碼如下:

01 const String16 IServiceManager::descriptor("android.os.IServiceManager");
02 const String16& IServiceManager::getInterfaceDescriptor() const {
03         return IServiceManager::descriptor;                                                       
04 }                                                                                             
05 sp<IServiceManager> IServiceManager::asInterface(const sp<IBinder>& obj)  {
06    sp<IServiceManager> intr;
07    if(obj!=NULL) {  
08      intr=static_cast<IServiceManager*>( 
09       obj->queryLocalInterface(IServiceManager::descriptor).get());
10      if (intr == NULL)   {
11        intr = new BpServiceManager(obj);
12      }
13    }
14         return intr;
15 }
16 IServiceManager::IServiceManager() { }
17 IServiceManager::~IServiceManager() { }

整個IServiceManager::asInterface()函式的關鍵是 new BpServiceManager(obj); 這一行程式代碼要注意這裡產生的是BpServiceManager 類別的物件類別BpServiceManager繼承自 IServiceManager, BpServiceManager建構式傳入的參數是 BpBinder 型態物件.提醒一下 BpBinder 型態物件 是和 service manager 之間的 IPC. BpServiceManager物件中的mRemote 就是此BpBinder物件.
回到getComposerService() 函式取得 IServiceManager 介面(BpServiceManager物件),接下來要透過BpServiceManagergetService()函式取得 SurfaceFlinger service 的資訊程式片段如下

01 binder = sm->getService(String16("SurfaceFlinger"));

關鍵在 getService() 這個函式看看程式碼:
/frameworks/base/libs/binder/IServiceManager.cpp

01 virtual sp<IBinder> getService(const String16& name) const
02     {
03         unsigned n;
04         for (n = 0; n < 5; n++){
05             sp<IBinder> svc = checkService(name);
06             if (svc != NULL) return svc;
07             LOGI("Waiting for sevice %s...\n", String8(name).string());
08             sleep(1);
09         }
10         return NULL;
11     }

調用checkService() 函式若返回為NULL,  process sleep 一秒鐘後繼續嘗試獲取最多嘗試五次這是為了防止SurfaceFlinger service 在嘗試獲取的當下還沒有啟動起來.
看看checkService()函式做了什麼:
/frameworks/base/libs/binder/IServiceManager.cpp

01 virtual sp<IBinder> checkService( const String16& name) const
02 {
03    Parcel data, reply;
04    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
05    data.writeString16(name);
06    remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
07    return reply.readStrongBinder();
08 }

宣告兩個Parcel 變數data, reply, 分別做為binder傳送和接收時的資料容器使用接下來

01 data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
02 data.writeString16(name);

這兩行代碼等效於

01 data.writeInterfaceToken("android.os.IServiceManager");
02 data.writeString16("SurfaceFlinger");

binder 通信是另一個精彩的主題這邊只要先理解成 client 透過 service manager 取得了和 surface flinger 之間的通信管道.

2016年7月14日 星期四

[轉] Windows雙系統完整移除Ubuntu

Easeus Partition Master Home 請至 http://www.partition-tool.com/personal.htm 下載
基本的Partition概念

開始:
1.下載mbrfix.zip,解壓縮可得mbrfix.exe mbrfix64.exe 及 mbrfix.htm3個檔案
2.打開命令列(開始->執行->cmd.exe),並移動到該目錄底下

注意,在開啟cmd.exe時必須要用管理員(Administrator)權限
mbr1 
指令表
mbr2 

3.開始修復磁區,找到安裝windows分區所在的硬碟
mbr3 
像我只有 drive 0 所以我知道Windows就該從drive 0開機 (注意,跟partition沒有關係)
如果有第二顆硬碟,那有可能是drive 1,第3個drive 2以此類推

4.在命令列中鍵入 mbrfix.exe /drive 0 fixmbr 如
mbr4 

註:這個版本是只能修復Win XP的,如果要修復Win 7或Vista
請下載最新版本 並鍵入
mbrfix.exe /drive 0 fixmbr /win7

mbrfix.exe /drive 0 fixmbr /vista
5.重新開機
6.利用Easeus Partition Master Home 把Linux(或其他)分區移除(詳細教學)