publicstaticabstractclassCallback{/**
* Called when the virtual display video projection has been
* paused by the system or when the surface has been detached
* by the application by calling setSurface(null).
* The surface will not receive any more buffers while paused.
*/publicvoidonPaused(){}/**
* Called when the virtual display video projection has been
* resumed after having been paused.
*/publicvoidonResumed(){}/**
* Called when the virtual display video projection has been
* stopped by the system. It will no longer receive frames
* and it will never be resumed. It is still the responsibility
* of the application to release() the virtual display.
*/publicvoidonStopped(){}}
// /frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java@Override// Binder callpublicintcreateVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,IVirtualDisplayCallback callback,IMediaProjection projection,String packageName){// 检查uid与包名,是否相符。finalint callingUid =Binder.getCallingUid();if(!validatePackageName(callingUid, packageName)){thrownewSecurityException("packageName must match the calling uid");}if(callback ==null){thrownewIllegalArgumentException("appToken must not be null");}if(virtualDisplayConfig ==null){thrownewIllegalArgumentException("virtualDisplayConfig must not be null");}// 拿到client端传过来的surface对象finalSurface surface = virtualDisplayConfig.getSurface();int flags = virtualDisplayConfig.getFlags();if(surface !=null&& surface.isSingleBuffered()){thrownewIllegalArgumentException("Surface can't be single-buffered");}// 下面开始针对Flag,做一些逻辑判断。if((flags &VIRTUAL_DISPLAY_FLAG_PUBLIC)!=0){
flags |=VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;// Public displays can't be allowed to show content when locked.if((flags &VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD)!=0){thrownewIllegalArgumentException("Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");}}if((flags &VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY)!=0){
flags &=~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;}if((flags &VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR)!=0){
flags &=~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;}if(projection !=null){try{if(!getProjectionService().isValidMediaProjection(projection)){thrownewSecurityException("Invalid media projection");}
flags = projection.applyVirtualDisplayFlags(flags);}catch(RemoteException e){thrownewSecurityException("unable to validate media projection or flags");}}if(callingUid !=Process.SYSTEM_UID&&(flags &VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR)!=0){if(!canProjectVideo(projection)){thrownewSecurityException("Requires CAPTURE_VIDEO_OUTPUT or "+"CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "+"MediaProjection token in order to create a screen sharing virtual "+"display.");}}if(callingUid !=Process.SYSTEM_UID&&(flags &VIRTUAL_DISPLAY_FLAG_SECURE)!=0){if(!canProjectSecureVideo(projection)){thrownewSecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "+"or an appropriate MediaProjection token to create a "+"secure virtual display.");}}if(callingUid !=Process.SYSTEM_UID&&(flags &VIRTUAL_DISPLAY_FLAG_TRUSTED)!=0){if(!checkCallingPermission(ADD_TRUSTED_DISPLAY,"createVirtualDisplay()")){EventLog.writeEvent(0x534e4554,"162627132", callingUid,"Attempt to create a trusted display without holding permission!");thrownewSecurityException("Requires ADD_TRUSTED_DISPLAY permission to "+"create a trusted virtual display.");}}if(callingUid !=Process.SYSTEM_UID&&(flags &VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP)!=0){if(!checkCallingPermission(ADD_TRUSTED_DISPLAY,"createVirtualDisplay()")){thrownewSecurityException("Requires ADD_TRUSTED_DISPLAY permission to "+"create a virtual display which is not in the default DisplayGroup.");}}if((flags &VIRTUAL_DISPLAY_FLAG_TRUSTED)==0){
flags &=~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;}// Sometimes users can have sensitive information in system decoration windows. An app// could create a virtual display with system decorations support and read the user info// from the surface.// We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS// to trusted virtual displays.finalint trustedDisplayWithSysDecorFlag =(VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS|VIRTUAL_DISPLAY_FLAG_TRUSTED);if((flags & trustedDisplayWithSysDecorFlag)==VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS&&!checkCallingPermission(INTERNAL_SYSTEM_WINDOW,"createVirtualDisplay()")){thrownewSecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");}finallong token =Binder.clearCallingIdentity();try{// 调用内部实现returncreateVirtualDisplayInternal(callback, projection, callingUid, packageName,
surface, flags, virtualDisplayConfig);}finally{Binder.restoreCallingIdentity(token);}}// /frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.javaprivateintcreateVirtualDisplayInternal(IVirtualDisplayCallback callback,IMediaProjection projection,int callingUid,String packageName,Surface surface,int flags,VirtualDisplayConfig virtualDisplayConfig){synchronized(mSyncRoot){if(mVirtualDisplayAdapter ==null){Slog.w(TAG,"Rejecting request to create private virtual display "+"because the virtual display adapter is not available.");return-1;}// 为虚拟屏创建Device(告知surfaceflinger创建Display)DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
callback, projection, callingUid, packageName, surface, flags,
virtualDisplayConfig);if(device ==null){return-1;}// 发送添加Device通知,这里比较重要
mDisplayDeviceRepo.onDisplayDeviceEvent(device,DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);// 检查Display是否创建成功finalLogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);if(display !=null){return display.getDisplayIdLocked();}// Something weird happened and the logical display was not created.Slog.w(TAG,"Rejecting request to create virtual display "+"because the logical display was not created.");
mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
mDisplayDeviceRepo.onDisplayDeviceEvent(device,DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);}return-1;}
一、迭代和进化式开发的优势 相对于顺序或“瀑布”软件开发模型,迭代和进化式开发(iterative and evolutionary development )对部分系统及早地引入了编程和测试,并重复这一循环。这种方式通常会还没有详细定义所有需求的情况下假…
今天,由云原生计算基金会 CNCF 主办的 KubeConCloudNativeConOpenSourceSummit China 2023 主论坛在上海举办。阿里云容器服务负责人易立在主论坛发表演讲,介绍阿里云为大模型提供的基础设施能力,以及通过云原生 AI 的方式助力大模型普惠提效…
文章目录 前言问题代码混淆存在的问题Java类文件加密存在的问题虚拟化保护存在的问题AOT编译存在的问题 Java应用的打包混淆器类加载与类加密Bootstrap Class LoaderExtension Class LoaderSystem Class Loader自定义ClassLoaderprotector4j 加壳采用Golang打包Java程序xjar 参…