1 /*
2  * Copyright (C) 2015 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.internal.policy;
18 
19 import android.content.AutofillOptions;
20 import android.content.ContentCaptureOptions;
21 import android.content.Context;
22 import android.content.res.AssetManager;
23 import android.content.res.Resources;
24 import android.view.ContextThemeWrapper;
25 import android.view.WindowManager;
26 import android.view.WindowManagerImpl;
27 import android.view.contentcapture.ContentCaptureManager;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 
31 import java.lang.ref.WeakReference;
32 
33 /**
34  * Context for decor views which can be seeded with pure application context and not depend on the
35  * activity, but still provide some of the facilities that Activity has,
36  * e.g. themes, activity-based resources, etc.
37  *
38  * @hide
39  */
40 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
41 public class DecorContext extends ContextThemeWrapper {
42     private PhoneWindow mPhoneWindow;
43     private WindowManager mWindowManager;
44     private Resources mActivityResources;
45     private ContentCaptureManager mContentCaptureManager;
46 
47     private WeakReference<Context> mActivityContext;
48 
49     @VisibleForTesting
DecorContext(Context context, Context activityContext)50     public DecorContext(Context context, Context activityContext) {
51         super(context.createDisplayContext(activityContext.getDisplay()), null);
52         mActivityContext = new WeakReference<>(activityContext);
53         mActivityResources = activityContext.getResources();
54     }
55 
setPhoneWindow(PhoneWindow phoneWindow)56     void setPhoneWindow(PhoneWindow phoneWindow) {
57         mPhoneWindow = phoneWindow;
58         mWindowManager = null;
59     }
60 
61     @Override
getSystemService(String name)62     public Object getSystemService(String name) {
63         if (Context.WINDOW_SERVICE.equals(name)) {
64             if (mWindowManager == null) {
65                 WindowManagerImpl wm =
66                         (WindowManagerImpl) super.getSystemService(Context.WINDOW_SERVICE);
67                 mWindowManager = wm.createLocalWindowManager(mPhoneWindow);
68             }
69             return mWindowManager;
70         }
71         if (Context.CONTENT_CAPTURE_MANAGER_SERVICE.equals(name)) {
72             if (mContentCaptureManager == null) {
73                 Context activityContext = mActivityContext.get();
74                 if (activityContext != null) {
75                     mContentCaptureManager = (ContentCaptureManager) activityContext
76                             .getSystemService(name);
77                 }
78             }
79             return mContentCaptureManager;
80         }
81         return super.getSystemService(name);
82     }
83 
84     @Override
getResources()85     public Resources getResources() {
86         Context activityContext = mActivityContext.get();
87         // Attempt to update the local cached Resources from the activity context. If the activity
88         // is no longer around, return the old cached values.
89         if (activityContext != null) {
90             mActivityResources = activityContext.getResources();
91         }
92 
93         return mActivityResources;
94     }
95 
96     @Override
getAssets()97     public AssetManager getAssets() {
98         return mActivityResources.getAssets();
99     }
100 
101     @Override
getAutofillOptions()102     public AutofillOptions getAutofillOptions() {
103         Context activityContext = mActivityContext.get();
104         if (activityContext != null) {
105             return activityContext.getAutofillOptions();
106         }
107         return null;
108     }
109 
110     @Override
getContentCaptureOptions()111     public ContentCaptureOptions getContentCaptureOptions() {
112         Context activityContext = mActivityContext.get();
113         if (activityContext != null) {
114             return activityContext.getContentCaptureOptions();
115         }
116         return null;
117     }
118 }
119