• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.managedprovisioning.analytics;
18 
19 import static com.android.internal.util.Preconditions.checkNotNull;
20 
21 import android.app.admin.DevicePolicyEventLogger;
22 import android.os.AsyncTask;
23 
24 import com.android.internal.util.Preconditions;
25 import com.android.managedprovisioning.DevicePolicyProtos.DevicePolicyEvent;
26 import com.android.managedprovisioning.common.ProvisionLogger;
27 
28 import java.io.File;
29 import java.io.FileNotFoundException;
30 import java.io.FileOutputStream;
31 import java.io.IOException;
32 import java.io.OutputStream;
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.Objects;
36 import java.util.stream.Collectors;
37 
38 /**
39  * A {@link MetricsWriter} which writes the {@link DevicePolicyEventLogger} events to a file.
40  *
41  * <p>To read the written logs, use {@link DeferredMetricsReader}.
42  *
43  * @see DeferredMetricsReader
44  */
45 public class DeferredMetricsWriter implements MetricsWriter {
46 
47     private static final Object sLock = new Object();
48 
49     private final File mFile;
50 
DeferredMetricsWriter(File file)51     DeferredMetricsWriter(File file) {
52         mFile = checkNotNull(file);
53     }
54 
55     @Override
write(DevicePolicyEventLogger... loggers)56     public void write(DevicePolicyEventLogger... loggers) {
57         try {
58             final OutputStream outputStream = new FileOutputStream(mFile, true);
59             new WriteDeferredMetricsAsyncTask(outputStream).execute(loggers);
60         } catch (FileNotFoundException e) {
61             // This is an acceptable scenario as we have a check in write(...).
62             ProvisionLogger.loge("Could not find file passed to DeferredMetricsWriter.", e);
63         }
64     }
65 
66     private static class WriteDeferredMetricsAsyncTask
67             extends AsyncTask<DevicePolicyEventLogger, Void, Void> {
68 
69         private final OutputStream mOutputStream;
70 
WriteDeferredMetricsAsyncTask(OutputStream file)71         WriteDeferredMetricsAsyncTask(OutputStream file) {
72             mOutputStream = file;
73         }
74 
75         @Override
doInBackground(DevicePolicyEventLogger... devicePolicyEventLoggers)76         protected Void doInBackground(DevicePolicyEventLogger... devicePolicyEventLoggers) {
77             final List<DevicePolicyEvent> events = Arrays.stream(devicePolicyEventLoggers)
78                     .map(WriteDeferredMetricsAsyncTask::eventLoggerToDevicePolicyEvent)
79                     .collect(Collectors.toList());
80             synchronized (sLock) {
81                 writeDevicePolicyEventsToStream(events, mOutputStream);
82             }
83             return null;
84         }
85 
writeDevicePolicyEventsToStream( List<DevicePolicyEvent> events, OutputStream outputStream)86         private static void writeDevicePolicyEventsToStream(
87                 List<DevicePolicyEvent> events, OutputStream outputStream) {
88             for (DevicePolicyEvent event : events) {
89                 try {
90                     event.writeDelimitedTo(outputStream);
91                 } catch (IOException e) {
92                     ProvisionLogger.loge("Failed to write DevicePolicyEvent to OutputStream.", e);
93                 }
94             }
95             try {
96                 outputStream.flush();
97             } catch (IOException e) {
98                 ProvisionLogger.loge("Failed to flush OutputStream.", e);
99             } finally {
100                 try {
101                     outputStream.close();
102                 } catch (IOException e) {
103                     ProvisionLogger.loge("Failed to close OutputStream.", e);
104                 }
105             }
106         }
107 
eventLoggerToDevicePolicyEvent( DevicePolicyEventLogger eventLogger)108         private static DevicePolicyEvent eventLoggerToDevicePolicyEvent(
109                 DevicePolicyEventLogger eventLogger) {
110             final DevicePolicyEvent.Builder builder = DevicePolicyEvent.newBuilder()
111                     .setEventId(eventLogger.getEventId())
112                     .setIntegerValue(eventLogger.getInt())
113                     .setBooleanValue(eventLogger.getBoolean())
114                     .setTimePeriodMillis(eventLogger.getTimePeriod());
115             if (eventLogger.getAdminPackageName() != null) {
116                 builder.setAdminPackageName(eventLogger.getAdminPackageName());
117             }
118             final String[] stringValues = eventLogger.getStringArray();
119             if (stringValues != null) {
120                 Arrays.stream(stringValues)
121                         .filter(Objects::nonNull)
122                         .forEach(stringValue -> builder.addStringListValue(stringValue));
123             }
124             return builder.build();
125         }
126     }
127 }
128