diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index 822a6669bd5c4..0383dee4f9c35 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -27,32 +27,29 @@ import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.Point; import android.graphics.drawable.Icon; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.MediaRecorder; -import android.media.ThumbnailUtils; import android.media.projection.MediaProjection; import android.media.projection.MediaProjectionManager; import android.net.Uri; -import android.os.Environment; import android.os.IBinder; import android.provider.MediaStore; import android.provider.Settings; import android.util.DisplayMetrics; import android.util.Log; +import android.util.Size; import android.view.Surface; import android.widget.Toast; -import androidx.core.content.FileProvider; - import com.android.systemui.R; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; -import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Date; @@ -79,12 +76,10 @@ public class RecordingService extends Service { private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE"; private static final int TOTAL_NUM_TRACKS = 1; - private static final String RECORD_DIR = "Captures"; // TODO: use a translatable string private static final int VIDEO_BIT_RATE = 6000000; private static final int VIDEO_FRAME_RATE = 30; private static final int AUDIO_BIT_RATE = 16; private static final int AUDIO_SAMPLE_RATE = 44100; - private static final String FILE_PROVIDER = "com.android.systemui.fileprovider"; private MediaProjectionManager mMediaProjectionManager; private MediaProjection mMediaProjection; @@ -120,11 +115,11 @@ public class RecordingService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "RecordingService is starting"); if (intent == null) { return Service.START_NOT_STICKY; } String action = intent.getAction(); + Log.d(TAG, "onStartCommand " + action); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); @@ -160,41 +155,7 @@ public class RecordingService extends Service { case ACTION_STOP: stopRecording(); - - String fileName = new SimpleDateFormat("'screen-'yyyyMMdd-HHmmss'.mp4'") - .format(new Date()); - - ContentValues values = new ContentValues(); - values.put(MediaStore.Video.Media.DISPLAY_NAME, fileName); - values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4"); - values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis()); - values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis()); - - ContentResolver resolver = getContentResolver(); - Uri collectionUri = MediaStore.Video.Media.getContentUri( - MediaStore.VOLUME_EXTERNAL_PRIMARY); - Uri itemUri = resolver.insert(collectionUri, values); - - File recordDir = new File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), - RECORD_DIR); - recordDir.mkdirs(); - Path path = new File(recordDir, fileName).toPath(); - try { - // Move file out of temp directory - Files.move(mTempFile.toPath(), path); - - // Add to the mediastore - OutputStream os = resolver.openOutputStream(itemUri, "w"); - Files.copy(path, os); - os.close(); - - Notification notification = createSaveNotification(itemUri, path); - notificationManager.notify(NOTIFICATION_ID, notification); - } catch (IOException e) { - e.printStackTrace(); - Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG) - .show(); - } + saveRecording(notificationManager); break; case ACTION_PAUSE: @@ -208,8 +169,7 @@ public class RecordingService extends Service { break; case ACTION_SHARE: - File shareFile = new File(intent.getStringExtra(EXTRA_PATH)); - Uri shareUri = FileProvider.getUriForFile(this, FILE_PROVIDER, shareFile); + Uri shareUri = Uri.parse(intent.getStringExtra(EXTRA_PATH)); Intent shareIntent = new Intent(Intent.ACTION_SEND) .setType("video/mp4") @@ -229,20 +189,18 @@ public class RecordingService extends Service { // Close quick shade sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - File file = new File(intent.getStringExtra(EXTRA_PATH)); - if (file.delete()) { - Toast.makeText( - this, - R.string.screenrecord_delete_description, - Toast.LENGTH_LONG).show(); + ContentResolver resolver = getContentResolver(); + Uri uri = Uri.parse(intent.getStringExtra(EXTRA_PATH)); + resolver.delete(uri, null, null); - // Remove notification - notificationManager.cancel(NOTIFICATION_ID); - } else { - Log.e(TAG, "Error deleting screen recording!"); - Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG) - .show(); - } + Toast.makeText( + this, + R.string.screenrecord_delete_description, + Toast.LENGTH_LONG).show(); + + // Remove notification + notificationManager.cancel(NOTIFICATION_ID); + Log.d(TAG, "Deleted recording " + uri); break; } return Service.START_STICKY; @@ -313,6 +271,7 @@ public class RecordingService extends Service { mMediaRecorder.start(); } catch (IOException e) { + Log.e(TAG, "Error starting screen recording: " + e.getMessage()); e.printStackTrace(); throw new RuntimeException(e); } @@ -370,9 +329,7 @@ public class RecordingService extends Service { notificationManager.notify(NOTIFICATION_ID, mRecordingNotificationBuilder.build()); } - private Notification createSaveNotification(Uri uri, Path path) { - Log.d(TAG, "Screen recording saved to " + uri.toString() + ", " + path.toString()); - + private Notification createSaveNotification(Uri uri) { Intent viewIntent = new Intent(Intent.ACTION_VIEW) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION) .setDataAndType(uri, "video/mp4"); @@ -411,8 +368,15 @@ public class RecordingService extends Service { .setAutoCancel(true); // Add thumbnail if available - Bitmap thumbnailBitmap = ThumbnailUtils.createVideoThumbnail(path.toString(), - MediaStore.Video.Thumbnails.MINI_KIND); + Bitmap thumbnailBitmap = null; + try { + ContentResolver resolver = getContentResolver(); + Size size = Point.convert(MediaStore.ThumbnailConstants.MINI_SIZE); + thumbnailBitmap = resolver.loadThumbnail(uri, size, null); + } catch (IOException e) { + Log.e(TAG, "Error creating thumbnail: " + e.getMessage()); + e.printStackTrace(); + } if (thumbnailBitmap != null) { Notification.BigPictureStyle pictureStyle = new Notification.BigPictureStyle() .bigPicture(thumbnailBitmap) @@ -434,6 +398,38 @@ public class RecordingService extends Service { stopSelf(); } + private void saveRecording(NotificationManager notificationManager) { + String fileName = new SimpleDateFormat("'screen-'yyyyMMdd-HHmmss'.mp4'") + .format(new Date()); + + ContentValues values = new ContentValues(); + values.put(MediaStore.Video.Media.DISPLAY_NAME, fileName); + values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4"); + values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis()); + values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis()); + + ContentResolver resolver = getContentResolver(); + Uri collectionUri = MediaStore.Video.Media.getContentUri( + MediaStore.VOLUME_EXTERNAL_PRIMARY); + Uri itemUri = resolver.insert(collectionUri, values); + + try { + // Add to the mediastore + OutputStream os = resolver.openOutputStream(itemUri, "w"); + Files.copy(mTempFile.toPath(), os); + os.close(); + + Notification notification = createSaveNotification(itemUri); + notificationManager.notify(NOTIFICATION_ID, notification); + + mTempFile.delete(); + } catch (IOException e) { + Log.e(TAG, "Error saving screen recording: " + e.getMessage()); + Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG) + .show(); + } + } + private void setTapsVisible(boolean turnOn) { int value = turnOn ? 1 : 0; Settings.System.putInt(getApplicationContext().getContentResolver(),