Android之WMS篇(六)壁纸窗口的添加和移除过程

对于WMS来说壁纸他也是一个窗口,它也有WindowToken和WindowState,不过壁纸的WindowToken是WallpaperWindowToken.
切换壁纸的场景:
(1)开机的时候由SystemServer设置壁纸

07-28 21:05:04.311   565   565 I Gary    : java.lang.Exception
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.bindWallpaperComponentLocked(WallpaperManagerService.java:3052)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.initializeFallbackWallpaper(WallpaperManagerService.java:3679)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.loadSettingsLocked(WallpaperManagerService.java:3582)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.initialize(WallpaperManagerService.java:1761)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.systemReady(WallpaperManagerService.java:1781)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.onBootPhase(WallpaperManagerService.java:1887)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService$Lifecycle.onBootPhase(WallpaperManagerService.java:178)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServiceManager.startBootPhase(SystemServiceManager.java:294)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer.lambda$startOtherServices$5$com-android-server-SystemServer(SystemServer.java:2804)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer$$ExternalSyntheticLambda7.run(Unknown Source:30)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:8141)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2801)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer.run(SystemServer.java:939)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer.main(SystemServer.java:649)
07-28 21:05:04.311   565   565 I Gary    : 	at java.lang.reflect.Method.invoke(Native Method)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-28 21:05:04.311   565   565 I Gary    : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)

(2)在多用户的场景下切换用户时设置壁纸

07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.bindWallpaperComponentLocked(WallpaperManagerService.java:3052)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.switchWallpaper(WallpaperManagerService.java:2016)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.switchUser(WallpaperManagerService.java:1996)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.onBootPhase(WallpaperManagerService.java:1889)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService$Lifecycle.onBootPhase(WallpaperManagerService.java:178)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.SystemServiceManager.startBootPhase(SystemServiceManager.java:294)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.SystemServer.lambda$startOtherServices$5$com-android-server-SystemServer(SystemServer.java:2928)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.SystemServer$$ExternalSyntheticLambda7.run(Unknown Source:30)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:8141)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2801)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.SystemServer.run(SystemServer.java:939)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.server.SystemServer.main(SystemServer.java:649)
07-28 21:05:04.729   565   565 I Gary    : 	at java.lang.reflect.Method.invoke(Native Method)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-28 21:05:04.729   565   565 I Gary    : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)

(3)在Gallary或者三方应用中通过WallpaperManager设置壁纸

07-28 21:05:29.641   565   603 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.bindWallpaperComponentLocked(WallpaperManagerService.java:3052)
07-28 21:05:29.641   565   603 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService$WallpaperObserver.onEvent(WallpaperManagerService.java:330)
07-28 21:05:29.641   565   603 I Gary    : 	at android.os.FileObserver$ObserverThread.onEvent(FileObserver.java:166)
07-28 21:05:29.641   565   603 I Gary    : 	at android.os.FileObserver$ObserverThread.observe(Native Method)
07-28 21:05:29.641   565   603 I Gary    : 	at android.os.FileObserver$ObserverThread.run(FileObserver.java:116)

这些场景最后都会调用到WallpaperMangaerService中的bindWallpaperComponentLocked方法从这里开机壁纸窗口在窗口层级树的操作

1.WallpaperManagerServeice启动时做的初始化操作
1.1.在systemReady阶段初始化FallbackWallpaper

	Line  8060: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.bindWallpaperComponentLocked(WallpaperManagerService.java:3052)
	Line  8061: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.initializeFallbackWallpaper(WallpaperManagerService.java:3679)
	Line  8062: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.loadSettingsLocked(WallpaperManagerService.java:3582)
	Line  8063: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.initialize(WallpaperManagerService.java:1761)
	Line  8064: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.systemReady(WallpaperManagerService.java:1781)
	Line  8065: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService.onBootPhase(WallpaperManagerService.java:1887)
	Line  8066: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.wallpaper.WallpaperManagerService$Lifecycle.onBootPhase(WallpaperManagerService.java:178)
	Line  8067: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServiceManager.startBootPhase(SystemServiceManager.java:294)
	Line  8068: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer.lambda$startOtherServices$5$com-android-server-SystemServer(SystemServer.java:2804)
	Line  8069: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer$$ExternalSyntheticLambda7.run(Unknown Source:30)
	Line  8070: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:8141)
	Line  8071: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2801)
	Line  8072: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer.run(SystemServer.java:939)
	Line  8073: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.server.SystemServer.main(SystemServer.java:649)
	Line  8074: 07-28 21:05:04.311   565   565 I Gary    : 	at java.lang.reflect.Method.invoke(Native Method)
	Line  8075: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
	Line  8076: 07-28 21:05:04.311   565   565 I Gary    : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)

在initializeFallbackWallpaper初始化mFallbackWallpaper

    private void initializeFallbackWallpaper() {
        if (mFallbackWallpaper == null) {
            if (DEBUG) Slog.d(TAG, "Initialize fallback wallpaper");
            final int systemUserId = UserHandle.USER_SYSTEM;
            mFallbackWallpaper = new WallpaperData(systemUserId, getWallpaperDir(systemUserId),
                    WALLPAPER, WALLPAPER_CROP);
            mFallbackWallpaper.allowBackup = false;
            mFallbackWallpaper.wallpaperId = makeWallpaperIdLocked();
            bindWallpaperComponentLocked(mImageWallpaper, true, false, mFallbackWallpaper, null);
        }
    }
   File getWallpaperDir(int userId) {
        return Environment.getUserSystemDirectory(userId);
    }
   WallpaperData(int userId, File wallpaperDir, String inputFileName, String cropFileName) {
            this.userId = userId;
            wallpaperFile = new File(wallpaperDir, inputFileName);
            cropFile = new File(wallpaperDir, cropFileName);
        }

-rw------- 1 system system 3218091 2024-07-28 21:05 wallpaper
-rwx------ 1 system system 3218091 2024-07-28 21:05 wallpaper_orig

这几个方法结合在一起看WallpaperData的构造方法中其实就是在/data/system/users/0创建了wallpaper和wallpaper_orig两个文件

1.2.通过WallpaperObserver监听这两个文件

 void switchUser(int userId, IRemoteCallback reply) {
    //省略代码
        try {
            final WallpaperData systemWallpaper;
            final WallpaperData lockWallpaper;
            synchronized (mLock) {
                //省略代码
                // Not started watching yet, in case wallpaper data was loaded for other reasons.
                if (systemWallpaper.wallpaperObserver == null) {
                    systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
                    systemWallpaper.wallpaperObserver.startWatching();
                }
                switchWallpaper(systemWallpaper, reply);
            }
            //省略代码
        } finally {
            t.traceEnd();
        }
    }

只要wallpaper和wallpaper_orig两个文件发生变化WallpaperObserver就会调用到onEvent,在onEvent方法中就会走到bindWallpaperComponentLocked方法中

2.bindWallpaperComponentLocked方法中跨进程到WallpaperService中

    boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
            boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) {
      //省略代码
        try {
            if (componentName == null) {
                componentName = mDefaultWallpaperComponent;
                if (componentName == null) {
                    // Fall back to static image wallpaper
                    componentName = mImageWallpaper;
                    //clearWallpaperComponentLocked();
                    //return;
                    if (DEBUG_LIVE) Slog.v(TAG, "No default component; using image wallpaper");
                }
            }
            //省略代码

            WallpaperInfo wi = null;

            Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
            // Bind the service!
            if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
            final int componentUid = mIPackageManager.getPackageUid(componentName.getPackageName(),
                    MATCH_DIRECT_BOOT_AUTO, wallpaper.userId);
            WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper, componentUid);
            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)),
                    PendingIntent.FLAG_IMMUTABLE, null, new UserHandle(serviceUserId)));
            //绑定壁纸服务
            if (!mContext.bindServiceAsUser(intent, newConn,
                    Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI
                            | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
                            | Context.BIND_INCLUDE_CAPABILITIES,
                    new UserHandle(serviceUserId))) {
                String msg = "Unable to bind service: "
                        + componentName;
                if (fromUser) {
                    throw new IllegalArgumentException(msg);
                }
                Slog.w(TAG, msg);
                return false;
            }
            //移除前一张壁纸的WallpaperWindowToken,WindowState和SurfaceControl
            if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null
                    && !wallpaper.equals(mFallbackWallpaper)) {
                detachWallpaperLocked(mLastWallpaper);
            }
            wallpaper.wallpaperComponent = componentName;
            wallpaper.connection = newConn;
            newConn.mReply = reply;
            if (wallpaper.userId == mCurrentUserId && !wallpaper.equals(mFallbackWallpaper)) {
                mLastWallpaper = wallpaper;
            }
            updateFallbackConnection();
        } catch (RemoteException e) {
            //省略代码
        }
        return true;
    }

2.1.如果配置了DefaultWallpaperComponent,下面就会绑定该服务,如果没有配置,下文就绑定SystemUI中的ImageWallpaper,它是
WallpaperService的一个子类
2.2.绑定壁纸服务,绑定壁纸服务的时候传递WallpaperConnection

  class WallpaperConnection extends IWallpaperConnection.Stub
            implements ServiceConnection {
            //省略代码
            }

从这里可以看出WallpaperConnection他也是一个Binder Service的服务端,WallpaperService绑定成功做就会调用到WallpaperConnection的onServiceConnected方法

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            synchronized (mLock) {
                if (mWallpaper.connection == this) {
                    mService = IWallpaperService.Stub.asInterface(service);
                    attachServiceLocked(this, mWallpaper);
               		//省略代码
                }
            }
        }
  private void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
        conn.forEachDisplayConnector(connector-> connector.connectLocked(conn, wallpaper));
    }
    void connectLocked(WallpaperConnection connection, WallpaperData wallpaper) {
              //省略代码
                if (DEBUG) Slog.v(TAG, "Adding window token: " + mToken);
                mWindowManagerInternal.addWindowToken(mToken, TYPE_WALLPAPER, mDisplayId,
                        null /* options */);
                final DisplayData wpdData = getDisplayDataOrCreate(mDisplayId);
                try {
                    connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false,
                            wpdData.mWidth, wpdData.mHeight,
                            wpdData.mPadding, mDisplayId);
                } catch (RemoteException e) {
                   //省略代码
                }
            }

mService就是WallpaperSerivce在WallpaperManagerSerivce端的代理了,通过它就可以跨进程调用WallpaperService的方法
2.2.1.添加壁纸的WindowToken

 @Override
    public void addWindowToken(@NonNull IBinder binder, int type, int displayId,
            @Nullable Bundle options) {
    		//省略代码
        synchronized (mGlobalLock) {
        		//省略代码
            if (type == TYPE_WALLPAPER) {
                new WallpaperWindowToken(this, binder, true, dc,
                        true /* ownerCanManageAppTokens */, options);
            } else {
              //省略代码
            }
        }
    }

addWindowToken的时传进来的type是TYPE_WALLPAPER,所有这里创建的是WallpaperWindowToken,最后该WindowToken会挂载层级结构树的第一层上
2.2.2.跨进程调用到WallpaperService类中的attach方法
这里有一点需要注意

public abstract class WallpaperService extends Service {
		//省略代码
      }

WallpaperService 它只是一个普通的Service,它并没有继承IwallpaperService.Stub,这里一定会觉得很奇怪,其实是由WallpaperService的内部类IWallpaperServiceWrapper继承了IwallpaperService.Stub

  class IWallpaperServiceWrapper extends IWallpaperService.Stub {
		//省略代码
		}

所以bindWallpaperComponentLocked方法中绑定是IWallpaperServiceWrapper ,所以这里调用的attach方法是IWallpaperServiceWrapper 中的attach方法

    @Override
        public void attach(IWallpaperConnection conn, IBinder windowToken,
                int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding,
                int displayId) {
            mEngineWrapper = new IWallpaperEngineWrapper(mTarget, conn, windowToken,
                    windowType, isPreview, reqWidth, reqHeight, padding, displayId);
        }
IWallpaperEngineWrapper(WallpaperService context,
                IWallpaperConnection conn, IBinder windowToken,
                int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding,
                int displayId) {
            //省略代码
            Message msg = mCaller.obtainMessage(DO_ATTACH);
            mCaller.sendMessage(msg);
        }
   @Override
        public void executeMessage(Message message) {
         	 //省略代码
            switch (message.what) {
                case DO_ATTACH: {
                    Engine engine = onCreateEngine();
                    mEngine = engine;
                    try {
                        mConnection.attachEngine(this, mDisplayId);
                    } catch (RemoteException e) {
                        engine.detach();
                        Log.w(TAG, "Wallpaper host disappeared", e);
                        return;
                    }
                    mActiveEngines.add(engine);
                    engine.attach(this);
                    return;
                }
       				//省略代码
                } break;
               //省略代码
            }
        }
    }

最终会调用到Engine类中的attach方法

void attach(IWallpaperEngineWrapper wrapper) {
            //省略代码
            updateSurface(false, false, false);
        }
 void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
       		//省略代码
        
            if (forceRelayout || creating || surfaceCreating || formatChanged || sizeChanged
                    || typeChanged || flagsChanged || redrawNeeded
                    || !mIWallpaperEngine.mShownReported) {
							//省略代码
                try {
                    
                    mLayout.flags = mWindowFlags
                            | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                            | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

             				//省略代码
                    mLayout.token = mWindowToken;//这里的mWindowToken是跨进程调用的时候传过来的

                    if (!mCreated) {
                   		//省略代码
                        InputChannel inputChannel = new InputChannel();

                        if (mSession.addToDisplay(mWindow, mLayout, View.VISIBLE,
                                mDisplay.getDisplayId(), mRequestedVisibilities, inputChannel,
                                mInsetsState, mTempControls) < 0) {
                            Log.w(TAG, "Failed to add window while updating wallpaper surface.");
                            return;
                        }
                       //省略代码
                    }

                   //省略代码
                    if (LOCAL_LAYOUT) {
                        //省略代码
                    } else {
                        relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight,
                                View.VISIBLE, 0, mWinFrames, mMergedConfiguration,
                                mSurfaceControl, mInsetsState, mTempControls, mSyncSeqIdBundle);
                    }

									//省略代码
                    if (mSurfaceControl.isValid()) {
                        if (mBbqSurfaceControl == null) {
                            mBbqSurfaceControl = new SurfaceControl.Builder()
                                    .setName("Wallpaper BBQ wrapper")
                                    .setHidden(false)
                                    // TODO(b/192291754)
                                    .setMetadata(METADATA_WINDOW_TYPE, TYPE_WALLPAPER)
                                    .setBLASTLayer()
                                    .setParent(mSurfaceControl)
                                    .setCallsite("Wallpaper#relayout")
                                    .build();
                        }
                       //省略代码
                    }
                   //省略代码
                   
                    try {
                 			//省略代码
                    } finally {
                        //省略代码
                        if (redrawNeeded) {
                            //省略代码
                            mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
                                                   Integer.MAX_VALUE);
                            //省略代码
                        }
                       //省略代码
                    }
                } catch (RemoteException ex) {
                }
                //省略代码
            }
        }

updateSurface方法中就会把Wallpaper的WindowState挂载到WallpaperWindowToken上,这里还是熟悉的套路
2.2.2.1.调用addToDisplay创建一个Wallpaper窗口的WindowState挂载到WallpaperWindowToken
2.2.2.2.调用relayout方法创建一个WindowSurfaceController并计算出Wallpaper窗口摆放的位置
2.2.2.3.这里需要注意一般的Window只需要一个WindowSurfaceController用于绘制,但是壁纸这里并没有直接在WindowSurfaceController上进行绘制,而是创建了一个“Wallpaper BBQ wrapper”的Buffer类型的SurfaceControl进行绘制
2.2.2.4.调用finishDrawing完成绘制工作并提交给SurfaceFlinger.
到这里壁纸窗口i添加的流程就结束了
方法调用图
在这里插入图片描述

3.壁纸窗口移除的过程
这里说的壁纸窗口移除指的是在壁纸切换的过程中,旧壁纸窗口移除的过程,这个移除的也是在bindWallpaperComponentLocked方法进行的

boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
            boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) {
       //省略代码
        try {
      			//省略代码
            if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null
                    && !wallpaper.equals(mFallbackWallpaper)) {
                detachWallpaperLocked(mLastWallpaper);
            }
           //省略代码
        } catch (RemoteException e) {
            //省略代码
        }
        return true;
    }
       private void detachWallpaperLocked(WallpaperData wallpaper) {
        if (wallpaper.connection != null) {
           //省略代码
            try {
                // It can be null if user switching happens before service connection.
                if (wallpaper.connection.mService != null) {
                    wallpaper.connection.mService.detach();
                }
            } catch (RemoteException e) {
               //省略代码
            }
           //省略代码
            wallpaper.connection.forEachDisplayConnector(
                    WallpaperConnection.DisplayConnector::disconnectLocked);
            //省略代码
        }
    }

3.1.跨进程调用到WallpaperService中去

    void detach() {
            if (mDestroyed) {
                return;
            }

            AnimationHandler.removeRequestor(this);

            mDestroyed = true;

            if (mIWallpaperEngine.mDisplayManager != null) {
                mIWallpaperEngine.mDisplayManager.unregisterDisplayListener(mDisplayListener);
            }

            if (mVisible) {
                mVisible = false;
                if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
                onVisibilityChanged(false);
            }

            reportSurfaceDestroyed();

            if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
            onDestroy();

            if (mCreated) {
                try {
                    if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
                            + mSurfaceHolder.getSurface() + " of: " + this);

                    if (mInputEventReceiver != null) {
                        mInputEventReceiver.dispose();
                        mInputEventReceiver = null;
                    }
					//移除掉窗口的windowState
                    mSession.remove(mWindow);
                } catch (RemoteException e) {
                }
                mSurfaceHolder.mSurface.release();
                if (mBlastBufferQueue != null) {
                    mBlastBufferQueue.destroy();
                    mBlastBufferQueue = null;
                }
                //移除掉mBbqSurfaceControl 
                if (mBbqSurfaceControl != null) {
                    new SurfaceControl.Transaction().remove(mBbqSurfaceControl).apply();
                    mBbqSurfaceControl = null;
                }
                mCreated = false;
            }
        }

3.1.1.移除掉窗口的windowState
3.1.2.移除掉mBbqSurfaceControl
3.2.从窗口层级树中移除掉前一个壁纸的WallpaperWindowToken.

 void disconnectLocked() {
                if (DEBUG) Slog.v(TAG, "Removing window token: " + mToken);
                mWindowManagerInternal.removeWindowToken(mToken, false/* removeWindows */,
                        mDisplayId);
                try {
                    if (mEngine != null) {
                        mEngine.destroy();
                    }
                } catch (RemoteException e) {
                }
                mEngine = null;
            }

方法调用图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值