1 /*
2  * Copyright (C) 2023 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.systemui.screenshot.appclips;
18 
19 import android.app.Service;
20 import android.content.Intent;
21 import android.os.IBinder;
22 import android.window.ScreenCapture.ScreenshotHardwareBuffer;
23 import android.window.ScreenCapture.SynchronousScreenCaptureListener;
24 
25 import androidx.annotation.Nullable;
26 
27 import com.android.wm.shell.bubbles.Bubbles;
28 
29 import java.util.Optional;
30 
31 import javax.inject.Inject;
32 
33 /**
34  * A helper service that runs in SysUI process and helps {@link AppClipsActivity} which runs in its
35  * own separate process take a screenshot.
36  *
37  * <p>Note: This service always runs in the SysUI process running on the system user irrespective of
38  * which user started the service. This is required so that the correct instance of {@link Bubbles}
39  * instance is injected. This is set via attribute {@code android:singleUser=”true”} in
40  * AndroidManifest.
41  */
42 public class AppClipsScreenshotHelperService extends Service {
43 
44     private final Optional<Bubbles> mOptionalBubbles;
45 
46     @Inject
AppClipsScreenshotHelperService(Optional<Bubbles> optionalBubbles)47     public AppClipsScreenshotHelperService(Optional<Bubbles> optionalBubbles) {
48         mOptionalBubbles = optionalBubbles;
49     }
50 
51     @Nullable
52     @Override
onBind(Intent intent)53     public IBinder onBind(Intent intent) {
54         return new IAppClipsScreenshotHelperService.Stub() {
55             @Override
56             @Nullable
57             public ScreenshotHardwareBufferInternal takeScreenshot(int displayId) {
58                 if (mOptionalBubbles.isEmpty()) {
59                     return null;
60                 }
61 
62                 SynchronousScreenCaptureListener screenshotSync =
63                         mOptionalBubbles.get().getScreenshotExcludingBubble(displayId);
64                 ScreenshotHardwareBuffer screenshotHardwareBuffer = screenshotSync.getBuffer();
65                 if (screenshotHardwareBuffer == null) {
66                     return null;
67                 }
68 
69                 return new ScreenshotHardwareBufferInternal(screenshotHardwareBuffer);
70             }
71         };
72     }
73 }
74