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.support.car;
18 
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.ServiceConnection;
22 import android.os.Handler;
23 import android.os.IBinder;
24 import android.os.Looper;
25 import android.os.Message;
26 import android.support.car.content.pm.CarPackageManagerEmbedded;
27 import android.support.car.hardware.CarSensorManagerEmbedded;
28 import android.support.car.media.CarAudioManagerEmbedded;
29 import android.support.car.navigation.CarNavigationManagerEmbedded;
30 
31 import java.util.LinkedList;
32 
33 /**
34  * Default CarServiceLoader for system with built-in car service (=embedded).
35  * @hide
36  */
37 public class CarServiceLoaderEmbedded extends CarServiceLoader {
38 
39     private final ServiceConnection mServiceConnection = new ServiceConnection() {
40 
41         @Override
42         public void onServiceConnected(ComponentName name, IBinder service) {
43             getConnectionListener().onServiceConnected(name);
44         }
45 
46         @Override
47         public void onServiceDisconnected(ComponentName name) {
48             getConnectionListener().onServiceDisconnected(name);
49         }
50     };
51 
52     private final android.car.Car mCar;
53     private final LinkedList<CarConnectionListener> mCarConnectionListeners =
54             new LinkedList<>();
55     private final CallbackHandler mHandler;
56 
CarServiceLoaderEmbedded(Context context, ServiceConnectionListener listener, Looper looper)57     public CarServiceLoaderEmbedded(Context context, ServiceConnectionListener listener,
58             Looper looper) {
59         super(context, listener, looper);
60         mCar = android.car.Car.createCar(context, mServiceConnection, looper);
61         mHandler = new CallbackHandler(looper);
62     }
63 
64     @Override
connect()65     public void connect() throws IllegalStateException {
66         mCar.connect();
67     }
68 
69     @Override
disconnect()70     public void disconnect() {
71         mCar.disconnect();
72     }
73 
74     @Override
isConnectedToCar()75     public boolean isConnectedToCar() {
76         // for embedded, connected to service means connected to car.
77         return mCar.isConnected();
78     }
79 
80     @Override
getCarConnectionType()81     public int getCarConnectionType() throws CarNotConnectedException {
82         return mCar.getCarConnectionType();
83     }
84 
85     @Override
registerCarConnectionListener(final CarConnectionListener listener)86     public void registerCarConnectionListener(final CarConnectionListener listener)
87             throws CarNotConnectedException {
88         synchronized (this) {
89             mCarConnectionListeners.add(listener);
90         }
91         // car service connection is checked when this is called. So just dispatch it.
92         mHandler.dispatchCarConnectionCall(listener, getCarConnectionType());
93     }
94 
95     @Override
unregisterCarConnectionListener(CarConnectionListener listener)96     public void unregisterCarConnectionListener(CarConnectionListener listener) {
97         synchronized (this) {
98             mCarConnectionListeners.remove(listener);
99         }
100     }
101 
102     @Override
getCarManager(String serviceName)103     public Object getCarManager(String serviceName) throws CarNotConnectedException {
104         Object manager;
105         try {
106             manager = mCar.getCarManager(serviceName);
107         } catch (android.car.CarNotConnectedException e) {
108             throw new CarNotConnectedException(e);
109         }
110 
111         if (manager == null) {
112             return null;
113         }
114         // For publicly available versions, return wrapper version.
115         switch (serviceName) {
116         case Car.AUDIO_SERVICE:
117             return new CarAudioManagerEmbedded(manager);
118         case Car.SENSOR_SERVICE:
119             return new CarSensorManagerEmbedded(manager);
120         case Car.INFO_SERVICE:
121             return new CarInfoManagerEmbedded(manager);
122         case Car.APP_CONTEXT_SERVICE:
123             return new CarAppContextManagerEmbedded(manager);
124         case Car.PACKAGE_SERVICE:
125             return new CarPackageManagerEmbedded(manager);
126         case Car.CAR_NAVIGATION_SERVICE:
127             return new CarNavigationManagerEmbedded(manager);
128         default:
129             return manager;
130         }
131     }
132 
133     private static class CallbackHandler extends Handler {
134 
135         private  static final int MSG_DISPATCH_CAR_CONNECTION = 0;
136 
CallbackHandler(Looper looper)137         private CallbackHandler(Looper looper) {
138             super(looper);
139         }
140 
dispatchCarConnectionCall(CarConnectionListener listener, int connectionType)141         private void dispatchCarConnectionCall(CarConnectionListener listener, int connectionType) {
142             sendMessage(obtainMessage(MSG_DISPATCH_CAR_CONNECTION, connectionType, 0, listener));
143         }
144 
145         @Override
handleMessage(Message msg)146         public void handleMessage(Message msg) {
147             switch (msg.what) {
148                 case MSG_DISPATCH_CAR_CONNECTION:
149                     CarConnectionListener listener = (CarConnectionListener) msg.obj;
150                     listener.onConnected(msg.arg1);
151                     break;
152             }
153         }
154     }
155 }
156