迅為RK3576開發板Android多屏顯示
迅為iTOP-3576開發板采用瑞芯微RK3576高性能、低功耗的應用處理芯片,集成了4個Cortex-A72和4個Cortex-A53核心,以及獨立的NEON協處理器。它適用于ARM PC、邊緣計算、個人移動互聯網設備及其他多媒體產品。
1.1 Android 多屏同顯
iTOP-RK3576開發板支持以下屏幕
迅為 MIPI 7 寸屏幕
標準 HDMI 屏幕(通過 HDMI 線連接)
迅為 LVDS 7 寸屏幕
迅為 LVDS 10.1 寸 1024*600 屏幕
迅為 LVDS 10.1 寸 1280*800 屏幕
然后修改Android源碼kernel-6.1/arch/arm64/boot/dts/rockchip/topeet-screen-lcds.dtsi中的
設備樹文件,如下圖所示。LVDS屏幕是MIPI通過轉接板連接顯示的,RK3576不支持LVDS
顯示接口。
我們可以根據自己的需求來修改topeet-screen-lcds.dtsi文件。總之,修改
topeet_screen_choose.dtsi的規律是:打開所連接的屏幕對應的宏定義,rk3576有三個顯示通
道vp0 vp1 vp2,所打開的宏定義對應的vp通道不能重復。默認打開對應的宏定義為多屏同顯。
如果打開的宏定義是#define LCD_TYPE_LVDS_10_1_1280x800_GT9271,需要將
kernel-6.1/arch/arm64/configs/rockchip_defconfig文件中的
CONFIG_TOUCHSCREEN_GT9271=y宏定義使能,然后再編譯源碼。
如果打開的宏定義是#define LCD_TYPE_LVDS_10_1_1024x600_GT911,需要將
kernel-6.1/arch/arm64/configs/rockchip_defconfig文件中的CONFIG_TOUCHSCREEN_GT9XX
宏定義使能,然后再編譯源碼。
1.2 Android 多屏異顯
如果要支持多屏異顯,首先要調試好雙屏或多屏都可以正常顯示,并且分別掛載在不同的
vp上,可以參考上一個小節根據自己的需求打開topeet-screen-lcds.dtsi設備樹中的宏定義。默
認開啟后,多屏顯示的是同一個畫面(如果要支持雙屏或者多屏異顯,需要應用支持異顯,才會顯示不同的內容)。查看當前的屏幕顯示狀態輸入以下命令
cat /sys/kernel/debug/dri/0/summary
如果雙屏或者多屏的顯示器分辨率比例不同,比如說主屏是16:9,副屏是4:3,那么副
屏顯示的畫面會拉伸或者縮小,原因是副屏的畫面是主屏映射過去的,所以副屏上顯示的是
主屏的分辨率。如果同樣的屏幕情況下,應用支持異顯,那么副屏會顯示實際正常的分辨率。
所以如果要支持雙屏或者多屏同顯并要求顯示正常,雙屏或者多屏的屏幕的分辨率比要一致。
1.2.1 指定主副屏
多屏異顯的實際應用中,需要指定哪個是主屏,哪個是副屏。修改Android14源碼目錄下
rk3576_android14/device/rockchip/rk3576/topeet_rk3576/topeet_rk3576.mk文件,添加如下內容:
如果要指定MIPI屏幕為主屏,HDMI屏幕為副屏,如下設置:
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=HDMI-A
如果要指定MIPI屏幕為主屏,EDP屏幕為副屏,如下設置:
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=eDP
如果需要定義多個主副屏時,需要用逗號隔開,比如指定MIPI eDP為主屏,HDMI-A為副屏,
設置如下:
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI,eDP
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=HDMI-A
1.2.2 異顯方案介紹
目前有兩種異顯方案分別是Android Presentation和Andorid Activity指定屏幕啟動。
Android Presentation,需要APP應用開發中調用相應接口使指定的view (Presentation
view是一個特殊的dialog類型view)在副屏中顯示。
Android Activity指定屏幕啟動,APP在啟動activity時可以使用display id參數在對應
的屏幕上直接顯示。
兩者主要區別在:
1前者的acitivity需要獨立開發,把需要顯示的內容投到副屏,后者可以不需要源碼,調用命令行或者系統接口把第三方app的acitivity投送到副屏;
2 .前者只有一個activity在頂層,通過特殊的dialog將指定內容顯示在副屏,后者是兩
個activity分別顯示在主副屏。
接下來我們詳細講述這倆種方法。
1.2.3 Android Presentation
本小節講解Android Presentation異顯方案,瑞芯微和迅為提供了使用Android Presentation
編寫好的APP例程,接下來進行測試。
1.2.3.1 ApiDemos APP
在Android12源碼中瑞芯微已經提供了使用Presentation接口的測試APP,在源碼
development/samples/ApiDemos目錄下,需要使用mm命令編譯APP。迅為提供了編譯好的
測試APP在網盤資料“iTOP-RK3576開發板/02_【iTOP-RK3576開發板】/07_多屏顯示配套
資料/Android/ApiDemosAPK”目錄下。
此APP源碼在Android源碼rk3576_android14/development/samples/ApiDemos目錄下,進
入此目錄,輸入“mm”命令進行編譯,如下圖所示:
然后使用adb命令安裝APP,依次點擊App->Activity->Presentation選項,即可進入
Presentation調用界面。如下圖所示:
在該界面需點擊如下副屏的checkbox選項,即可在副屏顯示相應圖片。如下所示:
副屏HDMi屏幕顯示圖片,如下所示:
1.2.3.2 Presentation sampleAPP
此APP在網盤資料“iTOP-RK3576開發板/02_【iTOP-RK3576開發板】/07_多屏顯示配
套資料/Android/Presentation-sample”目錄下,下載此APP工程,然后用Androidstudio打開,
并編譯apk。編譯成功之后,安裝APP,APP安裝成功之后如下圖所示:
打開APP如下圖所示:
點擊“顯示副屏”按鈕,會在副屏顯示,如下圖所示:
APP重要知識點講解:
隨著用戶的需求增多,特別是對于一些Android平板電腦以及其他的一些Android智能設
備可能有多個屏幕,用戶不僅想要在主屏幕上顯示內容,同樣在第二屏幕上也要顯示想要的
內容,這樣可以達到更好的體驗效果。Google也是不負眾望在Android4.2版本以后提供了
Presentation類,可以輕松實現在兩塊屏幕上同時顯示不同的內容。Presentation是一個特殊的
dialog,它的目的是顯示內容到第二屏幕。在Presentation創建的時候關聯一個目標設備,確
定Presentation要顯示在那個設備上,根據這個設備的信息來配置Presentation的context和
resources信息。目前系統提供了兩種方式來與目標顯示屏進行綁定。
1通過MediaRouter接口獲取并綁定:
選擇顯示presentation的設備最簡單的方法就是使用Media Router,media router服務持續
追蹤在系統中哪個音頻、視頻線路是可用的,當routes被選擇或者不被選擇,或者更好的顯
示presentation display的線路發生改變后media router就會發送消息。所以一些應用程序可以
自動監視這些消息來在首選設備上顯示或取消presentation。
首選顯示presentation的設備是Media Router進行推薦的,如果應用想要顯示內容在第二
屏幕上就該使用該設備。下面將給出如何使用media router在主屏的設備創建和顯示
presentation。
MediaRouter mediaRouter =(MediaRouter)
context.getSystemService(Context.MEDIA_ROUTER_SERVICE); MediaRouter.RouteInfo route =
mediaRouter.getSelectedRoute();
if(route !=null){
Display presentationDisplay = route.getPresentationDisplay();
if(presentationDisplay !=null){
Presentation presentation =newMyPresentation(context, presentationDisplay);
presentation.show();
}
}
根據上面代碼可以看出通過系統服務Media Router來選擇一個合適的route,從route中來
獲取首選的display,如果display不為空就會創建該presentation,創建完成后調用presentation
的show方法將該presentation顯示出來。
2通過DisplayManager接口獲取并綁定
另外一個獲取首選display的方法是直接使用display Manager來獲取。display manager服
務提供方法枚舉和描述系統中所有的設備,包括可以顯示presentation的設備。display manager
持續追蹤系統中所有的設備,然而,并不是所有的設備都適合顯示presentation,例如,如果
一個Activity試圖在主屏幕上顯示一個presentation,它可能會掩蓋自己的內容,這就像在
Activity上打開一個dialog一樣。
DisplayManager displayManager =(DisplayManager)
context.getSystemService(Context.DISPLAY_SERVICE); Display[] presentationDisplays
=displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
if(presentationDisplays.length >0){
// If there is more than one suitable presentation display, then we could consider
// giving the user a choice. For this example, we simply choose the first display
// which is the one the system recommends as the preferred presentation display.
Display display = presentationDisplays[1]; // displays[1]是副屏
Presentation presentation =new MyPresentation(context, presentationDisplay);
presentation.show();
}
根據上面代碼可以看出通過系統服務Display Manager來獲取所有適合顯示presentation的
display列表,如果獲取到了多個適合display對象,我們選擇副屏的display。最后顯示
presentation。
1.2.4 Android Activity 指定屏幕啟動
本小節講解Android Activity指定屏幕啟動異顯方案,瑞芯微提供了使用Android Activity
指定屏幕啟動編寫好的APP例程,接下來進行測試。
1.2.4.1 dualscreendemo APP
RK DualScreen主要區別與android presentation,在于它實現了應用的派發,允許廠商快
速根據現有的app功能,進行模塊的集成,減少開發周期和研發成本。示例代碼為
DualScreenDemo.zip工程,在網盤資料“iTOP-RK3576開發板/02_【iTOP-RK3576開發板】/07_
多屏顯示配套資料/Android/DualScreenDemo”目錄下下載。
使用Androidstudio打開此工程代碼,編譯安裝APP,安裝完成后如下所示:
打開此APP,如下所示,有三個按鈕。
第三個按鈕使用了Android Activity指定屏幕啟動,關鍵代碼如下所示,第一個和第二個
按鈕使用了Presentation。
private void showSecondByActivity(Context context){
ActivityOptions options = ActivityOptions.makeBasic();
MediaRouter mediaRouter = (MediaRouter)
context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route =
mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
if (route != null) {
Display presentationDisplay = route.getPresentationDisplay();
options.setLaunchDisplayId(presentationDisplay.getDisplayId());
Intent intent = new Intent("android.intent.action.MUSIC_PLAYER");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, options.toBundle());
}
}
在startActivity接口參數中設置指定屏幕的display id,Activity將在指定屏幕上直接啟
動顯示。
Activity的多顯示器支持需要設備支持
name="android.software.activities_on_secondary_displays" />。
同時application或者activity需要支持分屏屬性即或者標簽下設
置新的屬性android:resizeableActivity="true",這個屬性在你target到Android N后
android:resizeableActivity的默認值就是true。
ActivityOptions提供兩個新函數以支持多個顯示器,分別是setLaunchDisplayId()和
getLaunchDisplayId()。
setLaunchDisplayId()指定Activity在啟動后應顯示在哪個顯示器上。
getLaunchDisplayId()返回操作組件的當前啟動顯示器。
在上述代碼中使用MediaRouter接口獲取副屏的display id,同理也可以使用
DisplayManager接口獲取響應的display id。
1.2.5 支持輸入法在副屏顯示
修改Android14源碼下的device/rockchip/common/display_settings.xml文件,如下所示:
將設置相應屏幕shouldShowIme為true,如上配置支持輸入法在local:1的副屏上顯示。
1.2.6 副屏 DPI 設置
修改Android14源碼下的device/rockchip/common/display_settings.xml文件,如下所示:
修改forcedDensity的值可以修改副屏的屏幕密度。
1.2.7 主屏幕可以觸摸,副屏不觸摸
如果想要實現主屏可以觸摸,副屏不用觸摸的功能。有兩種解決方式:第一種是在App
應用代碼中實現。第二種需要修改framework層的源碼。
第一種方式:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
第二種方式:
修改Android14源碼frameworks/native/services/inputflinger/reader/EventHub.cpp文件,屏蔽掉device->classes |= InputDeviceClass::EXTERNAL;屬性,如下圖所示:
1.2.8 多屏異觸
多屏異觸需要指定主副屏。這里使用修改Android源碼的方式實現綁定副屏觸摸芯片。這
樣設置以后,系統開機會自動將ft5x06觸摸綁定到副屏上面去。修改文件:
frameworks/native/services/inputflinger/reader/EventHub.cpp,添加如下加紅的代碼。通過修改
EventHub.cpp文件,在isExternalDeviceLocked函數中判斷設備名稱為指定的副屏設備(比如
副屏的設備名稱是generic ft5x06 (79)),則返回true。
bool EventHub::Device::isExternalDeviceLocked() {
const char *I2C_DEVICE_NAME = "generic ft5x06 (79)";
ALOGE("input deviceis '%s' ",device->identifier.name.c_str());
if (strcmp(device->identifier.name.c_str(), I2C_DEVICE_NAME) == 0) {
return true;
}
if (configuration) {
std::optional isInternal = configuration->getBool("device.internal");
if (isInternal.has_value()) {
return !isInternal.value();
}
}
return identifier.bus == BUS_USB || identifier.bus == BUS_BLUETOOTH;
}
這里的I2C_DEVICE_NAME需要根據實際情況添加,用戶可根據ALOGE打印信息在
logcat中尋找識別到的芯片實際的名字。下面是添加了ALOGE打印信息后在logcat中得到的
設備名字的截圖:
上圖中的goodix-ts和generic ft5x06 (79)即為這里使用的觸摸IC芯片的名字,將這個復制
到代碼中即可。修改完畢,重新編譯Android鏡像,用戶測試的時候可以直接使用ApiDemo APP
進行測試。
1.2.9 鼠標異屏切換
在多屏異顯情況下,修改以下代碼使鼠標箭頭可以移動到需要的副屏上去進行操作。
我們需要修改Android14源碼中
frameworks/native/services/inputflinger/reader/mapper/CursorInputMapper.cpp文件
搜索"sys.mouse.presentation",然后將下面的代碼中0改為1。
//-----rk-code----
char mMousePresentation[PROPERTY_VALUE_MAX] = {1};
property_get("sys.mouse.presentation", mMousePresentation, "1");
if (strcmp(mMousePresentation, "1") == 0) {
if (std::optional rect = mPointerController->getBounds();
rect.has_value()) {
if(xCursorPosition==rect->left||xCursorPosition==rect->right||yCursorPosition==rect->top||yCursor
Position==rect->bottom){
mDisplayId=getPolicy()->notifyDisplayIdChanged();
}
}
}else{
mDisplayId = mPointerController->getDisplayId();
}
然后重新編譯Android源碼,然后燒寫鏡像。
1.2.10 副屏顯示配置
1.2.10.1 副屏全屏顯示
設置副屏(副屏1、副屏2等)是否全屏顯示可通過修改persist.sys.rotation.efull-n(n=1、
2、3、….)參數的取值進行配置,若配置為true則會進行全屏顯示。
現以MIPI主屏、HDMI副 屏 為 例 ,修改如下:
在device/rockchip/rk3576/topeet_rk3576/topeet_rk3576.mk文件中添加如下內容,使得
HDMI副屏可以全屏顯示(由于副屏圖像參考主屏寬高比進行縮放,若寬高比不一致,則出
現黑邊,所以默認HDMI副屏顯示會有黑邊):
PRODUCT_PROPERTY_OVERRIDES += persist.sys.rotation.efull-1=true
修改完成后,保存退出,重新編譯燒寫鏡像即可。
注:由于mipi豎屏顯示與HDMI寬高比相差較大,HDMI設置全屏顯示后拉伸較明顯!
1.2.10.2 副屏顯示方向
副屏的旋轉角度可通過persist.sys.rotation.einit-n(n=1、2、3、….)屬性控制,該屬性用
于設置副屏(副屏1、副屏2等)的顯示方向,可取值為0/1/2/3,分別表示將副屏顯示方
向旋轉(順時針)0度、90度、180度、270度。
現以MIPI主屏、HDMI副 屏 為 例 ,修改如下:
在device/rockchip/rk3576/topeet_rk3576/topeet_rk3576.mk文件中添加如下內容,使得
HDMI副屏的顯示方向旋轉90度:
PRODUCT_PROPERTY_OVERRIDES += persist.sys.rotation.einit-1=1
PRODUCT_PROPERTY_OVERRIDES += persist.sys.rotation.efull-1=false
修改完成后,保存退出,重新編譯燒寫鏡像即可,HDMI會旋轉90°豎屏顯示。
-
Android
+關注
關注
12文章
3940瀏覽量
127651 -
開發板
+關注
關注
25文章
5096瀏覽量
97825 -
rk3576
+關注
關注
1文章
54瀏覽量
155 -
迅為電子
+關注
關注
0文章
35瀏覽量
49
發布評論請先 登錄
相關推薦
評論