1 /*
2  * Copyright (C) 2017 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 package com.android.car;
17 
18 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
19 
20 import android.car.ICarBluetoothUserService;
21 import android.car.ICarPerUserService;
22 import android.car.ILocationManagerProxy;
23 import android.car.builtin.util.Slogf;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.os.IBinder;
27 
28 import com.android.car.bluetooth.CarBluetoothUserService;
29 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
30 import com.android.car.internal.ProxiedService;
31 import com.android.car.internal.util.IndentingPrintWriter;
32 import com.android.internal.annotations.Keep;
33 
34 import java.io.FileDescriptor;
35 import java.io.PrintWriter;
36 
37 /**
38  * {@link CarServiceImpl} process runs as the System User. When logged in as a different user, some
39  * services do not provide an API to register or bind as a User, hence CarService doesn't receive
40  * the events from services/processes running as a non-system user.
41  *
42  * This Service is run as the Current User on every User Switch and components of CarService can
43  * use this service to communicate with services/processes running as the current (non-system) user.
44  */
45 @Keep
46 public class CarPerUserServiceImpl extends ProxiedService {
47     private static final boolean DBG = true;
48     private static final String TAG = CarLog.tagFor(CarPerUserServiceImpl.class);
49 
50     private CarBluetoothUserService mCarBluetoothUserService;
51     private LocationManagerProxy mLocationManagerProxy;
52 
53     private CarPerUserServiceBinder mCarPerUserServiceBinder;
54 
55     @Override
onBind(Intent intent)56     public IBinder onBind(Intent intent) {
57         if (DBG) Slogf.d(TAG, "onBind()");
58 
59         if (mCarPerUserServiceBinder == null) {
60             Slogf.e(TAG, "CarPerUserServiceBinder null");
61         }
62         return mCarPerUserServiceBinder;
63     }
64 
65     @Override
onStartCommand(Intent intent, int flags, int startId)66     public int onStartCommand(Intent intent, int flags, int startId) {
67         if (DBG) Slogf.d(TAG, "onStart()");
68 
69         return START_STICKY;
70     }
71 
72     @Override
onCreate()73     public void onCreate() {
74         Context context = getApplicationContext();
75         Slogf.i(TAG, "created for user %s", context.getUser());
76 
77         mCarPerUserServiceBinder = new CarPerUserServiceBinder();
78         mCarBluetoothUserService = new CarBluetoothUserService(this);
79         mLocationManagerProxy = new LocationManagerProxy(this);
80         super.onCreate();
81     }
82 
83     @Override
onDestroy()84     public void onDestroy() {
85         Slogf.i(TAG, "destroyed for user %s", getApplicationContext().getUser());
86 
87         mCarPerUserServiceBinder = null;
88     }
89 
90     @Override
91     @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
dump(FileDescriptor fd, PrintWriter writer, String[] args)92     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
93         try (IndentingPrintWriter pw = new IndentingPrintWriter(writer)) {
94             pw.println("CarBluetoothUserService");
95             pw.increaseIndent();
96             mCarBluetoothUserService.dump(pw);
97             pw.decreaseIndent();
98             pw.println();
99             pw.println("LocationManagerProxy");
100             pw.increaseIndent();
101             mLocationManagerProxy.dump(pw);
102             pw.decreaseIndent();
103             pw.println();
104         }
105     }
106 
107     /**
108      * Other Services in CarService can create their own Binder interface and receive that interface
109      * through this CarPerUserService binder.
110      */
111     private final class CarPerUserServiceBinder extends ICarPerUserService.Stub {
112         @Override
getBluetoothUserService()113         public ICarBluetoothUserService getBluetoothUserService() {
114             return mCarBluetoothUserService;
115         }
116 
117         @Override
getLocationManagerProxy()118         public ILocationManagerProxy getLocationManagerProxy() {
119             return mLocationManagerProxy;
120         }
121     }
122 }
123