本發(fā)明屬于通信設(shè)備技術(shù)領(lǐng)域,涉及一種設(shè)備虛擬化技術(shù),尤其涉及一種應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法及裝置。
背景技術(shù):
Linux系統(tǒng)是一種開源電腦操作系統(tǒng)內(nèi)核,“內(nèi)核”指的是一個提供硬件抽象層、磁盤及文件系統(tǒng)控制、多任務(wù)等功能的系統(tǒng)軟件。而不同的硬件設(shè)備有各自不同的控制方法和操作邏輯,如果內(nèi)核針對每一套硬件都做一份特別的適配則會對內(nèi)核開發(fā)難度和上層應(yīng)用程序使用硬件帶來極大的困難;為了適配于大量的不同的硬件平臺,因此Linux內(nèi)核對每一個子系統(tǒng)都定義了一套標準的操作框架,不同硬件平臺廠商按照該框架來完成自己的設(shè)備驅(qū)動設(shè)計,并將驅(qū)動交給該框架統(tǒng)一管理。
為了使上層應(yīng)用進程在不同硬件平臺使用同類型設(shè)備時可以有統(tǒng)一的調(diào)用方法,在某些操作框架中,Linux自身實現(xiàn)了一個規(guī)范化的驅(qū)動,用于管理內(nèi)核中的某一類設(shè)備;該驅(qū)動向用戶層提供標準的調(diào)用接口,同時隱藏底層該設(shè)備驅(qū)動的實現(xiàn)細節(jié);底層具體硬件的設(shè)備驅(qū)動通過該驅(qū)動提供的函數(shù)向其注冊,并讓其負責(zé)控制自身的函數(shù)調(diào)用,用戶進程只需要通過規(guī)范的接口標準調(diào)用該規(guī)范化的設(shè)備驅(qū)動就能夠完成對硬件的控制,例如Linux內(nèi)核中的顯示處理框架和音頻處理框架就采用了這種方式。
音頻處理架構(gòu)為基于ALSA(Advanced Linux Sound Architecture,高級Linux聲音架構(gòu)的簡稱),該架構(gòu)主要分為兩個部分:用戶空間部分和驅(qū)動部分。用戶空間部分主要是由Google定制化裁減了ALSA LIB形成了自己獨有的tinyalsa,向用戶空間提供接口,Tinyalsa可以分為三部分,即播放實例、錄音實例和控件設(shè)置實例,Android HAL層通過調(diào)用上述實例完成播放、錄音和調(diào)控設(shè)備等操作。Tinyalsa的每一個實例都有一個完整的流程,例如播放實例的流程包括打開設(shè)備、獲取設(shè)備參數(shù)、設(shè)置參數(shù)、播放聲音等,這個完成的流程是通過架構(gòu)的驅(qū)動部分來完成的。ALSA driver處于內(nèi)核,是一個完整的設(shè)備驅(qū)向用戶空間提供(open、close、read、write、ioctl)來實現(xiàn)使用音頻設(shè)備。
在多Android系統(tǒng)同時運行但只有一個音頻設(shè)備的情況下,現(xiàn)有技術(shù)方案是將虛擬化實現(xiàn)在Framework層中,具體步驟為:APP請求使用音頻服務(wù),binder驅(qū)動截獲服務(wù)請求,binder驅(qū)動作為服務(wù)端對請求進行過濾,若通過過濾規(guī)則則為其請求Audio Finger服務(wù),否則不予響應(yīng)或者返回虛假響應(yīng)。
然而,隨著Android的音頻處理日趨多樣化,現(xiàn)有的技術(shù)方案已不適用。首先,Android在播放聲音的時候不僅會涉及到Audio Flinger還會涉及到Audio Manager,Audio Policy等服務(wù),各個服務(wù)之間還會交互,對于binder驅(qū)動來說過濾機制相當復(fù)雜,稍有不當?shù)倪^濾策略就會影響APP使用音頻服務(wù);其次,當前后臺Android系統(tǒng)發(fā)生切換的時候,無法保存前臺設(shè)備的狀態(tài)和播放進度等,當Android系統(tǒng)再次切換到前臺時,該系統(tǒng)對應(yīng)的設(shè)備狀態(tài)是未知的,不可預(yù)測的。
技術(shù)實現(xiàn)要素:
本發(fā)明的目的旨在針對上述現(xiàn)有技術(shù)中存在的問題,提供一種應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法及裝置,實現(xiàn)前后臺系統(tǒng)能夠正常使用設(shè)備,確保后臺系統(tǒng)無法操控設(shè)備,并在后臺系統(tǒng)切換到前臺時,實現(xiàn)任務(wù)的喚醒,恢復(fù)現(xiàn)場。
為了達到以上目的,本發(fā)明采用以下技術(shù)方案來實現(xiàn)。
本發(fā)明提供了一種應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法,其特征在于,步驟如下:
S1,經(jīng)Linux用戶空間接收來自當前系統(tǒng)的設(shè)備操作請求;
S2,根據(jù)操作請求,打開對應(yīng)設(shè)備;
S3,判斷當前系統(tǒng)處于前臺還是后臺,若當前系統(tǒng)處于前臺,依據(jù)操作請求,控制設(shè)備執(zhí)行操作;若當前系統(tǒng)處于后臺,將操作請求對應(yīng)的任務(wù)掛起。
上述應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法,根據(jù)操作請求,打開對應(yīng)設(shè)備包括以下分步驟:
S21,根據(jù)操作請求獲取當前任務(wù)結(jié)構(gòu)體;
S22,根據(jù)當前任務(wù)結(jié)構(gòu)體判斷當前系統(tǒng)處于前臺還是后臺;
S23,若操作請求來自前臺,搜索當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,若搜索不到則創(chuàng)建并記錄當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后記錄設(shè)備參數(shù)信息,打開對應(yīng)設(shè)備,同時將設(shè)備打開成功的消息反饋給當前系統(tǒng);
S24,若操作請求來自后臺,搜索當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,若搜索不到則創(chuàng)建并記錄當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后記錄設(shè)備參數(shù)信息,再將打開對應(yīng)設(shè)備的任務(wù)掛起。
上述應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法,步驟S3或步驟S24中,掛起具體實現(xiàn)方式為將任務(wù)對應(yīng)的進程修改為休眠狀態(tài),并利用Linux內(nèi)核調(diào)度函數(shù)將其掛起。
上述應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法,步驟S3中,通過當前任務(wù)結(jié)構(gòu)體或者記錄的與當前系統(tǒng)對應(yīng)的映射關(guān)系判斷當前系統(tǒng)處于前臺還是后臺。
上述應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法,進一步包括步驟S4,根據(jù)停止操作的請求關(guān)閉對應(yīng)設(shè)備或者執(zhí)行操作結(jié)束后關(guān)閉對應(yīng)設(shè)備,該步驟包括以下分步驟:
S41,通過當前任務(wù)結(jié)構(gòu)體或者記錄的與當前系統(tǒng)對應(yīng)的映射關(guān)系判斷當前系統(tǒng)處于前臺還是后臺;
S42,若當前系統(tǒng)處于前臺,則釋放對應(yīng)設(shè)備、清空設(shè)備狀態(tài),然后清空記錄的對應(yīng)設(shè)備參數(shù)信息;
S43,若當前系統(tǒng)處于后臺,則清空記錄的對應(yīng)設(shè)備參數(shù)信息即可。
上述應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法,其特征在于,當處于后臺的當前系統(tǒng)切換到前臺時,包括以下步驟:
K1,將來自前臺系統(tǒng)的操作請求掛起,釋放對應(yīng)設(shè)備,完成前臺系統(tǒng)到后臺系統(tǒng)的切換;
K2,根據(jù)記錄的與當前系統(tǒng)對應(yīng)的設(shè)備參數(shù)信息,重新打開設(shè)備,設(shè)置設(shè)備參數(shù)信息,然后喚醒記錄的與當前系統(tǒng)對應(yīng)的操作請求,加入任務(wù)序列,控制設(shè)備執(zhí)行操作。
本發(fā)明進一步提供了一種應(yīng)用于多系統(tǒng)的設(shè)備請求處理裝置,其特征在于,包括:
接收子裝置,用于經(jīng)Linux用戶空間接收來自當前系統(tǒng)的設(shè)備操作請求;
打開子裝置,用于根據(jù)操作請求,打開對應(yīng)設(shè)備,記錄設(shè)備參數(shù)信息;
操作子裝置,判斷當前系統(tǒng)處于前臺還是后臺,若當前系統(tǒng)處于前臺,依據(jù)操作請求,控制設(shè)備執(zhí)行操作;若當前系統(tǒng)處于后臺,將操作請求對應(yīng)的任務(wù)掛起。
打開子裝置進一步包括以下單元:
獲取單元,用于根據(jù)操作請求獲取當前任務(wù)結(jié)構(gòu)體;
第一判斷單元,用于根據(jù)當前任務(wù)結(jié)構(gòu)體判斷當前系統(tǒng)處于前臺還是后臺;
第一處理單元,若操作請求來自前臺,搜索當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,若搜索不到則創(chuàng)建并記錄當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后記錄設(shè)備參數(shù)信息,打開對應(yīng)設(shè)備,同時將設(shè)備打開成功的消息反饋給當前系統(tǒng);
第二處理單元,若操作請求來自后臺,搜索當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,若搜索不到則創(chuàng)建并記錄當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后記錄設(shè)備參數(shù)信息,再將打開對應(yīng)設(shè)備的任務(wù)掛起。
上述述應(yīng)用于多系統(tǒng)的設(shè)備請求處理裝置,進一步包括關(guān)閉子裝置,用于根據(jù)停止操作的請求或者執(zhí)行操作結(jié)束后關(guān)閉對應(yīng)設(shè)備的,該子裝置包括以下單元:
第二判斷單元,用于通過當前任務(wù)結(jié)構(gòu)體或者記錄的與當前系統(tǒng)對應(yīng)的映射關(guān)系判斷當前系統(tǒng)處于前臺還是后臺;
第一后處理單元,用于當前系統(tǒng)處于前臺時釋放對應(yīng)設(shè)備、清空設(shè)備狀態(tài),然后清空記錄的對應(yīng)設(shè)備參數(shù)信息;
第二后處理單元,用于若當前系統(tǒng)處于后臺時清空記錄的對應(yīng)設(shè)備參數(shù)信息即可。
上述述應(yīng)用于多系統(tǒng)的設(shè)備請求處理裝置,當處于后臺的當前系統(tǒng)切換到前臺時,進一步包括:
第一切換子裝置,用于將來自前臺系統(tǒng)的操作請求掛起,釋放對應(yīng)設(shè)備,完成前臺系統(tǒng)到后臺系統(tǒng)的切換;
第二切換子裝置,用于根據(jù)記錄的與當前系統(tǒng)對應(yīng)的設(shè)備參數(shù)信息,重新打開設(shè)備,設(shè)置設(shè)備參數(shù)信息,然后喚醒記錄的與當前系統(tǒng)對應(yīng)的操作請求,加入任務(wù)序列,控制設(shè)備執(zhí)行操作。
本發(fā)明提供的應(yīng)用于多系統(tǒng)的設(shè)備復(fù)用方法及裝置,具有以下至少一項有益效果:
1、由于本發(fā)明實現(xiàn)于Linux內(nèi)核,將處于后臺的系統(tǒng)對應(yīng)的任務(wù)保存并掛起,確保后臺系統(tǒng)無法操控設(shè)備,同時保證后臺切換到前臺時,能夠正常使用設(shè)備;
2、由于本發(fā)明虛擬化技術(shù)實現(xiàn)于Linux內(nèi)核,前后臺系統(tǒng)切換效率更高,且面向設(shè)備,架構(gòu)更加簡潔;
3、由于本發(fā)明請求處理方法不僅實現(xiàn)了設(shè)備復(fù)用,而且完美實現(xiàn)了設(shè)備操作的流暢性和無間斷性,避免了因前后臺系統(tǒng)切換可能引起的任務(wù)出錯等問題;
4、由于本發(fā)明采用的音頻請求處理方法實現(xiàn)于Linux內(nèi)核的ALSA驅(qū)動,具有跨平臺強、跨版本性強等特點,便于移植。
附圖說明
為了更清楚地說明本發(fā)明實施例或現(xiàn)有技術(shù)中的技術(shù)方案,以下將對實施例或現(xiàn)有技術(shù)描述中所需要使用的附圖作簡單的介紹,顯而易見地,以下描述中的附圖僅僅是本發(fā)明的一些實施例,對于本領(lǐng)域普通技術(shù)人員而言,在不付出創(chuàng)造性勞動的前提下,還可以根據(jù)這些附圖所示實施例得到其它的實施例及其附圖。
圖1為本發(fā)明實施例的應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法流程圖。
圖2為本發(fā)明實施例的打開數(shù)據(jù)處理設(shè)備流程圖。
圖3為本發(fā)明實施例的關(guān)閉對應(yīng)設(shè)備流程圖。
圖4為本發(fā)明實施例的前臺系統(tǒng)與后臺系統(tǒng)切換時序圖。
具體實施方式
以下將結(jié)合附圖對本發(fā)明各實施例的技術(shù)方案進行清楚、完整的描述,顯然,所描述實施例僅僅是本發(fā)明的一部分實施例,而不是全部的實施例?;诒景l(fā)明中的實施例,本領(lǐng)域普通技術(shù)人員在沒有做出創(chuàng)造性勞動的前提下所得到的所有其它實施例,都屬于本發(fā)明所保護的范圍。
本實施例應(yīng)用于多系統(tǒng)的設(shè)備復(fù)用方法實現(xiàn)于Linux內(nèi)核,不再面向系統(tǒng)(如手機軟件APP)實現(xiàn)虛擬化,而是在Linux內(nèi)核面向設(shè)備實現(xiàn)虛擬化。本實施例以面向音頻設(shè)備實現(xiàn)虛擬化為例,對應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法進行詳細解釋,但該解釋并不構(gòu)成對本發(fā)明的任何限定。
前面已經(jīng)介紹過,音頻設(shè)備位于音頻ALSA驅(qū)動層中。Android系統(tǒng)音頻驅(qū)動模塊簡記為ALSA driver,負責(zé)處理Android系統(tǒng)傳遞到內(nèi)核的音頻處理請求,通過讀取上層傳遞的參數(shù)和數(shù)據(jù)設(shè)置控件狀態(tài)、播放或錄音等。ALSA driver模塊包括Control設(shè)備和Pcm設(shè)備,其中Control設(shè)備是音頻控制設(shè)備(用于管理控件,即控件管理設(shè)備);Pcm設(shè)備用于播放或錄音(用于對上層傳遞的數(shù)據(jù)進行解析轉(zhuǎn)換,即數(shù)據(jù)處理設(shè)備),其下可以至少有一個substream子設(shè)備負責(zé)具體的播放或錄音任務(wù)(本實施例中假設(shè)一個Pcm設(shè)備下有一個substream子設(shè)備)。下面以針對Control設(shè)備和Pcm設(shè)備的操作請求為例,對本發(fā)明提供的實現(xiàn)與Linux內(nèi)核、應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法進行詳細解釋。
圖1示出了本實施例提供的應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法流程圖,步驟如下:
S1,經(jīng)Linux用戶空間接收來自當前系統(tǒng)的設(shè)備操作請求。
用戶通過上層系統(tǒng)(例如Android系統(tǒng))發(fā)起設(shè)備操作請求,并經(jīng)Linux用戶空間傳送至Linux內(nèi)核。
在處理應(yīng)用于多系統(tǒng)的音頻操作請求時,首先經(jīng)Linux用戶控件接收來自當前系統(tǒng)的音頻操作請求,以播放聲音為例,用戶通過上層Android系統(tǒng)發(fā)起播放請求,播放請求經(jīng)Linux用戶空間傳送至Linux內(nèi)核。
S2,根據(jù)操作請求,打開對應(yīng)設(shè)備。
當Linux內(nèi)核接收到設(shè)備操作請求以后,首先要打開對應(yīng)設(shè)備,才能對設(shè)備進行操作。對于音頻操作請求,即打開控件管理設(shè)備或/和數(shù)據(jù)處理設(shè)備。這是因為在ALSA驅(qū)動中,Pcm設(shè)備用于播放、Control設(shè)備用于設(shè)置控件狀態(tài),因此需要打開的至少其中一個設(shè)備。以播放聲音為例,首先要打開播放設(shè)備,才能將播放聲音的數(shù)據(jù)傳遞給播放設(shè)備,由播放設(shè)備播放聲音。
上述Control設(shè)備用于管理音頻控件,當Android系統(tǒng)要打開一個Pcm設(shè)備或者增減聲音之類的操作之時,首先需要保證該設(shè)備處于打開狀態(tài),然后由Control設(shè)備管理各個音頻控件的狀態(tài)(如MIX控件,MUX控件,輸入、輸出線路等),確??丶堰_到所需要求的狀態(tài),Control設(shè)備只有在內(nèi)核啟動時,才涉及打開操作,內(nèi)核啟動后Android系統(tǒng)啟動,打開control設(shè)備;Linux內(nèi)核初始化所有控件,為每個Android系統(tǒng)建立一張用于記錄所有控件狀態(tài)的控件表,并對每個控件最后一次設(shè)置的參數(shù)進行記錄(該記錄由Linux內(nèi)核在Android系統(tǒng)關(guān)閉設(shè)備或者系統(tǒng)切換時進行保存,以為現(xiàn)場恢復(fù)提供設(shè)備參數(shù))。
根據(jù)音頻操作請求,Pcm設(shè)備的打開流程如圖2所示,包括以下分步驟:
S21,根據(jù)操作請求獲取當前任務(wù)結(jié)構(gòu)體。
根據(jù)音頻操作請求進程,可以獲取當前進程的當前任務(wù)結(jié)構(gòu)體,當前任務(wù)結(jié)構(gòu)體包含指向與當前系統(tǒng)對應(yīng)容器的標識位。
例如,以打開Pcm設(shè)備的操作請求為例,其包括
struct task_struct*task=current;//獲取任務(wù)結(jié)構(gòu)體
struct nsproxy*nsproxy=task->nsproxy;//獲取當前任務(wù)對應(yīng)namespace
if(nsproxy==active_nsproxy){}//判斷容器是否處于前臺
內(nèi)核在執(zhí)行打開過程時可以根據(jù)current宏(內(nèi)核提供支持),獲取到對應(yīng)當前請求的任務(wù)結(jié)構(gòu)體指針(task_struct),通過該指針能訪問結(jié)構(gòu)體中的namespace指針,這里的namespace指針即為當前系統(tǒng)對應(yīng)容器的標識位。
S22,根據(jù)當前任務(wù)結(jié)構(gòu)體判斷當前系統(tǒng)處于前臺還是后臺。
通過當前結(jié)構(gòu)體中包含的指向與當前系統(tǒng)對應(yīng)容器的標識位可以確定當前系統(tǒng)處于前臺還是后臺。
例如,將獲取的當前結(jié)構(gòu)體中的namespace指針與前臺系統(tǒng)對應(yīng)的namespace指針進行比較則可判斷當前系統(tǒng)處于前臺還是后臺。
S23,若操作請求來自前臺,搜索當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,若搜索不到則創(chuàng)建并記錄當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后記錄設(shè)備參數(shù)信息,打開對應(yīng)設(shè)備,同時將設(shè)備打開成功的消息反饋給當前系統(tǒng)。
S24,若操作請求來自后臺,搜索當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,若搜索不到則創(chuàng)建并記錄當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后記錄設(shè)備參數(shù)信息,再將打開對應(yīng)設(shè)備的任務(wù)掛起。
步驟S23和S24的目的是根據(jù)當前系統(tǒng)處于前臺還是后臺來決定是否真實打開對應(yīng)設(shè)備。
以播放聲音為例,當Android系統(tǒng)需要播放聲音時,需要打開設(shè)備和設(shè)置相關(guān)參數(shù),不管Android系統(tǒng)來自前臺還是后臺,都需要先找到當前Android系統(tǒng)與對應(yīng)設(shè)備(這里是Pcm設(shè)備)的映射關(guān)系,然后將設(shè)備參數(shù)信息保存到相應(yīng)的位置??梢酝ㄟ^多種記錄方式(例如鏈表、HASH表)來保存映射關(guān)系。上述映射關(guān)系包括設(shè)備參數(shù)信息、當前進程對應(yīng)的任務(wù)結(jié)構(gòu)體((task_struct):current)對應(yīng)的指針、設(shè)備文件(struct file*file)結(jié)構(gòu)體指針等;所述設(shè)備參數(shù)主要包括硬件參數(shù)(hw_params)、軟件參數(shù)(sw_params)以及對應(yīng)的命名空間(namespace)指針。若找不到當前Android系統(tǒng)與Pcm設(shè)備的映射關(guān)系,則需要創(chuàng)建兩者的映射關(guān)系,并保存到鏈表等記錄方式中,然后也將設(shè)備參數(shù)信息保存到鏈表中。
若當前Android系統(tǒng)處于前臺,按照常規(guī)操作,記錄完設(shè)備參數(shù)信息后,打開Pcm設(shè)備,完成打開流程,同時將Pcm設(shè)備打開成功的消息反饋給當前Android系統(tǒng),這樣當前Android系統(tǒng)才會繼續(xù)傳遞播放聲音的數(shù)據(jù)。在打開完成之后,傳遞聲音數(shù)據(jù)之前,進一步將Android系統(tǒng)設(shè)置的設(shè)備相關(guān)參數(shù)作為設(shè)備參數(shù)信息保存到鏈表中,同時將當前設(shè)備狀態(tài)保存到相應(yīng)的設(shè)備狀態(tài)結(jié)構(gòu)體;當多個系統(tǒng)進行切換時,可以通過重設(shè)這些參數(shù)的方式來恢復(fù)設(shè)備,從而恢復(fù)設(shè)備的狀態(tài)。
若當前Android系統(tǒng)處于后臺,為了不影響前臺Android系統(tǒng)使用Pcm設(shè)備,對于當前Android系統(tǒng),記錄完設(shè)備參數(shù)信息后,將打開Pcm設(shè)備的任務(wù)掛起,這樣打開Pcm設(shè)備的任務(wù)被阻塞,直到被喚醒才能繼續(xù)播放流程。
這里的掛起操作,可以采用本領(lǐng)域披露的操作方法,本實施例采用的實現(xiàn)方式是將打開Pcm設(shè)備任務(wù)對應(yīng)的進程修改為休眠狀態(tài),并利用Linux內(nèi)核調(diào)度函數(shù)將其掛起。
S3,判斷當前系統(tǒng)處于前臺還是后臺,若當前系統(tǒng)處于前臺,依據(jù)操作請求,控制設(shè)備執(zhí)行操作;若當前系統(tǒng)處于后臺,記錄操作請求或/和將操作請求對應(yīng)的任務(wù)掛起。
本步驟的目的是根據(jù)當前系統(tǒng)處于前臺還是后臺來決定是否要依據(jù)操作請求,對設(shè)備進行操作。由于在步驟S2中可能已經(jīng)對前后臺進行過判斷,因此,本步驟中對于前后臺的判斷不一定是必須的。當步驟S2中未對前后臺系統(tǒng)進行過判斷時,則需要對前后臺系統(tǒng)進行判斷。
以播放聲音為例,就是根據(jù)當前系統(tǒng)處于前臺還是后臺決定是否需要播放聲音;前面已經(jīng)指出,首先需要將各控件設(shè)置為所需狀態(tài),才能進行相應(yīng)的操作,因此,Control設(shè)備和Pcm設(shè)備均會接收到播放聲音的操作請求(ioctl),下面對Control設(shè)備和Pcm設(shè)備對于該操作請求的處理過程進行詳細說明。
(1)對于ioctl操作請求,對Control設(shè)備的虛擬化處理過程包括以下分步驟:
L31,根據(jù)音頻操作請求,獲取當前任務(wù)結(jié)構(gòu)體。
前面已經(jīng)對當前任務(wù)結(jié)構(gòu)體進行了解釋,這里不再贅述。
L32,根據(jù)獲取當前任務(wù)結(jié)構(gòu)體判斷當前系統(tǒng)處于前臺還是后臺。
在這里,通過當前任務(wù)結(jié)構(gòu)體包含的指向與當前系統(tǒng)對應(yīng)容器的標識位,便可以確定當前系統(tǒng)處于前臺還是后臺。
L33,若當前系統(tǒng)處于前臺,依據(jù)操作請求,控制設(shè)備執(zhí)行操作;在這里具體為根據(jù)音頻操作請求控制控件管理設(shè)備設(shè)置控件狀態(tài),并更新控件狀態(tài)至控制表。
若當前系統(tǒng)處于前臺,根據(jù)播放聲音的操作請求,控制control設(shè)備設(shè)置輸入線路、MIX控件和MUX控件等,并將更新后的控件狀態(tài)保存到控件表。
L34,若當前系統(tǒng)處于后臺,僅對記錄操作請求進行記錄;在這里具體為根據(jù)音頻操作請求更新控件狀態(tài)至控制表,但不控制控件管理設(shè)備設(shè)置控件。
若當前Android系統(tǒng)處于后臺,為了不影響前臺使用控件,Control設(shè)備不能真實設(shè)置控件狀態(tài),而為了保持與上層Android系統(tǒng)保存的控件狀態(tài)一致,仍然需要更新對應(yīng)Android系統(tǒng)的控件表中對應(yīng)控件狀態(tài)。例如,若當前Android系統(tǒng)處于后臺,根據(jù)播放聲音的操作請求,更新對應(yīng)控制表中輸入線路、MIX控件和MUX控件等控件狀態(tài),但不真實操作control設(shè)備設(shè)置控件(也相當于忽略此任務(wù))。
當控件使用完畢后,再由control設(shè)備根據(jù)ioctl操作請求關(guān)閉相應(yīng)控件,這也主要是為了支持DAPM(DAPM是Dynamic Audio Power Management的縮寫,直譯過來就是動態(tài)音頻電源管理的意思,DAPM是為了使基于linux的移動設(shè)備上的音頻子系統(tǒng),在任何時候都工作在最小功耗狀態(tài)下)機制,以減少功耗。
(2)對于ioctl操作請求,對Pcm設(shè)備的虛擬化處理過程包括以下分步驟:
L31’,根據(jù)音頻操作請求,獲取當前任務(wù)結(jié)構(gòu)體。
前面已經(jīng)對當前任務(wù)結(jié)構(gòu)體進行了解釋,這里不再贅述。
L32’,根據(jù)獲取當前任務(wù)結(jié)構(gòu)體判斷當前系統(tǒng)處于前臺還是后臺。
在這里,通過當前任務(wù)結(jié)構(gòu)體包含的與當前系統(tǒng)對應(yīng)容器的標識位,便可以確定當前系統(tǒng)處于前臺還是后臺。除此之外,也可以先遍歷鏈表找出當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后根據(jù)映射關(guān)系找到設(shè)備對應(yīng)的系統(tǒng),判斷當前系統(tǒng)處于前臺系統(tǒng)還是后臺系統(tǒng)。
以播放聲音為例,本步驟對應(yīng)的即是通過ioctl流程來完成任務(wù)調(diào)度。當通過ioctl寫入數(shù)據(jù)時,用戶會傳入對應(yīng)要操作的設(shè)備文件指針(struct file*file),根據(jù)該項,遍歷打開設(shè)備過程中建立的設(shè)備鏈表找到對應(yīng)的表項,讀取表項中記錄的namespace指針,將其與前臺系統(tǒng)的namespace指針進行比較則可判斷發(fā)起“寫入數(shù)據(jù)”操作請求的Android系統(tǒng)處于前臺還是后臺。
L33’,若當前系統(tǒng)處于前臺,依據(jù)操作請求,控制設(shè)備執(zhí)行操作;在這里具體為根據(jù)音頻操作請求控制數(shù)據(jù)處理設(shè)備上層傳遞的數(shù)據(jù)進行解析轉(zhuǎn)換,執(zhí)行音頻操作。
以播放聲音為例,若處于前臺,進行正常io任務(wù)(即按操作請求控制設(shè)備執(zhí)行操作),寫入播放聲音數(shù)據(jù)、播放聲音。
L34’,若當前系統(tǒng)處于后臺,記錄操作請求并將操作請求對應(yīng)的任務(wù)掛起;在這里具體為將此次音頻操作請求記錄保存到鏈表中,并利用Linux內(nèi)核調(diào)度函數(shù)將其掛起。
以播放聲音為例,若當前Android系統(tǒng)處于后臺,由于沒有真正打開Pcm設(shè)備,就不能進行此次io任務(wù),需要將此次io任務(wù)保存到鏈表中,然后將此次io任務(wù)掛起,這里采用的是將io任務(wù)進程修改為休眠狀態(tài),再利用Linux內(nèi)核調(diào)度函數(shù)將其掛起。
當執(zhí)行完一次操作,為了不影響其它系統(tǒng)使用操作設(shè)備,需要將完成操作的設(shè)備釋放。此外,當突然接到上層系統(tǒng)的關(guān)閉設(shè)備請求時,也需要將設(shè)備關(guān)閉、釋放。
因此,上述應(yīng)用于多系統(tǒng)的設(shè)備請求處理方法進一步包括步驟S4,根據(jù)停止操作的請求關(guān)閉對應(yīng)設(shè)備或者執(zhí)行操作結(jié)束后關(guān)閉對應(yīng)設(shè)備,其流程圖如圖3所示,包括以下步驟;
S41,通過當前任務(wù)結(jié)構(gòu)體或者記錄的與當前系統(tǒng)對應(yīng)的映射關(guān)系判斷當前系統(tǒng)處于前臺還是后臺。
本步驟與步驟S3中相關(guān)部分解釋相似,這里不再贅述。
S42,若當前系統(tǒng)處于前臺,則釋放對應(yīng)設(shè)備、清空設(shè)備狀態(tài),然后清空記錄的對應(yīng)設(shè)備參數(shù)信息。
S43,若當前系統(tǒng)處于后臺,則清空記錄的對應(yīng)設(shè)備參數(shù)信息即可。
步驟S42和步驟S43的目的是根據(jù)當前系統(tǒng)處于前臺還是后臺來決定關(guān)閉設(shè)備的策略。
當當前系統(tǒng)處于前臺時,按照常規(guī)操作,釋放對應(yīng)設(shè)備、清空設(shè)備狀態(tài),然后清空記錄的對應(yīng)設(shè)備參數(shù)信息。以通過調(diào)度ioctl寫入數(shù)據(jù)為例,當數(shù)據(jù)寫完之后,就需要先釋放Pcm設(shè)備,再情況Pcm設(shè)備狀態(tài),然后清空記錄的Pcm設(shè)備參數(shù)信息。
當當前系統(tǒng)處于后臺時,由于沒有真正占用過此設(shè)備,因此只需要刪除鏈表等記錄的對應(yīng)的設(shè)備參數(shù)信息即可。以io任務(wù)為寫入數(shù)據(jù)為例,由于io任務(wù)已經(jīng)被掛起,沒有調(diào)度ioctl寫入數(shù)據(jù),此時只需要刪除鏈表等記錄記錄的Pcm設(shè)備參數(shù)信息。
前面已經(jīng)指出,Control設(shè)備是在內(nèi)核啟動時打開,其也在內(nèi)核關(guān)閉時關(guān)閉,其關(guān)閉流程采用本領(lǐng)域已經(jīng)披露的常規(guī)手段實現(xiàn),這里不再贅述。
以上是對應(yīng)用于多系統(tǒng)的基本操作請求的處理過程,當前后臺系統(tǒng)進行切換時,特別是當后臺系統(tǒng)切換到前臺時,如何實現(xiàn)現(xiàn)場的恢復(fù),接下來進行詳細說明。
當前臺系統(tǒng)與后臺系統(tǒng)進行切換時,主要涉及前臺系統(tǒng)切換到后臺系統(tǒng)和后臺系統(tǒng)切換到前臺系統(tǒng),時序圖如圖4所示,主要包括以下步驟:
K1,將來自前臺系統(tǒng)的操作請求掛起,釋放對應(yīng)設(shè)備,完成前臺系統(tǒng)到后臺系統(tǒng)的切換。
對于正在進行IO任務(wù)的音頻設(shè)備來講(例如Pcm設(shè)備),當進行前后臺切換時,需要先將來自前臺Android系統(tǒng)的操作請求掛起(掛起可以采用前面描述的方法),只有當全部IO任務(wù)都掛起后,才可以釋放前臺所占用的所有設(shè)備(如Control設(shè)備和Pcm設(shè)備),否則一旦釋放設(shè)備,而還有IO任務(wù)進行的話,會使Android系統(tǒng)崩潰。
K2,根據(jù)記錄的與當前系統(tǒng)對應(yīng)的設(shè)備參數(shù)信息,重新打開設(shè)備,設(shè)置設(shè)備參數(shù)信息,然后喚醒記錄的與當前系統(tǒng)對應(yīng)的操作請求,加入任務(wù)序列,控制設(shè)備執(zhí)行操作。
釋放設(shè)備以后,原處于后臺的系統(tǒng)先找到與該系統(tǒng)有映射關(guān)系的設(shè)備參數(shù)信息,打開相關(guān)設(shè)備,并根據(jù)記錄的設(shè)備參數(shù)信息重新對設(shè)備進行設(shè)置,使設(shè)備處于可用狀態(tài),當所有相關(guān)設(shè)備均恢復(fù)以后,調(diào)用Linux內(nèi)核調(diào)度函數(shù)喚醒之前掛起的任務(wù)(例如IO任務(wù)),則可繼續(xù)執(zhí)行之前的流程,從而恢復(fù)上下文。當執(zhí)行完操作后,也可以釋放設(shè)備,清楚記錄的設(shè)備信息,以減少設(shè)備占用。
由于是按照后臺系統(tǒng)記錄的設(shè)備參數(shù)信息和IO任務(wù)進行恢復(fù),因此當系統(tǒng)再次發(fā)生切換時,恢復(fù)后的處理過程與當初該系統(tǒng)由前臺變換為后臺時沒有區(qū)別,可以實現(xiàn)完美銜接。以播放或錄音為例,也即可以實現(xiàn)切換前的現(xiàn)場恢復(fù),不會導(dǎo)致切換回來之后,原有的播放或錄音任務(wù)因出錯終止。
本實施例還提供了一種應(yīng)用于多系統(tǒng)的設(shè)備請求處理裝置,包括:
接收子裝置,用于經(jīng)Linux用戶空間接收來自當前系統(tǒng)的設(shè)備操作請求;
打開子裝置,用于根據(jù)操作請求,打開對應(yīng)設(shè)備,記錄設(shè)備參數(shù)信息;
操作子裝置,判斷當前系統(tǒng)處于前臺還是后臺,若當前系統(tǒng)處于前臺,依據(jù)操作請求,控制設(shè)備執(zhí)行操作;若當前系統(tǒng)處于后臺,將操作請求對應(yīng)的任務(wù)掛起。
打開子裝置進一步包括以下單元:
獲取單元,用于根據(jù)操作請求獲取當前任務(wù)結(jié)構(gòu)體;
第一判斷單元,用于根據(jù)當前任務(wù)結(jié)構(gòu)體判斷當前系統(tǒng)處于前臺還是后臺;
第一處理單元,若操作請求來自前臺,搜索當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,若搜索不到則創(chuàng)建并記錄當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后記錄設(shè)備參數(shù)信息,打開對應(yīng)設(shè)備,同時將設(shè)備打開成功的消息反饋給當前系統(tǒng);
第二處理單元,若操作請求來自后臺,搜索當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,若搜索不到則創(chuàng)建并記錄當前系統(tǒng)與對應(yīng)設(shè)備的映射關(guān)系,然后記錄設(shè)備參數(shù)信息,再將打開對應(yīng)設(shè)備的任務(wù)掛起。
上述述應(yīng)用于多系統(tǒng)的設(shè)備請求處理裝置,進一步包括關(guān)閉子裝置,用于根據(jù)停止操作的請求或者執(zhí)行操作結(jié)束后關(guān)閉對應(yīng)設(shè)備的,該子裝置包括以下單元:
第二判斷單元,用于通過當前任務(wù)結(jié)構(gòu)體或者記錄的與當前系統(tǒng)對應(yīng)的映射關(guān)系判斷當前系統(tǒng)處于前臺還是后臺;
第一后處理單元,用于當前系統(tǒng)處于前臺時釋放對應(yīng)設(shè)備、清空設(shè)備狀態(tài),然后清空記錄的對應(yīng)設(shè)備參數(shù)信息;
第二后處理單元,用于若當前系統(tǒng)處于后臺時清空記錄的對應(yīng)設(shè)備參數(shù)信息即可。
上述述應(yīng)用于多系統(tǒng)的設(shè)備請求處理裝置,當處于后臺的當前系統(tǒng)切換到前臺時,進一步包括:
第一切換子裝置,用于將來自前臺系統(tǒng)的操作請求掛起,釋放對應(yīng)設(shè)備,完成前臺系統(tǒng)到后臺系統(tǒng)的切換;
第二切換子裝置,用于根據(jù)記錄的與當前系統(tǒng)對應(yīng)的設(shè)備參數(shù)信息,重新打開設(shè)備,設(shè)置設(shè)備參數(shù)信息,然后喚醒記錄的與當前系統(tǒng)對應(yīng)的操作請求,加入任務(wù)序列,控制設(shè)備執(zhí)行操作。
本領(lǐng)域的普通技術(shù)人員將會意識到,這里所述的實施例是為了幫助讀者理解本發(fā)明的原理,應(yīng)被理解為本發(fā)明的保護范圍并不局限于這樣的特別陳述和實施例。本領(lǐng)域的普通技術(shù)人員可以根據(jù)本發(fā)明公開的這些技術(shù)啟示做出各種不脫離本發(fā)明實質(zhì)的其它各種具體變形和組合,這些變形和組合仍然在本發(fā)明的保護范圍內(nèi)。