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

Commit 552d9571 authored by Beth Thibodeau's avatar Beth Thibodeau Committed by Android (Google) Code Review
Browse files

Merge "Use a unique notification per screen recording" into udc-dev

parents 64a9d868 a32cc10c
Loading
Loading
Loading
Loading
+45 −32
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
@@ -60,11 +61,10 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
    public static final int REQUEST_CODE = 2;

    private static final int USER_ID_NOT_SPECIFIED = -1;
    private static final int NOTIFICATION_RECORDING_ID = 4274;
    private static final int NOTIFICATION_PROCESSING_ID = 4275;
    private static final int NOTIFICATION_VIEW_ID = 4273;
    private static final int NOTIF_BASE_ID = 4273;
    private static final String TAG = "RecordingService";
    private static final String CHANNEL_ID = "screen_record";
    private static final String GROUP_KEY = "screen_record_saved";
    private static final String EXTRA_RESULT_CODE = "extra_resultCode";
    private static final String EXTRA_PATH = "extra_path";
    private static final String EXTRA_AUDIO_SOURCE = "extra_useAudio";
@@ -89,6 +89,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
    private final UiEventLogger mUiEventLogger;
    private final NotificationManager mNotificationManager;
    private final UserContextProvider mUserContextTracker;
    private int mNotificationId = NOTIF_BASE_ID;

    @Inject
    public RecordingService(RecordingController controller, @LongRunning Executor executor,
@@ -134,11 +135,20 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
        }
        String action = intent.getAction();
        Log.d(TAG, "onStartCommand " + action);
        NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID,
                getString(R.string.screenrecord_title),
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription(getString(R.string.screenrecord_channel_description));
        channel.enableVibration(true);
        mNotificationManager.createNotificationChannel(channel);

        int currentUserId = mUserContextTracker.getUserContext().getUserId();
        UserHandle currentUser = new UserHandle(currentUserId);
        switch (action) {
            case ACTION_START:
                // Get a unique ID for this recording's notifications
                mNotificationId = NOTIF_BASE_ID + (int) SystemClock.uptimeMillis();
                mAudioSource = ScreenRecordingAudioSource
                        .values()[intent.getIntExtra(EXTRA_AUDIO_SOURCE, 0)];
                Log.d(TAG, "recording with audio source " + mAudioSource);
@@ -169,7 +179,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
                } else {
                    updateState(false);
                    createErrorNotification();
                    stopForeground(true);
                    stopForeground(STOP_FOREGROUND_DETACH);
                    stopSelf();
                    return Service.START_NOT_STICKY;
                }
@@ -200,7 +210,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
                    startActivity(Intent.createChooser(shareIntent, shareLabel)
                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
                    // Remove notification
                    mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser);
                    mNotificationManager.cancelAsUser(null, mNotificationId, currentUser);
                    return false;
                }, false, false);

@@ -260,14 +270,6 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
    @VisibleForTesting
    protected void createErrorNotification() {
        Resources res = getResources();
        NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID,
                getString(R.string.screenrecord_title),
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription(getString(R.string.screenrecord_channel_description));
        channel.enableVibration(true);
        mNotificationManager.createNotificationChannel(channel);

        Bundle extras = new Bundle();
        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                res.getString(R.string.screenrecord_title));
@@ -277,7 +279,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
                .setSmallIcon(R.drawable.ic_screenrecord)
                .setContentTitle(notificationTitle)
                .addExtras(extras);
        startForeground(NOTIFICATION_RECORDING_ID, builder.build());
        startForeground(mNotificationId, builder.build());
    }

    @VisibleForTesting
@@ -288,14 +290,6 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
    @VisibleForTesting
    protected void createRecordingNotification() {
        Resources res = getResources();
        NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID,
                getString(R.string.screenrecord_title),
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription(getString(R.string.screenrecord_channel_description));
        channel.enableVibration(true);
        mNotificationManager.createNotificationChannel(channel);

        Bundle extras = new Bundle();
        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                res.getString(R.string.screenrecord_title));
@@ -323,7 +317,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
                .setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
                .addAction(stopAction)
                .addExtras(extras);
        startForeground(NOTIFICATION_RECORDING_ID, builder.build());
        startForeground(mNotificationId, builder.build());
    }

    @VisibleForTesting
@@ -337,11 +331,12 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                res.getString(R.string.screenrecord_title));

        Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID)
        Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
                .setContentTitle(notificationTitle)
                .setContentText(
                        getResources().getString(R.string.screenrecord_background_processing_label))
                .setSmallIcon(R.drawable.ic_screenrecord)
                .setGroup(GROUP_KEY)
                .addExtras(extras);
        return builder.build();
    }
@@ -378,6 +373,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
                        PendingIntent.FLAG_IMMUTABLE))
                .addAction(shareAction)
                .setAutoCancel(true)
                .setGroup(GROUP_KEY)
                .addExtras(extras);

        // Add thumbnail if available
@@ -391,6 +387,24 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
        return builder.build();
    }

    /**
     * Adds a group notification so that save notifications from multiple recordings are
     * grouped together, and the foreground service recording notification is not
     */
    private void postGroupNotification(UserHandle currentUser) {
        Bundle extras = new Bundle();
        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                getResources().getString(R.string.screenrecord_title));
        Notification groupNotif = new Notification.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_screenrecord)
                .setContentTitle(getResources().getString(R.string.screenrecord_save_title))
                .setGroup(GROUP_KEY)
                .setGroupSummary(true)
                .setExtras(extras)
                .build();
        mNotificationManager.notifyAsUser(TAG, NOTIF_BASE_ID, groupNotif, currentUser);
    }

    private void stopService() {
        stopService(USER_ID_NOT_SPECIFIED);
    }
@@ -423,27 +437,26 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
            Log.e(TAG, "stopRecording called, but recorder was null");
        }
        updateState(false);
        stopForeground(STOP_FOREGROUND_DETACH);
        stopSelf();
    }

    private void saveRecording(int userId) {
        UserHandle currentUser = new UserHandle(userId);
        mNotificationManager.notifyAsUser(null, NOTIFICATION_PROCESSING_ID,
        mNotificationManager.notifyAsUser(null, mNotificationId,
                createProcessingNotification(), currentUser);

        mLongExecutor.execute(() -> {
            try {
                Log.d(TAG, "saving recording");
                Notification notification = createSaveNotification(getRecorder().save());
                if (!mController.isRecording()) {
                    mNotificationManager.notifyAsUser(null, NOTIFICATION_VIEW_ID, notification,
                postGroupNotification(currentUser);
                mNotificationManager.notifyAsUser(null, mNotificationId,  notification,
                        currentUser);
                }
            } catch (IOException e) {
                Log.e(TAG, "Error saving screen recording: " + e.getMessage());
                showErrorToast(R.string.screenrecord_delete_error);
            } finally {
                mNotificationManager.cancelAsUser(null, NOTIFICATION_PROCESSING_ID, currentUser);
                mNotificationManager.cancelAsUser(null, mNotificationId, currentUser);
            }
        });
    }
+2 −2
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.systemui.screenrecord;

import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -94,6 +93,7 @@ public class RecordingServiceTest extends SysuiTestCase {
        doReturn(mContext.getUserId()).when(mRecordingService).getUserId();
        doReturn(mContext.getPackageName()).when(mRecordingService).getPackageName();
        doReturn(mContext.getContentResolver()).when(mRecordingService).getContentResolver();
        doReturn(mContext.getResources()).when(mRecordingService).getResources();

        // Mock notifications
        doNothing().when(mRecordingService).createRecordingNotification();
@@ -101,7 +101,7 @@ public class RecordingServiceTest extends SysuiTestCase {
        doReturn(mNotification).when(mRecordingService).createSaveNotification(any());
        doNothing().when(mRecordingService).createErrorNotification();
        doNothing().when(mRecordingService).showErrorToast(anyInt());
        doNothing().when(mRecordingService).stopForeground(anyBoolean());
        doNothing().when(mRecordingService).stopForeground(anyInt());

        doNothing().when(mRecordingService).startForeground(anyInt(), any());
        doReturn(mScreenMediaRecorder).when(mRecordingService).getRecorder();