1 /*
2  * Copyright (C) 2018 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.content.om;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.RequiresPermission;
22 import android.annotation.SystemApi;
23 import android.annotation.SystemService;
24 import android.content.Context;
25 import android.os.RemoteException;
26 import android.os.ServiceManager;
27 import android.os.UserHandle;
28 
29 import java.util.List;
30 
31 /**
32  * Updates OverlayManager state; gets information about installed overlay packages.
33  * @hide
34  */
35 @SystemApi
36 @SystemService(Context.OVERLAY_SERVICE)
37 public class OverlayManager {
38 
39     private final IOverlayManager mService;
40     private final Context mContext;
41 
42     /**
43      * Creates a new instance.
44      *
45      * @param context The current context in which to operate.
46      * @param service The backing system service.
47      *
48      * @hide
49      */
OverlayManager(Context context, IOverlayManager service)50     public OverlayManager(Context context, IOverlayManager service) {
51         mContext = context;
52         mService = service;
53     }
54 
55     /** @hide */
OverlayManager(Context context)56     public OverlayManager(Context context) {
57         this(context, IOverlayManager.Stub.asInterface(
58             ServiceManager.getService(Context.OVERLAY_SERVICE)));
59     }
60 
61     /**
62      * Request that an overlay package is enabled and any other overlay packages with the same
63      * target package and category are disabled.
64      *
65      * If a set of overlay packages share the same category, single call to this method is
66      * equivalent to multiple calls to {@link #setEnabled(String, boolean, UserHandle)}.
67      *
68      * @param packageName the name of the overlay package to enable.
69      * @param user The user for which to change the overlay.
70      *
71      * @hide
72      */
73     @SystemApi
74     @RequiresPermission(anyOf = {
75             "android.permission.INTERACT_ACROSS_USERS",
76             "android.permission.INTERACT_ACROSS_USERS_FULL"
77     })
setEnabledExclusiveInCategory(@onNull final String packageName, @NonNull UserHandle user)78     public void setEnabledExclusiveInCategory(@NonNull final String packageName,
79             @NonNull UserHandle user) {
80         try {
81             if (!mService.setEnabledExclusiveInCategory(packageName, user.getIdentifier())) {
82                 throw new IllegalStateException("setEnabledExclusiveInCategory failed");
83             }
84         } catch (RemoteException e) {
85             throw e.rethrowFromSystemServer();
86         }
87     }
88 
89     /**
90      * Request that an overlay package is enabled or disabled.
91      *
92      * While {@link #setEnabledExclusiveInCategory(String, UserHandle)} doesn't support disabling
93      * every overlay in a category, this method allows you to disable everything.
94      *
95      * @param packageName the name of the overlay package to enable.
96      * @param enable {@code false} if the overlay should be turned off.
97      * @param user The user for which to change the overlay.
98      *
99      * @hide
100      */
101     @SystemApi
102     @RequiresPermission(anyOf = {
103             "android.permission.INTERACT_ACROSS_USERS",
104             "android.permission.INTERACT_ACROSS_USERS_FULL"
105     })
setEnabled(@onNull final String packageName, final boolean enable, @NonNull UserHandle user)106     public void setEnabled(@NonNull final String packageName, final boolean enable,
107             @NonNull UserHandle user) {
108         try {
109             if (!mService.setEnabled(packageName, enable, user.getIdentifier())) {
110                 throw new IllegalStateException("setEnabled failed");
111             }
112         } catch (RemoteException e) {
113             throw e.rethrowFromSystemServer();
114         }
115         return;
116     }
117 
118     /**
119      * Returns information about the overlay with the given package name for
120      * the specified user.
121      *
122      * @param packageName The name of the package.
123      * @param userHandle The user to get the OverlayInfos for.
124      * @return An OverlayInfo object; if no overlays exist with the
125      *         requested package name, null is returned.
126      *
127      * @hide
128      */
129     @SystemApi
130     @Nullable
getOverlayInfo(@onNull final String packageName, @NonNull final UserHandle userHandle)131     public OverlayInfo getOverlayInfo(@NonNull final String packageName,
132             @NonNull final UserHandle userHandle) {
133         try {
134             return mService.getOverlayInfo(packageName, userHandle.getIdentifier());
135         } catch (RemoteException e) {
136             throw e.rethrowFromSystemServer();
137         }
138     }
139 
140     /**
141      * Returns information about all overlays for the given target package for
142      * the specified user. The returned list is ordered according to the
143      * overlay priority with the highest priority at the end of the list.
144      *
145      * @param targetPackageName The name of the target package.
146      * @param user The user to get the OverlayInfos for.
147      * @return A list of OverlayInfo objects; if no overlays exist for the
148      *         requested package, an empty list is returned.
149      *
150      * @hide
151      */
152     @SystemApi
153     @RequiresPermission(anyOf = {
154             "android.permission.INTERACT_ACROSS_USERS",
155             "android.permission.INTERACT_ACROSS_USERS_FULL"
156     })
157     @NonNull
getOverlayInfosForTarget(@onNull final String targetPackageName, @NonNull UserHandle user)158     public List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName,
159             @NonNull UserHandle user) {
160         try {
161             return mService.getOverlayInfosForTarget(targetPackageName, user.getIdentifier());
162         } catch (RemoteException e) {
163             throw e.rethrowFromSystemServer();
164         }
165     }
166 }
167