1 /* 2 * Copyright (C) 2018 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.textclassifier.downloader; 18 19 import static com.android.textclassifier.downloader.ModelDownloadException.DEFAULT_DOWNLOADER_LIB_ERROR_CODE; 20 21 import android.text.TextUtils; 22 import com.android.textclassifier.common.ModelType; 23 import com.android.textclassifier.common.ModelType.ModelTypeDef; 24 import com.android.textclassifier.common.base.TcLog; 25 import com.android.textclassifier.common.statsd.TextClassifierStatsLog; 26 import com.android.textclassifier.downloader.ModelDownloadException.ErrorCode; 27 import com.google.common.base.Preconditions; 28 import com.google.common.collect.ImmutableMap; 29 import java.util.Locale; 30 31 /** Logs TextClassifier download event. */ 32 final class TextClassifierDownloadLogger { 33 private static final String TAG = "TextClassifierDownloadLogger"; 34 35 // Values for TextClassifierDownloadReported.download_status 36 private static final int DOWNLOAD_STATUS_SUCCEEDED = 37 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__DOWNLOAD_STATUS__SUCCEEDED; 38 private static final int DOWNLOAD_STATUS_FAILED_AND_RETRY = 39 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__DOWNLOAD_STATUS__FAILED_AND_RETRY; 40 41 private static final int DEFAULT_MODEL_TYPE = 42 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__MODEL_TYPE__UNKNOWN_MODEL_TYPE; 43 private static final ImmutableMap<String, Integer> MODEL_TYPE_MAP = 44 ImmutableMap.of( 45 ModelType.ANNOTATOR, 46 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__MODEL_TYPE__ANNOTATOR, 47 ModelType.LANG_ID, 48 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__MODEL_TYPE__LANG_ID, 49 ModelType.ACTIONS_SUGGESTIONS, 50 TextClassifierStatsLog 51 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__MODEL_TYPE__ACTIONS_SUGGESTIONS); 52 53 private static final int DEFAULT_FILE_TYPE = 54 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FILE_TYPE__UNKNOWN_FILE_TYPE; 55 56 private static final int DEFAULT_FAILURE_REASON = 57 TextClassifierStatsLog 58 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__UNKNOWN_FAILURE_REASON; 59 private static final ImmutableMap<Integer, Integer> FAILURE_REASON_MAP = 60 ImmutableMap.<Integer, Integer>builder() 61 .put( 62 ModelDownloadException.UNKNOWN_FAILURE_REASON, 63 TextClassifierStatsLog 64 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__UNKNOWN_FAILURE_REASON) 65 .put( 66 ModelDownloadException.FAILED_TO_DOWNLOAD_SERVICE_CONN_BROKEN, 67 TextClassifierStatsLog 68 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_DOWNLOAD_SERVICE_CONN_BROKEN) 69 .put( 70 ModelDownloadException.FAILED_TO_DOWNLOAD_404_ERROR, 71 TextClassifierStatsLog 72 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_DOWNLOAD_404_ERROR) 73 .put( 74 ModelDownloadException.FAILED_TO_DOWNLOAD_OTHER, 75 TextClassifierStatsLog 76 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_DOWNLOAD_OTHER) 77 .put( 78 ModelDownloadException.DOWNLOADED_FILE_MISSING, 79 TextClassifierStatsLog 80 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__DOWNLOADED_FILE_MISSING) 81 .put( 82 ModelDownloadException.FAILED_TO_PARSE_MANIFEST, 83 TextClassifierStatsLog 84 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_PARSE_MANIFEST) 85 .put( 86 ModelDownloadException.FAILED_TO_VALIDATE_MODEL, 87 TextClassifierStatsLog 88 .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_VALIDATE_MODEL) 89 .buildOrThrow(); 90 91 // Reasons to schedule 92 public static final int REASON_TO_SCHEDULE_TCS_STARTED = 93 TextClassifierStatsLog 94 .TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED__REASON_TO_SCHEDULE__TCS_STARTED; 95 public static final int REASON_TO_SCHEDULE_LOCALE_SETTINGS_CHANGED = 96 TextClassifierStatsLog 97 .TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED__REASON_TO_SCHEDULE__LOCALE_SETTINGS_CHANGED; 98 public static final int REASON_TO_SCHEDULE_DEVICE_CONFIG_UPDATED = 99 TextClassifierStatsLog 100 .TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED__REASON_TO_SCHEDULE__DEVICE_CONFIG_UPDATED; 101 102 // Work results 103 public static final int WORK_RESULT_UNKNOWN_WORK_RESULT = 104 TextClassifierStatsLog 105 .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__UNKNOWN_WORK_RESULT; 106 public static final int WORK_RESULT_SUCCESS_MODEL_DOWNLOADED = 107 TextClassifierStatsLog 108 .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__SUCCESS_MODEL_DOWNLOADED; 109 public static final int WORK_RESULT_SUCCESS_NO_UPDATE_AVAILABLE = 110 TextClassifierStatsLog 111 .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__SUCCESS_NO_UPDATE_AVAILABLE; 112 public static final int WORK_RESULT_FAILURE_MODEL_DOWNLOADER_DISABLED = 113 TextClassifierStatsLog 114 .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__FAILURE_MODEL_DOWNLOADER_DISABLED; 115 public static final int WORK_RESULT_FAILURE_MAX_RUN_ATTEMPT_REACHED = 116 TextClassifierStatsLog 117 .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__FAILURE_MAX_RUN_ATTEMPT_REACHED; 118 public static final int WORK_RESULT_RETRY_MODEL_DOWNLOAD_FAILED = 119 TextClassifierStatsLog 120 .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__RETRY_MODEL_DOWNLOAD_FAILED; 121 public static final int WORK_RESULT_RETRY_RUNTIME_EXCEPTION = 122 TextClassifierStatsLog 123 .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__RETRY_RUNTIME_EXCEPTION; 124 public static final int WORK_RESULT_RETRY_STOPPED_BY_OS = 125 TextClassifierStatsLog 126 .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__RETRY_STOPPED_BY_OS; 127 128 /** Logs a succeeded download task. */ downloadSucceeded( long workId, @ModelTypeDef String modelType, String url, int runAttemptCount, long downloadDurationMillis)129 public static void downloadSucceeded( 130 long workId, 131 @ModelTypeDef String modelType, 132 String url, 133 int runAttemptCount, 134 long downloadDurationMillis) { 135 Preconditions.checkArgument(!TextUtils.isEmpty(url), "url cannot be null/empty"); 136 TextClassifierStatsLog.write( 137 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED, 138 MODEL_TYPE_MAP.getOrDefault(modelType, DEFAULT_MODEL_TYPE), 139 DEFAULT_FILE_TYPE, 140 DOWNLOAD_STATUS_SUCCEEDED, 141 url, 142 DEFAULT_FAILURE_REASON, 143 runAttemptCount, 144 DEFAULT_DOWNLOADER_LIB_ERROR_CODE, 145 downloadDurationMillis, 146 workId); 147 if (TcLog.ENABLE_FULL_LOGGING) { 148 TcLog.v( 149 TAG, 150 String.format( 151 Locale.US, 152 "Download Reported: modelType=%s, fileType=%d, status=%d, url=%s, " 153 + "failureReason=%d, runAttemptCount=%d, downloaderLibErrorCode=%d, " 154 + "downloadDurationMillis=%d, workId=%d", 155 MODEL_TYPE_MAP.getOrDefault(modelType, DEFAULT_MODEL_TYPE), 156 DEFAULT_FILE_TYPE, 157 DOWNLOAD_STATUS_SUCCEEDED, 158 url, 159 DEFAULT_FAILURE_REASON, 160 runAttemptCount, 161 DEFAULT_DOWNLOADER_LIB_ERROR_CODE, 162 downloadDurationMillis, 163 workId)); 164 } 165 } 166 167 /** Logs a failed download task which will be retried later. */ downloadFailed( long workId, @ModelTypeDef String modelType, String url, @ErrorCode int errorCode, int runAttemptCount, int downloaderLibErrorCode, long downloadDurationMillis)168 public static void downloadFailed( 169 long workId, 170 @ModelTypeDef String modelType, 171 String url, 172 @ErrorCode int errorCode, 173 int runAttemptCount, 174 int downloaderLibErrorCode, 175 long downloadDurationMillis) { 176 Preconditions.checkArgument(!TextUtils.isEmpty(url), "url cannot be null/empty"); 177 TextClassifierStatsLog.write( 178 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED, 179 MODEL_TYPE_MAP.getOrDefault(modelType, DEFAULT_MODEL_TYPE), 180 DEFAULT_FILE_TYPE, 181 DOWNLOAD_STATUS_FAILED_AND_RETRY, 182 url, 183 FAILURE_REASON_MAP.getOrDefault(errorCode, DEFAULT_FAILURE_REASON), 184 runAttemptCount, 185 downloaderLibErrorCode, 186 downloadDurationMillis, 187 workId); 188 if (TcLog.ENABLE_FULL_LOGGING) { 189 TcLog.v( 190 TAG, 191 String.format( 192 Locale.US, 193 "Download Reported: modelType=%s, fileType=%d, status=%d, url=%s, " 194 + "failureReason=%d, runAttemptCount=%d, downloaderLibErrorCode=%d, " 195 + "downloadDurationMillis=%d, workId=%d", 196 MODEL_TYPE_MAP.getOrDefault(modelType, DEFAULT_MODEL_TYPE), 197 DEFAULT_FILE_TYPE, 198 DOWNLOAD_STATUS_FAILED_AND_RETRY, 199 url, 200 FAILURE_REASON_MAP.getOrDefault(errorCode, DEFAULT_FAILURE_REASON), 201 runAttemptCount, 202 downloaderLibErrorCode, 203 downloadDurationMillis, 204 workId)); 205 } 206 } 207 downloadWorkScheduled( long workId, int reasonToSchedule, boolean failedToSchedule)208 public static void downloadWorkScheduled( 209 long workId, int reasonToSchedule, boolean failedToSchedule) { 210 TextClassifierStatsLog.write( 211 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED, 212 workId, 213 reasonToSchedule, 214 failedToSchedule); 215 if (TcLog.ENABLE_FULL_LOGGING) { 216 TcLog.v( 217 TAG, 218 String.format( 219 Locale.US, 220 "Download Work Scheduled: workId=%d, reasonToSchedule=%d, failedToSchedule=%b", 221 workId, 222 reasonToSchedule, 223 failedToSchedule)); 224 } 225 } 226 downloadWorkCompleted( long workId, int workResult, int runAttemptCount, long workScheduledToStartedDurationMillis, long workStartedToEndedDurationMillis)227 public static void downloadWorkCompleted( 228 long workId, 229 int workResult, 230 int runAttemptCount, 231 long workScheduledToStartedDurationMillis, 232 long workStartedToEndedDurationMillis) { 233 TextClassifierStatsLog.write( 234 TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED, 235 workId, 236 workResult, 237 runAttemptCount, 238 workScheduledToStartedDurationMillis, 239 workStartedToEndedDurationMillis); 240 if (TcLog.ENABLE_FULL_LOGGING) { 241 TcLog.v( 242 TAG, 243 String.format( 244 Locale.US, 245 "Download Work Completed: workId=%d, result=%d, runAttemptCount=%d, " 246 + "workScheduledToStartedDurationMillis=%d, " 247 + "workStartedToEndedDurationMillis=%d", 248 workId, 249 workResult, 250 runAttemptCount, 251 workScheduledToStartedDurationMillis, 252 workStartedToEndedDurationMillis)); 253 } 254 } 255 TextClassifierDownloadLogger()256 private TextClassifierDownloadLogger() {} 257 } 258