1 /* 2 * Copyright (C) 2017 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.car.vms; 18 19 import android.annotation.SystemApi; 20 import android.util.Log; 21 22 import com.android.internal.annotations.VisibleForTesting; 23 24 import org.json.JSONArray; 25 import org.json.JSONException; 26 import org.json.JSONObject; 27 28 /** 29 * Records VMS operations using the Android Log. 30 * 31 * This class records VMS operations. The recorded messages include the VMS operations and its 32 * arguments encoded as JSON text so that the string can be both read as a log message and easily 33 * parsed. VmsOperationRecorder is intended to be called after successful state change. 34 * 35 * Access the VmsOperationRecorder using the {@link #get()} method, which returns a singleton 36 * instance. Each VMS operation has a corresponding VmsOperationRecorder method. For instance: 37 * <pre>{@code 38 * VmsOperationRecorder.get().subscribe(layer); 39 * }</pre> 40 * 41 * @deprecated VmsOperationRecorder is no longer used by VMS and will produce no output 42 * @hide 43 */ 44 @Deprecated 45 @SystemApi 46 public final class VmsOperationRecorder { 47 private static final String TAG = "VmsOperationRecorder"; 48 private static final VmsOperationRecorder INSTANCE = new VmsOperationRecorder(new Writer()); 49 private final Writer mWriter; 50 51 /** @hide */ 52 @VisibleForTesting VmsOperationRecorder(Writer writer)53 public VmsOperationRecorder(Writer writer) { 54 mWriter = writer; 55 } 56 57 /** Return the singleton instance. */ get()58 public static VmsOperationRecorder get() { 59 return INSTANCE; 60 } 61 62 // VMS Client operations. 63 64 /** 65 * Records {@code subscribe} operation with the {@link VmsLayer} layer passed as parameter. 66 */ subscribe(VmsLayer layer)67 public void subscribe(VmsLayer layer) { 68 recordOp("subscribe", layer); 69 } 70 71 /** 72 * Records {@code unsubscribe} operation with the {@link VmsLayer} layer passed as parameter. 73 */ unsubscribe(VmsLayer layer)74 public void unsubscribe(VmsLayer layer) { 75 recordOp("unsubscribe", layer); 76 } 77 78 /** 79 * Records {@code subscribe} operation with the {@link VmsLayer} layer and publisher id passed 80 * both as parameter. 81 */ subscribe(VmsLayer layer, int publisherId)82 public void subscribe(VmsLayer layer, int publisherId) { 83 recordOp("subscribe", "publisherId", publisherId, layer); 84 } 85 86 /** 87 * Record {@code unsubscribe} operation with the {@link VmsLayer} layer and publisher id passed 88 * both as parameter. 89 */ unsubscribe(VmsLayer layer, int publisherId)90 public void unsubscribe(VmsLayer layer, int publisherId) { 91 recordOp("unsubscribe", "publisherId", publisherId, layer); 92 } 93 94 /** 95 * Records {@code startMonitoring} operation. 96 */ startMonitoring()97 public void startMonitoring() { 98 recordOp("startMonitoring"); 99 } 100 101 /** 102 * Records {@code stopMonitoring} operation. 103 */ stopMonitoring()104 public void stopMonitoring() { 105 recordOp("stopMonitoring"); 106 } 107 108 /** 109 * Records {@code setLayerOffering} operation with the {@link VmsLayerOffering} offering 110 * passed as parameter. 111 */ setLayersOffering(VmsLayersOffering layersOffering)112 public void setLayersOffering(VmsLayersOffering layersOffering) { 113 recordOp("setLayersOffering", layersOffering); 114 } 115 116 /** 117 * Records {@code getPublisherId} operation with the publisher id passed as parameter. 118 */ getPublisherId(int publisherId)119 public void getPublisherId(int publisherId) { 120 recordOp("getPublisherId", "publisherId", publisherId); 121 } 122 123 // VMS Service operations. 124 125 /** 126 * Records {@code addSubscription} operation with the {@link VmsLayer} and the sequenceNumber 127 * passed as parameter. 128 */ addSubscription(int sequenceNumber, VmsLayer layer)129 public void addSubscription(int sequenceNumber, VmsLayer layer) { 130 recordOp("addSubscription", "sequenceNumber", sequenceNumber, layer); 131 } 132 133 /** 134 * Records {@code addPromiscuousSubscription} operation with the {@link VmsLayer} and the 135 * sequenceNumber passed as parameter. 136 */ removeSubscription(int sequenceNumber, VmsLayer layer)137 public void removeSubscription(int sequenceNumber, VmsLayer layer) { 138 recordOp("removeSubscription", "sequenceNumber", sequenceNumber, layer); 139 } 140 141 /** 142 * Records {@code addPromiscuousSubscription} operation with the sequenceNumber passed as 143 * parameter. 144 */ addPromiscuousSubscription(int sequenceNumber)145 public void addPromiscuousSubscription(int sequenceNumber) { 146 recordOp("addPromiscuousSubscription", "sequenceNumber", sequenceNumber); 147 } 148 149 /** 150 * Records {@code removePromiscuousSubscription} operation with the sequenceNumber passed as 151 * parameter. 152 */ removePromiscuousSubscription(int sequenceNumber)153 public void removePromiscuousSubscription(int sequenceNumber) { 154 recordOp("removePromiscuousSubscription", "sequenceNumber", sequenceNumber); 155 } 156 157 /** 158 * Records {@code addHalSubscription} operation with the {@link VmsLayer} layer and 159 * sequenceNumber both passed as parameter. 160 */ addHalSubscription(int sequenceNumber, VmsLayer layer)161 public void addHalSubscription(int sequenceNumber, VmsLayer layer) { 162 recordOp("addHalSubscription", "sequenceNumber", sequenceNumber, layer); 163 } 164 165 /** 166 * Records {@code removeHalSubscription} operation with the {@link VmsLayer} layer and 167 * sequenceNumber both passed as parameter. 168 */ removeHalSubscription(int sequenceNumber, VmsLayer layer)169 public void removeHalSubscription(int sequenceNumber, VmsLayer layer) { 170 recordOp("removeHalSubscription", "sequenceNumber", sequenceNumber, layer); 171 } 172 173 /** 174 * Records {@code setPublisherLayersOffering} operation with the {@link VmsLayersOffering} 175 * layersOffering passed as parameter. 176 */ setPublisherLayersOffering(VmsLayersOffering layersOffering)177 public void setPublisherLayersOffering(VmsLayersOffering layersOffering) { 178 recordOp("setPublisherLayersOffering", layersOffering); 179 } 180 181 /** 182 * Records {@code setHalPublisherLayersOffering} operation with the {@link VmsLayersOffering} 183 * layersOffering passed as parameter. 184 */ setHalPublisherLayersOffering(VmsLayersOffering layersOffering)185 public void setHalPublisherLayersOffering(VmsLayersOffering layersOffering) { 186 recordOp("setHalPublisherLayersOffering", layersOffering); 187 } 188 recordOp(String operation)189 private void recordOp(String operation) { 190 if (isEnabled()) { 191 try { 192 write(new JSONObject().put(operation, new JSONObject())); 193 } catch (JSONException e) { 194 Log.e(TAG, e.toString()); 195 } 196 } 197 } 198 recordOp(String operation, VmsLayer layer)199 private void recordOp(String operation, VmsLayer layer) { 200 if (isEnabled()) { 201 try { 202 recordOp(operation, new JSONObject().put("layer", toJson(layer))); 203 } catch (JSONException e) { 204 Log.e(TAG, e.toString()); 205 } 206 } 207 } 208 recordOp(String operation, VmsLayersOffering layersOffering)209 private void recordOp(String operation, VmsLayersOffering layersOffering) { 210 if (isEnabled()) { 211 try { 212 JSONObject args = new JSONObject(); 213 args.put("publisherId", layersOffering.getPublisherId()); 214 JSONArray offering = toJson(layersOffering); 215 if (offering.length() > 0) { 216 args.put("layerDependency", offering); 217 } 218 recordOp(operation, args); 219 } catch (JSONException e) { 220 Log.e(TAG, e.toString()); 221 } 222 } 223 } 224 recordOp(String operation, String intArgName, int arg)225 private void recordOp(String operation, String intArgName, int arg) { 226 if (isEnabled()) { 227 try { 228 recordOp(operation, new JSONObject().put(intArgName, arg)); 229 } catch (JSONException e) { 230 Log.e(TAG, e.toString()); 231 } 232 } 233 } 234 recordOp(String operation, String intArgName, int arg, VmsLayer layer)235 private void recordOp(String operation, String intArgName, int arg, VmsLayer layer) { 236 if (isEnabled()) { 237 try { 238 recordOp(operation, 239 new JSONObject().put(intArgName, arg).put("layer", toJson(layer))); 240 } catch (JSONException e) { 241 Log.e(TAG, e.toString()); 242 } 243 } 244 } 245 recordOp(String operation, JSONObject args)246 private void recordOp(String operation, JSONObject args) { 247 if (isEnabled()) { 248 try { 249 write(new JSONObject().put(operation, args)); 250 } catch (JSONException e) { 251 Log.e(TAG, e.toString()); 252 } 253 } 254 } 255 toJson(VmsLayer layer)256 private static JSONObject toJson(VmsLayer layer) throws JSONException { 257 return new JSONObject() 258 .put("type", layer.getType()) 259 .put("subtype", layer.getSubtype()) 260 .put("version", layer.getVersion()); 261 } 262 toJson(VmsLayerDependency layerDependency)263 private static JSONObject toJson(VmsLayerDependency layerDependency) throws JSONException { 264 JSONObject dep = new JSONObject(); 265 dep.put("layer", toJson(layerDependency.getLayer())); 266 if (!layerDependency.getDependencies().isEmpty()) { 267 JSONArray dependencies = new JSONArray(); 268 for (VmsLayer dependency : layerDependency.getDependencies()) { 269 dependencies.put(toJson(dependency)); 270 } 271 dep.put("dependency", dependencies); 272 } 273 return dep; 274 } 275 toJson(VmsLayersOffering layersOffering)276 private static JSONArray toJson(VmsLayersOffering layersOffering) throws JSONException { 277 JSONArray offerings = new JSONArray(); 278 for (VmsLayerDependency layerDependency : layersOffering.getDependencies()) { 279 offerings.put(toJson(layerDependency)); 280 } 281 return offerings; 282 } 283 isEnabled()284 private boolean isEnabled() { 285 return mWriter.isEnabled(); 286 } 287 write(JSONObject object)288 private void write(JSONObject object) { 289 mWriter.write(object.toString()); 290 } 291 292 /** @hide */ 293 @VisibleForTesting 294 public static class Writer { 295 private static final String TAG = "VMS.RECORD.EVENT"; 296 private static final int LEVEL = Log.DEBUG; 297 isEnabled()298 public boolean isEnabled() { 299 return Log.isLoggable(TAG, LEVEL); 300 } 301 302 /** Logs the message passed as parameter. */ write(String msg)303 public void write(String msg) { 304 Log.println(LEVEL, TAG, msg); 305 } 306 } 307 } 308