当前位置: 首页 > news >正文

ghostwin8网站奖别人做常用的营销策略

ghostwin8网站奖别人做,常用的营销策略,网络推广协议合同范本,招聘网站评估怎么做1.概述 Android原生对MediaProjection的管理逻辑,是如果服务端已经保存有MediaProjection的实例,那么再次创建的时候,之前的MediaProjection实例就会被暂停,并且引用指向新的实例,也就导致了当开启后一个录屏应用时&a…

1.概述

Android原生对MediaProjection的管理逻辑,是如果服务端已经保存有MediaProjection的实例,那么再次创建的时候,之前的MediaProjection实例就会被暂停,并且引用指向新的实例,也就导致了当开启后一个录屏应用时,前一个录屏应用会被暂停。为了能实现多个录屏应用同时录屏(或者共享屏幕或投屏的时候录屏),我们需要对framework进行修改,只需对一个文件进行修改:frameworks/base/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java

2.实现能同时开启多个MediaProjection

大致的思路就是修改MediaProjectionManagerService.java,使得MediaProjectionManagerService服务端能够保存多个MediaProjeciton实例。

/** Copyright (C) 2014 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.android.server.media.projection;import android.Manifest;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.IProcessObserver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo;
import android.hardware.display.DisplayManager;
import android.media.MediaRouter;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionCallback;
import android.media.projection.IMediaProjectionManager;
import android.media.projection.IMediaProjectionWatcherCallback;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.Watchdog;import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** Manages MediaProjection sessions.** The {@link MediaProjectionManagerService} manages the creation and lifetime of MediaProjections,* as well as the capabilities they grant. Any service using MediaProjection tokens as permission* grants <b>must</b> validate the token before use by calling {@link* IMediaProjectionService#isValidMediaProjection}.*/
public final class MediaProjectionManagerService extends SystemServiceimplements Watchdog.Monitor {private static final boolean REQUIRE_FG_SERVICE_FOR_PROJECTION = true;private static final String TAG = "MediaProjectionManagerService";private static boolean DEBUG = false;private final Object mLock = new Object(); // Protects the list of media projectionsprivate final Map<IBinder, IBinder.DeathRecipient> mDeathEaters;private final CallbackDelegate mCallbackDelegate;private final Context mContext;private final AppOpsManager mAppOps;private final ActivityManagerInternal mActivityManagerInternal;private final PackageManager mPackageManager;private final MediaRouter mMediaRouter;private final MediaRouterCallback mMediaRouterCallback;private MediaRouter.RouteInfo mMediaRouteInfo;private Map<IBinder, MediaProjectionEntry> mEntryMap;public MediaProjectionManagerService(Context context) {super(context);mContext = context;mDeathEaters = new ArrayMap<IBinder, IBinder.DeathRecipient>();mCallbackDelegate = new CallbackDelegate();mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);mPackageManager = mContext.getPackageManager();mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);mMediaRouterCallback = new MediaRouterCallback();mEntryMap = new ArrayMap<IBinder, MediaProjectionEntry>();if ("userdebug".equals(SystemProperties.get("ro.build.type", "user"))) {DEBUG = true;}Watchdog.getInstance().addMonitor(this);}@Overridepublic void onStart() {logd("onStart");publishBinderService(Context.MEDIA_PROJECTION_SERVICE, new BinderService(),false /*allowIsolated*/);mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY, mMediaRouterCallback,MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);if (REQUIRE_FG_SERVICE_FOR_PROJECTION) {mActivityManagerInternal.registerProcessObserver(new IProcessObserver.Stub() {@Overridepublic void onForegroundActivitiesChanged(int pid, int uid, boolean fg) {}@Overridepublic void onForegroundServicesChanged(int pid, int uid, int serviceTypes) {MediaProjectionManagerService.this.handleForegroundServicesChanged(pid, uid,serviceTypes);}@Overridepublic void onProcessDied(int pid, int uid) {}});}}@Overridepublic void onSwitchUser(int userId) {logd("onSwitchUser: userId=" + userId);mMediaRouter.rebindAsUser(userId);synchronized (mLock) {if (mEntryMap != null && !mEntryMap.isEmpty()) {for (MediaProjectionEntry entry : mEntryMap.values()) {if (entry != null) {entry.getProjectionGrant().stop();}}}}}@Overridepublic void monitor() {synchronized (mLock) { /* check for deadlock */ }}/*** Called when the set of active foreground service types for a given {@code uid / pid} changes.* We will stop the active projection grant if its owner targets {@code Q} or higher and has no* started foreground services of type {@code FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION}.*/private void handleForegroundServicesChanged(int pid, int uid, int serviceTypes) {synchronized (mLock) {logd("handleForegroundServicesChanged: pid=" + pid + ", uid=" + uid+ ", serviceTypes=" + serviceTypes);if (mEntryMap == null || mEntryMap.isEmpty()) {return;}String uidpid = String.format("%s_%s", uid, pid);MediaProjectionEntry entry = getMediaProjectionEntryByUidPid(uidpid);if (entry == null || entry.getProjectionGrant() == null) {return;}MediaProjection mediaProjection = entry.getProjectionGrant();if (!mediaProjection.requiresForegroundService()) {return;}if ((serviceTypes & ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION) != 0) {return;}mediaProjection.stop();logd("handleForegroundServicesChanged: MediaProjection="+ mediaProjection.getProjectionInfo() + " hashCode "+ mediaProjection.asBinder().hashCode() + " stoped");}}private void startProjectionLocked(final String uidpid, final MediaProjection projection) {logd("startProjectionLocked: calling uidpid " + uidpid+ ", MediaProjection=" + projection.getProjectionInfo()+ " hashCode=" + projection.asBinder().hashCode()+ ", current MediaProjection count " + mEntryMap.size());if (mMediaRouteInfo != null) {mMediaRouter.getFallbackRoute().select();}List<IBinder> removedMediaProjections = new ArrayList<>();logd(">>> MediaProjections:");if (mEntryMap.isEmpty()) {logd(">>> null");} else {for (MediaProjectionEntry entry : mEntryMap.values()) {if (entry != null) {logd(">>> " + entry.getProjectionGrant().getProjectionInfo()+ " hashCode " + entry.getProjectionToken().hashCode());MediaProjection mp = entry.getProjectionGrant();if (mp.packageName.equals(projection.packageName)) {removedMediaProjections.add(entry.getProjectionToken());}} else {logd(">>> null");}}}for (IBinder token : removedMediaProjections) {MediaProjectionEntry entry = mEntryMap.get(token);if (entry != null) {MediaProjection mp = entry.getProjectionGrant();logd(mp.packageName + " already existing MediaProjection="+ mp.getProjectionInfo() + " hashCode " + mp.asBinder().hashCode()+ ", remove it");mp.stop();}}MediaProjectionEntry entry = new MediaProjectionEntry(uidpid, projection.asBinder(),projection);mEntryMap.put(projection.asBinder(), entry);dispatchStart(projection);logd("startProjectionLocked: start success, "+ "current MediaProjection count " + mEntryMap.size());}private void stopProjectionLocked(final MediaProjection projection) {logd("stopProjectionLocked: MediaProjection=" + projection.getProjectionInfo()+ " hashCode " + projection.asBinder().hashCode());mEntryMap.remove(projection.asBinder());dispatchStop(projection);logd("stopProjectionLocked: stop success, "+ "remaining MediaProjection count " + mEntryMap.size());}private void addCallback(final IMediaProjectionWatcherCallback callback) {logd("addCallback: callback=" + callback);IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {@Overridepublic void binderDied() {removeCallback(callback);}};synchronized (mLock) {mCallbackDelegate.add(callback);linkDeathRecipientLocked(callback, deathRecipient);}}private void removeCallback(IMediaProjectionWatcherCallback callback) {synchronized (mLock) {logd("removeCallback: callback=" + callback);unlinkDeathRecipientLocked(callback);mCallbackDelegate.remove(callback);}}private void linkDeathRecipientLocked(IMediaProjectionWatcherCallback callback,IBinder.DeathRecipient deathRecipient) {try {logd("linkDeathRecipientLocked: callback=" + callback+ ", deathRecipient=" + deathRecipient);final IBinder token = callback.asBinder();token.linkToDeath(deathRecipient, 0);mDeathEaters.put(token, deathRecipient);} catch (RemoteException e) {Slog.e(TAG, "Unable to link to death for media projection monitoring callback", e);}}private void unlinkDeathRecipientLocked(IMediaProjectionWatcherCallback callback) {logd("unlinkDeathRecipientLocked: callback=" + callback);final IBinder token = callback.asBinder();IBinder.DeathRecipient deathRecipient = mDeathEaters.remove(token);if (deathRecipient != null) {token.unlinkToDeath(deathRecipient, 0);}}private void dispatchStart(MediaProjection projection) {logd("dispatchStart: MediaProjection=" + projection.getProjectionInfo()+ " hashCode " + projection.asBinder().hashCode());mCallbackDelegate.dispatchStart(projection);}private void dispatchStop(MediaProjection projection) {logd("dispatchStop: MediaProjection=" + projection.getProjectionInfo()+ " hashCode " + projection.asBinder().hashCode());mCallbackDelegate.dispatchStop(projection);}private boolean isValidMediaProjection(IBinder token) {synchronized (mLock) {logd("isValidMediaProjection: MediaProjection hashCode " + token.hashCode());if (mEntryMap == null && mEntryMap.isEmpty()) {return false;}for (MediaProjectionEntry entry : mEntryMap.values()) {if (entry != null && entry.getProjectionToken().equals(token)) {logd("isValidMediaProjection: MediaProjection hashCode "+ token.hashCode() + " is valid");return true;}}logd("isValidMediaProjection: MediaProjection hashCode "+ token.hashCode() + " is invalid");return false;}}private MediaProjectionInfo getActiveProjectionInfo(String uidpid) {synchronized (mLock) {if (mEntryMap == null || mEntryMap.isEmpty()) {return null;}MediaProjectionEntry entry = getMediaProjectionEntryByUidPid(uidpid);if (entry == null) {return null;}logd("getActiveProjectionInfo: MediaProjection="+ entry.getProjectionGrant().getProjectionInfo()+ " hashCode " + entry.getProjectionToken().hashCode());return entry.getProjectionGrant().getProjectionInfo();}}private void dump(final PrintWriter pw) {pw.println("MEDIA PROJECTION MANAGER (dumpsys media_projection)");synchronized (mLock) {pw.println("Media Projection: ");if (mEntryMap != null && !mEntryMap.isEmpty()) {for (MediaProjectionEntry entry : mEntryMap.values()) {if (entry != null) {entry.dump(pw);}}} else {pw.println("null");}}}private final class BinderService extends IMediaProjectionManager.Stub {@Override // Binder callpublic boolean hasProjectionPermission(int uid, String packageName) {logd("BinderService hasProjectionPermission: uid=" + uid+ ", packageName=" + packageName);long token = Binder.clearCallingIdentity();boolean hasPermission = false;try {hasPermission |= checkPermission(packageName,android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)|| mAppOps.noteOpNoThrow(AppOpsManager.OP_PROJECT_MEDIA, uid, packageName)== AppOpsManager.MODE_ALLOWED;} finally {Binder.restoreCallingIdentity(token);}return hasPermission;}@Override // Binder callpublic IMediaProjection createProjection(int uid, String packageName, int type,boolean isPermanentGrant) {final String uidpid = getCallingUidPid();logd("BinderService createProjection: uid=" + uid+ ", packageName=" + packageName + ", " + "type=" + type+ ", isPermanentGrant=" + isPermanentGrant + ", calling uidpid " + uidpid);if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)!= PackageManager.PERMISSION_GRANTED) {throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to grant "+ "projection permission");}if (packageName == null || packageName.isEmpty()) {throw new IllegalArgumentException("package name must not be empty");}final UserHandle callingUser = Binder.getCallingUserHandle();long callingToken = Binder.clearCallingIdentity();MediaProjection projection;try {ApplicationInfo ai;try {ai = mPackageManager.getApplicationInfoAsUser(packageName, 0, callingUser);} catch (NameNotFoundException e) {throw new IllegalArgumentException("No package matching :" + packageName);}projection = new MediaProjection(type, uid, packageName, ai.targetSdkVersion,ai.isPrivilegedApp());if (isPermanentGrant) {mAppOps.setMode(AppOpsManager.OP_PROJECT_MEDIA,projection.uid, projection.packageName, AppOpsManager.MODE_ALLOWED);}} finally {Binder.restoreCallingIdentity(callingToken);}return projection;}@Override // Binder callpublic boolean isValidMediaProjection(IMediaProjection projection) {return MediaProjectionManagerService.this.isValidMediaProjection(projection.asBinder());}@Override // Binder callpublic MediaProjectionInfo getActiveProjectionInfo() {final String uidpid = getCallingUidPid();logd("BinderService getActiveProjectionInfo: calling uidpid " + uidpid);if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)!= PackageManager.PERMISSION_GRANTED) {throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to add "+ "projection callbacks");}final long token = Binder.clearCallingIdentity();try {return MediaProjectionManagerService.this.getActiveProjectionInfo(uidpid);} finally {Binder.restoreCallingIdentity(token);}}@Override // Binder callpublic void stopActiveProjection() {final String uidpid = getCallingUidPid();logd("BinderService stopActiveProjection: calling uidpid " + uidpid);if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)!= PackageManager.PERMISSION_GRANTED) {throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to add "+ "projection callbacks");}final long token = Binder.clearCallingIdentity();try {MediaProjectionEntry entry = getMediaProjectionEntryByUidPid(uidpid);if (entry != null) {logd("BinderService stopActiveProjection: MediaProjection="+ entry.getProjectionGrant().getProjectionInfo()+ " hashCode " + entry.getProjectionToken().hashCode());entry.getProjectionGrant().stop();}} finally {Binder.restoreCallingIdentity(token);}}@Override //Binder callpublic void addCallback(final IMediaProjectionWatcherCallback callback) {logd("BinderService addCallback: callback=" + callback);if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)!= PackageManager.PERMISSION_GRANTED) {throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to add "+ "projection callbacks");}final long token = Binder.clearCallingIdentity();try {MediaProjectionManagerService.this.addCallback(callback);} finally {Binder.restoreCallingIdentity(token);}}@Overridepublic void removeCallback(IMediaProjectionWatcherCallback callback) {logd("BinderService removeCallback: callback=" + callback);if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)!= PackageManager.PERMISSION_GRANTED) {throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to remove "+ "projection callbacks");}final long token = Binder.clearCallingIdentity();try {MediaProjectionManagerService.this.removeCallback(callback);} finally {Binder.restoreCallingIdentity(token);}}@Override // Binder callpublic void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;final long token = Binder.clearCallingIdentity();try {MediaProjectionManagerService.this.dump(pw);} finally {Binder.restoreCallingIdentity(token);}}private boolean checkPermission(String packageName, String permission) {return mContext.getPackageManager().checkPermission(permission, packageName)== PackageManager.PERMISSION_GRANTED;}}private final class MediaProjection extends IMediaProjection.Stub {public final int uid;public final String packageName;public final UserHandle userHandle;private final int mTargetSdkVersion;private final boolean mIsPrivileged;private final int mType;private IMediaProjectionCallback mCallback;private IBinder mToken;private IBinder.DeathRecipient mDeathEater;private boolean mRestoreSystemAlertWindow;MediaProjection(int type, int uid, String packageName, int targetSdkVersion,boolean isPrivileged) {mType = type;this.uid = uid;this.packageName = packageName;userHandle = new UserHandle(UserHandle.getUserId(uid));mTargetSdkVersion = targetSdkVersion;mIsPrivileged = isPrivileged;}@Override // Binder callpublic boolean canProjectVideo() {return mType == MediaProjectionManager.TYPE_MIRRORING ||mType == MediaProjectionManager.TYPE_SCREEN_CAPTURE;}@Override // Binder callpublic boolean canProjectSecureVideo() {return false;}@Override // Binder callpublic boolean canProjectAudio() {return mType == MediaProjectionManager.TYPE_MIRRORING|| mType == MediaProjectionManager.TYPE_PRESENTATION|| mType == MediaProjectionManager.TYPE_SCREEN_CAPTURE;}@Override // Binder callpublic int applyVirtualDisplayFlags(int flags) {if (mType == MediaProjectionManager.TYPE_SCREEN_CAPTURE) {flags &= ~DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR| DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;return flags;} else if (mType == MediaProjectionManager.TYPE_MIRRORING) {flags &= ~(DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR);flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;return flags;} else if (mType == MediaProjectionManager.TYPE_PRESENTATION) {flags &= ~DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION |DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;return flags;} else {throw new RuntimeException("Unknown MediaProjection type");}}@Override // Binder callpublic void start(final IMediaProjectionCallback callback) {if (callback == null) {throw new IllegalArgumentException("callback must not be null");}synchronized (mLock) {final String uidpid = getCallingUidPid();logd("MediaProjection start: calling uidpid " + uidpid+ ", callback=" + callback);if (isValidMediaProjection(asBinder())) {Slog.w(TAG, "UID " + Binder.getCallingUid()+ " attempted to start already started MediaProjection");return;}if (REQUIRE_FG_SERVICE_FOR_PROJECTION&& requiresForegroundService()&& !mActivityManagerInternal.hasRunningForegroundService(uid, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)) {throw new SecurityException("Media projections require a foreground service"+ " of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION");}mCallback = callback;registerCallback(mCallback);try {mToken = callback.asBinder();mDeathEater = new IBinder.DeathRecipient() {@Overridepublic void binderDied() {mCallbackDelegate.remove(asBinder(), callback);stop();}};mToken.linkToDeath(mDeathEater, 0);} catch (RemoteException e) {Slog.w(TAG, "MediaProjectionCallbacks must be valid, aborting " +"MediaProjection", e);return;}if (mType == MediaProjectionManager.TYPE_SCREEN_CAPTURE) {final long token = Binder.clearCallingIdentity();try {// We allow an app running a current screen capture session to use// SYSTEM_ALERT_WINDOW for the duration of the session, to enable// them to overlay their UX on top of what is being captured.// We only do this if the app requests the permission, and the appop// is in its default state (the user has neither explicitly allowed nor// disallowed it).final PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageName, PackageManager.GET_PERMISSIONS,UserHandle.getUserId(uid));if (ArrayUtils.contains(packageInfo.requestedPermissions,Manifest.permission.SYSTEM_ALERT_WINDOW)) {final int currentMode = mAppOps.unsafeCheckOpRawNoThrow(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, packageName);if (currentMode == AppOpsManager.MODE_DEFAULT) {mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid,packageName, AppOpsManager.MODE_ALLOWED);mRestoreSystemAlertWindow = true;}}} catch (PackageManager.NameNotFoundException e) {Slog.w(TAG, "Package not found, aborting MediaProjection", e);return;} finally {Binder.restoreCallingIdentity(token);}}startProjectionLocked(uidpid, this);}}@Override // Binder callpublic void stop() {synchronized (mLock) {logd("MediaProjection stop: calling uidpid " + getCallingUidPid());if (!isValidMediaProjection(asBinder())) {Slog.w(TAG, "Attempted to stop inactive MediaProjection "+ "(uid=" + Binder.getCallingUid() + ", "+ "pid=" + Binder.getCallingPid() + ")");return;}if (mRestoreSystemAlertWindow) {final long token = Binder.clearCallingIdentity();try {// Put the appop back how it was, unless it has been changed from what// we set it to.// Note that WindowManager takes care of removing any existing overlay// windows when we do this.final int currentMode = mAppOps.unsafeCheckOpRawNoThrow(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, packageName);if (currentMode == AppOpsManager.MODE_ALLOWED) {mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, packageName,AppOpsManager.MODE_DEFAULT);}mRestoreSystemAlertWindow = false;} finally {Binder.restoreCallingIdentity(token);}}stopProjectionLocked(this);mToken.unlinkToDeath(mDeathEater, 0);mToken = null;unregisterCallbacks();mCallback = null;}}@Overridepublic void registerCallback(IMediaProjectionCallback callback) {if (callback == null) {throw new IllegalArgumentException("callback must not be null");}logd("MediaProjection registerCallback: MediaProjection(hashCode "+ asBinder().hashCode() + ") callback=" + callback);mCallbackDelegate.add(asBinder(), callback);}@Overridepublic void unregisterCallback(IMediaProjectionCallback callback) {if (callback == null) {throw new IllegalArgumentException("callback must not be null");}logd("MediaProjection unregisterCallback: MediaProjection(hashCode "+ asBinder().hashCode() + ") callback=" + callback);mCallbackDelegate.remove(asBinder(), callback);}private void unregisterCallbacks() {logd("MediaProjection unregister callbacks for MediaProjection(hashCode "+ asBinder().hashCode() + ") because media projection stopped");mCallbackDelegate.remove(asBinder());}public MediaProjectionInfo getProjectionInfo() {return new MediaProjectionInfo(packageName, userHandle);}boolean requiresForegroundService() {return mTargetSdkVersion >= Build.VERSION_CODES.Q && !mIsPrivileged;}public void dump(PrintWriter pw) {pw.println("(" + packageName + ", uid=" + uid + "): " + typeToString(mType));}}private class MediaRouterCallback extends MediaRouter.SimpleCallback {@Overridepublic void onRouteSelected(MediaRouter router, int type, MediaRouter.RouteInfo info) {synchronized (mLock) {logd("MediaRouterCallback onRouteSelected: router=" + router + ", type="+ type + ", info=" + info + ", calling uidpid " + getCallingUidPid());if ((type & MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY) != 0) {mMediaRouteInfo = info;for (MediaProjectionEntry entry : mEntryMap.values()) {if (entry != null) {entry.getProjectionGrant().stop();}}}}}@Overridepublic void onRouteUnselected(MediaRouter route, int type, MediaRouter.RouteInfo info) {logd("MediaRouterCallback onRouteUnselected: router=" + route+ ", type=" + type + ", info=" + info);if (mMediaRouteInfo == info) {mMediaRouteInfo = null;}}}private static class CallbackDelegate {private Map<IBinder, Map<IBinder, IMediaProjectionCallback>> mClientCallbacks;private Map<IBinder, IMediaProjectionWatcherCallback> mWatcherCallbacks;private Handler mHandler;private Object mLock = new Object();public CallbackDelegate() {mHandler = new Handler(Looper.getMainLooper(), null, true /*async*/);mClientCallbacks = new ArrayMap<IBinder, Map<IBinder, IMediaProjectionCallback>>();mWatcherCallbacks = new ArrayMap<IBinder, IMediaProjectionWatcherCallback>();}public void add(IBinder token, IMediaProjectionCallback callback) {synchronized (mLock) {if (mClientCallbacks.get(token) == null) {mClientCallbacks.put(token, new ArrayMap<IBinder, IMediaProjectionCallback>());logd("CallbackDelegate add: create callback container for "+ "MediaProjection(hashCode " + token.hashCode() + ")");}Map<IBinder, IMediaProjectionCallback> callbacks = mClientCallbacks.get(token);callbacks.put(callback.asBinder(), callback);logd("CallbackDelegate add callback: MediaProjection(hashCode "+ token.hashCode() + ") callback=" + callback+ ", remaining IMediaProjectionCallback for MediaProjection(hashCode "+ token.hashCode() + ") count " + callbacks.size()+ ", remaining IMediaProjectionCallback count "+ mClientCallbacks.size());}}public void add(IMediaProjectionWatcherCallback callback) {synchronized (mLock) {mWatcherCallbacks.put(callback.asBinder(), callback);logd("CallbackDelegate add callback " + callback.hashCode()+ ", remaining IMediaProjectionWatcherCallback count "+ mWatcherCallbacks.size());}}public void remove(IBinder token, IMediaProjectionCallback callback) {synchronized (mLock) {Map<IBinder, IMediaProjectionCallback> callbacks = mClientCallbacks.get(token);if (callbacks != null) {callbacks.remove(callback.asBinder());logd("CallbackDelegate remove callback: MediaProjection(hashCode "+ token.hashCode() + ") callback=" + callback+ ", remaining IMediaProjectionCallback for MediaProjection(hashCode "+ token.hashCode() + ") count " + callbacks.size()+ ", remaining IMediaProjectionCallback count "+ mClientCallbacks.size());if (callbacks.isEmpty()) {mClientCallbacks.remove(token);}}}}public void remove(IBinder token) {synchronized (mLock) {mClientCallbacks.remove(token);logd("CallbackDelegate remove all callbacks for MediaProjection(hashCode "+ token.hashCode() + ")");}}public void remove(IMediaProjectionWatcherCallback callback) {synchronized (mLock) {mWatcherCallbacks.remove(callback.asBinder());logd("CallbackDelegate remove callback " + callback.hashCode()+ ", remaining IMediaProjectionWatcherCallback count "+ mWatcherCallbacks.size());}}public void dispatchStart(MediaProjection projection) {if (projection == null) {Slog.e(TAG, "Tried to dispatch start notification for a null media projection."+ " Ignoring!");return;}synchronized (mLock) {logd("CallbackDelegate dispatchStart: projection="+ projection.getProjectionInfo() + " hashCode "+ projection.asBinder().hashCode()+ ", IMediaProjectionWatcherCallback count " + mWatcherCallbacks.size());for (IMediaProjectionWatcherCallback callback : mWatcherCallbacks.values()) {MediaProjectionInfo info = projection.getProjectionInfo();mHandler.post(new WatcherStartCallback(info, callback));}}}public void dispatchStop(MediaProjection projection) {if (projection == null) {Slog.e(TAG, "Tried to dispatch stop notification for a null media projection."+ " Ignoring!");return;}synchronized (mLock) {logd("CallbackDelegate dispatchStop: projection="+ projection.getProjectionInfo() + " hashCode "+ projection.asBinder().hashCode()+ ", IMediaProjectionWatcherCallback count " + mWatcherCallbacks.size()+ ", IMediaProjectionCallback count " + mClientCallbacks.size());Map<IBinder, IMediaProjectionCallback> callbacks =mClientCallbacks.get(projection.asBinder());if (callbacks != null) {for (IMediaProjectionCallback cb : callbacks.values()) {logd("CallbackDelegate dispatchStop: post IMediaProjectionCallback=" + cb);mHandler.post(new ClientStopCallback(cb));}}for (IMediaProjectionWatcherCallback callback : mWatcherCallbacks.values()) {MediaProjectionInfo info = projection.getProjectionInfo();mHandler.post(new WatcherStopCallback(info, callback));}}}}private static final class WatcherStartCallback implements Runnable {private IMediaProjectionWatcherCallback mCallback;private MediaProjectionInfo mInfo;public WatcherStartCallback(MediaProjectionInfo info,IMediaProjectionWatcherCallback callback) {mInfo = info;mCallback = callback;}@Overridepublic void run() {try {mCallback.onStart(mInfo);} catch (RemoteException e) {Slog.w(TAG, "Failed to notify media projection has stopped", e);}}}private static final class WatcherStopCallback implements Runnable {private IMediaProjectionWatcherCallback mCallback;private MediaProjectionInfo mInfo;public WatcherStopCallback(MediaProjectionInfo info,IMediaProjectionWatcherCallback callback) {mInfo = info;mCallback = callback;}@Overridepublic void run() {try {mCallback.onStop(mInfo);} catch (RemoteException e) {Slog.w(TAG, "Failed to notify media projection has stopped", e);}}}private static final class ClientStopCallback implements Runnable {private IMediaProjectionCallback mCallback;public ClientStopCallback(IMediaProjectionCallback callback) {mCallback = callback;}@Overridepublic void run() {try {mCallback.onStop();} catch (RemoteException e) {Slog.w(TAG, "Failed to notify media projection has stopped", e);}}}private static String typeToString(int type) {switch (type) {case MediaProjectionManager.TYPE_SCREEN_CAPTURE:return "TYPE_SCREEN_CAPTURE";case MediaProjectionManager.TYPE_MIRRORING:return "TYPE_MIRRORING";case MediaProjectionManager.TYPE_PRESENTATION:return "TYPE_PRESENTATION";}return Integer.toString(type);}private static final class MediaProjectionEntry {private String mUidPid;private IBinder mProjectionToken;private MediaProjection mProjectionGrant;public MediaProjectionEntry(String uidpid, IBinder token, MediaProjection mp) {this.mUidPid = uidpid;this.mProjectionToken = token;this.mProjectionGrant = mp;}public String getUidPid() {return mUidPid;}public IBinder getProjectionToken() {return mProjectionToken;}public MediaProjection getProjectionGrant() {return mProjectionGrant;}public void dump(PrintWriter pw) {pw.println("(" + mProjectionGrant.packageName + ", uid_pid=" + mUidPid+ ", token=" + mProjectionToken.hashCode() + "): "+ typeToString(mProjectionGrant.mType));}}private MediaProjectionEntry getMediaProjectionEntryByUidPid(String uidpid) {if (mEntryMap == null || mEntryMap.isEmpty() || uidpid == null || uidpid.length() <= 0) {return null;}for (MediaProjectionEntry entry : mEntryMap.values()) {if (entry != null && uidpid.equals(entry.getUidPid())) {return entry;}}return null;}private String getCallingUidPid() {int pid = Binder.getCallingPid();int uid = Binder.getCallingUid();return String.format("%s_%s", uid, pid);}private static void logd(String msg) {logd(TAG, msg);}private static void loge(String msg) {loge(TAG, msg);}private static void logd(String tag, String msg) {if (DEBUG) {Slog.d(tag, msg);}}private static void loge(String tag, String msg) {Slog.e(tag, msg);}}

文章转载自:
http://wanjiasortable.bbrf.cn
http://wanjiahumorlessly.bbrf.cn
http://wanjiadowthcory.bbrf.cn
http://wanjiaderelict.bbrf.cn
http://wanjiasalt.bbrf.cn
http://wanjiatechnophile.bbrf.cn
http://wanjiamacruran.bbrf.cn
http://wanjiathy.bbrf.cn
http://wanjiachaise.bbrf.cn
http://wanjianiddering.bbrf.cn
http://wanjiasudd.bbrf.cn
http://wanjiaturku.bbrf.cn
http://wanjiarewater.bbrf.cn
http://wanjiareentrance.bbrf.cn
http://wanjiagranddam.bbrf.cn
http://wanjiaoh.bbrf.cn
http://wanjiarhapsodic.bbrf.cn
http://wanjiaprn.bbrf.cn
http://wanjiaautoeciousness.bbrf.cn
http://wanjiateutomaniac.bbrf.cn
http://wanjialorelei.bbrf.cn
http://wanjiauglily.bbrf.cn
http://wanjiasegmental.bbrf.cn
http://wanjiastockyard.bbrf.cn
http://wanjiapsilocybin.bbrf.cn
http://wanjiacanvas.bbrf.cn
http://wanjiaagin.bbrf.cn
http://wanjiafluorin.bbrf.cn
http://wanjiastabbed.bbrf.cn
http://wanjiaelitism.bbrf.cn
http://wanjiading.bbrf.cn
http://wanjiathurberesque.bbrf.cn
http://wanjiainterstice.bbrf.cn
http://wanjiabiographee.bbrf.cn
http://wanjiacaernarvon.bbrf.cn
http://wanjiamoronity.bbrf.cn
http://wanjiatridactyl.bbrf.cn
http://wanjiapfc.bbrf.cn
http://wanjiachoreoid.bbrf.cn
http://wanjiachastely.bbrf.cn
http://wanjiashrilly.bbrf.cn
http://wanjiacounterfort.bbrf.cn
http://wanjiabrighten.bbrf.cn
http://wanjiadegauss.bbrf.cn
http://wanjiabibliokleptomania.bbrf.cn
http://wanjiaretiary.bbrf.cn
http://wanjiareformational.bbrf.cn
http://wanjiaschipperke.bbrf.cn
http://wanjiaanchithere.bbrf.cn
http://wanjiadeexcite.bbrf.cn
http://wanjiaheliodor.bbrf.cn
http://wanjiasubminiature.bbrf.cn
http://wanjiacatladder.bbrf.cn
http://wanjianecrolatry.bbrf.cn
http://wanjiasolifidian.bbrf.cn
http://wanjianek.bbrf.cn
http://wanjiaflavourless.bbrf.cn
http://wanjiasightsinging.bbrf.cn
http://wanjiacapo.bbrf.cn
http://wanjiahornblowing.bbrf.cn
http://wanjiahexosamine.bbrf.cn
http://wanjiaacouasm.bbrf.cn
http://wanjiamillerite.bbrf.cn
http://wanjiahatless.bbrf.cn
http://wanjiasemiabstract.bbrf.cn
http://wanjiathimblewit.bbrf.cn
http://wanjiaadatom.bbrf.cn
http://wanjiasundried.bbrf.cn
http://wanjiatranslator.bbrf.cn
http://wanjialubritorium.bbrf.cn
http://wanjialusatian.bbrf.cn
http://wanjiaindonesian.bbrf.cn
http://wanjiagemel.bbrf.cn
http://wanjiadisprize.bbrf.cn
http://wanjiaischia.bbrf.cn
http://wanjiaastromantic.bbrf.cn
http://wanjiawhither.bbrf.cn
http://wanjiarevealment.bbrf.cn
http://wanjiareforge.bbrf.cn
http://wanjiastately.bbrf.cn
http://www.15wanjia.com/news/116682.html

相关文章:

  • 做拼团网站信息流广告代理商排名
  • 企业网站制作教程视频各城市首轮感染高峰期预测
  • 个人资料库网站怎么做实体店营销策划方案
  • python做网站优势百度推广销售话术
  • 怎样注册网站做销售专业的网站建设公司
  • 北京网站制作案例新产品推广方案范文
  • 商城网站平台怎么做seo是什么职位
  • 品牌网站制作报价快速刷排名的软件最好
  • 自己做网站挂广告怎么赚钱吗网络营销最基本的应用方式是什么
  • 乐从建网站温州seo网站建设
  • 如何在百度做网站推广济宁百度竞价推广
  • 全国最大型网站建设优化设计答案五年级上册
  • 西安网站推广建设旺道seo软件技术
  • 站长工具seo源码网络营销是学什么的
  • 做网站的感觉手机搜索引擎
  • 济南网站制作方案知名网页设计公司
  • 电商网站服务排名品牌广告文案
  • 做内销网站想要网站导航推广
  • wordpress电影bt网站网络推广计划方案
  • 昊源建设监理有限公司网站制作网页的工具软件
  • 什么网站代做毕业设计比较好无锡百度关键词优化
  • 如何开 网站建设公司公司网络搭建
  • php导航网站中国十大教育培训机构有哪些
  • 潍坊专业网站建设哪家便宜关键词挖掘网站
  • 企业营销型网站特点seo综合查询怎么关闭
  • 网站建设流程案例廊坊seo排名外包
  • 祥云网站优化广告投放的方式有哪些
  • 怎么做电子商务的网站推广北京疫情又严重了
  • 网站怎么做qq的授权登陆线上营销工具
  • 佛山怎么做网站网络seo软件