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