Android 镜像模式和扩展模式区别探讨-Android14
Android 镜像模式和扩展模式区别探讨
- 1、区分镜像模式和扩展模式
- 1.1 扩展屏是否有显示内容
- 1.2 镜像模式显示条件
- 2、镜像模式界面
同屏显示和异屏显示探讨
DisplayManagerService启动及主屏添加-Android13
Android主副屏显示-Android14
1、区分镜像模式和扩展模式
LogicalDisplay.java#mHasContent
当前LogicalDisplay是否有内容显示
DisplayContent.java#mLastHasContent
当前DisplayContent是否有内容显示
Android14上默认扩展屏没有显示内容mHasContent=false
,扩展屏显示的是主屏DEFAULT_DISPLAY
镜像
1.1 扩展屏是否有显示内容
ActivityOptions副屏启动 有Activity启动到扩展屏上,就表示扩展屏上有显示内容,即
mHasContent=true
LogicalDisplay.java#mHasContent
是由DisplayContent.java#mLastHasContent
设置下去的,就是mTmpApplySurfaceChangesTransactionState.displayHasContent
RootWindowContainer.java
界面刷新时,在mApplySurfaceChangesTransaction
中同步,forAllWindows(mApplySurfaceChangesTransaction, true)
当扩展屏没有界面mChildren
就会返回false
。RootWindowContainer.java#handleNotObscuredLocked
有界面时,界面对应DisplayContent
是主屏isDefaultDisplay
就为displayHasContent = true;
,而扩展屏界面对应的DisplayContent
判断主屏不是屏保和锁屏(!mObscureApplicationContentOnSecondaryDisplays
)、或者 扩展屏是解锁状态(displayContent.isKeyguardAlwaysUnlocked()
,默认无Display.FLAG_ALWAYS_UNLOCKED
标志,是未解锁状态,该条件为false
)、或者 界面覆盖且为TYPE_KEYGUARD_DIALOG
类型((obscured && type == TYPE_KEYGUARD_DIALOG)
),某个条件满足就为displayHasContent = true;
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java#applySurfaceChangesTransaction
mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
if (!inTransition() && !mDisplayRotation.isRotatingSeamlessly()) {mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,mLastHasContent,mTmpApplySurfaceChangesTransactionState.preferredRefreshRate,mTmpApplySurfaceChangesTransactionState.preferredModeId,mTmpApplySurfaceChangesTransactionState.preferredMinRefreshRate,mTmpApplySurfaceChangesTransactionState.preferredMaxRefreshRate,mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing,mTmpApplySurfaceChangesTransactionState.disableHdrConversion,true /* inTraversal, must call performTraversalInTrans... below */);
}
private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;final boolean obscuredChanged = w.mObscured !=mTmpApplySurfaceChangesTransactionState.obscured;final RootWindowContainer root = mWmService.mRoot;// Update effect.w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured;if (!mTmpApplySurfaceChangesTransactionState.obscured) {final boolean isDisplayed = w.isDisplayed();if (isDisplayed && w.isObscuringDisplay()) {// This window completely covers everything behind it, so we want to leave all// of them as undimmed (for performance reasons).mObscuringWindow = w;mTmpApplySurfaceChangesTransactionState.obscured = true;}final boolean displayHasContent = root.handleNotObscuredLocked(w,mTmpApplySurfaceChangesTransactionState.obscured,mTmpApplySurfaceChangesTransactionState.syswin);if (!mTmpApplySurfaceChangesTransactionState.displayHasContent&& !getDisplayPolicy().isWindowExcludedFromContent(w)) {mTmpApplySurfaceChangesTransactionState.displayHasContent |= displayHasContent;}if (w.mHasSurface && isDisplayed) {if ((w.mAttrs.flags & FLAG_KEEP_SCREEN_ON) != 0) {mTmpHoldScreenWindow = w;} else if (w == mLastWakeLockHoldingWindow) {ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,"handleNotObscuredLocked: %s was holding screen wakelock but no longer "+ "has FLAG_KEEP_SCREEN_ON!!! called by%s",w, Debug.getCallers(10));}final int type = w.mAttrs.type;if (type == TYPE_SYSTEM_DIALOG|| type == TYPE_SYSTEM_ERROR|| (type == TYPE_NOTIFICATION_SHADE&& mWmService.mPolicy.isKeyguardShowing())) {mTmpApplySurfaceChangesTransactionState.syswin = true;}if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0&& w.mAttrs.preferredRefreshRate != 0) {mTmpApplySurfaceChangesTransactionState.preferredRefreshRate= w.mAttrs.preferredRefreshRate;}mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing|= w.mAttrs.preferMinimalPostProcessing;mTmpApplySurfaceChangesTransactionState.disableHdrConversion|= !(w.mAttrs.isHdrConversionEnabled());final int preferredModeId = getDisplayPolicy().getRefreshRatePolicy().getPreferredModeId(w);if (w.getWindowingMode() != WINDOWING_MODE_PINNED&& mTmpApplySurfaceChangesTransactionState.preferredModeId == 0&& preferredModeId != 0) {mTmpApplySurfaceChangesTransactionState.preferredModeId = preferredModeId;}final float preferredMinRefreshRate = getDisplayPolicy().getRefreshRatePolicy().getPreferredMinRefreshRate(w);if (mTmpApplySurfaceChangesTransactionState.preferredMinRefreshRate == 0&& preferredMinRefreshRate != 0) {mTmpApplySurfaceChangesTransactionState.preferredMinRefreshRate =preferredMinRefreshRate;}final float preferredMaxRefreshRate = getDisplayPolicy().getRefreshRatePolicy().getPreferredMaxRefreshRate(w);if (mTmpApplySurfaceChangesTransactionState.preferredMaxRefreshRate == 0&& preferredMaxRefreshRate != 0) {mTmpApplySurfaceChangesTransactionState.preferredMaxRefreshRate =preferredMaxRefreshRate;}}}if (obscuredChanged && w.isVisible() && mWallpaperController.isWallpaperTarget(w)) {// This is the wallpaper target and its obscured state changed... make sure the// current wallpaper's visibility has been updated accordingly.mWallpaperController.updateWallpaperVisibility();}w.handleWindowMovedIfNeeded();final WindowStateAnimator winAnimator = w.mWinAnimator;//Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");w.resetContentChanged();// Moved from updateWindowsAndWallpaperLocked().if (w.mHasSurface) {// Take care of the window being ready to display.final boolean committed = winAnimator.commitFinishDrawingLocked();if (isDefaultDisplay && committed) {if (w.hasWallpaper()) {ProtoLog.v(WM_DEBUG_WALLPAPER,"First draw done in potential wallpaper target %s", w);mWallpaperMayChange = true;pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;if (DEBUG_LAYOUT_REPEATS) {surfacePlacer.debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",pendingLayoutChanges);}}}}final ActivityRecord activity = w.mActivityRecord;if (activity != null && activity.isVisibleRequested()) {activity.updateLetterboxSurface(w);final boolean updateAllDrawn = activity.updateDrawnWindowStates(w);if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(activity)) {mTmpUpdateAllDrawn.add(activity);}}w.updateResizingWindowIfNeeded();
};
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java#handleNotObscuredLocked
boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {final WindowManager.LayoutParams attrs = w.mAttrs;final int attrFlags = attrs.flags;final boolean onScreen = w.isOnScreen();final boolean canBeSeen = w.isDisplayed();final int privateflags = attrs.privateFlags;boolean displayHasContent = false;ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,"handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w"+ ".isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d",w, w.mHasSurface, onScreen, w.isDisplayed(), w.mAttrs.userActivityTimeout);if (w.mHasSurface && onScreen) {if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {mUserActivityTimeout = w.mAttrs.userActivityTimeout;ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "mUserActivityTimeout set to %d",mUserActivityTimeout);}}if (w.mHasSurface && canBeSeen) {if (!syswin && w.mAttrs.screenBrightness >= 0&& Float.isNaN(mScreenBrightnessOverride)) {mScreenBrightnessOverride = w.mAttrs.screenBrightness;}final int type = attrs.type;// This function assumes that the contents of the default display are processed first// before secondary displays.final DisplayContent displayContent = w.getDisplayContent();if (displayContent != null && displayContent.isDefaultDisplay) {// While a dream or keyguard is showing, obscure ordinary application content on// secondary displays (by forcibly enabling mirroring unless there is other content// we want to show) but still allow opaque keyguard dialogs to be shown.if (w.isDreamWindow() || mWmService.mPolicy.isKeyguardShowing()) {mObscureApplicationContentOnSecondaryDisplays = true;}displayHasContent = true;} else if (displayContent != null &&(!mObscureApplicationContentOnSecondaryDisplays|| displayContent.isKeyguardAlwaysUnlocked()|| (obscured && type == TYPE_KEYGUARD_DIALOG))) {// Allow full screen keyguard presentation dialogs to be seen, or simply ignore the// keyguard if this display is always unlocked.displayHasContent = true;}if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {mSustainedPerformanceModeCurrent = true;}}return displayHasContent;
}
1.2 镜像模式显示条件
Android14上默认扩展屏没有显示内容
mHasContent=false
,扩展屏显示的是主屏DEFAULT_DISPLAY
镜像。其实还有两个条件。
- 扩展屏信息
getDisplayDeviceInfoLocked
的flag没有DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY
- 扩展屏是否可以显示镜像
displayDevice.isWindowManagerMirroringLocked()
,如果为false
,则SurfaceFlinger
不会在此显示器上执行层镜像,该方法目前Android14
返回就是false
固定值。- 当
mContentRecorder.updateRecording()
更新镜像时,如果扩展屏有内容mDisplayContent.getLastHasContent()
或者扩展屏时关闭状态mDisplayContent.getDisplayInfo().state == Display.STATE_OFF
,就会停止镜像pauseRecording()
。
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
void updateRecording() {if (mContentRecorder == null || !mContentRecorder.isContentRecordingSessionSet()) {if (!setDisplayMirroring()) {return;}}mContentRecorder.updateRecording();
}boolean setDisplayMirroring() {int mirrorDisplayId = mWmService.mDisplayManagerInternal.getDisplayIdToMirror(mDisplayId);if (mirrorDisplayId == INVALID_DISPLAY) {return false;}if (mirrorDisplayId == mDisplayId) {if (mDisplayId != DEFAULT_DISPLAY) {ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,"Content Recording: Attempting to mirror self on %d", mirrorDisplayId);}return false;}// This is very unlikely, and probably impossible, but if the current display is// DEFAULT_DISPLAY and the displayId to mirror results in an invalid display, we don't want// to mirror the DEFAULT_DISPLAY so instead we just returnDisplayContent mirrorDc = mRootWindowContainer.getDisplayContentOrCreate(mirrorDisplayId);if (mirrorDc == null && mDisplayId == DEFAULT_DISPLAY) {ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,"Content Recording: Found no matching mirror display for id=%d for "+ "DEFAULT_DISPLAY. Nothing to mirror.",mirrorDisplayId);return false;}if (mirrorDc == null) {mirrorDc = mRootWindowContainer.getDefaultDisplay();ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,"Content Recording: Attempting to mirror %d from %d but no DisplayContent "+ "associated. Changing to mirror default display.",mirrorDisplayId, mDisplayId);}// Create a session for mirroring the display content to this virtual display.ContentRecordingSession session = ContentRecordingSession.createDisplaySession(mirrorDc.getDisplayId()).setVirtualDisplayId(mDisplayId);setContentRecordingSession(session);ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,"Content Recording: Successfully created a ContentRecordingSession for "+ "displayId=%d to mirror content from displayId=%d",mDisplayId, mirrorDisplayId);return true;
}
frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public int getDisplayIdToMirror(int displayId) {synchronized (mSyncRoot) {final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);if (display == null) {return Display.INVALID_DISPLAY;}final DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();final boolean ownContent = (displayDevice.getDisplayDeviceInfoLocked().flags& DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;// If the display has enabled mirroring, but specified that it will be managed by// WindowManager, return an invalid display id. This is to ensure we don't// accidentally select the display id to mirror based on DM logic and instead allow// the caller to specify what area to mirror.if (ownContent || displayDevice.isWindowManagerMirroringLocked()) {return Display.INVALID_DISPLAY;}int displayIdToMirror = displayDevice.getDisplayIdToMirrorLocked();LogicalDisplay displayToMirror = mLogicalDisplayMapper.getDisplayLocked(displayIdToMirror);// If the displayId for the requested mirror doesn't exist, fallback to mirroring// default display.if (displayToMirror == null) {displayIdToMirror = Display.DEFAULT_DISPLAY;}return displayIdToMirror;}
}
frameworks/base/services/core/java/com/android/server/wm/ContentRecorder.java
/*** Start recording if this DisplayContent no longer has content. Pause recording if it now* has content or the display is not on.*/
@VisibleForTesting void updateRecording() {if (isCurrentlyRecording() && (mDisplayContent.getLastHasContent()|| mDisplayContent.getDisplayInfo().state == Display.STATE_OFF)) {pauseRecording();} else {// Display no longer has content, or now has a surface to write to, so try to start// recording.startRecordingIfNeeded();}
}
2、镜像模式界面
- 创建镜像
SurfaceControl
:mRecordedSurface = SurfaceControl.mirrorSurface(mRecordedWindowContainer.getSurfaceControl())
- 创建镜像
SurfaceControl
对应的Transaction
:SurfaceControl.Transaction transaction = mDisplayContent.mWmService.mTransactionFactory.get().reparent(mRecordedSurface, mDisplayContent.getSurfaceControl()).reparent(mDisplayContent.getWindowingLayer(), null).reparent(mDisplayContent.getOverlayLayer(), null);
- 根据主屏和扩展屏大小处理:
mRecordedWindowContainer.getBounds()
,surfaceSize
,updateMirroredSurface
frameworks/base/services/core/java/com/android/server/wm/ContentRecorder.java
/*** Start recording to this DisplayContent if it does not have its own content. Captures the* content of a WindowContainer indicated by a WindowToken. If unable to start recording, falls* back to original MediaProjection approach.*/
private void startRecordingIfNeeded() {// Only record if this display does not have its own content, is not recording already,// and if this display is on (it has a surface to write output to).if (mDisplayContent.getLastHasContent() || isCurrentlyRecording()|| mDisplayContent.getDisplayInfo().state == Display.STATE_OFF|| mContentRecordingSession == null) {return;}if (mContentRecordingSession.isWaitingForConsent()) {ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, "Content Recording: waiting to record, so do "+ "nothing");return;}mRecordedWindowContainer = retrieveRecordedWindowContainer();if (mRecordedWindowContainer == null) {// Either the token is missing, or the window associated with the token is missing.// Error has already been handled, so just leave.return;}final Point surfaceSize = fetchSurfaceSizeIfPresent();if (surfaceSize == null) {ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,"Content Recording: Unable to start recording for display %d since the "+ "surface is not available.",mDisplayContent.getDisplayId());return;}ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,"Content Recording: Display %d has no content and is on, so start recording for "+ "state %d",mDisplayContent.getDisplayId(), mDisplayContent.getDisplayInfo().state);// TODO(b/274790702): Do not start recording if waiting for consent - for now,// go ahead.// Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture.mRecordedSurface = SurfaceControl.mirrorSurface(mRecordedWindowContainer.getSurfaceControl());SurfaceControl.Transaction transaction =mDisplayContent.mWmService.mTransactionFactory.get()// Set the mMirroredSurface's parent to the root SurfaceControl for this// DisplayContent. This brings the new mirrored hierarchy under this// DisplayContent,// so SurfaceControl will write the layers of this hierarchy to the// output surface// provided by the app..reparent(mRecordedSurface, mDisplayContent.getSurfaceControl())// Reparent the SurfaceControl of this DisplayContent to null, to prevent// content// being added to it. This ensures that no app launched explicitly on the// VirtualDisplay will show up as part of the mirrored content..reparent(mDisplayContent.getWindowingLayer(), null).reparent(mDisplayContent.getOverlayLayer(), null);// Retrieve the size of the DisplayArea to mirror.updateMirroredSurface(transaction, mRecordedWindowContainer.getBounds(), surfaceSize);// Notify the client about the visibility of the mirrored region, now that we have begun// capture.if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {mMediaProjectionManager.notifyActiveProjectionCapturedContentVisibilityChanged(mRecordedWindowContainer.asTask().isVisibleRequested());} else {int currentDisplayState =mRecordedWindowContainer.asDisplayContent().getDisplayInfo().state;mMediaProjectionManager.notifyActiveProjectionCapturedContentVisibilityChanged(currentDisplayState != DISPLAY_STATE_OFF);}// No need to clean up. In SurfaceFlinger, parents hold references to their children. The// mirrored SurfaceControl is alive since the parent DisplayContent SurfaceControl is// holding a reference to it. Therefore, the mirrored SurfaceControl will be cleaned up// when the VirtualDisplay is destroyed - which will clean up this DisplayContent.
}
/*** Apply transformations to the mirrored surface to ensure the captured contents are scaled to* fit and centred in the output surface.** @param transaction the transaction to include transformations of mMirroredSurface* to. Transaction is not applied before returning.* @param recordedContentBounds bounds of the content to record to the surface provided by* the app.* @param surfaceSize the default size of the surface to write the display area* content to*/@VisibleForTesting void updateMirroredSurface(SurfaceControl.Transaction transaction,Rect recordedContentBounds, Point surfaceSize) {// Calculate the scale to apply to the root mirror SurfaceControl to fit the size of the// output surface.float scaleX = surfaceSize.x / (float) recordedContentBounds.width();float scaleY = surfaceSize.y / (float) recordedContentBounds.height();float scale = Math.min(scaleX, scaleY);int scaledWidth = Math.round(scale * (float) recordedContentBounds.width());int scaledHeight = Math.round(scale * (float) recordedContentBounds.height());// Calculate the shift to apply to the root mirror SurfaceControl to centre the mirrored// contents in the output surface.int shiftedX = 0;if (scaledWidth != surfaceSize.x) {shiftedX = (surfaceSize.x - scaledWidth) / 2;}int shiftedY = 0;if (scaledHeight != surfaceSize.y) {shiftedY = (surfaceSize.y - scaledHeight) / 2;}transaction// Crop the area to capture to exclude the 'extra' wallpaper that is used// for parallax (b/189930234)..setWindowCrop(mRecordedSurface, recordedContentBounds.width(),recordedContentBounds.height())// Scale the root mirror SurfaceControl, based upon the size difference between the// source (DisplayArea to capture) and output (surface the app reads images from)..setMatrix(mRecordedSurface, scale, 0 /* dtdx */, 0 /* dtdy */, scale)// Position needs to be updated when the mirrored DisplayArea has changed, since// the content will no longer be centered in the output surface..setPosition(mRecordedSurface, shiftedX /* x */, shiftedY /* y */).apply();mLastRecordedBounds = new Rect(recordedContentBounds);// Request to notify the client about the resize.mMediaProjectionManager.notifyActiveProjectionCapturedContentResized(mLastRecordedBounds.width(), mLastRecordedBounds.height());}
相关文章:
Android 镜像模式和扩展模式区别探讨-Android14
Android 镜像模式和扩展模式区别探讨 1、区分镜像模式和扩展模式1.1 扩展屏是否有显示内容1.2 镜像模式显示条件 2、镜像模式界面 同屏显示和异屏显示探讨DisplayManagerService启动及主屏添加-Android13 Android主副屏显示-Android14 1、区分镜像模式和扩展模式 LogicalDispla…...
链表头文件大更新!!!
引言 原文章:链表简介及自制链表操作头文件_自己写一个链表头文件-CSDN博客。 此次更新添加了更多功能,让改头文件更 人性化 。 安装教程见原文章。 介绍 linked_list.h 头文件 linked_list.h 是一个 C 头文件,定义了一个模板类 LinkedListÿ…...
ROS2创建 base 包用于其他模块的参数配置和头文件依赖
Demo 背景 ROS2项目开发中存在以下需求:有多个包需要读取一些共同的配置项(以txt或者yaml形式存在),且依赖于一些公用的utils工具代码(C)。Solution: 创建一个 base_config 包来“存放” 配置文件和公用的头文件。gitee address: Gitee/CDal…...
设计模式の软件设计原则
文章目录 前言一、聚合&组合&继承&依赖1.1、继承1.2、组合1.3、聚合1.4、依赖 二、单一职责原则2.1、单一职责原则反面案例2.2、单一职责原则反面案例的改进 三、接口隔离原则3.1、接口隔离原则反面案例3.2、接口隔离原则反面案例的改进 四、依赖倒转原则4.1、依赖…...
【python自动化四】日志打印
我们在进行自动化测试时,需要打印过程日志和结果日志等,这里记录下日志的相关配置。这里我们直接自己新建一个logger。 先贴上日志代码如下,可根据需要修改: import logging import os import timefrom logging.handlers import …...
E498 ThinkPHP+MYSQL+LW+纯洁婚纱网站系统的设计与实现 源码 配置 文档 全套资料
婚纱网站系统的设计与实现 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 在互联网和电子商务迅速发展的今天,网络已经是人们日常生活所不可缺少的信息获取渠道,人们日常生活基本已完全被网络所覆盖,互联网影响到各…...
【PostgreSQL系列】列类型从整数转换为 UUID
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
shell脚本实战案例
文章目录 实战第一坑功能说明脚本实现 实战第一坑 实战第一坑:在Windows系统写了一个脚本,比如上面,随后上传到服务,执行会报错 原因: 解决方案:在linux系统touch文件,并通过vim添加内容&…...
VAE为什么叫变分(variational),相对于AE有什么区别。
VAE为什么叫变分(variational),相对于AE有什么区别。 VAE为什么叫变分(variational)?VAE相对于AE有什么区别? VAE为什么叫变分(variational)? 变分自编码器&…...
Codeforces Round 991 (Div. 3)
补题连接 A. Line Breaks 思路:从头开始累加单词个数,超过m就退出。 代码: #include <bits/stdc.h> using namespace std; #define int long longvoid solve() {int n, m, k;cin >> n >> m;vector<string> a(n);…...
红日靶场vulnstark 4靶机的测试报告[细节](一)
目录 一、测试环境 1、系统环境 2、注意事项 3、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、漏洞利用Getshell ①Struts 2 s2-045漏洞 手工利用s2-45漏洞 Msf综合利用 ②Tomcat框架(CVE-2017-12615) ③phpMyAdmin(CVE-2018-12613) 构造语句写入冰蝎木…...
Android上运行OpenCV(Android Studio)
用Android Studio的话,整体来说没什么难的,照着教程来做就好了。 【OpenCV】OpenCV库的安装 - Android与OpenCV系列教程_哔哩哔哩_bilibili 主要就是导入module,然后加入依赖。代码只有几行。 if(OpenCVLoader.initLocal()){Toast.makeText(…...
代码随想录算法训练营day50|动态规划12
不同的子序列 给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。、 编辑距离中的删除元素,其实就是直接变数字,其只删除原来的较长的数组里的元素 递推模拟,使用s的最后一个元素匹配,或者删除…...
图像生成-扩散模型的经典之作DDPM
论文:https://arxiv.org/pdf/2006.11239 项目:https://github.com/hojonathanho/diffusion Denoising Diffusion Probabilistic Models (DDPM) 是一种生成模型,它通过一系列逐步添加噪声的过程将数据点映射到一个简单的先验分布(…...
知识拓展 ?. 连选链操作
?. 连选链操作 ?. 可选链操作符 ?. 是可选链操作符,常用于访问引用类型具有不确定性的内部数据时,比如要访问一个对象中的数组,不确定数组一定有数据就可以使用 ? 取读取它的 length 属性,如果对象没有这个属性也仅会返回 …...
API设计指南:详解HTTP状态码错误解析、HTTP方法及参数命名规则
目录 1、HTTP API规范1.1 原则1.2 协议1.3 版本1.4 路径1.5 HTTP 方法(Method)1.6 过滤信息1.7 参数命名1.8 HTTP 状态码(Response Code)1.9 鉴权 2、状态码2.1 API返回基础规范2.2 常见的 HTTP 状态码2.3 API错误信息应该放到响应…...
【D3.js in Action 3 精译_043】5.1 饼图和环形图的创建(三):圆弧的绘制
当前内容所在位置: 第五章 饼图布局与堆叠布局 ✔️ 5.1 饼图和环形图的创建 ✔️ 5.1.1 准备阶段(一)5.1.2 饼图布局生成器(二)5.1.3 圆弧的绘制(三) ✔️5.1.4 数据标签的添加(四&…...
7. 一分钟读懂“单例模式”
7.1 模式介绍 单例模式就像公司里的 打印机队列管理系统,无论有多少员工提交打印任务,大家的请求都汇总到唯一的打印管理中心,按顺序排队输出。这个中心必须全局唯一,避免多个队列出现资源冲突,保证打印任务井然有序。…...
如何让谷歌外链看起来更真实?
在SEO优化过程中,外链的自然性往往会被忽视,尤其是在一些急于见效的策略中,外链往往集中在高权重的少数几个网站上,导致外链结构单一且缺乏多样性。这样的外链网络容易让搜索引擎怀疑其真实性,进而影响网站排名。如何才…...
C标签和 EL表达式的在前端界面的应用
目录 前言 常用的c标签有: for循环 1 表示 普通的for循环的 2 常在集合中使用 表示 选择关系 1 简单的表示如果 2 表示如果。。否则。。 EL表达式 格式 : ${属性名/对象/ 集合} 前言 本篇博客介绍 c标签和el表达式的使用 使用C标签 要引入 …...
Luma 视频生成 API 对接说明
Luma 视频生成 API 对接说明 随着 AI 的应用变广,各类 AI 程序已逐渐普及。AI 已逐渐深入到人们的工作生活方方面面。而 AI 涉及的行业也越来越多,从最初的写作,到医疗教育,再到现在的视频。 Luma 是一个专业高质量的视频生成平…...
嵌入式基础:Linux C语言:Day7
重点: strlen()函数\strcpy()函数\strcat实现\strcmp()实现 数组的清空:bzero函数、memset函数 一、字符数组 <1> 概念 字符数组本质上就是一个数组,保存一个个字符,也一般用来保存字符串 字符串由多个字符组成的一个字符…...
阿里云盘permission denied
问题是执行 ./aliyunpan 时遇到了 Permission denied 的错误。这通常是因为文件没有执行权限。以下是解决问题的步骤: 检查文件权限 运行以下命令检查文件的权限: ls -l aliyunpan输出中会看到类似以下内容: -rw-r--r-- 1 user group 123…...
Flink学习连载文章12--FlinkSQL高级部分
eventTime 测试数据如下: {"username":"zs","price":20,"event_time":"2023-07-17 10:10:10"} {"username":"zs","price":15,"event_time":"2023-07-17 10:10:3…...
缓冲区溢出基础与实践
缓冲区溢出 缓冲区溢出是指当计算机向缓冲区内填充数据时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。理想的情况是:程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹…...
matlab figure函数 single 数据类型
1.matlab figure函数详细介绍 在MATLAB中,figure函数用于创建新的图形窗口或激活现有的图形窗口。以下是figure函数的详细介绍和用法: 基本用法 创建新图形窗口:不带任何参数调用figure会创建一个新的图形窗口,并将其设为当前活…...
量化交易系统开发-实时行情自动化交易-8.15.Ptrade/恒生平台
19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来会对于Ptrade/恒生平台介绍。 P…...
Vue03
目录 一、今日目标 1.生命周期 2.综合案例-小黑记账清单 3.工程化开发入门 4.综合案例-小兔仙首页 二、Vue生命周期 三、Vue生命周期钩子 四、生命周期钩子小案例 1.在created中发送数据 六、工程化开发模式和脚手架 1.开发Vue的两种方式 2.Vue CLI脚手架 基本介绍…...
【AI学习】Mamba学习(十九):关于S4-FouT
在前面《Mamba学习(十六):从S4到S5模型》一文中,提到了S4D-Lin,其具体状态矩阵A的初始化形式为: S4D-Lin对比S4D-Inv是一种更简单的形式,可以看作是对S4-FouT(S4的另外一种变体&am…...
YOLOv5-C3模块实现
YOLOv5-C3模块实现 🍨 本文为🔗365天深度学习训练营 中的学习记录博客 🍖 原作者:K同学啊 电脑系统:Windows11 显卡型号:NVIDIA Quadro P620 语言环境:python 3.9.7 编译器:jupyt…...
ubuntu下Qt5自动编译配置QtMqtt环境(10)
文章目录 [toc]1、概述2、下载QtMqtt源码3、编译4、验证5、参考6、视频 更多精彩内容👉内容导航 👈👉Qt网络编程 👈 1、概述 Qt默认是不包含mqtt库的,如果需要使用到mqtt库就只能自己编译配置; 网络所有的…...
切比雪夫不等式:方差约束下的概率估计
切比雪夫不等式:方差约束下的概率估计 背景 在概率分析中,切比雪夫不等式是一个常用的工具,它通过引入随机变量的 方差信息,给出了偏离均值的概率界限。这一不等式是对 马尔科夫不等式 的自然扩展,结合了更丰富的分布…...
SIP系列七:ICE框架(P2P通话)
我的音视频/流媒体开源项目(github) SIP系列目录 目录 一、NAT 1、NAT介绍 2、NAT类型 2.1、 完全圆锥型NAT 2.2、受限圆锥型NAT 2.3、端口受限圆锥型NAT 2.4、对称NAT 3、NAT打洞 3.1、不同一NAT下 3.2、同一NAT下 二、ICE 三、ICE中的SDP 至此&#x…...
小程序-基于java+SpringBoot+Vue的智慧校园管理系统设计与实现
项目运行 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:…...
Visual Studio 2022创建离线安装包
步骤1: 下载 Visual Studio 引导程序(最新版) 历史版本 步骤2 新建文件夹“E:\VS2022”,将下载的“vs_Professional.exe”拷贝到文件夹下在此文件夹窗口按住shift鼠标右键,选择“在此处打开powershell窗口” 步骤3 根据需要将代码复制到…...
Android 实现中英文切换
在开发海外项目的时候,需要实现app内部的中英文切换功能,所有的英文都是内置的,整体思路为: 创建一个sp对象,存储当前系统的语言类型,然后在BaseActivity中对语言进行判断; //公共Activitypubl…...
CmakeLists学习刨根问底
必要的两项内容 cmake_minimum_required(VERSION 2.5)project(mymuduo) 这行代码指定了构建项目所需的CMake最低版本为2.5。CMake是一个跨平台的自动化构建系统,它使用CMakeLists.txt文件来定义项目的构建过程。定义项目的名称为mymuduo。CMake将使用这个名称来生成…...
策略模式实战 - 猜拳游戏
**可以整体的替换一套算法,这就是策略模式。**这样对于同一个问题,可以有多种解决方案——算法实现的时候,可以通过策略模式来非常方便的进行算法的整体替换,而各种算法是独立封装好的,不用修改其内部逻辑。 具体的实…...
VoCo-LLaMA: Towards Vision Compression with Large Language Models
视觉语言模型在各种多模态任务上取得了显著的成功,但经常受到有限上下文窗口和处理高分辨率图像输入和视频的高计算成本的瓶颈。视觉压缩可以通过减少视觉令牌数量避免该问题。先前方法使用额外模块压缩视觉令牌并强制LLM理解压缩的令牌。然而,LLM对视觉…...
每日小知识
Kafka是一个分布式流平台,具有高性能、高可靠性和可扩展性的特点。它主要用于处理实时的数据流,将数据以高吞吐量的方式进行发布和订阅。以下是关于Kafka的几个基本概念和优势的介绍: 概念: 生产者(Producer…...
Linux其二设置端口号,静态ip以及命令
目录 1、VI编辑器 【linux版本的文本文件】 2) 补充的vi编辑器的其他内容(了解) 2、ln 连接的意思 link的缩写 3、文件的查看 【重点】 4、压缩与解压(重点) 5、find 查找命令 6、which & whereis 作用是一样的,表示某…...
吉林大学23级数据结构上机实验(第7周)
A 去火车站 寒假到了,小明准备坐火车回老家,现在他从学校出发去火车站,CC市去火车站有两种方式:轻轨和公交车。小明为了省钱,准备主要以乘坐公交为主。CC市还有一项优惠政策,持学生证可以免费乘坐一站轻轨&…...
SpringBoot(整合MyBatis + MyBatis-Plus + MyBatisX插件使用)
文章目录 1.整合MyBatis 1.需求分析2.数据库表设计3.数据库环境配置 1.新建maven项目2.pom.xml 引入依赖3.application.yml 配置数据源4.Application.java 编写启动类5.测试6.配置类切换druid数据源7.测试数据源是否成功切换 4.Mybatis基础配置 1.编写映射表的bean2.MonsterMap…...
【2024最新】基于Springboot+Vue的网上图书商城平台Lw+PPT
作者:计算机搬砖家 开发技术:SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:Java精选实战项…...
JAVA-面向对象基础
文章目录 概要封装多态抽象类接口内部类为什么需要内部类 概要 面向对象是一种编程范式或设计哲学,它将软件系统设计为由多个对象组成,这些对象通过特定的方式相互作用 封装 将数据和操作数据的方法封装在一个类中,并通过访问修饰符控制对…...
Y3编辑器官方文档1:编辑器简介及菜单栏详解(文件、编辑、窗口、细节、调试)
文章目录 一、新建项目二、 编辑器主界面2.1 游戏场景2.2 导航栏/菜单栏2.3 功能栏三、菜单栏详细介绍3.1 文件3.1.1 版本管理3.1.2 项目管理(多关卡)3.1.2.1 多关卡功能说明3.1.2.2 关卡切换与关卡存档3.2 编辑3.2.1 通用设置3.2.2 键位设置3.3 窗口(日志)3.4 细节3.4.1 语言…...
力扣94题:二叉树的中序遍历
力扣94题:二叉树的中序遍历(C语言实现详解) 题目描述 给定一个二叉树的根节点 root ,返回它的中序遍历(Inorder Traversal)。 中序遍历的规则是: 先访问左子树;再访问根节点&…...
【数据结构】二叉树的性质和存储结构
性质 在二叉树的第i层上至多有2^{i-1}个结点,至少有1个结点 深度为k的二叉树至多有2^{k-1}个结点(k≥1),至少有k个结点 对任何一棵二叉树T,如果其叶子数为n0,度为2的结点数为n2,则n0n21 具有n个结点的完…...
【Spring项目】图书管理系统
阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 一:项目实现准备 1:需求 (1)登录 2:准备…...
TCP编程案例
笔记:(本题可能需要的) TCP协议: TCP协议进行通信的两个应用进程:客户端、服务端。 使用TCP协议前,须先建立TCP连接,形成基于字节流的传输数据通道 传输前,采用“三次握手”方式…...