diff --git a/packages/SystemUI/res/drawable/ic_touch.xml b/packages/SystemUI/res/drawable/ic_touch.xml
new file mode 100644
index 0000000000000..4f6698de5251f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_touch.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/screen_record_dialog.xml b/packages/SystemUI/res/layout/screen_record_dialog.xml
new file mode 100644
index 0000000000000..df576d83323f1
--- /dev/null
+++ b/packages/SystemUI/res/layout/screen_record_dialog.xml
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5a1d1e21ae1cc..c4fa4e5d4ef3a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1209,5 +1209,7 @@
2dp
-
+
+ 18dp
+ 24dp
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 07a926fa75d3b..b85b51e4f2cc0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -217,15 +217,31 @@
your organization
- Screen Recording
+ Screen Recorder
Ongoing notification for a screen record session
-
- Start Recording
-
- Record voiceover
+
+ Start Recording?
+
+ While recording, Android System can capture any sensitive information that\u2019s visible on your screen or played on your device. This includes passwords, payment info, photos, messages, and audio.
+
+ Record audio
+
+ Device audio
+
+ Sound from your device, like music, calls, and ringtones
+
+ Microphone
+
+ Device audio and microphone
+
+ Start
+
+ Recording screen
+
+ Recording screen and audio
- Show taps
+ Show touches on screen
Tap to stop
@@ -250,6 +266,8 @@
Error deleting screen recording
Failed to get permissions
+
+ Error starting screen recording
USB file transfer options
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index b091ad8c0db84..626f298055a09 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -16,7 +16,6 @@
package com.android.systemui.screenrecord;
-import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -26,16 +25,21 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
+import android.media.projection.IMediaProjection;
+import android.media.projection.IMediaProjectionManager;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.provider.MediaStore;
import android.provider.Settings;
import android.util.DisplayMetrics;
@@ -83,7 +87,6 @@ public class RecordingService extends Service {
private static final int AUDIO_SAMPLE_RATE = 44100;
private final RecordingController mController;
- private MediaProjectionManager mMediaProjectionManager;
private MediaProjection mMediaProjection;
private Surface mInputSurface;
private VirtualDisplay mVirtualDisplay;
@@ -134,13 +137,30 @@ public class RecordingService extends Service {
switch (action) {
case ACTION_START:
- int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, Activity.RESULT_CANCELED);
mUseAudio = intent.getBooleanExtra(EXTRA_USE_AUDIO, false);
mShowTaps = intent.getBooleanExtra(EXTRA_SHOW_TAPS, false);
- Intent data = intent.getParcelableExtra(EXTRA_DATA);
- if (data != null) {
- mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);
+ try {
+ IBinder b = ServiceManager.getService(MEDIA_PROJECTION_SERVICE);
+ IMediaProjectionManager mediaService =
+ IMediaProjectionManager.Stub.asInterface(b);
+ IMediaProjection proj = mediaService.createProjection(getUserId(),
+ getPackageName(),
+ MediaProjectionManager.TYPE_SCREEN_CAPTURE, false);
+ IBinder projection = proj.asBinder();
+ if (projection == null) {
+ Log.e(TAG, "Projection was null");
+ Toast.makeText(this, R.string.screenrecord_start_error, Toast.LENGTH_LONG)
+ .show();
+ return Service.START_NOT_STICKY;
+ }
+ mMediaProjection = new MediaProjection(getApplicationContext(),
+ IMediaProjection.Stub.asInterface(projection));
startRecording();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ Toast.makeText(this, R.string.screenrecord_start_error, Toast.LENGTH_LONG)
+ .show();
+ return Service.START_NOT_STICKY;
}
break;
@@ -195,9 +215,6 @@ public class RecordingService extends Service {
@Override
public void onCreate() {
super.onCreate();
-
- mMediaProjectionManager =
- (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
}
/**
@@ -269,6 +286,7 @@ public class RecordingService extends Service {
}
private void createRecordingNotification() {
+ Resources res = getResources();
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
getString(R.string.screenrecord_name),
@@ -281,11 +299,15 @@ public class RecordingService extends Service {
Bundle extras = new Bundle();
extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
- getResources().getString(R.string.screenrecord_name));
+ res.getString(R.string.screenrecord_name));
+
+ String notificationTitle = mUseAudio
+ ? res.getString(R.string.screenrecord_ongoing_screen_and_audio)
+ : res.getString(R.string.screenrecord_ongoing_screen_only);
mRecordingNotificationBuilder = new Notification.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_screenrecord)
- .setContentTitle(getResources().getString(R.string.screenrecord_name))
+ .setContentTitle(notificationTitle)
.setContentText(getResources().getString(R.string.screenrecord_stop_text))
.setUsesChronometer(true)
.setColorized(true)
@@ -332,8 +354,7 @@ public class RecordingService extends Service {
Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_screenrecord)
- .setContentTitle(getResources().getString(R.string.screenrecord_name))
- .setContentText(getResources().getString(R.string.screenrecord_save_message))
+ .setContentTitle(getResources().getString(R.string.screenrecord_save_message))
.setContentIntent(PendingIntent.getActivity(
this,
REQUEST_CODE,
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
index 8324986123bd0..566f12b427957 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
@@ -16,15 +16,14 @@
package com.android.systemui.screenrecord;
-import android.Manifest;
import android.app.Activity;
import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
-import android.widget.Toast;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.Switch;
import com.android.systemui.R;
@@ -34,15 +33,11 @@ import javax.inject.Inject;
* Activity to select screen recording options
*/
public class ScreenRecordDialog extends Activity {
- private static final int REQUEST_CODE_VIDEO_ONLY = 200;
- private static final int REQUEST_CODE_VIDEO_TAPS = 201;
- private static final int REQUEST_CODE_PERMISSIONS = 299;
- private static final int REQUEST_CODE_VIDEO_AUDIO = 300;
- private static final int REQUEST_CODE_VIDEO_AUDIO_TAPS = 301;
- private static final int REQUEST_CODE_PERMISSIONS_AUDIO = 399;
private static final long DELAY_MS = 3000;
private final RecordingController mController;
+ private Switch mAudioSwitch;
+ private Switch mTapsSwitch;
@Inject
public ScreenRecordDialog(RecordingController controller) {
@@ -52,81 +47,42 @@ public class ScreenRecordDialog extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- requestScreenCapture();
+
+ Window window = getWindow();
+ // Inflate the decor view, so the attributes below are not overwritten by the theme.
+ window.getDecorView();
+ window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ window.setGravity(Gravity.TOP);
+
+ setContentView(R.layout.screen_record_dialog);
+
+ Button cancelBtn = findViewById(R.id.button_cancel);
+ cancelBtn.setOnClickListener(v -> {
+ finish();
+ });
+
+ Button startBtn = findViewById(R.id.button_start);
+ startBtn.setOnClickListener(v -> {
+ requestScreenCapture();
+ finish();
+ });
+
+ mAudioSwitch = findViewById(R.id.screenrecord_audio_switch);
+ mTapsSwitch = findViewById(R.id.screenrecord_taps_switch);
}
private void requestScreenCapture() {
- MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(
- Context.MEDIA_PROJECTION_SERVICE);
- Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent();
-
- // TODO get saved settings
- boolean useAudio = false;
- boolean showTaps = false;
- if (useAudio) {
- startActivityForResult(permissionIntent,
- showTaps ? REQUEST_CODE_VIDEO_AUDIO_TAPS : REQUEST_CODE_VIDEO_AUDIO);
- } else {
- startActivityForResult(permissionIntent,
- showTaps ? REQUEST_CODE_VIDEO_TAPS : REQUEST_CODE_VIDEO_ONLY);
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- boolean showTaps = (requestCode == REQUEST_CODE_VIDEO_TAPS
- || requestCode == REQUEST_CODE_VIDEO_AUDIO_TAPS);
- boolean useAudio = (requestCode == REQUEST_CODE_VIDEO_AUDIO
- || requestCode == REQUEST_CODE_VIDEO_AUDIO_TAPS);
- switch (requestCode) {
- case REQUEST_CODE_VIDEO_TAPS:
- case REQUEST_CODE_VIDEO_AUDIO_TAPS:
- case REQUEST_CODE_VIDEO_ONLY:
- case REQUEST_CODE_VIDEO_AUDIO:
- if (resultCode == RESULT_OK) {
- PendingIntent startIntent = PendingIntent.getForegroundService(
- this, RecordingService.REQUEST_CODE, RecordingService.getStartIntent(
- ScreenRecordDialog.this, resultCode, data, useAudio,
- showTaps),
- PendingIntent.FLAG_UPDATE_CURRENT
- );
- PendingIntent stopIntent = PendingIntent.getService(
- this, RecordingService.REQUEST_CODE,
- RecordingService.getStopIntent(this),
- PendingIntent.FLAG_UPDATE_CURRENT);
- mController.startCountdown(DELAY_MS, startIntent, stopIntent);
- } else {
- Toast.makeText(this,
- getResources().getString(R.string.screenrecord_permission_error),
- Toast.LENGTH_SHORT).show();
- }
- finish();
- break;
- case REQUEST_CODE_PERMISSIONS:
- int permission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
- if (permission != PackageManager.PERMISSION_GRANTED) {
- Toast.makeText(this,
- getResources().getString(R.string.screenrecord_permission_error),
- Toast.LENGTH_SHORT).show();
- finish();
- } else {
- requestScreenCapture();
- }
- break;
- case REQUEST_CODE_PERMISSIONS_AUDIO:
- int videoPermission = checkSelfPermission(
- Manifest.permission.WRITE_EXTERNAL_STORAGE);
- int audioPermission = checkSelfPermission(Manifest.permission.RECORD_AUDIO);
- if (videoPermission != PackageManager.PERMISSION_GRANTED
- || audioPermission != PackageManager.PERMISSION_GRANTED) {
- Toast.makeText(this,
- getResources().getString(R.string.screenrecord_permission_error),
- Toast.LENGTH_SHORT).show();
- finish();
- } else {
- requestScreenCapture();
- }
- break;
- }
+ boolean useAudio = mAudioSwitch.isChecked();
+ boolean showTaps = mTapsSwitch.isChecked();
+ PendingIntent startIntent = PendingIntent.getForegroundService(this,
+ RecordingService.REQUEST_CODE,
+ RecordingService.getStartIntent(
+ ScreenRecordDialog.this, RESULT_OK, null, useAudio, showTaps),
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent stopIntent = PendingIntent.getService(this,
+ RecordingService.REQUEST_CODE,
+ RecordingService.getStopIntent(this),
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ mController.startCountdown(DELAY_MS, startIntent, stopIntent);
}
}