Android—— 4.2 Vold掛載管理_NetlinkManager (四),androidvold
在前文Android—— 4.2 Vold掛載管理_主體構建main (一)中有結構圖表示,Vold是kernel與使用者層的一個互動管理模組,
Android—— 4.2 Vold掛載管理_VolumeManager (三)簡單介紹了核心VolumeManager的構建,這篇分析從kernel進程溝通到VolumeManager進程的關鍵:NetlinkManager
撰寫不易,轉載請註明出處:http://blog.csdn.net/jscese/article/details/38586021
一:NetlinkManager構建
依舊從/system/vold/main.cpp中的main中:
if (!(nm = NetlinkManager::Instance())) { SLOGE("Unable to create NetlinkManager"); exit(1); }; ... if (nm->start()) { SLOGE("Unable to start NetlinkManager (%s)", strerror(errno)); exit(1); }
建構函式沒幹啥,主要的構建由這個 start 函數開始
/system/vold/NetlinkManager.cpp中:
int NetlinkManager::start() { struct sockaddr_nl nladdr;//使用的 socket 結構 用於與kernel進程通訊 int sz = 64 * 1024; int on = 1; memset(&nladdr, 0, sizeof(nladdr));// 初始化 nladdr.nl_family = AF_NETLINK; nladdr.nl_pid = getpid(); nladdr.nl_groups = 0xffffffff; if ((mSock = socket(PF_NETLINK,//建立 類型為 PF_NETLINK SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) { SLOGE("Unable to create uevent socket: %s", strerror(errno)); return -1; } if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {//配置大小 SLOGE("Unable to set uevent socket SO_RECBUFFORCE option: %s", strerror(errno)); return -1; } if (setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) { SLOGE("Unable to set uevent socket SO_PASSCRED option: %s", strerror(errno)); return -1; } if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {//綁定socket地址 SLOGE("Unable to bind uevent socket: %s", strerror(errno)); return -1; } mHandler = new NetlinkHandler(mSock);//傳入建立的socket的標識構造一個NetlinkHandler執行個體 if (mHandler->start()) {//開啟socket監控 SLOGE("Unable to start NetlinkHandler: %s", strerror(errno)); return -1; } return 0;}
這裡使用的是Netlink通訊端,Netlink通訊端是用以實現使用者進程與核心進程通訊的一種特殊的處理序間通訊(IPC) ,也是網路應用程式與核心通訊的最常用的介面,結構定義:
struct sockaddr_nl {__kernel_sa_family_tnl_family;/* AF_NETLINK*/unsigned shortnl_pad;/* zero*/__u32nl_pid;/* port ID*/ __u32nl_groups;/* multicast groups mask */};
看NetlinkHandler的構造:
NetlinkHandler::NetlinkHandler(int listenerSocket) : NetlinkListener(listenerSocket) {}
跟著父類:
NetlinkListener::NetlinkListener(int socket) : SocketListener(socket, false) { mFormat = NETLINK_FORMAT_ASCII;}
這裡又是構造了一個
SockListener的執行個體,傳入了上面建立的socket標識。
接著調用的start()函數,也是最終實現在SockListener的startListener()。
繼承關係:NetlinkHandler——>NetlinkListener——>SocketListener
關於構造SockListener以及startListener()函數開啟socket監聽的實現流程在前文Android—— 4.2 Vold掛載管理_CommandListener (二)中已分析,
區別在於socket不同,而且不是正常監聽的socket,這裡的mListen為false,CommandListener的為true,不再做分析!
二:NetlinkManager實現:
當監聽到了socket事件的時候,同CommandListener一樣,調用當時SocketListener執行個體的虛函數onDataAvailable的子類中的實現,
這裡是system/core/libsysutils/src/NetlinkListener.cpp中:
bool NetlinkListener::onDataAvailable(SocketClient *cli){ int socket = cli->getSocket(); ssize_t count; uid_t uid = -1; count = TEMP_FAILURE_RETRY(uevent_kernel_multicast_uid_recv( socket, mBuffer, sizeof(mBuffer), &uid));//從socket中抽取出event的buffer if (count < 0) { if (uid > 0) LOG_EVENT_INT(65537, uid); SLOGE("recvmsg failed (%s)", strerror(errno)); return false; } NetlinkEvent *evt = new NetlinkEvent(); if (!evt->decode(mBuffer, count, mFormat)) {//交給NetlinkEent 執行個體解析buffer,儲存參數 SLOGE("Error decoding NetlinkEvent"); } else { onEvent(evt);//虛函數~傳遞evt給子類NetlinkHandler實現 } delete evt; return true;}
到NetlinkHandler.cpp中:
void NetlinkHandler::onEvent(NetlinkEvent *evt) { VolumeManager *vm = VolumeManager::Instance(); const char *subsys = evt->getSubsystem(); if (!subsys) { SLOGW("No subsystem found in netlink event"); return; } if (!strcmp(subsys, "block")) { vm->handleBlockEvent(evt);//把event事件交給VolumeManager }}
這裡真正傳遞到了VolumeManager中,實現了從kernel到vold,看下VolumeManager的handle處理:
void VolumeManager::handleBlockEvent(NetlinkEvent *evt) { const char *devpath = evt->findParam("DEVPATH"); /* Lookup a volume to handle this device */ VolumeCollection::iterator it; bool hit = false; for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {//遍曆容器中的Volume 執行個體依次傳入event if (!(*it)->handleBlockEvent(evt)) {//Volume類的虛函數,子類DirectVolume實現#ifdef NETLINK_DEBUG SLOGD("Device '%s' event handled by volume %s\n", devpath, (*it)->getLabel());#endif hit = true; break; } } if (!hit) {#ifdef NETLINK_DEBUG SLOGW("No volumes handled block event for '%s'", devpath);#endif }}
可以看到這裡用到了Android—— 4.2 Vold掛載管理_VolumeManager (三)中解析出來加入進Volume容器中的Volume。
畫了一張NetlinkManager部分大體的功能結構圖:
整個NetlinkManager部分的實現大體就是這樣,至於kernel層如果檢測到存放裝置的熱插拔髮出uevent的以及Volume的處理後續分析!
安卓版本421是真的
Android 4.2 Jelly Bean新特性
Google Now 更新
在 新的Google Now 中,它可以索引你郵件裡關於機票、訂餐、酒店、包裹、入場券等資訊,在合適的時間提醒你。不過這些功能需要使用者授權,如果你有所擔心,那麼這些新的功能對 你來說就沒有任何意義了。同時Google Now也增加了電影、音樂會、股票以及新聞的顯示。
鍵盤手勢輸入功能
如 果你使用過Swype IME又或者看過SwiftKey Flow 的視頻,相信會非常期待Android 4.2的這個新功能,使用者只要在鍵盤上滑動想要輸入單詞的每一個字母,IME就會猜測你想要的單詞。如果看到想要的單詞,只要選擇它即可。在實際測試中, 這個功能表現得非常不錯,猜測出單詞的時間比預期的要早得多。
Miracast無線視頻技術
Android 的這個Miracast技術類似於蘋果的AirPlay ,這一功能可以允許手機平板通過無線串連的的方式將裝置中的內容投放到支援Mircast的電視上。這一技術是由Wi-Fi聯盟制定,並且是一個開放標 准,可以允許任何製造商使用。但到目前為止,只有極少數的支援Miracast的裝置。當然如果這個技術被廣泛採用,Android 使用者將從中受益。
快速設定
這是另外一個Android勝過其競爭者的功能,當你單指下拉可以快速存取通知欄,包括了Wi-Fi、藍芽。顯示屏亮度、電池續航、飛航模式以及一個讓你進入完整設定的按鈕。而當你雙指下拉通知欄時將進入快速設定,對於經常調整設定的人來說,這是非常方便的。
HDR模式
這是Android 內建的相機應用裡首次帶HDR模式。HDR拍攝需要相機對同一個情境拍攝兩張或以上的照片,這些照片採用不同的曝光進行拍攝,最後拼接成單張拍攝,這樣的好處是照片的明暗部分將有更加合理的曝光。
Photo Sphere全景球面拍照功能
Photo Sphere 也是Android 專屬的功能,這是Google Maps團隊和Android 團隊一同推出的功能。Photo Sphere 不僅可以讓照片以橫向取景模式進行拍攝,還可以將上下的內容拍攝進去,最後以球面情境的方式進行展示,這將讓照片的觀看方式更加生動。同時你也可以非常輕 松的將照片分享到Google+甚至是添加到Google Maps上。
照片濾鏡
在Android 4.2中,Google 在拍照應用中增加了類似Instagram的拍照濾鏡,這些濾鏡可以讓你改變照片的色調、添加顆粒感或建立複古感覺。而這些處理都是非破壞性的編輯,應用只會產生新的圖片而不會去修改原有的照片。
全新的相機介面
相機應用的介面比以前更加簡潔,它大部分按鈕都是隱藏的,可以讓你更加專心拍攝,而且新的介面對於使用者來說也更容易操作。只要在介面上任意位置向四個斜方向進行滑動就可以預覽相應的功能。拍照後想要刪除或查看照片也很容是,只需輕輕一掃即可。
平板的多使用者支援
目前的Android,每個裝置僅支援一個帳戶。而在Android 4.2平板中多個使用者可以分享一個Android平板電腦,但使用者只能訪問自己賬戶裡的應用程式和資料。
安卓42怎擷取root許可權
Google 剛剛為 Nexus 7 發布了 Android 4.2 更新,而 Galaxy Nexus 和 Nexus 7 的使用者確處於是否升級的兩難的抉擇。但不用害怕,你仍然可以為最新更新的 Android 4.2 取得 ROOT 許可權。
本教程的方法並不難,同樣適合經驗並不豐富的使用者。
開始
為了取得 Android 4.2 的 ROOT 許可權,必須準備下面三個軟體工具:
下載 Android SDK,:Google Developers
一個定製的 Recovery 工具,如ClockworkMod (CWM) 或 Team Win Recovery Project (TWRP) ,請選擇對應裝置
SuperSU 可以從 CF-Root 下載
兩個 Recovery 工具並沒有太多不同,TWRP 更適合於觸控螢幕裝置上使用,因為按鈕比較大。CWM 同樣可用於觸摸裝置,按鈕小得多。你可以根據個人喜好來選擇。
在開始之前建議你先備份下資料,也可以直接將 SD 記憶卡的內容複寫到一個安全的地方,如雲端儲存或者電腦的硬碟。
設定階段
檔案下載完後第一步需要做的就是安裝 Android SDK,然後開啟 Android SDK Manager 然後選擇下面兩項:
Android SDK Platform-tools -- 包含所需程式以安裝 Android 4.2 Jelly Bean
Google USB Driver -- 包含 Nexus device 必須的驅動
然後你建立一個檔案夾在可從命令列輕易訪問的路徑。這裡我們假設建立的路徑是 C:\Root。
在 Android SDK 平台工具安裝的路徑中 (我這裡是 "C:\Program Files x86)\Android\android-sdk\platform-tools") 將下面四個檔案複製到 C:\Root 目錄:
adb.exe
AdbWinApi.dll
AdbWinUsbApi.dll
fastboot.exe
下面檔案也必須複製到 C:\Root 檔案夾:
CWM-SuperSU-v0.97.zip -- SuperSU 檔案
之前下載的 Recovery 工具
我使用的是三星 Google Galaxy Nexus (代碼 "maguro") ,我將使用 TWRP 這個工具,檔案名稱:"openrecovery-twrp-2.3.1.0-maguro.img".
由於裝置不同,你所複製的檔案可能會有所不同。
為了讓我們的過程順利些,可將 SuperSU 檔案重新命名為 root.zip,而 Recovery 工具檔案重新命名為 customercovery.zip。這隻是臨時處理,不過我還是保留原來的檔案名稱。
前面幾步完成後,你的 Root 檔案夾就有下面 6 個檔案:
adb.exe
AdbWinApi.dll
AdbWinUsbApi.dll
fastboot.exe
CWM-SuperSU-v0.97.zip -- SuperSU file
定製的 recovery. 我這裡是 "openrecovery-twrp-2.3.1.0-maguro.img"
到這裡,你可為 "fastboo......餘下全文>>