• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package android.car.vms;
2 
3 import android.annotation.SystemApi;
4 import android.util.Log;
5 
6 import com.android.internal.annotations.VisibleForTesting;
7 
8 import org.json.JSONArray;
9 import org.json.JSONException;
10 import org.json.JSONObject;
11 
12 /**
13  * Records VMS operations using the Android Log.
14  *
15  * This class records VMS operations. The recorded messages include the VMS operations and its
16  * arguments encoded as JSON text so that the string can be both read as a log message and easily
17  * parsed. VmsOperationRecorder is intended to be called after successful state change.
18  *
19  * Access the VmsOperationRecorder using the {@link #get()} method, which returns a singleton
20  * instance. Each VMS operation has a corresponding VmsOperationRecorder method. For instance:
21  * <pre>{@code
22  *   VmsOperationRecorder.get().subscribe(layer);
23  * }</pre>
24  *
25  * @hide
26  */
27 @SystemApi
28 public final class VmsOperationRecorder {
29     private static final String TAG = "VmsOperationRecorder";
30     private static final VmsOperationRecorder INSTANCE = new VmsOperationRecorder(new Writer());
31     private final Writer mWriter;
32 
33     @VisibleForTesting
VmsOperationRecorder(Writer writer)34     public VmsOperationRecorder(Writer writer) {
35         mWriter = writer;
36     }
37 
38     /** Return the singleton instance. */
get()39     public static VmsOperationRecorder get() {
40         return INSTANCE;
41     }
42 
43     // VMS Client operations.
44 
subscribe(VmsLayer layer)45     public void subscribe(VmsLayer layer) {
46         recordOp("subscribe", layer);
47     }
48 
unsubscribe(VmsLayer layer)49     public void unsubscribe(VmsLayer layer) {
50         recordOp("unsubscribe", layer);
51     }
52 
subscribe(VmsLayer layer, int publisherId)53     public void subscribe(VmsLayer layer, int publisherId) {
54         recordOp("subscribe", "publisherId", publisherId, layer);
55     }
56 
unsubscribe(VmsLayer layer, int publisherId)57     public void unsubscribe(VmsLayer layer, int publisherId) {
58         recordOp("unsubscribe", "publisherId", publisherId, layer);
59     }
60 
startMonitoring()61     public void startMonitoring() {
62         recordOp("startMonitoring");
63     }
64 
stopMonitoring()65     public void stopMonitoring() {
66         recordOp("stopMonitoring");
67     }
68 
setLayersOffering(VmsLayersOffering layersOffering)69     public void setLayersOffering(VmsLayersOffering layersOffering) {
70         recordOp("setLayersOffering", layersOffering);
71     }
72 
getPublisherId(int publisherId)73     public void getPublisherId(int publisherId) {
74         recordOp("getPublisherId", "publisherId", publisherId);
75     }
76 
77     // VMS Service operations.
78 
addSubscription(int sequenceNumber, VmsLayer layer)79     public void addSubscription(int sequenceNumber, VmsLayer layer) {
80         recordOp("addSubscription", "sequenceNumber", sequenceNumber, layer);
81     }
82 
removeSubscription(int sequenceNumber, VmsLayer layer)83     public void removeSubscription(int sequenceNumber, VmsLayer layer) {
84         recordOp("removeSubscription", "sequenceNumber", sequenceNumber, layer);
85     }
86 
addPromiscuousSubscription(int sequenceNumber)87     public void addPromiscuousSubscription(int sequenceNumber) {
88         recordOp("addPromiscuousSubscription", "sequenceNumber", sequenceNumber);
89     }
90 
removePromiscuousSubscription(int sequenceNumber)91     public void removePromiscuousSubscription(int sequenceNumber) {
92         recordOp("removePromiscuousSubscription", "sequenceNumber", sequenceNumber);
93     }
94 
addHalSubscription(int sequenceNumber, VmsLayer layer)95     public void addHalSubscription(int sequenceNumber, VmsLayer layer) {
96         recordOp("addHalSubscription", "sequenceNumber", sequenceNumber, layer);
97     }
98 
removeHalSubscription(int sequenceNumber, VmsLayer layer)99     public void removeHalSubscription(int sequenceNumber, VmsLayer layer) {
100         recordOp("removeHalSubscription", "sequenceNumber", sequenceNumber, layer);
101     }
102 
setPublisherLayersOffering(VmsLayersOffering layersOffering)103     public void setPublisherLayersOffering(VmsLayersOffering layersOffering) {
104         recordOp("setPublisherLayersOffering", layersOffering);
105     }
106 
setHalPublisherLayersOffering(VmsLayersOffering layersOffering)107     public void setHalPublisherLayersOffering(VmsLayersOffering layersOffering) {
108         recordOp("setHalPublisherLayersOffering", layersOffering);
109     }
110 
recordOp(String operation)111     private void recordOp(String operation) {
112         if (isEnabled()) {
113             try {
114                 write(new JSONObject().put(operation, new JSONObject()));
115             } catch (JSONException e) {
116                 Log.e(TAG, e.toString());
117             }
118         }
119     }
120 
recordOp(String operation, VmsLayer layer)121     private void recordOp(String operation, VmsLayer layer) {
122         if (isEnabled()) {
123             try {
124                 recordOp(operation, new JSONObject().put("layer", toJson(layer)));
125             } catch (JSONException e) {
126                 Log.e(TAG, e.toString());
127             }
128         }
129     }
130 
recordOp(String operation, VmsLayersOffering layersOffering)131     private void recordOp(String operation, VmsLayersOffering layersOffering) {
132         if (isEnabled()) {
133             try {
134                 JSONObject args = new JSONObject();
135                 JSONArray offering = toJson(layersOffering);
136                 if (offering.length() > 0) {
137                     args.put("layerDependency", offering);
138                 }
139                 recordOp(operation, args);
140             } catch (JSONException e) {
141                 Log.e(TAG, e.toString());
142             }
143         }
144     }
145 
recordOp(String operation, String intArgName, int arg)146     private void recordOp(String operation, String intArgName, int arg) {
147         if (isEnabled()) {
148             try {
149                 recordOp(operation, new JSONObject().put(intArgName, arg));
150             } catch (JSONException e) {
151                 Log.e(TAG, e.toString());
152             }
153         }
154     }
155 
recordOp(String operation, String intArgName, int arg, VmsLayer layer)156     private void recordOp(String operation, String intArgName, int arg, VmsLayer layer) {
157         if (isEnabled()) {
158             try {
159                 recordOp(operation,
160                         new JSONObject().put(intArgName, arg).put("layer", toJson(layer)));
161             } catch (JSONException e) {
162                 Log.e(TAG, e.toString());
163             }
164         }
165     }
166 
recordOp(String operation, JSONObject args)167     private void recordOp(String operation, JSONObject args) {
168         if (isEnabled()) {
169             try {
170                 write(new JSONObject().put(operation, args));
171             } catch (JSONException e) {
172                 Log.e(TAG, e.toString());
173             }
174         }
175     }
176 
toJson(VmsLayer layer)177     private static JSONObject toJson(VmsLayer layer) throws JSONException {
178         return new JSONObject()
179                 .put("type", layer.getType())
180                 .put("subtype", layer.getSubtype())
181                 .put("version", layer.getVersion());
182     }
183 
toJson(VmsLayerDependency layerDependency)184     private static JSONObject toJson(VmsLayerDependency layerDependency) throws JSONException {
185         JSONObject dep = new JSONObject();
186         dep.put("layer", toJson(layerDependency.getLayer()));
187         if (!layerDependency.getDependencies().isEmpty()) {
188             JSONArray dependencies = new JSONArray();
189             for (VmsLayer dependency : layerDependency.getDependencies()) {
190                 dependencies.put(toJson(dependency));
191             }
192             dep.put("dependency", dependencies);
193         }
194         return dep;
195     }
196 
toJson(VmsLayersOffering layersOffering)197     private static JSONArray toJson(VmsLayersOffering layersOffering) throws JSONException {
198         JSONArray offerings = new JSONArray();
199         for (VmsLayerDependency layerDependency : layersOffering.getDependencies()) {
200             offerings.put(toJson(layerDependency));
201         }
202         return offerings;
203     }
204 
isEnabled()205     private boolean isEnabled() {
206         return mWriter.isEnabled();
207     }
208 
write(JSONObject object)209     private void write(JSONObject object) {
210         mWriter.write(object.toString());
211     }
212 
213     /** @hide */
214     @VisibleForTesting
215     public static class Writer {
216         private static final String TAG = "VMS.RECORD.EVENT";
217         private static final int LEVEL = Log.DEBUG;
218 
isEnabled()219         public boolean isEnabled() {
220             return Log.isLoggable(TAG, LEVEL);
221         }
222 
write(String msg)223         public void write(String msg) {
224             Log.println(LEVEL, TAG, msg);
225         }
226     }
227 }
228