• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.hal;
18 
19 import static android.car.evs.CarEvsManager.SERVICE_TYPE_REARVIEW;
20 import static android.car.evs.CarEvsManager.SERVICE_TYPE_SURROUNDVIEW;
21 import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.EVS_SERVICE_REQUEST;
22 
23 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
24 
25 import android.car.evs.CarEvsManager.CarEvsServiceType;
26 import android.hardware.automotive.vehicle.V2_0.EvsServiceRequestIndex;
27 import android.hardware.automotive.vehicle.V2_0.EvsServiceState;
28 import android.hardware.automotive.vehicle.V2_0.EvsServiceType;
29 import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig;
30 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
31 import android.util.Log;
32 import android.util.Slog;
33 import android.util.SparseArray;
34 
35 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
36 import com.android.internal.annotations.GuardedBy;
37 
38 import java.io.PrintWriter;
39 import java.util.Collection;
40 import java.util.List;
41 
42 /*
43  * Translates HAL events, CarEvsService is interested in, into the higher-level semantic
44  * information.
45  */
46 public class EvsHalService extends HalServiceBase {
47 
48     private static final String TAG = EvsHalService.class.getSimpleName();
49     private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
50 
51     private static final int[] SUPPORTED_PROPERTIES = new int[] {
52         EVS_SERVICE_REQUEST,
53     };
54 
55     private final Object mLock = new Object();
56 
57     @GuardedBy("mLock")
58     private final SparseArray<VehiclePropConfig> mProperties = new SparseArray();
59 
60     private final VehicleHal mHal;
61 
62     @GuardedBy("mLock")
63     private EvsHalEventListener mListener;
64 
65     private @CarEvsServiceType int mLastServiceTypeRequested;
66 
67     private boolean mIsEvsServiceRequestSupported;
68 
EvsHalService(VehicleHal hal)69     public EvsHalService(VehicleHal hal) {
70         mHal = hal;
71     }
72 
73     /**
74      * Interface to be implemented by any client that wants to get notified upon a new EVS service
75      * request.
76      */
77     public interface EvsHalEventListener {
78         /** Called when a value of monitoring VHAL property gets changed */
onEvent(@arEvsServiceType int id, boolean on)79         void onEvent(@CarEvsServiceType int id, boolean on);
80     }
81 
82     /**
83      * Sets the event listener to receive Vehicle's EVS-related events.
84      *
85      * @param listener {@link EvsHalEventListener}
86      * @throws {@link IllegalStateException} if none of required VHAL properties are not supported
87      *         on this device.
88      */
setListener(EvsHalEventListener listener)89     public void setListener(EvsHalEventListener listener) {
90         if (!mIsEvsServiceRequestSupported) {
91             throw new IllegalStateException(
92                     "Any of required VHAL properties are not supported.");
93         }
94 
95         synchronized (mLock) {
96             mListener = listener;
97         }
98 
99         mHal.subscribeProperty(this, EVS_SERVICE_REQUEST);
100     }
101 
102     /** Returns whether {@code EVS_SERVICE_REQUEST} is supported */
isEvsServiceRequestSupported()103     public boolean isEvsServiceRequestSupported() {
104         return mIsEvsServiceRequestSupported;
105     }
106 
107     @Override
init()108     public void init() {
109         synchronized (mLock) {
110             for (int i = 0; i < mProperties.size(); i++) {
111                 VehiclePropConfig config = mProperties.valueAt(i);
112                 if (VehicleHal.isPropertySubscribable(config)) {
113                     mHal.subscribeProperty(this, config.prop);
114                 }
115             }
116         }
117     }
118 
119     @Override
release()120     public void release() {
121         synchronized (mLock) {
122             mListener = null;
123             mProperties.clear();
124         }
125     }
126 
127     @Override
getAllSupportedProperties()128     public int[] getAllSupportedProperties() {
129         return SUPPORTED_PROPERTIES;
130     }
131 
132     @Override
takeProperties(Collection<VehiclePropConfig> configs)133     public void takeProperties(Collection<VehiclePropConfig> configs) {
134         if (configs.isEmpty()) {
135             return;
136         }
137 
138         synchronized (mLock) {
139             for (VehiclePropConfig config : configs) {
140                 mProperties.put(config.prop, config);
141             }
142         }
143 
144         mIsEvsServiceRequestSupported = mProperties.contains(EVS_SERVICE_REQUEST);
145     }
146 
147     @Override
onHalEvents(List<VehiclePropValue> values)148     public void onHalEvents(List<VehiclePropValue> values) {
149         EvsHalEventListener listener;
150         synchronized (mLock) {
151             listener = mListener;
152         }
153 
154         if (listener == null) {
155             Slog.w(TAG, "EVS Hal event occurs while the listener is null.");
156             return;
157         }
158 
159         dispatchHalEvents(values, listener);
160     }
161 
dispatchHalEvents(List<VehiclePropValue> values, EvsHalEventListener listener)162     private void dispatchHalEvents(List<VehiclePropValue> values, EvsHalEventListener listener) {
163         for (int i = 0; i < values.size(); ++i) {
164             VehiclePropValue v = values.get(i);
165             boolean on = false;
166             switch (v.prop) {
167                 case EVS_SERVICE_REQUEST:
168                     // Sees
169                     // android.hardware.automotive.vehicle.V2_0.VehicleProperty.EVS_SERVICE_REQUEST
170                     int rawServiceType =
171                             v.value.int32Values.get(EvsServiceRequestIndex.TYPE);
172                     @CarEvsServiceType int type = rawServiceType == EvsServiceType.REARVIEW ?
173                             SERVICE_TYPE_REARVIEW : SERVICE_TYPE_SURROUNDVIEW;
174                     on = v.value.int32Values.get(
175                             EvsServiceRequestIndex.STATE) == EvsServiceState.ON;
176                     if (DBG) {
177                         Slog.d(TAG, "Received EVS_SERVICE_REQUEST: type = " + type + " on = " + on);
178                     }
179 
180                     listener.onEvent(type, on);
181                     break;
182 
183                 default:
184                     if (DBG) {
185                         Slog.d(TAG, "Received unknown property change: " + v);
186                     }
187                     break;
188             }
189         }
190     }
191 
192     @Override
193     @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
dump(PrintWriter writer)194     public void dump(PrintWriter writer) {
195         writer.println("*EVSHALSERVICE*");
196         writer.printf("Use EVS_SERVICE_REQUEST: %b\n", isEvsServiceRequestSupported());
197     }
198 }
199