• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.window;
18 
19 import static android.view.Display.DEFAULT_DISPLAY;
20 
21 import android.annotation.CallSuper;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.SuppressLint;
25 import android.annotation.TestApi;
26 import android.annotation.UiContext;
27 import android.app.ActivityThread;
28 import android.app.LoadedApk;
29 import android.app.Service;
30 import android.content.Context;
31 import android.hardware.display.DisplayManager;
32 import android.os.Bundle;
33 import android.os.IBinder;
34 import android.view.Display;
35 import android.view.WindowManager;
36 import android.view.WindowManager.LayoutParams.WindowType;
37 import android.view.WindowManagerImpl;
38 
39 // TODO(b/159767464): handle #onConfigurationChanged(Configuration)
40 /**
41  * A {@link Service} responsible for showing a non-activity window, such as software keyboards or
42  * accessibility overlay windows. This {@link Service} has similar behavior to
43  * {@link WindowContext}, but is represented as {@link Service}.
44  *
45  * @see android.inputmethodservice.InputMethodService
46  * @see android.accessibilityservice.AccessibilityService
47  *
48  * @hide
49  */
50 @TestApi
51 @UiContext
52 public abstract class WindowProviderService extends Service {
53 
54     private final WindowTokenClient mWindowToken = new WindowTokenClient();
55     private final WindowContextController mController = new WindowContextController(mWindowToken);
56     private WindowManager mWindowManager;
57 
58     /**
59      * Returns the type of this {@link WindowProviderService}.
60      * Each inheriting class must implement this method to provide the type of the window. It is
61      * used similar to {@code type} of {@link Context#createWindowContext(int, Bundle)}
62      *
63      * @see Context#createWindowContext(int, Bundle)
64      *
65      * @hide
66      */
67     @TestApi
68     @SuppressLint("OnNameExpected")
69     // Suppress the lint because it is not a callback and users should provide window type
70     // so we cannot make it final.
getWindowType()71     public abstract @WindowType int getWindowType();
72 
73     /**
74      * Returns the option of this {@link WindowProviderService}.
75      * Default is {@code null}. The inheriting class can implement this method to provide the
76      * customization {@code option} of the window. It is used similar to {@code options} of
77      * {@link Context#createWindowContext(int, Bundle)}
78      *
79      * @see Context#createWindowContext(int, Bundle)
80      *
81      * @hide
82      */
83     @TestApi
84     @SuppressLint({"OnNameExpected", "NullableCollection"})
85     // Suppress the lint because it is not a callback and users may override this API to provide
86     // launch option. Also, the return value of this API is null by default.
87     @Nullable
getWindowContextOptions()88     public Bundle getWindowContextOptions() {
89         return null;
90     }
91 
92     /**
93      * Attaches this WindowProviderService to the {@code windowToken}.
94      *
95      * @hide
96      */
97     @TestApi
attachToWindowToken(@onNull IBinder windowToken)98     public final void attachToWindowToken(@NonNull IBinder windowToken) {
99         mController.attachToWindowToken(windowToken);
100     }
101 
102     /** @hide */
103     @Override
createServiceBaseContext(ActivityThread mainThread, LoadedApk packageInfo)104     public final Context createServiceBaseContext(ActivityThread mainThread,
105             LoadedApk packageInfo) {
106         final Context context = super.createServiceBaseContext(mainThread, packageInfo);
107         // Always associate with the default display at initialization.
108         final Display defaultDisplay = context.getSystemService(DisplayManager.class)
109                 .getDisplay(DEFAULT_DISPLAY);
110         return context.createTokenContext(mWindowToken, defaultDisplay);
111     }
112 
113     @CallSuper
114     @Override
onCreate()115     public void onCreate() {
116         super.onCreate();
117         mWindowToken.attachContext(this);
118         mController.attachToDisplayArea(getWindowType(), getDisplayId(), getWindowContextOptions());
119         mWindowManager = WindowManagerImpl.createWindowContextWindowManager(this);
120     }
121 
122     @SuppressLint("OnNameExpected")
123     @Override
124     // Suppress the lint because ths is overridden from Context.
getSystemService(@onNull String name)125     public @Nullable Object getSystemService(@NonNull String name) {
126         if (WINDOW_SERVICE.equals(name)) {
127             return mWindowManager;
128         }
129         return super.getSystemService(name);
130     }
131 
132     @CallSuper
133     @Override
onDestroy()134     public void onDestroy() {
135         super.onDestroy();
136         mController.detachIfNeeded();
137     }
138 }
139