• 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 android.app;
18 
19 import static android.app.Activity.FULLSCREEN_MODE_REQUEST_EXIT;
20 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
21 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
22 
23 import android.annotation.IntDef;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.content.res.Configuration;
27 import android.os.Bundle;
28 import android.os.IBinder;
29 import android.os.IRemoteCallback;
30 import android.os.OutcomeReceiver;
31 import android.window.DesktopModeFlags;
32 
33 /**
34  * @hide
35  */
36 public class FullscreenRequestHandler {
37     @IntDef(prefix = { "RESULT_" }, value = {
38             RESULT_APPROVED,
39             RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY,
40             RESULT_FAILED_NOT_TOP_FOCUSED,
41             RESULT_FAILED_ALREADY_FULLY_EXPANDED
42     })
43     public @interface RequestResult {}
44 
45     public static final int RESULT_APPROVED = 0;
46     public static final int RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY = 1;
47     public static final int RESULT_FAILED_NOT_TOP_FOCUSED = 2;
48     public static final int RESULT_FAILED_ALREADY_FULLY_EXPANDED = 3;
49 
50     public static final String REMOTE_CALLBACK_RESULT_KEY = "result";
51 
requestFullscreenMode(@onNull @ctivity.FullscreenModeRequest int request, @Nullable OutcomeReceiver<Void, Throwable> approvalCallback, Configuration config, IBinder token)52     static void requestFullscreenMode(@NonNull @Activity.FullscreenModeRequest int request,
53             @Nullable OutcomeReceiver<Void, Throwable> approvalCallback, Configuration config,
54             IBinder token) {
55         int earlyCheck = earlyCheckRequestMatchesWindowingMode(
56                 request, config.windowConfiguration.getWindowingMode());
57         if (earlyCheck != RESULT_APPROVED) {
58             if (approvalCallback != null) {
59                 notifyFullscreenRequestResult(approvalCallback, earlyCheck);
60             }
61             return;
62         }
63         try {
64             if (approvalCallback != null) {
65                 ActivityClient.getInstance().requestMultiwindowFullscreen(token, request,
66                         new IRemoteCallback.Stub() {
67                             @Override
68                             public void sendResult(Bundle res) {
69                                 notifyFullscreenRequestResult(
70                                         approvalCallback, res.getInt(REMOTE_CALLBACK_RESULT_KEY));
71                             }
72                         });
73             } else {
74                 ActivityClient.getInstance().requestMultiwindowFullscreen(token, request, null);
75             }
76         } catch (Throwable e) {
77             if (approvalCallback != null) {
78                 approvalCallback.onError(e);
79             }
80         }
81     }
82 
notifyFullscreenRequestResult( OutcomeReceiver<Void, Throwable> callback, int result)83     private static void notifyFullscreenRequestResult(
84             OutcomeReceiver<Void, Throwable> callback, int result) {
85         Throwable e = null;
86         switch (result) {
87             case RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY:
88                 e = new IllegalStateException("The window is not in fullscreen by calling the "
89                         + "requestFullscreenMode API before, such that cannot be restored.");
90                 break;
91             case RESULT_FAILED_NOT_TOP_FOCUSED:
92                 e = new IllegalStateException("The window is not the top focused window.");
93                 break;
94             case RESULT_FAILED_ALREADY_FULLY_EXPANDED:
95                 e = new IllegalStateException("The window is already fully expanded.");
96                 break;
97             default:
98                 callback.onResult(null);
99                 break;
100         }
101         if (e != null) {
102             callback.onError(e);
103         }
104     }
105 
earlyCheckRequestMatchesWindowingMode(int request, int windowingMode)106     private static int earlyCheckRequestMatchesWindowingMode(int request, int windowingMode) {
107         if (request == FULLSCREEN_MODE_REQUEST_EXIT) {
108             if (windowingMode != WINDOWING_MODE_FULLSCREEN) {
109                 return RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY;
110             }
111             return RESULT_APPROVED;
112         }
113         if (DesktopModeFlags.ENABLE_REQUEST_FULLSCREEN_BUGFIX.isTrue()
114                 && (windowingMode == WINDOWING_MODE_FULLSCREEN
115                 || windowingMode == WINDOWING_MODE_MULTI_WINDOW)) {
116             return RESULT_FAILED_ALREADY_FULLY_EXPANDED;
117         }
118         return RESULT_APPROVED;
119     }
120 }
121