MediaProjection.java revision 9469cdde2ce55051b18fdbd6bf80bc710517c358
1c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright/* 2c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Copyright (C) 2014 The Android Open Source Project 3c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 4c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Licensed under the Apache License, Version 2.0 (the "License"); 5c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * you may not use this file except in compliance with the License. 6c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * You may obtain a copy of the License at 7c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 8c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * http://www.apache.org/licenses/LICENSE-2.0 9c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 10c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Unless required by applicable law or agreed to in writing, software 11c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * distributed under the License is distributed on an "AS IS" BASIS, 12c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * See the License for the specific language governing permissions and 14c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * limitations under the License. 15c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 16c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 17c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightpackage android.media.projection; 18c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 19c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.annotation.NonNull; 20c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.annotation.Nullable; 21c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.content.Context; 22c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.hardware.display.DisplayManager; 23c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.hardware.display.VirtualDisplay; 24c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.media.AudioRecord; 25c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.media.projection.IMediaProjection; 26c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.media.projection.IMediaProjectionCallback; 27c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.os.Handler; 28c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.os.Looper; 29c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.os.RemoteException; 30c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.util.ArrayMap; 31c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.util.Log; 32c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport android.view.Surface; 33c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 34c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightimport java.util.Map; 35c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 36c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright/** 37c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * A token granting applications the ability to capture screen contents and/or 38c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * record system audio. The exact capabilities granted depend on the type of 39c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * MediaProjection. 40c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 41c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * <p> 42c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * A screen capture session can be started through {@link 43c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * MediaProjectionManager#getScreenCaptureIntent}. This grants the ability to 44c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * capture screen contents, but not system audio. 45c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * </p> 46c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 47c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wrightpublic final class MediaProjection { 48c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private static final String TAG = "MediaProjection"; 49c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 50c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private final IMediaProjection mImpl; 51c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private final Context mContext; 52c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private final Map<Callback, CallbackRecord> mCallbacks; 53c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 54c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** @hide */ 55c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public MediaProjection(Context context, IMediaProjection impl) { 56c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallbacks = new ArrayMap<Callback, CallbackRecord>(); 57c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mContext = context; 58c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mImpl = impl; 59c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright try { 60c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mImpl.start(new MediaProjectionCallback()); 61c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } catch (RemoteException e) { 62c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright throw new RuntimeException("Failed to start media projection", e); 63c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 64c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 65c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 66c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** Register a listener to receive notifications about when the {@link 67c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * MediaProjection} changes state. 68c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 69c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param callback The callback to call. 70c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param handler The handler on which the callback should be invoked, or 71c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * null if the callback should be invoked on the calling thread's looper. 72c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 73c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @see #removeCallback 74c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 75c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void addCallback(Callback callback, Handler handler) { 76c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright if (callback == null) { 77c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright throw new IllegalArgumentException("callback should not be null"); 78c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 79c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallbacks.put(callback, new CallbackRecord(callback, handler)); 80c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 81c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 82c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** Unregister a MediaProjection listener. 83c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 84c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param callback The callback to unregister. 85c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 86c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @see #addCallback 87c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 88c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void removeCallback(Callback callback) { 89c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright if (callback == null) { 90c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright throw new IllegalArgumentException("callback should not be null"); 91c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 92c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallbacks.remove(callback); 93c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 94c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 95c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 96c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Creates a {@link android.hardware.display.VirtualDisplay} to capture the 97c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * contents of the screen. 98c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 99c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param name The name of the virtual display, must be non-empty. 100c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param width The width of the virtual display in pixels. Must be 101c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * greater than 0. 102c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param height The height of the virtual display in pixels. Must be 103c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * greater than 0. 104c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param dpi The density of the virtual display in dpi. Must be greater 105c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * than 0. 106c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param surface The surface to which the content of the virtual display 107c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * should be rendered, or null if there is none initially. 108c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param isSecure Whether the display should be considered a secure 109c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * display. This typically requires special permissions not available to 110c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * third party applications. 111c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param callbacks Callbacks to call when the virtual display's state 112c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * changes, or null if none. 113c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param handler The {@link android.os.Handler} on which the callback should be 114c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * invoked, or null if the callback should be invoked on the calling 115c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * thread's main {@link android.os.Looper}. 116c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 117c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @see android.hardware.display.DisplayManager#createVirtualDisplay( 118c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * String, int, int, int, int, Surface, VirtualDisplay.Callbacks, Handler) 119c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 120c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public VirtualDisplay createVirtualDisplay(@NonNull String name, 121c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright int width, int height, int dpi, boolean isSecure, @Nullable Surface surface, 122c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright @Nullable VirtualDisplay.Callbacks callbacks, @Nullable Handler handler) { 123c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); 124c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright int flags = isSecure ? DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE : 0; 125c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright return dm.createVirtualDisplay( 126c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright this, name, width, height, dpi, surface, flags, callbacks, handler); 127c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 128c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 129c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 130c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Creates an AudioRecord to capture audio played back by the system. 131c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 132c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public AudioRecord createAudioRecord( 133c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright int sampleRateInHz, int channelConfig, 134c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright int audioFormat, int bufferSizeInBytes) { 135c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright return null; 136c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 137c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 138c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 139c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Stops projection. 140c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 141c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void stop() { 142c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright try { 143c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mImpl.stop(); 144c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } catch (RemoteException e) { 145c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright Log.e(TAG, "Unable to stop projection", e); 146c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 147c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 148c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 149c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 150c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Get the underlying IMediaProjection. 151c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @hide 152c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 153c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public IMediaProjection getProjection() { 154c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright return mImpl; 155c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 156c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 157c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 158c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Callbacks for the projection session. 159c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 160c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public static abstract class Callback { 161c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 162c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Called when the MediaProjection session is no longer valid. 1639469cdde2ce55051b18fdbd6bf80bc710517c358Michael Wright * <p> 164c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Once a MediaProjection has been stopped, it's up to the application to release any 165c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * resources it may be holding (e.g. {@link android.hardware.display.VirtualDisplay}s). 1669469cdde2ce55051b18fdbd6bf80bc710517c358Michael Wright * </p> 167c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 168c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void onStop() { } 169c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 170c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 171c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private final class MediaProjectionCallback extends IMediaProjectionCallback.Stub { 172c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright @Override 173c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void onStop() { 174c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright final int N = mCallbacks.size(); 175c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright for (int i = 0; i < N; i++) { 176c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallbacks.get(i).onStop(); 177c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 178c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 179c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 180c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 181c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private final static class CallbackRecord { 182c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private Callback mCallback; 183c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private Handler mHandler; 184c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 185c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public CallbackRecord(Callback callback, Handler handler) { 186c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallback = callback; 187c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mHandler = handler; 188c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 189c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 190c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void onStop() { 191c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mHandler.post(new Runnable() { 192c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright @Override 193c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void run() { 194c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallback.onStop(); 195c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 196c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright }); 197c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 198c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 199c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright} 200