The document records your learning process for future reference.
First, you need to know the general process of wallpaper settings: Upper-layer applications call wallpapermanager. setstream () or other interfaces to set the wallpaper. wallpapermanagerservice first copies the wallpaper to the/data/system/user/0/directory, and wallpapermanagerservice registers a wallpaperobserver for the directory, after the wallpaper is copied, wallpaperobserver is called. onevent () function, onevent () function first calls notifycallbackslocked () to trigger the callback, and then calls bindwallpapercomponentlocked () for further wallpaper replacement. Although the whole wallpaper mechanism includes data structures such as wallpapermanager, wallpaperservice, imagewallpaper, wallpapermanagerservice, globals, drawableengine, wallpaperdata, and wallpaperconnection, it is quite complicated and we should strip out its appearance, see his nature. We just need to figure out how they interact? Exchange something? I have figured out the entire wallpaper mechanism. To put it bluntly, I just need to figure out the iwallpaperservice. aidl, iwallpaperengine. aidl, iwallpaperconnection. the three files aidl are OK, because these files are the key to communication.
1. iwallpaperservice. aidl
oneway interface IWallpaperService { void attach(IWallpaperConnection connection, IBinder windowToken, int windowType, boolean isPreview, int reqWidth, int reqHeight);}The aidl language is designed for binder, so the functions in it can be seen as communication interfaces.
(1). wallpaperservice. iwallpaperservicewrapper extends iwallpaperservice. stub;
(2). wallpaperservice. onbind ()
/** * Implement to return the implementation of the internal accessibility * service interface. Subclasses should not override. */ @Override public final IBinder onBind(Intent intent) { return new IWallpaperServiceWrapper(this); }From the above two points, we can know that the binder of iwallpaperservice is in the wallpaperservice; The wallpaperservice will call the mcontext. the proxy object of iwallpaperservice is enabled in serviceconnection. onserviceconnected. It is easy to verify that wallpapermanagerservice does this.
Wallpapermanagerservice. bindwallpapercomponentlocked ():
boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force, boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) { ........ Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE); ........ WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper); intent.setComponent(componentName); intent.putExtra(Intent.EXTRA_CLIENT_LABEL, com.android.internal.R.string.wallpaper_binding_label); intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser( mContext, 0, Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER), mContext.getText(com.android.internal.R.string.chooser_wallpaper)), 0, null, new UserHandle(serviceUserId))); if (!mContext.bindServiceAsUser(intent, newConn, Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI, new UserHandle(serviceUserId))) { .......... } }At the beginning of the article, the bindwallpapercomponentlocked () function is called every time you set the wallpaper. That is to say, every time you set the wallpaper, the new wallpaperconnection and mcontext are called again. bindserviceasuser () is bound to start the wallpaperservice. Why do I need to re-bind the service every time? Why can't wallpaper be set when systemui is disabled? Remember to bind wallpaperservice once every time you set the wallpaper, and call the wallpaperconnection. onserviceconnected () function. The onserviceconnected () function actually obtains the binder proxy object of iwallpaperservice.
public void onServiceConnected(ComponentName name, IBinder service) { synchronized (mLock) { if (mWallpaper.connection == this) { mWallpaper.lastDiedTime = SystemClock.uptimeMillis(); mService = IWallpaperService.Stub.asInterface(service); attachServiceLocked(this, mWallpaper); // XXX should probably do saveSettingsLocked() later // when we have an engine, but I'm not sure about // locking there and anyway we always need to be able to // recover if there is something wrong. saveSettingsLocked(mWallpaper); } } }The mservice = iwallpaperservice. stub. asinterface (service); statement gets the binder proxy object of iwallpaperservice. Let's see what the wallpaperconnection. onserviceconnected () function calls wallpapermanagerservice. attachservicelocked?
void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) { try { conn.mService.attach(conn, conn.mToken, WindowManager.LayoutParams.TYPE_WALLPAPER, false, wallpaper.width, wallpaper.height); } catch (RemoteException e) { Slog.w(TAG, "Failed attaching wallpaper; clearing", e); if (!wallpaper.wallpaperUpdating) { bindWallpaperComponentLocked(null, false, false, wallpaper, null); } } }Well, cross-binder calls attach () on the local side of iwallpaperservice (). What does attach () do?
public void attach(IWallpaperConnection conn, IBinder windowToken, int windowType, boolean isPreview, int reqWidth, int reqHeight) { new IWallpaperEngineWrapper(mTarget, conn, windowToken, windowType, isPreview, reqWidth, reqHeight); }Directly new iwallpaperenginewrapper object. Pay attention to the passed parameters, including the wallpaper display parameters. Extends iwallpaperengine. Stub implements handlercaller. Callback, so I know that the binder of iwallpaperengine is stored locally in wallpaperservice, and the proxy returns the variables to wallpapermanagerservice. wallpaperconnection. mengine? This research should be done later. The constructor of iwallpaperenginewrapper will be called, and a handle message do_attach will be post in the constructor,
switch (message.what) { case DO_ATTACH: { try { mConnection.attachEngine(this); } catch (RemoteException e) { Log.w(TAG, "Wallpaper host disappeared", e); return; } Engine engine = onCreateEngine(); mEngine = engine; mActiveEngines.add(engine); engine.attach(this); return; }I feel more and more involved. It doesn't matter. I will analyze them one by one.
Work first, work later.
Analysis of wallpaper Mechanism