package com.android.internal.util; import static android.content.Intent.ACTION_USER_SWITCHED; import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; import android.view.WindowManager.ScreenshotSource; import android.view.WindowManager.ScreenshotType; import com.android.internal.annotations.VisibleForTesting; import java.util.function.Consumer; public class ScreenshotHelper { public static final int SCREENSHOT_MSG_URI = 1; public static final int SCREENSHOT_MSG_PROCESS_COMPLETE = 2; private static final String TAG = "ScreenshotHelper"; // Time until we give up on the screenshot & show an error instead. private final int SCREENSHOT_TIMEOUT_MS = 10000; private final Object mScreenshotLock = new Object(); private IBinder mScreenshotService = null; private ServiceConnection mScreenshotConnection = null; private final Context mContext; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { synchronized (mScreenshotLock) { if (ACTION_USER_SWITCHED.equals(intent.getAction())) { resetConnection(); } } } }; public ScreenshotHelper(Context context) { mContext = context; IntentFilter filter = new IntentFilter(ACTION_USER_SWITCHED); mContext.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED); } /** * Request a screenshot be taken. *
* Convenience method for taking a full screenshot with provided source.
*
* @param source source of the screenshot request, defined by {@link
* ScreenshotSource}
* @param handler used to process messages received from the screenshot service
* @param completionConsumer receives the URI of the captured screenshot, once saved or
* null if no screenshot was saved
*/
public void takeScreenshot(@ScreenshotSource int source, @NonNull Handler handler,
@Nullable Consumer
* Convenience method for taking a full screenshot with provided source.
*
* @param type type of screenshot, defined by {@link ScreenshotType}
* @param source source of the screenshot request, defined by {@link
* ScreenshotSource}
* @param handler used to process messages received from the screenshot service
* @param completionConsumer receives the URI of the captured screenshot, once saved or
* null if no screenshot was saved
*/
public void takeScreenshot(@ScreenshotType int type, @ScreenshotSource int source,
@NonNull Handler handler, @Nullable Consumer
*
* @param request description of the screenshot request, either for taking a
* screenshot or
* providing a bitmap
* @param handler used to process messages received from the screenshot service
* @param completionConsumer receives the URI of the captured screenshot, once saved or
* null if no screenshot was saved
*/
public void takeScreenshot(ScreenshotRequest request, @NonNull Handler handler,
@Nullable Consumer
* Added to support reducing unit test duration; the method variant without a timeout argument
* is recommended for general use.
*
* @param request description of the screenshot request, either for taking a
* screenshot or providing a bitmap
* @param handler used to process messages received from the screenshot service
* @param timeoutMs time limit for processing, intended only for testing
* @param completionConsumer receives the URI of the captured screenshot, once saved or
* null if no screenshot was saved
*/
@VisibleForTesting
public void takeScreenshotInternal(ScreenshotRequest request, @NonNull Handler handler,
@Nullable Consumer