/* * Tencent is pleased to support the open source community by making Tinker available. * * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. * * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * 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.dl7.tinkerlib.reporter; import com.dl7.tinkerlib.util.Utils; import com.tencent.tinker.lib.util.TinkerLog; import com.tencent.tinker.loader.shareutil.ShareConstants; import com.tencent.tinker.loader.shareutil.ShareTinkerInternals; /** * a simple tinker data reporter * Created by zhangshaowen on 16/9/17. */ public class SampleTinkerReport { private static final String TAG = "Tinker.SampleTinkerReport"; // KEY - PV public static final int KEY_REQUEST = 0; public static final int KEY_DOWNLOAD = 1; public static final int KEY_TRY_APPLY = 2; public static final int KEY_TRY_APPLY_SUCCESS = 3; public static final int KEY_APPLIED_START = 4; public static final int KEY_APPLIED = 5; public static final int KEY_LOADED = 6; public static final int KEY_CRASH_FAST_PROTECT = 7; public static final int KEY_CRASH_CAUSE_XPOSED_DALVIK = 8; public static final int KEY_CRASH_CAUSE_XPOSED_ART = 9; public static final int KEY_APPLY_WITH_RETRY = 10; //Key -- try apply detail public static final int KEY_TRY_APPLY_UPGRADE = 70; public static final int KEY_TRY_APPLY_DISABLE = 71; public static final int KEY_TRY_APPLY_RUNNING = 72; public static final int KEY_TRY_APPLY_INSERVICE = 73; public static final int KEY_TRY_APPLY_NOT_EXIST = 74; public static final int KEY_TRY_APPLY_GOOGLEPLAY = 75; public static final int KEY_TRY_APPLY_ROM_SPACE = 76; public static final int KEY_TRY_APPLY_ALREADY_APPLY = 77; public static final int KEY_TRY_APPLY_MEMORY_LIMIT = 78; public static final int KEY_TRY_APPLY_CRASH_LIMIT = 79; public static final int KEY_TRY_APPLY_CONDITION_NOT_SATISFIED = 80; //Key -- apply detail public static final int KEY_APPLIED_UPGRADE = 100; public static final int KEY_APPLIED_UPGRADE_FAIL = 101; public static final int KEY_APPLIED_EXCEPTION = 120; public static final int KEY_APPLIED_DEXOPT = 121; public static final int KEY_APPLIED_INFO_CORRUPTED = 122; //package check public static final int KEY_APPLIED_PACKAGE_CHECK_SIGNATURE = 150; public static final int KEY_APPLIED_PACKAGE_CHECK_DEX_META = 151; public static final int KEY_APPLIED_PACKAGE_CHECK_LIB_META = 152; public static final int KEY_APPLIED_PACKAGE_CHECK_APK_TINKER_ID_NOT_FOUND = 153; public static final int KEY_APPLIED_PACKAGE_CHECK_PATCH_TINKER_ID_NOT_FOUND = 154; public static final int KEY_APPLIED_PACKAGE_CHECK_META_NOT_FOUND = 155; public static final int KEY_APPLIED_PACKAGE_CHECK_TINKER_ID_NOT_EQUAL = 156; public static final int KEY_APPLIED_PACKAGE_CHECK_RES_META = 157; public static final int KEY_APPLIED_PACKAGE_CHECK_TINKERFLAG_NOT_SUPPORT = 158; //version check public static final int KEY_APPLIED_VERSION_CHECK = 180; //extract error public static final int KEY_APPLIED_PATCH_FILE_EXTRACT = 181; public static final int KEY_APPLIED_DEX_EXTRACT = 182; public static final int KEY_APPLIED_LIB_EXTRACT = 183; public static final int KEY_APPLIED_RESOURCE_EXTRACT = 184; //cost time public static final int KEY_APPLIED_SUCC_COST_5S_LESS = 200; public static final int KEY_APPLIED_SUCC_COST_10S_LESS = 201; public static final int KEY_APPLIED_SUCC_COST_30S_LESS = 202; public static final int KEY_APPLIED_SUCC_COST_60S_LESS = 203; public static final int KEY_APPLIED_SUCC_COST_OTHER = 204; public static final int KEY_APPLIED_FAIL_COST_5S_LESS = 205; public static final int KEY_APPLIED_FAIL_COST_10S_LESS = 206; public static final int KEY_APPLIED_FAIL_COST_30S_LESS = 207; public static final int KEY_APPLIED_FAIL_COST_60S_LESS = 208; public static final int KEY_APPLIED_FAIL_COST_OTHER = 209; // KEY -- load detail public static final int KEY_LOADED_UNKNOWN_EXCEPTION = 250; public static final int KEY_LOADED_UNCAUGHT_EXCEPTION = 251; public static final int KEY_LOADED_EXCEPTION_DEX = 252; public static final int KEY_LOADED_EXCEPTION_DEX_CHECK = 253; public static final int KEY_LOADED_EXCEPTION_RESOURCE = 254; public static final int KEY_LOADED_EXCEPTION_RESOURCE_CHECK = 255; public static final int KEY_LOADED_MISMATCH_DEX = 300; public static final int KEY_LOADED_MISMATCH_LIB = 301; public static final int KEY_LOADED_MISMATCH_RESOURCE = 302; public static final int KEY_LOADED_MISSING_DEX = 303; public static final int KEY_LOADED_MISSING_LIB = 304; public static final int KEY_LOADED_MISSING_PATCH_FILE = 305; public static final int KEY_LOADED_MISSING_PATCH_INFO = 306; public static final int KEY_LOADED_MISSING_DEX_OPT = 307; public static final int KEY_LOADED_MISSING_RES = 308; public static final int KEY_LOADED_INFO_CORRUPTED = 309; //load package check public static final int KEY_LOADED_PACKAGE_CHECK_SIGNATURE = 350; public static final int KEY_LOADED_PACKAGE_CHECK_DEX_META = 351; public static final int KEY_LOADED_PACKAGE_CHECK_LIB_META = 352; public static final int KEY_LOADED_PACKAGE_CHECK_APK_TINKER_ID_NOT_FOUND = 353; public static final int KEY_LOADED_PACKAGE_CHECK_PATCH_TINKER_ID_NOT_FOUND = 354; public static final int KEY_LOADED_PACKAGE_CHECK_TINKER_ID_NOT_EQUAL = 355; public static final int KEY_LOADED_PACKAGE_CHECK_PACKAGE_META_NOT_FOUND = 356; public static final int KEY_LOADED_PACKAGE_CHECK_RES_META = 357; public static final int KEY_LOADED_PACKAGE_CHECK_TINKERFLAG_NOT_SUPPORT = 358; public static final int KEY_LOADED_SUCC_COST_500_LESS = 400; public static final int KEY_LOADED_SUCC_COST_1000_LESS = 401; public static final int KEY_LOADED_SUCC_COST_3000_LESS = 402; public static final int KEY_LOADED_SUCC_COST_5000_LESS = 403; public static final int KEY_LOADED_SUCC_COST_OTHER = 404; interface Reporter { void onReport(int key); void onReport(String message); } private static Reporter reporter = null; public void setReporter(Reporter reporter) { this.reporter = reporter; } public static void onTryApply(boolean success) { if (reporter == null) { return; } reporter.onReport(KEY_TRY_APPLY); reporter.onReport(KEY_TRY_APPLY_UPGRADE); if (success) { reporter.onReport(KEY_TRY_APPLY_SUCCESS); } } public static void onTryApplyFail(int errorCode) { if (reporter == null) { return; } switch (errorCode) { case ShareConstants.ERROR_PATCH_NOTEXIST: reporter.onReport(KEY_TRY_APPLY_NOT_EXIST); break; case ShareConstants.ERROR_PATCH_DISABLE: reporter.onReport(KEY_TRY_APPLY_DISABLE); break; case ShareConstants.ERROR_PATCH_INSERVICE: reporter.onReport(KEY_TRY_APPLY_INSERVICE); break; case ShareConstants.ERROR_PATCH_RUNNING: reporter.onReport(KEY_TRY_APPLY_RUNNING); break; case Utils.ERROR_PATCH_ROM_SPACE: reporter.onReport(KEY_TRY_APPLY_ROM_SPACE); break; case Utils.ERROR_PATCH_GOOGLEPLAY_CHANNEL: reporter.onReport(KEY_TRY_APPLY_GOOGLEPLAY); break; case Utils.ERROR_PATCH_ALREADY_APPLY: reporter.onReport(KEY_TRY_APPLY_ALREADY_APPLY); break; case Utils.ERROR_PATCH_CRASH_LIMIT: reporter.onReport(KEY_TRY_APPLY_CRASH_LIMIT); break; case Utils.ERROR_PATCH_MEMORY_LIMIT: reporter.onReport(KEY_TRY_APPLY_MEMORY_LIMIT); break; case Utils.ERROR_PATCH_CONDITION_NOT_SATISFIED: reporter.onReport(KEY_TRY_APPLY_CONDITION_NOT_SATISFIED); break; } } public static void onLoadPackageCheckFail(int errorCode) { if (reporter == null) { return; } switch (errorCode) { case ShareConstants.ERROR_PACKAGE_CHECK_SIGNATURE_FAIL: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_SIGNATURE); break; case ShareConstants.ERROR_PACKAGE_CHECK_DEX_META_CORRUPTED: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_DEX_META); break; case ShareConstants.ERROR_PACKAGE_CHECK_LIB_META_CORRUPTED: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_LIB_META); break; case ShareConstants.ERROR_PACKAGE_CHECK_PATCH_TINKER_ID_NOT_FOUND: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_PATCH_TINKER_ID_NOT_FOUND); break; case ShareConstants.ERROR_PACKAGE_CHECK_APK_TINKER_ID_NOT_FOUND: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_APK_TINKER_ID_NOT_FOUND); break; case ShareConstants.ERROR_PACKAGE_CHECK_TINKER_ID_NOT_EQUAL: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_TINKER_ID_NOT_EQUAL); break; case ShareConstants.ERROR_PACKAGE_CHECK_PACKAGE_META_NOT_FOUND: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_PACKAGE_META_NOT_FOUND); break; case ShareConstants.ERROR_PACKAGE_CHECK_RESOURCE_META_CORRUPTED: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_RES_META); break; case ShareConstants.ERROR_PACKAGE_CHECK_TINKERFLAG_NOT_SUPPORT: reporter.onReport(KEY_LOADED_PACKAGE_CHECK_TINKERFLAG_NOT_SUPPORT); break; } } public static void onLoaded(long cost) { if (reporter == null) { return; } reporter.onReport(KEY_LOADED); if (cost < 0L) { TinkerLog.e(TAG, "hp_report report load cost failed, invalid cost"); return; } if (cost <= 500) { reporter.onReport(KEY_LOADED_SUCC_COST_500_LESS); } else if (cost <= 1000) { reporter.onReport(KEY_LOADED_SUCC_COST_1000_LESS); } else if (cost <= 3000) { reporter.onReport(KEY_LOADED_SUCC_COST_3000_LESS); } else if (cost <= 5000) { reporter.onReport(KEY_LOADED_SUCC_COST_5000_LESS); } else { reporter.onReport(KEY_LOADED_SUCC_COST_OTHER); } } public static void onLoadInfoCorrupted() { if (reporter == null) { return; } reporter.onReport(KEY_LOADED_INFO_CORRUPTED); } public static void onLoadFileNotFound(int fileType) { if (reporter == null) { return; } switch (fileType) { case ShareConstants.TYPE_DEX_OPT: reporter.onReport(KEY_LOADED_MISSING_DEX_OPT); break; case ShareConstants.TYPE_DEX: reporter.onReport(KEY_LOADED_MISSING_DEX); break; case ShareConstants.TYPE_LIBRARY: reporter.onReport(KEY_LOADED_MISSING_LIB); break; case ShareConstants.TYPE_PATCH_FILE: reporter.onReport(KEY_LOADED_MISSING_PATCH_FILE); break; case ShareConstants.TYPE_PATCH_INFO: reporter.onReport(KEY_LOADED_MISSING_PATCH_INFO); break; case ShareConstants.TYPE_RESOURCE: reporter.onReport(KEY_LOADED_MISSING_RES); break; } } public static void onLoadFileMisMatch(int fileType) { if (reporter == null) { return; } switch (fileType) { case ShareConstants.TYPE_DEX: reporter.onReport(KEY_LOADED_MISMATCH_DEX); break; case ShareConstants.TYPE_LIBRARY: reporter.onReport(KEY_LOADED_MISMATCH_LIB); break; case ShareConstants.TYPE_RESOURCE: reporter.onReport(KEY_LOADED_MISMATCH_RESOURCE); break; } } public static void onLoadException(Throwable throwable, int errorCode) { if (reporter == null) { return; } boolean isCheckFail = false; switch (errorCode) { case ShareConstants.ERROR_LOAD_EXCEPTION_DEX: if (throwable.getMessage().contains(ShareConstants.CHECK_DEX_INSTALL_FAIL)) { reporter.onReport(KEY_LOADED_EXCEPTION_DEX_CHECK); isCheckFail = true; TinkerLog.e(TAG, "tinker dex check fail:" + throwable.getMessage()); } else { reporter.onReport(KEY_LOADED_EXCEPTION_DEX); TinkerLog.e(TAG, "tinker dex reflect fail:" + throwable.getMessage()); } break; case ShareConstants.ERROR_LOAD_EXCEPTION_RESOURCE: if (throwable.getMessage().contains(ShareConstants.CHECK_RES_INSTALL_FAIL)) { reporter.onReport(KEY_LOADED_EXCEPTION_RESOURCE_CHECK); isCheckFail = true; TinkerLog.e(TAG, "tinker res check fail:" + throwable.getMessage()); } else { reporter.onReport(KEY_LOADED_EXCEPTION_RESOURCE); TinkerLog.e(TAG, "tinker res reflect fail:" + throwable.getMessage()); } break; case ShareConstants.ERROR_LOAD_EXCEPTION_UNCAUGHT: reporter.onReport(KEY_LOADED_UNCAUGHT_EXCEPTION); break; case ShareConstants.ERROR_LOAD_EXCEPTION_UNKNOWN: reporter.onReport(KEY_LOADED_UNKNOWN_EXCEPTION); break; } //reporter exception, for dex check fail, we don't need to report stacktrace if (!isCheckFail) { reporter.onReport("Tinker Exception:load tinker occur exception " + Utils.getExceptionCauseString(throwable)); } } public static void onApplyPatchServiceStart() { if (reporter == null) { return; } reporter.onReport(KEY_APPLIED_START); } public static void onApplyDexOptFail(Throwable throwable) { if (reporter == null) { return; } reporter.onReport(KEY_APPLIED_DEXOPT); reporter.onReport("Tinker Exception:apply tinker occur exception " + Utils.getExceptionCauseString(throwable)); } public static void onApplyInfoCorrupted() { if (reporter == null) { return; } reporter.onReport(KEY_APPLIED_INFO_CORRUPTED); } public static void onApplyVersionCheckFail() { if (reporter == null) { return; } reporter.onReport(KEY_APPLIED_VERSION_CHECK); } public static void onApplyExtractFail(int fileType) { if (reporter == null) { return; } switch (fileType) { case ShareConstants.TYPE_DEX: reporter.onReport(KEY_APPLIED_DEX_EXTRACT); break; case ShareConstants.TYPE_LIBRARY: reporter.onReport(KEY_APPLIED_LIB_EXTRACT); break; case ShareConstants.TYPE_PATCH_FILE: reporter.onReport(KEY_APPLIED_PATCH_FILE_EXTRACT); break; case ShareConstants.TYPE_RESOURCE: reporter.onReport(KEY_APPLIED_RESOURCE_EXTRACT); break; } } public static void onApplied(long cost, boolean success) { if (reporter == null) { return; } if (success) { reporter.onReport(KEY_APPLIED); } if (success) { reporter.onReport(KEY_APPLIED_UPGRADE); } else { reporter.onReport(KEY_APPLIED_UPGRADE_FAIL); } TinkerLog.i(TAG, "hp_report report apply cost = %d", cost); if (cost < 0L) { TinkerLog.e(TAG, "hp_report report apply cost failed, invalid cost"); return; } if (cost <= 5000) { if (success) { reporter.onReport(KEY_APPLIED_SUCC_COST_5S_LESS); } else { reporter.onReport(KEY_APPLIED_FAIL_COST_5S_LESS); } } else if (cost <= 10 * 1000) { if (success) { reporter.onReport(KEY_APPLIED_SUCC_COST_10S_LESS); } else { reporter.onReport(KEY_APPLIED_FAIL_COST_10S_LESS); } } else if (cost <= 30 * 1000) { if (success) { reporter.onReport(KEY_APPLIED_SUCC_COST_30S_LESS); } else { reporter.onReport(KEY_APPLIED_FAIL_COST_30S_LESS); } } else if (cost <= 60 * 1000) { if (success) { reporter.onReport(KEY_APPLIED_SUCC_COST_60S_LESS); } else { reporter.onReport(KEY_APPLIED_FAIL_COST_60S_LESS); } } else { if (success) { reporter.onReport(KEY_APPLIED_SUCC_COST_OTHER); } else { reporter.onReport(KEY_APPLIED_FAIL_COST_OTHER); } } } public static void onApplyPackageCheckFail(int errorCode) { if (reporter == null) { return; } TinkerLog.i(TAG, "hp_report package check failed, error = %d", errorCode); switch (errorCode) { case ShareConstants.ERROR_PACKAGE_CHECK_SIGNATURE_FAIL: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_SIGNATURE); break; case ShareConstants.ERROR_PACKAGE_CHECK_DEX_META_CORRUPTED: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_DEX_META); break; case ShareConstants.ERROR_PACKAGE_CHECK_LIB_META_CORRUPTED: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_LIB_META); break; case ShareConstants.ERROR_PACKAGE_CHECK_PATCH_TINKER_ID_NOT_FOUND: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_PATCH_TINKER_ID_NOT_FOUND); break; case ShareConstants.ERROR_PACKAGE_CHECK_APK_TINKER_ID_NOT_FOUND: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_APK_TINKER_ID_NOT_FOUND); break; case ShareConstants.ERROR_PACKAGE_CHECK_TINKER_ID_NOT_EQUAL: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_TINKER_ID_NOT_EQUAL); break; case ShareConstants.ERROR_PACKAGE_CHECK_PACKAGE_META_NOT_FOUND: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_META_NOT_FOUND); break; case ShareConstants.ERROR_PACKAGE_CHECK_RESOURCE_META_CORRUPTED: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_RES_META); break; case ShareConstants.ERROR_PACKAGE_CHECK_TINKERFLAG_NOT_SUPPORT: reporter.onReport(KEY_APPLIED_PACKAGE_CHECK_TINKERFLAG_NOT_SUPPORT); break; } } public static void onApplyCrash(Throwable throwable) { if (reporter == null) { return; } reporter.onReport(KEY_APPLIED_EXCEPTION); reporter.onReport("Tinker Exception:apply tinker occur exception " + Utils.getExceptionCauseString(throwable)); } public static void onFastCrashProtect() { if (reporter == null) { return; } reporter.onReport(KEY_CRASH_FAST_PROTECT); } public static void onXposedCrash() { if (reporter == null) { return; } if (ShareTinkerInternals.isVmArt()) { reporter.onReport(KEY_CRASH_CAUSE_XPOSED_ART); } else { reporter.onReport(KEY_CRASH_CAUSE_XPOSED_DALVIK); } } public static void onReportRetryPatch() { if (reporter == null) { return; } reporter.onReport(KEY_APPLY_WITH_RETRY); } }