• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wm;
18 
19 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONTENT_RECORDING;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.view.ContentRecordingSession;
24 
25 import com.android.internal.annotations.VisibleForTesting;
26 import com.android.internal.protolog.common.ProtoLog;
27 
28 /**
29  * Orchestrates the handoff between displays if the recording session changes, and keeps track of
30  * the current recording session state. Only supports one content recording session on the device at
31  * once.
32  */
33 final class ContentRecordingController {
34 
35     /**
36      * The current recording session.
37      */
38     @Nullable
39     private ContentRecordingSession mSession = null;
40 
41     @Nullable
42     private DisplayContent mDisplayContent = null;
43 
44     /**
45      * Returns the current recording session. If returns {@code null}, then recording is not taking
46      * place.
47      */
48     @Nullable
49     @VisibleForTesting
getContentRecordingSessionLocked()50     ContentRecordingSession getContentRecordingSessionLocked() {
51         // Copy out the session, to allow it to be modified without updating this reference.
52         return mSession;
53     }
54 
55     /**
56      * Updates the current recording session. If a new display is taking over recording, then
57      * stops the prior display from recording.
58      *
59      * @param incomingSession the new recording session. Should either have a {@code null} token, to
60      *                        stop the current session, or a session on a new/different display
61      *                        than the current session.
62      * @param wmService       the window manager service
63      */
setContentRecordingSessionLocked(@ullable ContentRecordingSession incomingSession, @NonNull WindowManagerService wmService)64     void setContentRecordingSessionLocked(@Nullable ContentRecordingSession incomingSession,
65             @NonNull WindowManagerService wmService) {
66         if (incomingSession != null && (!ContentRecordingSession.isValid(incomingSession)
67                 || ContentRecordingSession.isSameDisplay(mSession, incomingSession))) {
68             // Ignore an invalid session, or a session for the same display as currently recording.
69             return;
70         }
71         DisplayContent incomingDisplayContent = null;
72         if (incomingSession != null) {
73             // Recording will start on a new display, possibly taking over from a current session.
74             ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
75                     "Handle incoming session on display %d, with a pre-existing session %s",
76                     incomingSession.getDisplayId(),
77                     mSession == null ? null : mSession.getDisplayId());
78             incomingDisplayContent = wmService.mRoot.getDisplayContentOrCreate(
79                     incomingSession.getDisplayId());
80             incomingDisplayContent.setContentRecordingSession(incomingSession);
81         }
82         if (mSession != null) {
83             // Update the pre-existing display about the new session.
84             ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, "Pause the recording session on display %s",
85                     mDisplayContent.getDisplayId());
86             mDisplayContent.pauseRecording();
87             mDisplayContent.setContentRecordingSession(null);
88         }
89         // Update the cached states.
90         mDisplayContent = incomingDisplayContent;
91         mSession = incomingSession;
92     }
93 }
94