【Android】圖文解密Android WallpaperManagerService

1、簡介

WallpaperManagerService,下面簡稱WPMS,是Android中與壁紙相關的一個服務,下圖是WPMS的啓動流程。
在這裏插入圖片描述
1)WPMS在SystemServer中啓動,屬於Other Service。此外,還有Bootstrap Service和Core Service。Android在啓動過程中,SystemService定義了啓動過程的六個階段,WPMS在wait for default display和lock settings ready階段之間,如下圖所示。
在這裏插入圖片描述
2)通過SystemServiceManager啓動WPMS。啓動WPMS有兩個條件,一個是系統屬性config.disable_noncore的值爲false,另一個是res中config_enableWallpaperService的屬性值爲true。
3)啓動WPMS是通過其中的Lifecycle開始的,Lifecycle繼承自SystemService。在SystemServiceManager中通過反射創建WPMS的Lifecycle對象,然後調用onStart。
4)在WPMS.Lifecycle的onStart中,創建了WPMS對象。在WPMS的構造函數中,做了許多重要的事情。第一步,加載ImageWallpaper,這個ImageWallpaper在res的config.xml中通過image_wallpaper_component屬性指定,指定的是SystemUI中的ImageWallpaper,繼承自WallpaperService。第二步,加載默認Wallpaper,這個Wallpaper通過屬性ro.config.wallpaper_component指定,或者在res的config.xml中通過default_wallpaper_component指定。第三步,取得WindowManager、PackageManager、AppOpsmanager對象。第四步,創建MyPackageMonitor,監聽Package變化。PackageMonitor,本質上是利用了Android的廣播機制。第五步,創建Wallpaper目錄,目錄與User Id相關,如/data/system/users/0,與壁紙相關的數據將來會放到這個目錄。第六步,loadSettingsLocked,加載一些持久存儲的數據,如壁紙。第七步,getWallpaperSafeLocked,多用戶相關,保證Wallpaper數據正確。最後一步,創建ColorChangedListener。
5)activity manager ready後,調用systemReady,主要是裁剪壁紙、重置壁紙,以及註冊接收User刪除、切換、關機的廣播。
6)third party apps can start後,調用switchUser,根據User切換壁紙。還會創建WallpaperObserver,主要就是堅持檢查壁紙目錄的壁紙相關文件的變化,發生變化時通知IWallpaperManagerCallback。

2、壁紙相關類

下面是壁紙相關的類。
在這裏插入圖片描述

3、壁紙相關文件

下面是壁紙相關的Android源文件。

opengl:
frameworks/base/opengl/java/android/opengl/GLWallpaperService.java

app:
frameworks/base/core/java/android/app/WallpaperManager.java
frameworks/base/core/java/android/app/WallpaperInfo.java
frameworks/base/core/java/android/app/IWallpaperManagerCallback.aidl
frameworks/base/core/java/android/app/WallpaperInfo.aidl
frameworks/base/core/java/android/app/WallpaperColors.java
frameworks/base/core/java/android/app/backup/WallpaperBackupHelper.java
frameworks/base/core/java/android/app/WallpaperColors.aidl
frameworks/base/core/java/android/app/IWallpaperManager.aidl

view:
frameworks/base/core/java/android/view/IWallpaperVisibilityListener.aidl

service:
frameworks/base/core/java/android/service/wallpaper/IWallpaperEngine.aidl
frameworks/base/core/java/android/service/wallpaper/WallpaperService.java
frameworks/base/core/java/android/service/wallpaper/IWallpaperConnection.aidl
frameworks/base/core/java/android/service/wallpaper/WallpaperSettingsActivity.java
frameworks/base/core/java/android/service/wallpaper/IWallpaperService.aidl

res:
frameworks/base/core/res/res/drawable-hdpi/perm_group_wallpaper.png
frameworks/base/core/res/res/drawable-xxxhdpi/perm_group_wallpaper.png
frameworks/base/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
frameworks/base/core/res/res/drawable-xhdpi/perm_group_wallpaper.png
frameworks/base/core/res/res/drawable-xxhdpi/perm_group_wallpaper.png
frameworks/base/core/res/res/drawable-mdpi/perm_group_wallpaper.png
frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png
frameworks/base/core/res/res/anim/wallpaper_open_enter.xml
frameworks/base/core/res/res/anim/wallpaper_enter.xml
frameworks/base/core/res/res/anim/wallpaper_exit.xml
frameworks/base/core/res/res/anim/wallpaper_close_enter.xml
frameworks/base/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml
frameworks/base/core/res/res/anim/wallpaper_intra_open_enter.xml
frameworks/base/core/res/res/anim/wallpaper_intra_close_exit.xml
frameworks/base/core/res/res/anim/wallpaper_intra_close_enter.xml
frameworks/base/core/res/res/anim/wallpaper_intra_open_exit.xml
frameworks/base/core/res/res/anim/lock_screen_wallpaper_exit.xml
frameworks/base/core/res/res/anim/wallpaper_open_exit.xml
frameworks/base/core/res/res/anim/wallpaper_close_exit.xml
frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png

server:
frameworks/base/services/core/java/com/android/server/wallpaper/IWallpaperManagerService.java
frameworks/base/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
frameworks/base/services/core/java/com/android/server/wm/WallpaperController.java
frameworks/base/services/core/java/com/android/server/wm/WallpaperVisibilityListeners.java
frameworks/base/services/core/java/com/android/server/wm/WallpaperWindowToken.java

cropper:
frameworks/base/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
frameworks/base/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml
frameworks/base/packages/WallpaperCropper/res/layout/actionbar_set_wallpaper.xml

systemui:
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
frameworks/base/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
frameworks/base/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java

backup:
frameworks/base/packages/WallpaperBackup/src/com/android/wallpaperbackup
frameworks/base/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java

live:
packages/wallpapers/LivePicker/src/com/android/wallpaper/livepicker/LiveWallpaperChange.java
packages/wallpapers/LivePicker/src/com/android/wallpaper/livepicker/LiveWallpaperPreview.java
packages/wallpapers/LivePicker/src/com/android/wallpaper/livepicker/LiveWallpaperListAdapter.java
packages/wallpapers/LivePicker/src/com/android/wallpaper/livepicker/LiveWallpaperActivity.java
packages/wallpapers/LivePicker/res/drawable-hdpi/wallpaper_picker_preview.png
packages/wallpapers/LivePicker/res/drawable-hdpi/livewallpaper_placeholder.png
packages/wallpapers/LivePicker/res/mipmap-mdpi/ic_launcher_live_wallpaper.png
packages/wallpapers/LivePicker/res/drawable-mdpi/wallpaper_picker_preview.png
packages/wallpapers/LivePicker/res/drawable-mdpi/livewallpaper_placeholder.png
packages/wallpapers/LivePicker/res/xml/wallpaper_picker_preview.xml
packages/wallpapers/LivePicker/res/mipmap-xhdpi/ic_launcher_live_wallpaper.png
packages/wallpapers/LivePicker/res/mipmap-xxhdpi/ic_launcher_live_wallpaper.png
packages/wallpapers/LivePicker/res/layout/wallpaper_target_dialog_item.xml
packages/wallpapers/LivePicker/res/layout/live_wallpaper_preview.xml
packages/wallpapers/LivePicker/res/layout/live_wallpaper_entry.xml
packages/wallpapers/LivePicker/res/layout/live_wallpaper_base.xml
packages/wallpapers/LivePicker/res/layout/set_wallpaper_action.xml
packages/wallpapers/LivePicker/res/mipmap-hdpi/ic_launcher_live_wallpaper.png
packages/wallpapers/LivePicker/android.software.live_wallpaper.xml

4、默認壁紙

默認壁紙位置:frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png
取得默認壁紙的接口在WallpaperManager.java中定義,不設置壁紙的話會使用默認壁紙。

5、壁紙設置

壁紙包括兩種類型,一種是系統壁紙(FLAG_SYSTEM),一種是鎖屏壁紙(FLAG_LOCK)。設置壁紙,可以是setBitmap,也可以是setResource,還可以是setStream,並指定壁紙類型,默認會同時設置到系統壁紙和鎖屏壁紙。另外,每個Wallpaper還對應一個Id,可以通過getWallpaperId取得。
設置壁紙需要添加權限android.Manifest.permission#SET_WALLPAPER,設置壁紙成功後會發送廣播Intent#ACTION_WALLPAPER_CHANGED。
在App中想看到壁紙,還要在AndroidManifest.xml中給App或Activity設置一個壁紙相關的Theme。

6、動態壁紙

動態壁紙需要繼承自WallpaperService,然後定義自己的Engine。動態壁紙除了動態刷新外,還可以響應點擊事件,可參照上面列出的systemui的ImageWallpaper。

7、壁紙設置流程

以setBitmap爲例,壁紙設置流程如下圖。
在這裏插入圖片描述
在設置壁紙的WallpaperSetCompletion中,用到了一個Java同步工具類CountDownLatch。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章