The flow of ActivityView trying to create the VirtualDisplayDevice

@ActivityView.java

 public ActivityView(Contextcontext, AttributeSet attrs, int defStyle) {

       super(context, attrs, defStyle);

 

       while (context instanceof ContextWrapper) {

           if (context instanceof Activity) {

                mActivity = (Activity)context;

                break;

           }

           context = ((ContextWrapper)context).getBaseContext();

       }

       if (mActivity == null) {

           throw new IllegalStateException("The ActivityView's Context is notan Activity.");

       }

 

       try {

           mActivityContainer = new ActivityContainerWrapper(

                    ActivityManagerNative.getDefault().createActivityContainer(

                           mActivity.getActivityToken(), new ActivityContainerCallback(this)));

       } catch (RemoteException e) {

            throw newRuntimeException("ActivityView: Unable to create ActivityContainer. "

                    + e);

       }

 

       mTextureView = new TextureView(context);

       mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());

       addView(mTextureView);//putthis view show on System’s device display

 

       WindowManager wm =(WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);

       mMetrics = new DisplayMetrics();

       wm.getDefaultDisplay().getMetrics(mMetrics);

 

       mLastVisibility = getVisibility();

 

       if (DEBUG) Log.v(TAG, "ctor()");

    }

@ActivityManagerNative.java

 public IActivityContainer createActivityContainer(IBinderparentActivityToken,

           IActivityContainerCallback callback) throws RemoteException {

       Parcel data = Parcel.obtain();

       Parcel reply = Parcel.obtain();

       data.writeInterfaceToken(IActivityManager.descriptor);

       data.writeStrongBinder(parentActivityToken);

       data.writeStrongBinder(callback == null ? null : callback.asBinder());

       mRemote.transact(CREATE_ACTIVITY_CONTAINER_TRANSACTION,data, reply, 0);

       reply.readException();

       final int result = reply.readInt();

       final IActivityContainer res;

       if (result == 1) {

           res = IActivityContainer.Stub.asInterface(reply.readStrongBinder());

       } else {

           res = null;

       }

       data.recycle();

       reply.recycle();

       return res;

    }

 

public abstract class ActivityManagerNative extends Binderimplements IActivityManager

{

case CREATE_ACTIVITY_CONTAINER_TRANSACTION:{

           data.enforceInterface(IActivityManager.descriptor);

           IBinder parentActivityToken = data.readStrongBinder();

           IActivityContainerCallback callback =

                   IActivityContainerCallback.Stub.asInterface(data.readStrongBinder());

           IActivityContainer activityContainer =

                    createActivityContainer(parentActivityToken,callback);

           reply.writeNoException();

           if (activityContainer != null) {

                reply.writeInt(1);

               reply.writeStrongBinder(activityContainer.asBinder());

           } else {

                reply.writeInt(0);

           }

           return true;

}

@ActivityManagerService.java

 @Override

   public IActivityContainer createActivityContainer(IBinderparentActivityToken,

           IActivityContainerCallback callback) throws RemoteException {

       enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,

               "createActivityContainer()");

       synchronized (this) {

           if (parentActivityToken == null) {

                throw newIllegalArgumentException("parent token must not be null");

           }

           ActivityRecord r = ActivityRecord.forToken(parentActivityToken);

           if (r == null) {

                return null;

           }

           if (callback == null) {

                throw newIllegalArgumentException("callback must not be null");

           }

            return mStackSupervisor.createActivityContainer(r,callback);

       }

    }

 note: after the ActivityView is shown , the funtion of  onSurfaceTextureAvailable would be called , then it would try to set up the VirtualDisplayDevice

@ActivityView.java

 public void onSurfaceTextureAvailable(SurfaceTexturesurfaceTexture, int width,

                int height) {

           

           mWidth = width;

           mHeight = height;

           attachToSurfaceWhenReady();

       }

private void attachToSurfaceWhenReady(){

       final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();

       if (surfaceTexture == null || mSurface != null) {

           // Either not ready to attach, or already attached.

           return;

       }

 

       mSurface = new Surface(surfaceTexture);

       try {

           mActivityContainer.setSurface(mSurface, mWidth, mHeight,mMetrics.densityDpi);

          //mActivityContainer  --binderto  VirtualActivityContainer

       } catch (RemoteException e) {

           mSurface.release();

           mSurface = null;

           throw new RuntimeException("ActivityView: Unable to createActivityContainer. " + e);

       }

     

    }

// class ActivityContainerextends android.app.IActivityContainer.Stub

// class VirtualActivityContainerextends ActivityContainer

public void VirtualActivityContainer::setSurface(Surface surface, int width, intheight, int density) {

           super.setSurface(surface, width, height, density);

 

           synchronized (mService) {

                final long origId =Binder.clearCallingIdentity();

                try {

                    setSurfaceLocked(surface,width, height, density);

                } finally {

                   Binder.restoreCallingIdentity(origId);

                }

           }

       }

// class ActivityContainerextends android.app.IActivityContainer.Stub

// class VirtualActivityContainerextends ActivityContainer

private void VirtualActivityContainer::setSurfaceLocked(Surface surface, int width, int height, intdensity) {

           if (mContainerState == CONTAINER_STATE_FINISHING) {

                return;

           }

           VirtualActivityDisplay virtualActivityDisplay =

                    (VirtualActivityDisplay)mActivityDisplay;

           if (virtualActivityDisplay == null) {

                virtualActivityDisplay =

                        new VirtualActivityDisplay(width,height, density);

                mActivityDisplay =virtualActivityDisplay;

               mActivityDisplays.put(virtualActivityDisplay.mDisplayId,virtualActivityDisplay);

                attachToDisplayLocked(virtualActivityDisplay);

           }

 

           if (mSurface != null) {

                mSurface.release();

           }

 

           mSurface = surface;

           if (surface != null) {

                mStack.resumeTopActivityLocked(null);

           } else {

                mContainerState =CONTAINER_STATE_NO_SURFACE;

                ((VirtualActivityDisplay)mActivityDisplay).setSurface(null);

                if (mStack.mPausingActivity ==null && mStack.mResumedActivity != null) {

                   mStack.startPausingLocked(false, true, false, false);

                }

           }

           setSurfaceIfReadyLocked();

       }

@ActivityStackSupervisor.java

 classVirtualActivityDisplay extends ActivityDisplay {

       VirtualDisplay mVirtualDisplay;

 

       VirtualActivityDisplay(int width, int height, int density) {

           DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();

           mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,

                    VIRTUAL_DISPLAY_BASE_NAME,width, height, density, null,

                   DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |

                   DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);

 

           init(mVirtualDisplay.getDisplay());

 

           mWindowManager.handleDisplayAdded(mDisplayId);

       }

@DisplayManager.java

 public VirtualDisplay createVirtualDisplay(@NonNull String name,

           int width, int height, int densityDpi, @Nullable Surface surface, int flags,

           @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {

       return createVirtualDisplay(null,

                name, width, height,densityDpi, surface, flags, callback, handler);

    }

     //thesurface parameter would be set by call setSurface(Surfacesurface, int width, int height,int density);

   /** @hide */

   public VirtualDisplay createVirtualDisplay(@NullableMediaProjection projection,

           @NonNull String name, int width, int height, int densityDpi, @NullableSurface surface,

           int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handlerhandler) {

       return mGlobal.createVirtualDisplay(mContext, projection,

                name, width, height,densityDpi, surface, flags, callback, handler);

    }

@DisplayManagerGlobal.java

public VirtualDisplay createVirtualDisplay(Context context,MediaProjection projection,

           String name, int width, int height, int densityDpi, Surface surface, int flags,

           VirtualDisplay.Callback callback, Handler handler) {

 VirtualDisplayCallback callbackWrapper = newVirtualDisplayCallback(callback, handler);

       IMediaProjection projectionToken = projection != null ?projection.getProjection() : null;

       int displayId;

       try {//private final IDisplayManager mDm;//DisplayManagerService.java

           displayId = mDm.createVirtualDisplay(callbackWrapper,projectionToken,

                    context.getPackageName(),name, width, height, densityDpi, surface,flags);

       } catch (RemoteException ex) {

           Log.e(TAG, "Could not create virtual display: " + name, ex);

           return null;

       }

       Display display = getRealDisplay(displayId);

       return new VirtualDisplay(this,display, callbackWrapper,surface);

}

@DisplayManagerService.java

 public int createVirtualDisplay(IVirtualDisplayCallbackcallback,

                IMediaProjection projection,String packageName, String name,

                int width, int height, intdensityDpi, Surface surface, int flags)

{

 return createVirtualDisplayInternal(callback,projection, callingUid,

                        packageName, name,width, height, densityDpi, surface, flags);

}

 

 

 private int createVirtualDisplayInternal(IVirtualDisplayCallbackcallback,

           IMediaProjection projection, int callingUid, String packageName,

           String name, int width, int height, int densityDpi, Surface surface, int flags)

{

 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(

                    callback, projection,callingUid, packageName,

                    name, width, height,densityDpi, surface, flags);

           if (device == null) {

                return -1;

           }

 

           handleDisplayDeviceAddedLocked(device);

           LogicalDisplay display =findLogicalDisplayForDeviceLocked(device);

           if (display != null) {

                returndisplay.getDisplayIdLocked();

           }

}

 

 

 private void registerVirtualDisplayAdapterLocked(){

       mVirtualDisplayAdapter = new VirtualDisplayAdapter(

                mSyncRoot, mContext, mHandler,mDisplayAdapterListener);

       registerDisplayAdapterLocked(mVirtualDisplayAdapter);

}

@VirtualDisplayAdapter.java

 public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallbackcallback,

           IMediaProjection projection, int ownerUid, String ownerPackageName,

           String name, int width, int height, int densityDpi, Surface surface, int flags) {

       boolean secure = (flags &DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0;

       IBinder appToken = callback.asBinder();

       IBinder displayToken = SurfaceControl.createDisplay(name,secure);

       VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken,appToken,

                ownerUid, ownerPackageName,name, width, height, densityDpi, surface, flags,

                new Callback(callback,mHandler));

 

       mVirtualDisplayDevices.put(appToken, device);

 

       try {

           if (projection != null) {

                projection.registerCallback(newMediaProjectionCallback(appToken));

           }

           appToken.linkToDeath(device, 0);

       } catch (RemoteException ex) {

           mVirtualDisplayDevices.remove(appToken);

           device.destroyLocked();

           return null;

       }

 

       // Return the display device without actually sending the eventindicating

       // that it was added.  The callerwill handle it.

       return device;

    }

 

   public VirtualDisplayDevice(IBinderdisplayToken, IBinder appToken,

                int ownerUid, StringownerPackageName,

                String name, int width, intheight, int densityDpi, Surface surface, intflags,

                Callback callback) {

           super(VirtualDisplayAdapter.this, displayToken);

           mAppToken = appToken;

           mOwnerUid = ownerUid;

           mOwnerPackageName = ownerPackageName;

           mName = name;

           mWidth = width;

           mHeight = height;

           mDensityDpi = densityDpi;

           mSurface= surface;

           mFlags = flags;

           mCallback = callback;

           mDisplayState = Display.STATE_UNKNOWN;

           mPendingChanges |= PENDING_SURFACE_CHANGE;

       }

     Please be noted that the surface marked by red, which would be used by the SurfaceFlinger  to composition.

     and after create the TextureView, it would be added by call addView(); which would make this view to be show on the device's display.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值