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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18723155

Change-Id: Idc5126896fb308bb8ad8bd2e8ca92780069cda39
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Matt Casey
2022-06-10 20:28:59 +00:00
committed by Automerger Merge Worker
2 changed files with 56 additions and 20 deletions

View File

@@ -83,6 +83,8 @@ import android.view.accessibility.AccessibilityManager;
import android.widget.Toast; import android.widget.Toast;
import android.window.WindowContext; import android.window.WindowContext;
import androidx.concurrent.futures.CallbackToFutureAdapter;
import com.android.internal.app.ChooserActivity; import com.android.internal.app.ChooserActivity;
import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.PhoneWindow; import com.android.internal.policy.PhoneWindow;
@@ -254,7 +256,7 @@ public class ScreenshotController {
private final WindowManager mWindowManager; private final WindowManager mWindowManager;
private final WindowManager.LayoutParams mWindowLayoutParams; private final WindowManager.LayoutParams mWindowLayoutParams;
private final AccessibilityManager mAccessibilityManager; private final AccessibilityManager mAccessibilityManager;
private final MediaPlayer mCameraSound; private final ListenableFuture<MediaPlayer> mCameraSound;
private final ScrollCaptureClient mScrollCaptureClient; private final ScrollCaptureClient mScrollCaptureClient;
private final PhoneWindow mWindow; private final PhoneWindow mWindow;
private final DisplayManager mDisplayManager; private final DisplayManager mDisplayManager;
@@ -338,13 +340,7 @@ public class ScreenshotController {
reloadAssets(); reloadAssets();
// Setup the Camera shutter sound // Setup the Camera shutter sound
mCameraSound = MediaPlayer.create(mContext, mCameraSound = loadCameraSound();
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());
mCopyBroadcastReceiver = new BroadcastReceiver() { mCopyBroadcastReceiver = new BroadcastReceiver() {
@Override @Override
@@ -442,16 +438,32 @@ public class ScreenshotController {
return mScreenshotView.isPendingSharedTransition(); return mScreenshotView.isPendingSharedTransition();
} }
// Any cleanup needed when the service is being destroyed.
void onDestroy() {
removeWindow();
releaseMediaPlayer();
releaseContext();
mBgExecutor.shutdownNow();
}
/** /**
* Release the constructed window context. * Release the constructed window context.
*/ */
void releaseContext() { private void releaseContext() {
mContext.unregisterReceiver(mCopyBroadcastReceiver); mContext.unregisterReceiver(mCopyBroadcastReceiver);
mContext.release(); 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 * Save the bitmap but don't show the normal screenshot UI.. just a toast (or notification on
* failure). * failure).
*/ */
private void saveScreenshotAndToast(Consumer<Uri> finisher) { private void saveScreenshotAndToast(Consumer<Uri> finisher) {
// Play the shutter sound to notify that we've taken a screenshot // Play the shutter sound to notify that we've taken a screenshot
if (mCameraSound != null) { playCameraSound();
mCameraSound.start();
}
saveScreenshotInWorkerThread( saveScreenshotInWorkerThread(
/* onComplete */ finisher, /* onComplete */ finisher,
@@ -864,9 +903,7 @@ public class ScreenshotController {
mScreenshotView.createScreenshotDropInAnimation(screenRect, showFlash); mScreenshotView.createScreenshotDropInAnimation(screenRect, showFlash);
// Play the shutter sound to notify that we've taken a screenshot // Play the shutter sound to notify that we've taken a screenshot
if (mCameraSound != null) { playCameraSound();
mCameraSound.start();
}
if (DEBUG_ANIM) { if (DEBUG_ANIM) {
Log.d(TAG, "starting post-screenshot animation"); Log.d(TAG, "starting post-screenshot animation");

View File

@@ -153,8 +153,7 @@ public class TakeScreenshotService extends Service {
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
if (mScreenshot != null) { if (mScreenshot != null) {
mScreenshot.removeWindow(); mScreenshot.onDestroy();
mScreenshot.releaseContext();
mScreenshot = null; mScreenshot = null;
} }
if (DEBUG_SERVICE) { if (DEBUG_SERVICE) {