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 43cde5bb45cc86d181d96ee69da1832e6132162871Michael Wright * MediaProjectionManager#createScreenCaptureIntent}. 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 * 73cde5bb45cc86d181d96ee69da1832e6132162871Michael Wright * @see #unregisterCallback 74c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 75cde5bb45cc86d181d96ee69da1832e6132162871Michael Wright public void registerCallback(Callback callback, Handler handler) { 76c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright if (callback == null) { 77c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright throw new IllegalArgumentException("callback should not be null"); 78c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 799e8d9aca07913b3e8a017614088048c721a82ccbMichael Wright if (handler == null) { 809e8d9aca07913b3e8a017614088048c721a82ccbMichael Wright handler = new Handler(); 819e8d9aca07913b3e8a017614088048c721a82ccbMichael Wright } 82c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallbacks.put(callback, new CallbackRecord(callback, handler)); 83c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 84c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 85c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** Unregister a MediaProjection listener. 86c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 87c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param callback The callback to unregister. 88c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 89cde5bb45cc86d181d96ee69da1832e6132162871Michael Wright * @see #registerCallback 90c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 91cde5bb45cc86d181d96ee69da1832e6132162871Michael Wright public void unregisterCallback(Callback callback) { 92c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright if (callback == null) { 93c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright throw new IllegalArgumentException("callback should not be null"); 94c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 95c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallbacks.remove(callback); 96c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 97c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 98c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 996720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright * @hide 1006720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright */ 1016720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright public VirtualDisplay createVirtualDisplay(@NonNull String name, 1026720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright int width, int height, int dpi, boolean isSecure, @Nullable Surface surface, 10375ee9fcde4d9e1be3883eba6c8d193db4375b052Michael Wright @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) { 1046720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); 1056720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright int flags = isSecure ? DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE : 0; 1066720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright return dm.createVirtualDisplay(this, name, width, height, dpi, surface, 1076720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright flags | DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR | 10875ee9fcde4d9e1be3883eba6c8d193db4375b052Michael Wright DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, callback, handler); 1096720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright } 1106720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright 1116720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright /** 112c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Creates a {@link android.hardware.display.VirtualDisplay} to capture the 113c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * contents of the screen. 114c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 115c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param name The name of the virtual display, must be non-empty. 116c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param width The width of the virtual display in pixels. Must be 117c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * greater than 0. 118c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param height The height of the virtual display in pixels. Must be 119c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * greater than 0. 120c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param dpi The density of the virtual display in dpi. Must be greater 121c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * than 0. 122c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param surface The surface to which the content of the virtual display 123c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * should be rendered, or null if there is none initially. 1246720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright * @param flags A combination of virtual display flags. See {@link DisplayManager} for the full 1256720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright * list of flags. 12675ee9fcde4d9e1be3883eba6c8d193db4375b052Michael Wright * @param callback Callback to call when the virtual display's state 127c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * changes, or null if none. 128c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @param handler The {@link android.os.Handler} on which the callback should be 129c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * invoked, or null if the callback should be invoked on the calling 130c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * thread's main {@link android.os.Looper}. 131c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * 1321e88cf0796c8b15952b7d6b3160d0d097e857f15Ryan Lothian * @see android.hardware.display.VirtualDisplay 133c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 134c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public VirtualDisplay createVirtualDisplay(@NonNull String name, 1356720be4e8c65e90d4453ddad5cef192bc3820038Michael Wright int width, int height, int dpi, int flags, @Nullable Surface surface, 13675ee9fcde4d9e1be3883eba6c8d193db4375b052Michael Wright @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) { 137c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); 138c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright return dm.createVirtualDisplay( 13975ee9fcde4d9e1be3883eba6c8d193db4375b052Michael Wright this, name, width, height, dpi, surface, flags, callback, handler); 140c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 141c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 142c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 143c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Creates an AudioRecord to capture audio played back by the system. 144d5bfcff975cadc037d836bdab2f0976a40fad4dfMichael Wright * @hide 145c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 146c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public AudioRecord createAudioRecord( 147c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright int sampleRateInHz, int channelConfig, 148c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright int audioFormat, int bufferSizeInBytes) { 149c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright return null; 150c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 151c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 152c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 153c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Stops projection. 154c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 155c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void stop() { 156c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright try { 157c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mImpl.stop(); 158c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } catch (RemoteException e) { 159c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright Log.e(TAG, "Unable to stop projection", e); 160c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 161c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 162c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 163c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 164c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Get the underlying IMediaProjection. 165c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * @hide 166c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 167c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public IMediaProjection getProjection() { 168c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright return mImpl; 169c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 170c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 171c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 172c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Callbacks for the projection session. 173c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 174c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public static abstract class Callback { 175c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright /** 176c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Called when the MediaProjection session is no longer valid. 1779469cdde2ce55051b18fdbd6bf80bc710517c358Michael Wright * <p> 178c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * Once a MediaProjection has been stopped, it's up to the application to release any 179c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright * resources it may be holding (e.g. {@link android.hardware.display.VirtualDisplay}s). 1809469cdde2ce55051b18fdbd6bf80bc710517c358Michael Wright * </p> 181c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright */ 182c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void onStop() { } 183c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 184c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 185c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private final class MediaProjectionCallback extends IMediaProjectionCallback.Stub { 186c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright @Override 187c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void onStop() { 1889e8d9aca07913b3e8a017614088048c721a82ccbMichael Wright for (CallbackRecord cbr : mCallbacks.values()) { 1899e8d9aca07913b3e8a017614088048c721a82ccbMichael Wright cbr.onStop(); 190c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 191c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 192c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 193c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 194c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright private final static class CallbackRecord { 1959e8d9aca07913b3e8a017614088048c721a82ccbMichael Wright private final Callback mCallback; 1969e8d9aca07913b3e8a017614088048c721a82ccbMichael Wright private final Handler mHandler; 197c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 198c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public CallbackRecord(Callback callback, Handler handler) { 199c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallback = callback; 200c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mHandler = handler; 201c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 202c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright 203c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void onStop() { 204c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mHandler.post(new Runnable() { 205c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright @Override 206c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright public void run() { 207c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright mCallback.onStop(); 208c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 209c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright }); 210c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 211c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright } 212c39d47a8e7c74bd539104b0efab898ef6fc43ddfMichael Wright} 213