1 /* 2 * Copyright 2022 Google LLC 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 package com.google.android.libraries.mobiledatadownload.internal.logging; 17 18 import static com.google.common.util.concurrent.Futures.immediateVoidFuture; 19 import static com.google.common.util.concurrent.MoreExecutors.directExecutor; 20 21 import android.content.Context; 22 23 import com.google.android.libraries.mobiledatadownload.Flags; 24 import com.google.android.libraries.mobiledatadownload.annotations.InstanceId; 25 import com.google.android.libraries.mobiledatadownload.internal.ApplicationContext; 26 import com.google.android.libraries.mobiledatadownload.tracing.PropagatedFutures; 27 import com.google.common.base.Optional; 28 import com.google.common.util.concurrent.ListenableFuture; 29 import com.google.mobiledatadownload.LogProto.DataDownloadFileGroupStats; 30 import com.google.mobiledatadownload.LogProto.MddNetworkStats; 31 import com.google.mobiledatadownload.internal.MetadataProto.FileGroupLoggingState; 32 33 import java.util.List; 34 35 import javax.inject.Inject; 36 37 /** 38 * Log MDD network stats at daily maintenance. For each file group, it will log the total bytes 39 * downloaded on Wifi and Cellular and also total bytes downloaded by MDD on Wifi and Cellular. 40 */ 41 public class NetworkLogger { 42 43 private final EventLogger eventLogger; 44 private final Flags flags; 45 private final LoggingStateStore loggingStateStore; 46 47 @Inject NetworkLogger( @pplicationContext Context context, EventLogger eventLogger, @InstanceId Optional<String> instanceIdOptional, Flags flags, LoggingStateStore loggingStateStore)48 public NetworkLogger( 49 @ApplicationContext Context context, 50 EventLogger eventLogger, 51 @InstanceId Optional<String> instanceIdOptional, 52 Flags flags, 53 LoggingStateStore loggingStateStore) { 54 this.eventLogger = eventLogger; 55 this.flags = flags; 56 this.loggingStateStore = loggingStateStore; 57 } 58 log()59 public ListenableFuture<Void> log() { 60 if (!flags.logNetworkStats()) { 61 return immediateVoidFuture(); 62 } 63 64 // Clear the accumulated network usage even if the device isn't logging, otherwise with 1% 65 // sampling, we could potentially log network usage for up to 100 days. 66 ListenableFuture<List<FileGroupLoggingState>> allDataUsageFuture = 67 loggingStateStore.getAndResetAllDataUsage(); 68 69 return eventLogger.logMddNetworkStats( 70 () -> 71 PropagatedFutures.transform( 72 allDataUsageFuture, this::buildNetworkStats, directExecutor())); 73 } 74 buildNetworkStats(List<FileGroupLoggingState> allDataUsage)75 private MddNetworkStats buildNetworkStats(List<FileGroupLoggingState> allDataUsage) { 76 long totalMddWifiCount = 0; 77 long totalMddCellularCount = 0; 78 MddNetworkStats.Builder networkStatsBuilder = MddNetworkStats.newBuilder(); 79 80 for (FileGroupLoggingState fileGroupLoggingState : allDataUsage) { 81 networkStatsBuilder.addGroupStats( 82 MddNetworkStats.GroupStats.newBuilder() 83 .setDataDownloadFileGroupStats( 84 DataDownloadFileGroupStats.newBuilder() 85 .setOwnerPackage(fileGroupLoggingState.getGroupKey().getOwnerPackage()) 86 .setFileGroupName(fileGroupLoggingState.getGroupKey().getGroupName()) 87 .setFileGroupVersionNumber(fileGroupLoggingState.getFileGroupVersionNumber()) 88 .setBuildId(fileGroupLoggingState.getBuildId()) 89 .setVariantId(fileGroupLoggingState.getVariantId()) 90 .build()) 91 .setTotalWifiBytes(fileGroupLoggingState.getWifiUsage()) 92 .setTotalCellularBytes(fileGroupLoggingState.getCellularUsage())); 93 94 totalMddWifiCount += fileGroupLoggingState.getWifiUsage(); 95 totalMddCellularCount += fileGroupLoggingState.getCellularUsage(); 96 } 97 98 networkStatsBuilder 99 .setTotalMddWifiBytes(totalMddWifiCount) 100 .setTotalMddCellularBytes(totalMddCellularCount); 101 return networkStatsBuilder.build(); 102 } 103 } 104