Home | History | Annotate | Download | only in pm
      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