Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7358c9d authored by Matt Casey's avatar Matt Casey Committed by Android (Google) Code Review
Browse files

Merge "Use MediaPlayer in a background thread." into tm-dev

parents ae7ebc51 e51f6556
Loading
Loading
Loading
Loading
+55 −18
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@ import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
import android.window.WindowContext;

import androidx.concurrent.futures.CallbackToFutureAdapter;

import com.android.internal.app.ChooserActivity;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.PhoneWindow;
@@ -254,7 +256,7 @@ public class ScreenshotController {
    private final WindowManager mWindowManager;
    private final WindowManager.LayoutParams mWindowLayoutParams;
    private final AccessibilityManager mAccessibilityManager;
    private final MediaPlayer mCameraSound;
    private final ListenableFuture<MediaPlayer> mCameraSound;
    private final ScrollCaptureClient mScrollCaptureClient;
    private final PhoneWindow mWindow;
    private final DisplayManager mDisplayManager;
@@ -338,13 +340,7 @@ public class ScreenshotController {
        reloadAssets();

        // Setup the Camera shutter sound
        mCameraSound = MediaPlayer.create(mContext,
                Uri.fromFile(new File(mContext.getResources().getString(
                        com.android.internal.R.string.config_cameraShutterSound))), null,
                new AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .build(), AudioSystem.newAudioSessionId());
        mCameraSound = loadCameraSound();

        mCopyBroadcastReceiver = new BroadcastReceiver() {
            @Override
@@ -442,16 +438,32 @@ public class ScreenshotController {
        return mScreenshotView.isPendingSharedTransition();
    }

    // Any cleanup needed when the service is being destroyed.
    void onDestroy() {
        removeWindow();
        releaseMediaPlayer();
        releaseContext();
        mBgExecutor.shutdownNow();
    }

    /**
     * Release the constructed window context.
     */
    void releaseContext() {
    private void releaseContext() {
        mContext.unregisterReceiver(mCopyBroadcastReceiver);
        mContext.release();
        if (mCameraSound != null) {
            mCameraSound.release();
    }
        mBgExecutor.shutdownNow();

    private void releaseMediaPlayer() {
        // Note that this may block if the sound is still being loaded (very unlikely) but we can't
        // reliably release in the background because the service is being destroyed.
        try {
            MediaPlayer player = mCameraSound.get();
            if (player != null) {
                player.release();
            }
        } catch (InterruptedException | ExecutionException e) {
        }
    }

    /**
@@ -822,15 +834,42 @@ public class ScreenshotController {
        }
    }

    private ListenableFuture<MediaPlayer> loadCameraSound() {
        // The media player creation is slow and needs on the background thread.
        return CallbackToFutureAdapter.getFuture((completer) -> {
            mBgExecutor.execute(() -> {
                MediaPlayer player = MediaPlayer.create(mContext,
                        Uri.fromFile(new File(mContext.getResources().getString(
                                com.android.internal.R.string.config_cameraShutterSound))), null,
                        new AudioAttributes.Builder()
                                .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                                .build(), AudioSystem.newAudioSessionId());
                completer.set(player);
            });
            return "ScreenshotController#loadCameraSound";
        });
    }

    private void playCameraSound() {
        mCameraSound.addListener(() -> {
            try {
                MediaPlayer player = mCameraSound.get();
                if (player != null) {
                    player.start();
                }
            } catch (InterruptedException | ExecutionException e) {
            }
        }, mBgExecutor);
    }

    /**
     * Save the bitmap but don't show the normal screenshot UI.. just a toast (or notification on
     * failure).
     */
    private void saveScreenshotAndToast(Consumer<Uri> finisher) {
        // Play the shutter sound to notify that we've taken a screenshot
        if (mCameraSound != null) {
            mCameraSound.start();
        }
        playCameraSound();

        saveScreenshotInWorkerThread(
                /* onComplete */ finisher,
@@ -864,9 +903,7 @@ public class ScreenshotController {
                mScreenshotView.createScreenshotDropInAnimation(screenRect, showFlash);

        // Play the shutter sound to notify that we've taken a screenshot
        if (mCameraSound != null) {
            mCameraSound.start();
        }
        playCameraSound();

        if (DEBUG_ANIM) {
            Log.d(TAG, "starting post-screenshot animation");
+1 −2
Original line number Diff line number Diff line
@@ -153,8 +153,7 @@ public class TakeScreenshotService extends Service {
    public void onDestroy() {
        super.onDestroy();
        if (mScreenshot != null) {
            mScreenshot.removeWindow();
            mScreenshot.releaseContext();
            mScreenshot.onDestroy();
            mScreenshot = null;
        }
        if (DEBUG_SERVICE) {