1 /*
2  * Copyright (C) 2021 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 com.android.car.am;
18 
19 import android.app.ActivityManager;
20 import android.car.Car;
21 import android.car.app.CarActivityManager;
22 import android.car.app.ICarActivityService;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.pm.PackageManager;
26 import android.os.Binder;
27 import android.os.RemoteException;
28 import android.os.UserHandle;
29 import android.util.IndentingPrintWriter;
30 
31 import com.android.car.CarServiceBase;
32 import com.android.car.internal.ICarServiceHelper;
33 import com.android.internal.annotations.GuardedBy;
34 import com.android.internal.annotations.VisibleForTesting;
35 
36 /**
37  * Service responsible for Activities in Car.
38  */
39 public final class CarActivityService extends ICarActivityService.Stub
40         implements CarServiceBase {
41 
42     private final Context mContext;
43 
44     private final Object mLock = new Object();
45 
46     @GuardedBy("mLock")
47     ICarServiceHelper mICarServiceHelper;
48 
CarActivityService(Context context)49     public CarActivityService(Context context) {
50         mContext = context;
51     }
52 
53     @Override
init()54     public void init() {}
55 
56     @Override
release()57     public void release() {}
58 
59     /**
60      * Sets {@code ICarServiceHelper}.
61      */
setICarServiceHelper(ICarServiceHelper helper)62     public void setICarServiceHelper(ICarServiceHelper helper) {
63         synchronized (mLock) {
64             mICarServiceHelper = helper;
65         }
66     }
67 
68     @Override
setPersistentActivity(ComponentName activity, int displayId, int featureId)69     public int setPersistentActivity(ComponentName activity, int displayId, int featureId) throws
70             RemoteException {
71         if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
72                 Car.PERMISSION_CONTROL_CAR_APP_LAUNCH)) {
73             throw new SecurityException("Requires " + Car.PERMISSION_CONTROL_CAR_APP_LAUNCH);
74         }
75         int caller = getCaller();
76         if (caller != UserHandle.USER_SYSTEM && caller != ActivityManager.getCurrentUser()) {
77             return CarActivityManager.RESULT_INVALID_USER;
78         }
79 
80         ICarServiceHelper helper;
81         synchronized (mLock) {
82             helper = mICarServiceHelper;
83         }
84         if (helper == null) {
85             throw new IllegalStateException("ICarServiceHelper isn't connected yet");
86         }
87         return helper.setPersistentActivity(activity, displayId, featureId);
88     }
89 
90     @VisibleForTesting
getCaller()91     int getCaller() {  // Non static for mocking.
92         return UserHandle.getUserId(Binder.getCallingUid());
93     }
94 
95     @Override
dump(IndentingPrintWriter writer)96     public void dump(IndentingPrintWriter writer) {}
97 }
98