/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.textclassifier.downloader; import static com.android.textclassifier.downloader.ModelDownloadException.DEFAULT_DOWNLOADER_LIB_ERROR_CODE; import android.text.TextUtils; import com.android.textclassifier.common.ModelType; import com.android.textclassifier.common.ModelType.ModelTypeDef; import com.android.textclassifier.common.base.TcLog; import com.android.textclassifier.common.statsd.TextClassifierStatsLog; import com.android.textclassifier.downloader.ModelDownloadException.ErrorCode; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import java.util.Locale; /** Logs TextClassifier download event. */ final class TextClassifierDownloadLogger { private static final String TAG = "TextClassifierDownloadLogger"; // Values for TextClassifierDownloadReported.download_status private static final int DOWNLOAD_STATUS_SUCCEEDED = TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__DOWNLOAD_STATUS__SUCCEEDED; private static final int DOWNLOAD_STATUS_FAILED_AND_RETRY = TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__DOWNLOAD_STATUS__FAILED_AND_RETRY; private static final int DEFAULT_MODEL_TYPE = TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__MODEL_TYPE__UNKNOWN_MODEL_TYPE; private static final ImmutableMap MODEL_TYPE_MAP = ImmutableMap.of( ModelType.ANNOTATOR, TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__MODEL_TYPE__ANNOTATOR, ModelType.LANG_ID, TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__MODEL_TYPE__LANG_ID, ModelType.ACTIONS_SUGGESTIONS, TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__MODEL_TYPE__ACTIONS_SUGGESTIONS); private static final int DEFAULT_FILE_TYPE = TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FILE_TYPE__UNKNOWN_FILE_TYPE; private static final int DEFAULT_FAILURE_REASON = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__UNKNOWN_FAILURE_REASON; private static final ImmutableMap FAILURE_REASON_MAP = ImmutableMap.builder() .put( ModelDownloadException.UNKNOWN_FAILURE_REASON, TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__UNKNOWN_FAILURE_REASON) .put( ModelDownloadException.FAILED_TO_DOWNLOAD_SERVICE_CONN_BROKEN, TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_DOWNLOAD_SERVICE_CONN_BROKEN) .put( ModelDownloadException.FAILED_TO_DOWNLOAD_404_ERROR, TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_DOWNLOAD_404_ERROR) .put( ModelDownloadException.FAILED_TO_DOWNLOAD_OTHER, TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_DOWNLOAD_OTHER) .put( ModelDownloadException.DOWNLOADED_FILE_MISSING, TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__DOWNLOADED_FILE_MISSING) .put( ModelDownloadException.FAILED_TO_PARSE_MANIFEST, TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_PARSE_MANIFEST) .put( ModelDownloadException.FAILED_TO_VALIDATE_MODEL, TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_REPORTED__FAILURE_REASON__FAILED_TO_VALIDATE_MODEL) .buildOrThrow(); // Reasons to schedule public static final int REASON_TO_SCHEDULE_TCS_STARTED = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED__REASON_TO_SCHEDULE__TCS_STARTED; public static final int REASON_TO_SCHEDULE_LOCALE_SETTINGS_CHANGED = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED__REASON_TO_SCHEDULE__LOCALE_SETTINGS_CHANGED; public static final int REASON_TO_SCHEDULE_DEVICE_CONFIG_UPDATED = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED__REASON_TO_SCHEDULE__DEVICE_CONFIG_UPDATED; // Work results public static final int WORK_RESULT_UNKNOWN_WORK_RESULT = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__UNKNOWN_WORK_RESULT; public static final int WORK_RESULT_SUCCESS_MODEL_DOWNLOADED = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__SUCCESS_MODEL_DOWNLOADED; public static final int WORK_RESULT_SUCCESS_NO_UPDATE_AVAILABLE = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__SUCCESS_NO_UPDATE_AVAILABLE; public static final int WORK_RESULT_FAILURE_MODEL_DOWNLOADER_DISABLED = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__FAILURE_MODEL_DOWNLOADER_DISABLED; public static final int WORK_RESULT_FAILURE_MAX_RUN_ATTEMPT_REACHED = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__FAILURE_MAX_RUN_ATTEMPT_REACHED; public static final int WORK_RESULT_RETRY_MODEL_DOWNLOAD_FAILED = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__RETRY_MODEL_DOWNLOAD_FAILED; public static final int WORK_RESULT_RETRY_RUNTIME_EXCEPTION = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__RETRY_RUNTIME_EXCEPTION; public static final int WORK_RESULT_RETRY_STOPPED_BY_OS = TextClassifierStatsLog .TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED__WORK_RESULT__RETRY_STOPPED_BY_OS; /** Logs a succeeded download task. */ public static void downloadSucceeded( long workId, @ModelTypeDef String modelType, String url, int runAttemptCount, long downloadDurationMillis) { Preconditions.checkArgument(!TextUtils.isEmpty(url), "url cannot be null/empty"); TextClassifierStatsLog.write( TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED, MODEL_TYPE_MAP.getOrDefault(modelType, DEFAULT_MODEL_TYPE), DEFAULT_FILE_TYPE, DOWNLOAD_STATUS_SUCCEEDED, url, DEFAULT_FAILURE_REASON, runAttemptCount, DEFAULT_DOWNLOADER_LIB_ERROR_CODE, downloadDurationMillis, workId); if (TcLog.ENABLE_FULL_LOGGING) { TcLog.v( TAG, String.format( Locale.US, "Download Reported: modelType=%s, fileType=%d, status=%d, url=%s, " + "failureReason=%d, runAttemptCount=%d, downloaderLibErrorCode=%d, " + "downloadDurationMillis=%d, workId=%d", MODEL_TYPE_MAP.getOrDefault(modelType, DEFAULT_MODEL_TYPE), DEFAULT_FILE_TYPE, DOWNLOAD_STATUS_SUCCEEDED, url, DEFAULT_FAILURE_REASON, runAttemptCount, DEFAULT_DOWNLOADER_LIB_ERROR_CODE, downloadDurationMillis, workId)); } } /** Logs a failed download task which will be retried later. */ public static void downloadFailed( long workId, @ModelTypeDef String modelType, String url, @ErrorCode int errorCode, int runAttemptCount, int downloaderLibErrorCode, long downloadDurationMillis) { Preconditions.checkArgument(!TextUtils.isEmpty(url), "url cannot be null/empty"); TextClassifierStatsLog.write( TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_REPORTED, MODEL_TYPE_MAP.getOrDefault(modelType, DEFAULT_MODEL_TYPE), DEFAULT_FILE_TYPE, DOWNLOAD_STATUS_FAILED_AND_RETRY, url, FAILURE_REASON_MAP.getOrDefault(errorCode, DEFAULT_FAILURE_REASON), runAttemptCount, downloaderLibErrorCode, downloadDurationMillis, workId); if (TcLog.ENABLE_FULL_LOGGING) { TcLog.v( TAG, String.format( Locale.US, "Download Reported: modelType=%s, fileType=%d, status=%d, url=%s, " + "failureReason=%d, runAttemptCount=%d, downloaderLibErrorCode=%d, " + "downloadDurationMillis=%d, workId=%d", MODEL_TYPE_MAP.getOrDefault(modelType, DEFAULT_MODEL_TYPE), DEFAULT_FILE_TYPE, DOWNLOAD_STATUS_FAILED_AND_RETRY, url, FAILURE_REASON_MAP.getOrDefault(errorCode, DEFAULT_FAILURE_REASON), runAttemptCount, downloaderLibErrorCode, downloadDurationMillis, workId)); } } public static void downloadWorkScheduled( long workId, int reasonToSchedule, boolean failedToSchedule) { TextClassifierStatsLog.write( TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED, workId, reasonToSchedule, failedToSchedule); if (TcLog.ENABLE_FULL_LOGGING) { TcLog.v( TAG, String.format( Locale.US, "Download Work Scheduled: workId=%d, reasonToSchedule=%d, failedToSchedule=%b", workId, reasonToSchedule, failedToSchedule)); } } public static void downloadWorkCompleted( long workId, int workResult, int runAttemptCount, long workScheduledToStartedDurationMillis, long workStartedToEndedDurationMillis) { TextClassifierStatsLog.write( TextClassifierStatsLog.TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED, workId, workResult, runAttemptCount, workScheduledToStartedDurationMillis, workStartedToEndedDurationMillis); if (TcLog.ENABLE_FULL_LOGGING) { TcLog.v( TAG, String.format( Locale.US, "Download Work Completed: workId=%d, result=%d, runAttemptCount=%d, " + "workScheduledToStartedDurationMillis=%d, " + "workStartedToEndedDurationMillis=%d", workId, workResult, runAttemptCount, workScheduledToStartedDurationMillis, workStartedToEndedDurationMillis)); } } private TextClassifierDownloadLogger() {} }