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: Ica974b8a19803eb27759c03b1c3cad7538188fd6 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user