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.telemetry.publisher;
18 
19 import android.os.Handler;
20 
21 import com.android.car.CarPropertyService;
22 import com.android.car.telemetry.TelemetryProto;
23 
24 import java.io.File;
25 
26 /**
27  * Lazy factory class for Publishers. It's expected to have a single factory instance.
28  * Must be called from the telemetry thread.
29  *
30  * <p>It doesn't instantiate all the publishers right away, as in some cases some publishers are
31  * not needed.
32  *
33  * <p>Methods in this class must be called on telemetry thread unless specified as thread-safe.
34  */
35 public class PublisherFactory {
36     private final Object mLock = new Object();
37     private final CarPropertyService mCarPropertyService;
38     private final File mPublisherDirectory;
39     private final Handler mTelemetryHandler;
40     private final StatsManagerProxy mStatsManager;
41     private VehiclePropertyPublisher mVehiclePropertyPublisher;
42     private CarTelemetrydPublisher mCarTelemetrydPublisher;
43     private StatsPublisher mStatsPublisher;
44 
45     private AbstractPublisher.PublisherFailureListener mFailureListener;
46 
PublisherFactory( CarPropertyService carPropertyService, Handler handler, StatsManagerProxy statsManager, File publisherDirectory)47     public PublisherFactory(
48             CarPropertyService carPropertyService,
49             Handler handler,
50             StatsManagerProxy statsManager,
51             File publisherDirectory) {
52         mCarPropertyService = carPropertyService;
53         mTelemetryHandler = handler;
54         mStatsManager = statsManager;
55         mPublisherDirectory = publisherDirectory;
56     }
57 
58     /** Returns the publisher by given type. This method is thread-safe. */
getPublisher(TelemetryProto.Publisher.PublisherCase type)59     public AbstractPublisher getPublisher(TelemetryProto.Publisher.PublisherCase type) {
60         // No need to optimize locks, as this method is infrequently called.
61         synchronized (mLock) {
62             switch (type.getNumber()) {
63                 case TelemetryProto.Publisher.VEHICLE_PROPERTY_FIELD_NUMBER:
64                     if (mVehiclePropertyPublisher == null) {
65                         mVehiclePropertyPublisher = new VehiclePropertyPublisher(
66                                 mCarPropertyService, mFailureListener, mTelemetryHandler);
67                     }
68                     return mVehiclePropertyPublisher;
69                 case TelemetryProto.Publisher.CARTELEMETRYD_FIELD_NUMBER:
70                     if (mCarTelemetrydPublisher == null) {
71                         mCarTelemetrydPublisher = new CarTelemetrydPublisher(
72                                 mFailureListener, mTelemetryHandler);
73                     }
74                     return mCarTelemetrydPublisher;
75                 case TelemetryProto.Publisher.STATS_FIELD_NUMBER:
76                     if (mStatsPublisher == null) {
77                         mStatsPublisher = new StatsPublisher(
78                                 mFailureListener, mStatsManager, mPublisherDirectory,
79                                 mTelemetryHandler);
80                     }
81                     return mStatsPublisher;
82                 default:
83                     throw new IllegalArgumentException(
84                             "Publisher type " + type + " is not supported");
85             }
86         }
87     }
88 
89     /**
90      * Removes all {@link com.android.car.telemetry.databroker.DataSubscriber} from all publishers.
91      */
removeAllDataSubscribers()92     public void removeAllDataSubscribers() {
93         if (mVehiclePropertyPublisher != null) {
94             mVehiclePropertyPublisher.removeAllDataSubscribers();
95         }
96         if (mCarTelemetrydPublisher != null) {
97             mCarTelemetrydPublisher.removeAllDataSubscribers();
98         }
99         if (mStatsPublisher != null) {
100             mStatsPublisher.removeAllDataSubscribers();
101         }
102     }
103 
104     /**
105      * Sets the publisher failure listener for all the publishers. This is expected to be called
106      * before {@link #getPublisher} method, because the listener is set after
107      * {@code PublisherFactory} initialized. This is not the best approach, but it suits for this
108      * case.
109      */
setFailureListener(AbstractPublisher.PublisherFailureListener listener)110     public void setFailureListener(AbstractPublisher.PublisherFailureListener listener) {
111         mFailureListener = listener;
112     }
113 }
114