1 /*
2  * Copyright (C) 2023 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.internal.property;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import android.car.hardware.CarPropertyValue;
22 import android.car.hardware.property.CarPropertyEvent;
23 import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
24 import android.util.Log;
25 import android.util.Slog;
26 
27 import java.util.concurrent.Executor;
28 
29 /**
30  * Manages a group of property IDs and area IDs registered for the same {@link
31  * CarPropertyEventCallback} at possibly different update rates.
32  *
33  * @hide
34  */
35 public final class CarPropertyEventCallbackController extends CarPropertyEventController {
36     // Abbreviating TAG because class name is longer than the 23 character Log tag limit.
37     private static final String TAG = "CPECallbackController";
38     private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
39     private final CarPropertyEventCallback mCarPropertyEventCallback;
40     private final Executor mExecutor;
41 
CarPropertyEventCallbackController(CarPropertyEventCallback carPropertyEventCallback, Executor executor)42     public CarPropertyEventCallbackController(CarPropertyEventCallback carPropertyEventCallback,
43             Executor executor) {
44         super(/* useSystemLogger= */ false);
45         requireNonNull(carPropertyEventCallback);
46         mCarPropertyEventCallback = carPropertyEventCallback;
47         mExecutor = executor;
48     }
49 
50     /**
51      * Forward a {@link CarPropertyEvent} to {@link #mCarPropertyEventCallback} if the event is an
52      * error event or the update rate threshold is met for a change event.
53      */
onEvent(CarPropertyEvent carPropertyEvent)54     public void onEvent(CarPropertyEvent carPropertyEvent) {
55         requireNonNull(carPropertyEvent);
56         CarPropertyValue<?> carPropertyValue =
57                 getCarPropertyValueIfCallbackRequired(carPropertyEvent);
58         if (carPropertyValue == null) {
59             if (DBG) {
60                 Slog.d(TAG, "onEvent should not be invoked, event: " + carPropertyEvent);
61             }
62             return;
63         }
64         CarPropertyEvent updatedCarPropertyEvent;
65         if (!carPropertyValue.equals(carPropertyEvent.getCarPropertyValue())) {
66             updatedCarPropertyEvent = new CarPropertyEvent(carPropertyEvent.getEventType(),
67                     carPropertyValue, carPropertyEvent.getErrorCode());
68         } else {
69             updatedCarPropertyEvent = carPropertyEvent;
70         }
71         switch (updatedCarPropertyEvent.getEventType()) {
72             case CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE:
73                 mExecutor.execute(() -> mCarPropertyEventCallback.onChangeEvent(carPropertyValue));
74                 break;
75             case CarPropertyEvent.PROPERTY_EVENT_ERROR:
76                 if (DBG) {
77                     Slog.d(TAG, "onErrorEvent for event: " + updatedCarPropertyEvent);
78                 }
79                 mExecutor.execute(() -> mCarPropertyEventCallback.onErrorEvent(
80                         carPropertyValue.getPropertyId(), carPropertyValue.getAreaId(),
81                         updatedCarPropertyEvent.getErrorCode()));
82                 break;
83             default:
84                 Slog.e(TAG, "onEvent: unknown errorCode=" + updatedCarPropertyEvent.getErrorCode()
85                         + ", for event: " + updatedCarPropertyEvent);
86                 break;
87         }
88     }
89 
getExecutor()90     public Executor getExecutor() {
91         return mExecutor;
92     }
93 }
94