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.NonNull; 21 import android.annotation.SystemApi; 22 import android.annotation.TestApi; 23 import android.app.PendingIntent; 24 import android.car.Car; 25 import android.car.CarManagerBase; 26 import android.content.ComponentName; 27 import android.os.IBinder; 28 import android.os.Looper; 29 import android.os.RemoteException; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 34 /** 35 * Provides car specific API related with package management. 36 */ 37 public final class CarPackageManager extends CarManagerBase { 38 private static final String TAG = "CarPackageManager"; 39 40 /** 41 * Flag for {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)}. When this 42 * flag is set, the call will be blocked until policy is set to system. This can take time 43 * and the flag cannot be used in main thread. 44 * 45 * @hide 46 * @deprecated see the {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)} 47 * documentation for alternative mechanism. 48 */ 49 @SystemApi 50 @Deprecated 51 public static final int FLAG_SET_POLICY_WAIT_FOR_CHANGE = 0x1; 52 /** 53 * Flag for {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)}. When this 54 * flag is set, passed policy is added to existing policy set from the current package. 55 * If none of {@link #FLAG_SET_POLICY_ADD} or {@link #FLAG_SET_POLICY_REMOVE} is set, existing 56 * policy is replaced. Note that policy per each package is always replaced and will not be 57 * added. 58 * 59 * @hide 60 * @deprecated see the {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)} 61 * documentation for alternative mechanism. 62 */ 63 @SystemApi 64 @Deprecated 65 public static final int FLAG_SET_POLICY_ADD = 0x2; 66 /** 67 * Flag for {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)}. When this 68 * flag is set, passed policy is removed from existing policy set from the current package. 69 * If none of {@link #FLAG_SET_POLICY_ADD} or {@link #FLAG_SET_POLICY_REMOVE} is set, existing 70 * policy is replaced. 71 * 72 * @hide 73 * @deprecated see the {@link #setAppBlockingPolicy(String, CarAppBlockingPolicy, int)} 74 * documentation for alternative mechanism. 75 */ 76 @SystemApi 77 @Deprecated 78 public static final int FLAG_SET_POLICY_REMOVE = 0x4; 79 80 /** @hide */ 81 @IntDef(flag = true, 82 value = {FLAG_SET_POLICY_WAIT_FOR_CHANGE, FLAG_SET_POLICY_ADD, FLAG_SET_POLICY_REMOVE}) 83 @Retention(RetentionPolicy.SOURCE) 84 public @interface SetPolicyFlags {} 85 86 private final ICarPackageManager mService; 87 88 /** @hide */ CarPackageManager(Car car, IBinder service)89 public CarPackageManager(Car car, IBinder service) { 90 super(car); 91 mService = ICarPackageManager.Stub.asInterface(service); 92 } 93 94 /** @hide */ 95 @Override onCarDisconnected()96 public void onCarDisconnected() { 97 // nothing to do 98 } 99 100 /** 101 * Set Application blocking policy for system app. {@link #FLAG_SET_POLICY_ADD} or 102 * {@link #FLAG_SET_POLICY_REMOVE} flag allows adding or removing from already set policy. When 103 * none of these flags are set, it will completely replace existing policy for each package 104 * specified. 105 * When {@link #FLAG_SET_POLICY_WAIT_FOR_CHANGE} flag is set, this call will be blocked 106 * until the policy is set to system and become effective. Otherwise, the call will start 107 * changing the policy but it will be completed asynchronously and the call will return 108 * without waiting for system level policy change. 109 * 110 * @param packageName Package name of the client. If wrong package name is passed, exception 111 * will be thrown. This name is used to update the policy. 112 * @param policy 113 * @param flags 114 * @throws SecurityException if caller has no permission. 115 * @throws IllegalArgumentException For wrong or invalid arguments. 116 * @throws IllegalStateException If {@link #FLAG_SET_POLICY_WAIT_FOR_CHANGE} is set while 117 * called from main thread. 118 * @hide 119 * @deprecated It is no longer possible to change the app blocking policy at runtime. The first 120 * choice to mark an activity as safe for driving should always be to to include 121 * {@code <meta-data android:name="distractionOptimized" android:value="true"/>} in its 122 * manifest. All other activities will be blocked whenever driving restrictions are required. If 123 * an activity's manifest cannot be changed, then you can explicitly make an exception to its 124 * behavior using the build-time XML configuration. Allow or deny specific activities by 125 * changing the appropriate value ({@code R.string.activityAllowlist}, 126 * {@code R.string.activityDenylist}) within the 127 * {@code packages/services/Car/service/res/values/config.xml} overlay. 128 */ 129 @SystemApi 130 @Deprecated setAppBlockingPolicy( String packageName, CarAppBlockingPolicy policy, @SetPolicyFlags int flags)131 public void setAppBlockingPolicy( 132 String packageName, CarAppBlockingPolicy policy, @SetPolicyFlags int flags) { 133 if ((flags & FLAG_SET_POLICY_WAIT_FOR_CHANGE) != 0 134 && Looper.getMainLooper().isCurrentThread()) { 135 throw new IllegalStateException( 136 "FLAG_SET_POLICY_WAIT_FOR_CHANGE cannot be used in main thread"); 137 } 138 try { 139 mService.setAppBlockingPolicy(packageName, policy, flags); 140 } catch (RemoteException e) { 141 handleRemoteExceptionFromCarService(e); 142 } 143 } 144 145 /** 146 * Restarts the requested task. If task with {@code taskId} does not exist, do nothing. 147 * 148 * <p>This requires {@code android.permission.REAL_GET_TASKS} permission. 149 * 150 * @hide 151 */ restartTask(int taskId)152 public void restartTask(int taskId) { 153 try { 154 mService.restartTask(taskId); 155 } catch (RemoteException e) { 156 handleRemoteExceptionFromCarService(e); 157 } 158 } 159 160 /** 161 * Check if finishing Activity will lead into safe Activity (=allowed Activity) to be shown. 162 * This can be used by unsafe activity blocking Activity to check if finishing itself can 163 * lead into being launched again due to unsafe activity shown. Note that checking this does not 164 * guarantee that blocking will not be done as driving state can change after this call is made. 165 * 166 * @param activityName 167 * @return true if there is a safe Activity (or car is stopped) in the back of task stack 168 * so that finishing the Activity will not trigger another Activity blocking. If 169 * the given Activity is not in foreground, then it will return true as well as 170 * finishing the Activity will not make any difference. 171 * 172 * @hide 173 */ 174 @SystemApi isActivityBackedBySafeActivity(ComponentName activityName)175 public boolean isActivityBackedBySafeActivity(ComponentName activityName) { 176 try { 177 return mService.isActivityBackedBySafeActivity(activityName); 178 } catch (RemoteException e) { 179 return handleRemoteExceptionFromCarService(e, false); 180 } 181 } 182 183 /** 184 * Enable/Disable Activity Blocking. This is to provide an option for toggling app blocking 185 * behavior for development purposes. 186 * @hide 187 */ 188 @TestApi setEnableActivityBlocking(boolean enable)189 public void setEnableActivityBlocking(boolean enable) { 190 try { 191 mService.setEnableActivityBlocking(enable); 192 } catch (RemoteException e) { 193 handleRemoteExceptionFromCarService(e); 194 } 195 } 196 197 /** 198 * Returns whether an activity is distraction optimized, i.e, allowed in a restricted 199 * driving state. 200 * 201 * @param packageName the activity's {@link android.content.pm.ActivityInfo#packageName}. 202 * @param className the activity's {@link android.content.pm.ActivityInfo#name}. 203 * @return true if the activity is distraction optimized, false if it isn't or if the value 204 * could not be determined. 205 */ isActivityDistractionOptimized(String packageName, String className)206 public boolean isActivityDistractionOptimized(String packageName, String className) { 207 try { 208 return mService.isActivityDistractionOptimized(packageName, className); 209 } catch (RemoteException e) { 210 return handleRemoteExceptionFromCarService(e, false); 211 } 212 } 213 214 /** 215 * Returns whether the given {@link PendingIntent} represents an activity that is distraction 216 * optimized, i.e, allowed in a restricted driving state. 217 * 218 * @param pendingIntent the {@link PendingIntent} to check. 219 * @return true if the pending intent represents an activity that is distraction optimized, 220 * false if it isn't or if the value could not be determined. 221 */ isPendingIntentDistractionOptimized(@onNull PendingIntent pendingIntent)222 public boolean isPendingIntentDistractionOptimized(@NonNull PendingIntent pendingIntent) { 223 try { 224 return mService.isPendingIntentDistractionOptimized(pendingIntent); 225 } catch (RemoteException e) { 226 return handleRemoteExceptionFromCarService(e, false); 227 } 228 } 229 230 /** 231 * Check if given service is distraction optimized, i.e, allowed in a restricted 232 * driving state. 233 * 234 * @param packageName 235 * @param className 236 * @return 237 */ isServiceDistractionOptimized(String packageName, String className)238 public boolean isServiceDistractionOptimized(String packageName, String className) { 239 try { 240 return mService.isServiceDistractionOptimized(packageName, className); 241 } catch (RemoteException e) { 242 return handleRemoteExceptionFromCarService(e, false); 243 } 244 } 245 } 246