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 android.car.content.pm;
18 
19 import android.annotation.IntDef;
20 import android.annotation.SystemApi;
21 import android.annotation.TestApi;
22 import android.car.Car;
23 import android.car.CarManagerBase;
24 import android.content.ComponentName;
25 import android.os.IBinder;
26 import android.os.Looper;
27 import android.os.RemoteException;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 
32 /**
33  * Provides car specific API related with package management.
34  */
35 public final class CarPackageManager extends CarManagerBase {
36     private static final String TAG = "CarPackageManager";
37 
38     /**
39      * Flag for {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)}. When this
40      * flag is set, the call will be blocked until policy is set to system. This can take time
41      * and the flag cannot be used in main thread.
42      * @hide
43      */
44     @SystemApi
45     public static final int FLAG_SET_POLICY_WAIT_FOR_CHANGE = 0x1;
46     /**
47      * Flag for {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)}. When this
48      * flag is set, passed policy is added to existing policy set from the current package.
49      * If none of {@link #FLAG_SET_POLICY_ADD} or {@link #FLAG_SET_POLICY_REMOVE} is set, existing
50      * policy is replaced. Note that policy per each package is always replaced and will not be
51      * added.
52      * @hide
53      */
54     @SystemApi
55     public static final int FLAG_SET_POLICY_ADD = 0x2;
56     /**
57      * Flag for {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)}. When this
58      * flag is set, passed policy is removed from existing policy set from the current package.
59      * If none of {@link #FLAG_SET_POLICY_ADD} or {@link #FLAG_SET_POLICY_REMOVE} is set, existing
60      * policy is replaced.
61      * @hide
62      */
63     @SystemApi
64     public static final int FLAG_SET_POLICY_REMOVE = 0x4;
65 
66     /** @hide */
67     @IntDef(flag = true,
68             value = {FLAG_SET_POLICY_WAIT_FOR_CHANGE, FLAG_SET_POLICY_ADD, FLAG_SET_POLICY_REMOVE})
69     @Retention(RetentionPolicy.SOURCE)
70     public @interface SetPolicyFlags {}
71 
72     private final ICarPackageManager mService;
73 
74     /** @hide */
CarPackageManager(Car car, IBinder service)75     public CarPackageManager(Car car, IBinder service) {
76         super(car);
77         mService = ICarPackageManager.Stub.asInterface(service);
78     }
79 
80     /** @hide */
81     @Override
onCarDisconnected()82     public void onCarDisconnected() {
83         // nothing to do
84     }
85 
86     /**
87      * Set Application blocking policy for system app. {@link #FLAG_SET_POLICY_ADD} or
88      * {@link #FLAG_SET_POLICY_REMOVE} flag allows adding or removing from already set policy. When
89      * none of these flags are set, it will completely replace existing policy for each package
90      * specified.
91      * When {@link #FLAG_SET_POLICY_WAIT_FOR_CHANGE} flag is set, this call will be blocked
92      * until the policy is set to system and become effective. Otherwise, the call will start
93      * changing the policy but it will be completed asynchronously and the call will return
94      * without waiting for system level policy change.
95      *
96      * @param packageName Package name of the client. If wrong package name is passed, exception
97      *        will be thrown. This name is used to update the policy.
98      * @param policy
99      * @param flags
100      * @throws SecurityException if caller has no permission.
101      * @throws IllegalArgumentException For wrong or invalid arguments.
102      * @throws IllegalStateException If {@link #FLAG_SET_POLICY_WAIT_FOR_CHANGE} is set while
103      *         called from main thread.
104      * @hide
105      */
106     @SystemApi
setAppBlockingPolicy( String packageName, CarAppBlockingPolicy policy, @SetPolicyFlags int flags)107     public void setAppBlockingPolicy(
108             String packageName, CarAppBlockingPolicy policy, @SetPolicyFlags int flags) {
109         if ((flags & FLAG_SET_POLICY_WAIT_FOR_CHANGE) != 0 &&
110                 Looper.getMainLooper().isCurrentThread()) {
111             throw new IllegalStateException(
112                     "FLAG_SET_POLICY_WAIT_FOR_CHANGE cannot be used in main thread");
113         }
114         try {
115             mService.setAppBlockingPolicy(packageName, policy, flags);
116         } catch (RemoteException e) {
117             handleRemoteExceptionFromCarService(e);
118         }
119     }
120 
121     /**
122      * Restarts the requested task. If task with {@code taskId} does not exist, do nothing.
123      *
124      * @hide
125      */
restartTask(int taskId)126     public void restartTask(int taskId) {
127         try {
128             mService.restartTask(taskId);
129         } catch (RemoteException e) {
130             handleRemoteExceptionFromCarService(e);
131         }
132     }
133 
134     /**
135      * Check if finishing Activity will lead into safe Activity (=allowed Activity) to be shown.
136      * This can be used by unsafe activity blocking Activity to check if finishing itself can
137      * lead into being launched again due to unsafe activity shown. Note that checking this does not
138      * guarantee that blocking will not be done as driving state can change after this call is made.
139      *
140      * @param activityName
141      * @return true if there is a safe Activity (or car is stopped) in the back of task stack
142      *         so that finishing the Activity will not trigger another Activity blocking. If
143      *         the given Activity is not in foreground, then it will return true as well as
144      *         finishing the Activity will not make any difference.
145      *
146      * @hide
147      */
148     @SystemApi
isActivityBackedBySafeActivity(ComponentName activityName)149     public boolean isActivityBackedBySafeActivity(ComponentName activityName) {
150         try {
151             return mService.isActivityBackedBySafeActivity(activityName);
152         } catch (RemoteException e) {
153             return handleRemoteExceptionFromCarService(e, false);
154         }
155     }
156 
157     /**
158      * Enable/Disable Activity Blocking.  This is to provide an option for toggling app blocking
159      * behavior for development purposes.
160      * @hide
161      */
162     @TestApi
setEnableActivityBlocking(boolean enable)163     public void setEnableActivityBlocking(boolean enable) {
164         try {
165             mService.setEnableActivityBlocking(enable);
166         } catch (RemoteException e) {
167             handleRemoteExceptionFromCarService(e);
168         }
169     }
170 
171     /**
172      * Check if given activity is distraction optimized, i.e, allowed in a
173      * restricted driving state
174      *
175      * @param packageName
176      * @param className
177      * @return
178      */
isActivityDistractionOptimized(String packageName, String className)179     public boolean isActivityDistractionOptimized(String packageName, String className) {
180         try {
181             return mService.isActivityDistractionOptimized(packageName, className);
182         } catch (RemoteException e) {
183             return handleRemoteExceptionFromCarService(e, false);
184         }
185     }
186 
187     /**
188      * Check if given service is distraction optimized, i.e, allowed in a restricted
189      * driving state.
190      *
191      * @param packageName
192      * @param className
193      * @return
194      */
isServiceDistractionOptimized(String packageName, String className)195     public boolean isServiceDistractionOptimized(String packageName, String className) {
196         try {
197             return mService.isServiceDistractionOptimized(packageName, className);
198         } catch (RemoteException e) {
199             return handleRemoteExceptionFromCarService(e, false);
200         }
201     }
202 }
203