diff --git a/build.gradle b/build.gradle index a3a424da..a1f50a55 100644 --- a/build.gradle +++ b/build.gradle @@ -11,8 +11,8 @@ buildscript { ] releaseConfiguration = [ - releaseVersion : "3.3.6", - releaseVersionCode: 30306, + releaseVersion : "3.4.0", + releaseVersionCode: 30400, ] versions = [ @@ -36,6 +36,7 @@ buildscript { 'androidx' : [ 'appcompat' : 'androidx.appcompat:appcompat:1.3.1', + 'material' : 'com.google.android.material:material:1.6.0', 'fragment' : 'androidx.fragment:fragment:1.3.1', 'recyclerview' : 'androidx.recyclerview:recyclerview:1.2.1', "swiperefreshlayout": "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0", @@ -52,6 +53,8 @@ buildscript { 'annotation' : "com.growingio.android:annotation:$releaseConfiguration.releaseVersion", 'compiler' : "com.growingio.android:compiler:$releaseConfiguration.releaseVersion", + 'analytics-fa' : "com.growingio.android:analytics-fa:$releaseConfiguration.releaseVersion", + 'analytics-ga' : "com.growingio.android:analytics-ga:$releaseConfiguration.releaseVersion", 'hybrid' : "com.growingio.android:hybrid:$releaseConfiguration.releaseVersion", 'okhttp3' : "com.growingio.android:okhttp3:$releaseConfiguration.releaseVersion", 'database' : "com.growingio.android:database:$releaseConfiguration.releaseVersion", @@ -123,7 +126,7 @@ buildscript { 'asm_tree' : 'org.ow2.asm:asm-tree:9.1', ], ] - kotlin_version = '1.4.32' + kotlin_version = '1.6.10' } repositories { diff --git a/config/checkstyle/checkstyle.sh b/config/checkstyle/checkstyle.sh index 2c58036c..4c4817e7 100755 --- a/config/checkstyle/checkstyle.sh +++ b/config/checkstyle/checkstyle.sh @@ -1,6 +1,5 @@ -./gradlew :growingio-autotracker-gradle-plugin:checkstyle \ -&& ./gradlew :growingio-annotation:checkstyle \ +./gradlew :growingio-annotation:checkstyle \ && ./gradlew :growingio-annotation:compiler:checkstyle \ && ./gradlew :growingio-tracker-core:checkstyle \ && ./gradlew :growingio-autotracker-core:checkstyle \ @@ -17,6 +16,8 @@ && ./gradlew :growingio-tools:crash:checkstyle \ && ./gradlew :growingio-tools:oaid:checkstyle \ && ./gradlew :growingio-tools:snappy:checkstyle \ +&& ./gradlew :growingio-adapter:analytics-fa:checkstyle \ +&& ./gradlew :growingio-adapter:analytics-ga:checkstyle \ && ./gradlew :gio-sdk:tracker:checkstyle \ && ./gradlew :gio-sdk:tracker-cdp:checkstyle \ && ./gradlew :gio-sdk:autotracker:checkstyle \ diff --git a/demos/demo/build.gradle b/demos/demo/build.gradle index cc875384..7562d642 100644 --- a/demos/demo/build.gradle +++ b/demos/demo/build.gradle @@ -1,11 +1,7 @@ apply plugin: 'com.android.application' apply plugin: 'jacoco' -def withAutotrack = true - -if (withAutotrack) { - apply plugin: 'com.growingio.android.autotracker' -} +apply plugin: 'com.growingio.android.autotracker' buildscript { repositories { @@ -16,7 +12,7 @@ buildscript { } dependencies { classpath "com.growingio.android:autotracker-gradle-plugin:${releaseConfiguration.releaseVersion}" - //classpath "com.growingio.android:autotracker-gradle-plugin:3.3.1" + //classpath "com.growingio.android:autotracker-gradle-plugin:3.4.0" } } @@ -27,8 +23,6 @@ android { minSdkVersion 26 targetSdkVersion buildConfiguration.targetSdkVersion - buildConfigField "boolean", "withAutotrack", "$withAutotrack" - testInstrumentationRunner "com.growingio.autotest.TrackAndroidJUnitRunner" testInstrumentationRunnerArguments listener: "com.growingio.autotest.TrackTestRunListener" @@ -76,9 +70,10 @@ android { } growingAutotracker { - development true logEnabled true -// excludePackages "com.gio.test.three.autotrack.fragments", "com.example" + skipDependencyCheck true + //includePackages "com.growingio.android.plugin" + //excludePackages "com.cpacm" } dependencies { @@ -110,7 +105,7 @@ dependencies { compileOnly libraries.androidx.appcompat // leakcanary 避免发版前未使用Profiler进行内存泄漏检测 - debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7' + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1' } apply from: "${rootProject.projectDir}/gradle/jacoco.gradle" diff --git a/gradle/jacoco.gradle b/gradle/jacoco.gradle index 49788c53..099843fd 100644 --- a/gradle/jacoco.gradle +++ b/gradle/jacoco.gradle @@ -11,7 +11,6 @@ def coverageSourceDirs = [ "$rootDir/growingio-annotation/src/main/java", "$rootDir/growingio-tracker-core/src/main/java", "$rootDir/growingio-autotracker-core/src/main/java", - "$rootDir/growingio-autotracker-gradle-plugin/src/main/java", "$rootDir/growingio-data/encoder/src/main/java", "$rootDir/growingio-data/json/src/main/java", "$rootDir/growingio-data/protobuf/src/main/java", @@ -20,13 +19,14 @@ def coverageSourceDirs = [ "$rootDir/growingio-network/okhttp3/src/main/java", "$rootDir/growingio-network/volley/src/main/java", "$rootDir/growingio-network/urlconnection/src/main/java", + "$rootDir/growingio-adapter/analytics-fa/src/main/java", + "$rootDir/growingio-adapter/analytics-ga/src/main/java", "$rootDir/growingio-tools/crash/src/main/java", "$rootDir/growingio-tools/snappy/src/main/java", "$rootDir/growingio-tools/oaid/src/main/java", "$rootDir/growingio-webservice/circler/src/main/java", "$rootDir/growingio-webservice/debugger/src/main/java", "$rootDir/growingio-annotation/compiler/src/main/java", - "$rootDir/inject-annotation/compiler/src/main/java", // "$rootDir/gio-sdk/tracker/src/main/java", // "$rootDir/gio-sdk/tracker-cdp/src/main/java", // "$rootDir/gio-sdk/autotracker/src/main/java", @@ -38,7 +38,6 @@ def coverageClassDirs = [ "$rootDir/growingio-annotation/build/intermediates/javac/debug/classes", "$rootDir/growingio-tracker-core/build/intermediates/javac/debug/classes", "$rootDir/growingio-autotracker-core/build/intermediates/javac/debug/classes", - "$rootDir/growingio-autotracker-gradle-plugin/build/intermediates/javac/debug/classes", "$rootDir/growingio-data/encoder/build/intermediates/javac/debug/classes", "$rootDir/growingio-data/json/build/intermediates/javac/debug/classes", "$rootDir/growingio-data/protobuf/build/intermediates/javac/debug/classes", @@ -49,11 +48,12 @@ def coverageClassDirs = [ "$rootDir/growingio-tools/crash/build/intermediates/javac/debug/classes", "$rootDir/growingio-tools/snappy/build/intermediates/javac/debug/classes", "$rootDir/growingio-tools/oaid/build/intermediates/javac/debug/classes", + "$rootDir/growingio-adapter/analytics-fa/build/intermediates/javac/debug/classes", + "$rootDir/growingio-adapter/analytics-ga/build/intermediates/javac/debug/classes", "$rootDir/growingio-webservice/circler/build/intermediates/javac/debug/classes", "$rootDir/growingio-webservice/debugger/build/intermediates/javac/debug/classes", "$rootDir/growingio-hybrid/build/intermediates/javac/debug/classes", "$rootDir/growingio-annotation/compiler/build/classes/java/main", - "$rootDir/inject-annotation/compiler/build/classes/java/main", // "$rootDir/gio-sdk/tracker/build/intermediates/javac/debug/classes", // "$rootDir/gio-sdk/tracker-cdp/build/intermediates/javac/debug/classes", // "$rootDir/gio-sdk/autotracker/build/intermediates/javac/debug/classes", diff --git a/gradle/publishAllToMavenLocal.sh b/gradle/publishAllToMavenLocal.sh index e1bfc3c5..124868f8 100755 --- a/gradle/publishAllToMavenLocal.sh +++ b/gradle/publishAllToMavenLocal.sh @@ -18,10 +18,11 @@ export IS_EXCLUDE_DEMOS=true && ./gradlew :growingio-webservice:circler:publishMavenAgentPublicationToMavenLocal \ && ./gradlew :growingio-tools:crash:publishMavenAgentPublicationToMavenLocal \ && ./gradlew :growingio-tools:oaid:publishMavenAgentPublicationToMavenLocal \ +&& ./gradlew :growingio-adapter:analytics-fa:publishMavenAgentPublicationToMavenLocal \ +&& ./gradlew :growingio-adapter:analytics-ga:publishMavenAgentPublicationToMavenLocal \ && ./gradlew :gio-sdk:tracker:publishMavenAgentPublicationToMavenLocal \ && ./gradlew :gio-sdk:tracker-cdp:publishMavenAgentPublicationToMavenLocal \ && ./gradlew :gio-sdk:autotracker:publishMavenAgentPublicationToMavenLocal \ && ./gradlew :gio-sdk:autotracker-cdp:publishMavenAgentPublicationToMavenLocal \ -&& ./gradlew :growingio-autotracker-gradle-plugin:publishMavenAgentPublicationToMavenLocal \ && ./gradlew clean export IS_EXCLUDE_DEMOS=false \ No newline at end of file diff --git a/gradle/publishAutotrackerPluginToMavenLocal.sh b/gradle/publishAutotrackerPluginToMavenLocal.sh deleted file mode 100755 index 5a0a4ae9..00000000 --- a/gradle/publishAutotrackerPluginToMavenLocal.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -echo "准备开始打包 autotracker-gradle-plugin ..." -export IS_EXCLUDE_DEMOS=true -./gradlew clean \ -&& ./gradlew :growingio-autotracker-gradle-plugin:publishMavenAgentPublicationToMavenLocal \ -&& ./gradlew clean \ -&& export IS_EXCLUDE_DEMOS=false \ No newline at end of file diff --git a/inject-annotation/.gitignore b/growingio-adapter/analytics-fa/.gitignore similarity index 100% rename from inject-annotation/.gitignore rename to growingio-adapter/analytics-fa/.gitignore diff --git a/growingio-adapter/analytics-fa/build.gradle b/growingio-adapter/analytics-fa/build.gradle new file mode 100644 index 00000000..60b98491 --- /dev/null +++ b/growingio-adapter/analytics-fa/build.gradle @@ -0,0 +1,59 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdkVersion buildConfiguration.compileVersion + defaultConfig { + minSdkVersion 19 + targetSdkVersion buildConfiguration.targetSdkVersion + versionName releaseConfiguration.releaseVersion + versionCode releaseConfiguration.releaseVersionCode + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility buildConfiguration.sourceCompatibility + targetCompatibility buildConfiguration.targetCompatibility + } + + testOptions { + unitTests.all { + jacoco { + includeNoLocationClasses = true + excludes = ['jdk.internal.*'] + } + } + unitTests { + returnDefaultValues = true + includeAndroidResources = true + } + } +} + + +dependencies { + testImplementation libraries.test.junit + testImplementation libraries.test.truth + testImplementation libraries.test.androidx_core + testImplementation libraries.test.robolectric + + testImplementation platform('com.google.firebase:firebase-bom:30.0.1') + testImplementation 'com.google.firebase:firebase-analytics-ktx' + + implementation project(':growingio-tracker-core') + + implementation project(":growingio-annotation") + annotationProcessor project(":growingio-annotation:compiler") + + compileOnly platform('com.google.firebase:firebase-bom:30.0.1') + compileOnly 'com.google.firebase:firebase-analytics-ktx' +} +apply from: "${rootProject.projectDir}/gradle/publishMaven.gradle" +apply from: "${rootProject.projectDir}/gradle/jacocoModule.gradle" \ No newline at end of file diff --git a/growingio-adapter/analytics-fa/consumer-rules.pro b/growingio-adapter/analytics-fa/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/growingio-adapter/analytics-fa/gradle.properties b/growingio-adapter/analytics-fa/gradle.properties new file mode 100644 index 00000000..ca879f1f --- /dev/null +++ b/growingio-adapter/analytics-fa/gradle.properties @@ -0,0 +1,4 @@ +POM_NAME=analytics-fa +POM_ARTIFACT_ID=analytics-fa +POM_PACKAGING=aar +POM_DESCRIPTION=Adapter Google Analytics data to Growingio's sdk. \ No newline at end of file diff --git a/growingio-autotracker-gradle-plugin/proguard-rules.pro b/growingio-adapter/analytics-fa/proguard-rules.pro similarity index 94% rename from growingio-autotracker-gradle-plugin/proguard-rules.pro rename to growingio-adapter/analytics-fa/proguard-rules.pro index f1b42451..481bb434 100644 --- a/growingio-autotracker-gradle-plugin/proguard-rules.pro +++ b/growingio-adapter/analytics-fa/proguard-rules.pro @@ -18,4 +18,4 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/growingio-adapter/analytics-fa/src/main/AndroidManifest.xml b/growingio-adapter/analytics-fa/src/main/AndroidManifest.xml new file mode 100644 index 00000000..9351c9b6 --- /dev/null +++ b/growingio-adapter/analytics-fa/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsAdapter.java b/growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsAdapter.java new file mode 100644 index 00000000..62ecc212 --- /dev/null +++ b/growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsAdapter.java @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.analytics.firebase; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Build; +import android.os.Bundle; +import android.os.Parcelable; +import android.text.TextUtils; +import android.util.Size; +import android.util.SizeF; +import android.util.SparseArray; + +import androidx.annotation.NonNull; + +import com.google.android.gms.measurement.api.AppMeasurementSdk; +import com.google.firebase.analytics.FirebaseAnalytics; +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.track.TrackMainThread; +import com.growingio.android.sdk.track.events.TrackEventGenerator; +import com.growingio.android.sdk.track.log.Logger; +import com.growingio.android.sdk.track.providers.ConfigurationProvider; +import com.growingio.android.sdk.track.providers.SessionProvider; +import com.growingio.android.sdk.track.providers.UserInfoProvider; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * + * @author cpacm 2022/5/19 + */ +class FirebaseAnalyticsAdapter { + + private static final String TAG = "GrowingAdapter"; + private static final String DUEL_VECTOR_LINK = "_"; + private static volatile FirebaseAnalyticsAdapter sGaAdapter; + private FirebaseAnalytics firebaseAnalytics; + private String appInstanceId; + + public static FirebaseAnalyticsAdapter get() { + if (sGaAdapter == null) { + return new FirebaseAnalyticsAdapter(); + } + synchronized (FirebaseAnalyticsAdapter.class) { + if (sGaAdapter != null) { + return sGaAdapter; + } + return new FirebaseAnalyticsAdapter(); + } + } + + public static void init(Context context) { + if (sGaAdapter == null) { + sGaAdapter = new FirebaseAnalyticsAdapter(context); + } + } + + private FirebaseAnalyticsAdapter() { + //initFAdapter(TrackerContext.get()); + //registerAppMeasureEvent(TrackerContext.get()); + } + + private FirebaseAnalyticsAdapter(Context context) { + initFAdapter(context); + registerAppMeasureEvent(context); + } + + @SuppressLint("MissingPermission") + private void initFAdapter(Context context) { + if (firebaseAnalytics == null) { + firebaseAnalytics = FirebaseAnalytics.getInstance(context); + } + firebaseAnalytics.getAppInstanceId().addOnCompleteListener(task -> { + appInstanceId = task.getResult(); + Map attr = new HashMap<>(); + attr.put("app_instance_id", appInstanceId); + TrackEventGenerator.generateLoginUserAttributesEvent(new HashMap<>(attr)); + }); + } + + @SuppressLint("MissingPermission") + private void registerAppMeasureEvent(Context context) { + AppMeasurementSdk.getInstance(context).registerOnMeasurementEventListener(new AppMeasurementSdk.OnEventListener() { + @Override + public void onEvent(@NonNull String type, @NonNull String eventName, @NonNull Bundle bundle, long timeMill) { + Logger.d("FA Event", type + ":" + eventName + ":" + bundle + ":" + timeMill); + if ("auto".equals(type)) { + // exclude auto event,like:_ab(应用进入后台),_e(设置页面名称) .etc. + return; + } + logEvent(eventName, bundle); + } + }); + } + + void logEvent(String name, Bundle bundle) { + if (!checkAnalyticsValid()) return; + if (TextUtils.isEmpty(name)) { + Logger.e(TAG, "trackCustomEvent: eventName is NULL"); + return; + } + TrackEventGenerator.generateCustomEvent(name, parseBundle(bundle)); + } + + @SuppressLint("MissingPermission") + void setAnalyticsCollectionEnabled(boolean enabled) { + try { + if (!checkAnalyticsValid()) return; + TrackMainThread.trackMain().postActionToTrackMain(() -> { + if (enabled == ConfigurationProvider.core().isDataCollectionEnabled()) { + Logger.e(TAG, "当前数据采集开关 = " + enabled + ", 请勿重复操作"); + } else { + ConfigurationProvider.core().setDataCollectionEnabled(enabled); + if (enabled) { + SessionProvider.get().generateVisit(); + initFAdapter(TrackerContext.get()); + } + } + }); + } catch (Exception ignored) { + } + } + + void setUserId(String userId) { + if (!checkAnalyticsValid()) return; + TrackMainThread.trackMain().postActionToTrackMain(() -> UserInfoProvider.get().setLoginUserId(userId)); + } + + void setUserProperty(String name, String value) { + if (!checkAnalyticsValid()) return; + Map attr = new HashMap<>(); + if (value == null) value = ""; + attr.put(name, value); + TrackEventGenerator.generateLoginUserAttributesEvent(new HashMap<>(attr)); + } + + /** + * 将 bundle 转化为扁平化Map + */ + Map parseBundle(Bundle bundle) { + return duelVectorFoil("", bundle); + } + + private Map duelVectorFoil(String prefix, Bundle bundle) { + Map attr = new HashMap<>(); + for (String key : bundle.keySet()) { + if (key.startsWith("_")) continue; // exclude Firebase generate params + Object value = bundle.get(key); + String realKey = prefix + key; + if (value instanceof Bundle) { + Map childMap = duelVectorFoil(realKey + DUEL_VECTOR_LINK, (Bundle) value); + attr.putAll(childMap); + } else if (value.getClass().isArray()) { + if (value instanceof boolean[]) { + int index = 0; + for (Object child : (boolean[]) value) { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + index += 1; + } + } else if (value instanceof byte[]) { + int index = 0; + for (Object child : (byte[]) value) { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + index += 1; + } + } else if (value instanceof float[]) { + int index = 0; + for (Object child : (float[]) value) { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + index += 1; + } + } else if (value instanceof double[]) { + int index = 0; + for (Object child : (double[]) value) { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + index += 1; + } + } else if (value instanceof int[]) { + int index = 0; + for (Object child : (int[]) value) { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + index += 1; + } + } else if (value instanceof char[]) { + int index = 0; + for (Object child : (char[]) value) { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + index += 1; + } + } else if (value instanceof short[]) { + int index = 0; + for (Object child : (short[]) value) { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + index += 1; + } + } else { + int index = 0; + for (Object child : (Object[]) value) { + if (child instanceof Bundle) { + Map childMap = duelVectorFoil(realKey + DUEL_VECTOR_LINK + index + DUEL_VECTOR_LINK, (Bundle) child); + attr.putAll(childMap); + } else { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + } + index += 1; + } + } + } else if (value instanceof ArrayList) { + int index = 0; + for (Object child : (ArrayList) value) { + if (child instanceof Bundle) { + Map childMap = duelVectorFoil(realKey + DUEL_VECTOR_LINK + index + DUEL_VECTOR_LINK, (Bundle) child); + attr.putAll(childMap); + } else { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + } + index += 1; + } + } else if (value instanceof SparseArray) { + SparseArray sa = (SparseArray) value; + for (int i = 0; i < sa.size(); i++) { + int index = sa.keyAt(i); + Object child = sa.get(index); + if (child instanceof Bundle) { + Map childMap = duelVectorFoil(realKey + DUEL_VECTOR_LINK + index + DUEL_VECTOR_LINK, (Bundle) child); + attr.putAll(childMap); + } else { + attr.put(realKey + DUEL_VECTOR_LINK + index, child.toString()); + } + } + } else if (value instanceof Parcelable) { + attr.put(realKey, value.toString()); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (value instanceof Size) { + attr.put(realKey, value.toString()); + } else if (value instanceof SizeF) { + attr.put(realKey, value.toString()); + } else { + attr.put(realKey, value.toString()); + } + } else { + attr.put(realKey, value.toString()); + } + } + return attr; + } + + boolean checkAnalyticsValid() { + if (firebaseAnalytics == null || TextUtils.isEmpty(appInstanceId)) return false; + return TrackerContext.initializedSuccessfully(); + } + +// private boolean readManifestScreenTrackEnabled(Context context) { +// try { +// PackageManager packageManager = context.getPackageManager(); +// if (packageManager != null) { +// ApplicationInfo applicationInfo = +// packageManager.getApplicationInfo( +// context.getPackageName(), PackageManager.GET_META_DATA); +// if (applicationInfo != null +// && applicationInfo.metaData != null +// && applicationInfo.metaData.containsKey(DATA_SCREEN_TRACK_ENABLED)) { +// return applicationInfo.metaData.getBoolean(DATA_SCREEN_TRACK_ENABLED); +// } +// } +// } catch (PackageManager.NameNotFoundException e) { +// // This shouldn't happen since it's this app's package, but fall through to default if so. +// } +// return true; +// } +// +// public static final String DATA_SCREEN_TRACK_ENABLED = "google_analytics_automatic_screen_reporting_enabled"; + +} diff --git a/growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsInjector.java b/growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsInjector.java new file mode 100644 index 00000000..fb73fed2 --- /dev/null +++ b/growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsInjector.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.analytics.firebase; + +import android.os.Bundle; + +/** + *

+ * Google Analytics message sender + * + * @author cpacm 2022/5/19 + */ +public class FirebaseAnalyticsInjector { + + private FirebaseAnalyticsInjector() { + } + + public static void logEvent(String name, Bundle bundle) { + //FirebaseAnalyticsAdapter.get().logEvent(name, bundle); + } + + public static void setDefaultEventParameters(Bundle bundle) { + //FirebaseAnalyticsAdapter.get().setDefaultEventParameters(bundle); + } + + public static void setUserId(String userId) { + FirebaseAnalyticsAdapter.get().setUserId(userId); + } + + public static void setUserProperty(String name, String value) { + FirebaseAnalyticsAdapter.get().setUserProperty(name, value); + } + + public static void setAnalyticsCollectionEnabled(boolean enabled) { + FirebaseAnalyticsAdapter.get().setAnalyticsCollectionEnabled(enabled); + } +} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/ErrorLog.java b/growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsLibraryModule.java similarity index 51% rename from growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/ErrorLog.java rename to growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsLibraryModule.java index 664979cc..78109990 100644 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/ErrorLog.java +++ b/growingio-adapter/analytics-fa/src/main/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsLibraryModule.java @@ -13,24 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.growingio.android.analytics.firebase; -package com.growingio.sdk.plugin.autotrack.compile; +import android.content.Context; -public final class ErrorLog extends SystemLog { - - @Override - public void info(String message) { - } - - @Override - public void debug(String message) { - } - - @Override - public void warning(String message) { - } +import com.growingio.android.sdk.LibraryGioModule; +import com.growingio.android.sdk.track.modelloader.TrackerRegistry; +import com.growingio.sdk.annotation.GIOLibraryModule; +/** + *

+ * + * @author cpacm 2022/5/19 + */ +@GIOLibraryModule +public class FirebaseAnalyticsLibraryModule extends LibraryGioModule { @Override - public void warning(String message, Throwable cause) { + public void registerComponents(Context context, TrackerRegistry registry) { + //just init + FirebaseAnalyticsAdapter.init(context); + //registry.register(this.getClass(), Void.class, null); } } diff --git a/growingio-adapter/analytics-fa/src/test/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsTest.java b/growingio-adapter/analytics-fa/src/test/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsTest.java new file mode 100644 index 00000000..53ec99b0 --- /dev/null +++ b/growingio-adapter/analytics-fa/src/test/java/com/growingio/android/analytics/firebase/FirebaseAnalyticsTest.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.analytics.firebase; + +import android.app.Application; +import android.os.Bundle; +import android.os.Parcelable; +import android.util.Size; +import android.util.SizeF; +import android.util.SparseArray; + +import androidx.test.core.app.ApplicationProvider; + +import com.growingio.android.sdk.CoreConfiguration; +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.track.providers.ConfigurationProvider; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * + * @author cpacm 2022/5/23 + */ +@Config(manifest = Config.NONE, sdk = 30) +@RunWith(RobolectricTestRunner.class) +public class FirebaseAnalyticsTest { + + Application application = ApplicationProvider.getApplicationContext(); + + @Before + public void setup() { + TrackerContext.init(application); + TrackerContext.initSuccess(); + ConfigurationProvider.initWithConfig(new CoreConfiguration("test", "test"), new HashMap<>()); + //FirebaseAnalyticsAdapter.init(application); + } + + @Test + public void duelVectorFoilTest() { + + Bundle bundle = new Bundle(); + bundle.putString("s", "String"); + bundle.putStringArray("s[]", new String[]{"s1", "s2"}); + ArrayList arrayList = new ArrayList<>(); + arrayList.add("name"); + arrayList.add("cpacm"); + bundle.putStringArrayList("slist", arrayList); + + bundle.putInt("i", 1); + bundle.putIntArray("i[]", new int[]{1, 2, 3, 4}); + ArrayList arrayList1 = new ArrayList<>(); + arrayList1.add(1); + arrayList1.add(2); + bundle.putIntegerArrayList("ilist", arrayList1); + + bundle.putChar("c", 'a'); + bundle.putCharArray("c[]", "cpacm".toCharArray()); + bundle.putCharSequence("cs", "CharSequence"); + bundle.putCharSequenceArray("cs[]", new CharSequence[]{"s1", "s2"}); + ArrayList arrayList2 = new ArrayList<>(); + arrayList2.add("name"); + arrayList2.add("cpacm"); + bundle.putCharSequenceArrayList("cslist", arrayList2); + + bundle.putByte("b", "cpacm".getBytes()[0]); + bundle.putByteArray("b[]", "cpacm".getBytes()); + bundle.putFloat("f", 1.0f); + bundle.putFloatArray("f[]", new float[]{1.0f, 2.0f}); + bundle.putDouble("d", 1d); + bundle.putDoubleArray("d[]", new double[]{1d, 2d}); + bundle.putShort("st", Short.MIN_VALUE); + bundle.putShortArray("st[]", new short[]{Short.MIN_VALUE, Short.MAX_VALUE}); + bundle.putBoolean("bool", false); + bundle.putBooleanArray("bool[]", new boolean[]{false, false, true}); + + bundle.putSize("size", new Size(100, 200)); + bundle.putSizeF("sizeF", new SizeF(100f, 200f)); + + Bundle deepBundle = bundle.deepCopy(); + + bundle.putParcelable("p", deepBundle); + bundle.putParcelableArray("p[]", new Parcelable[]{deepBundle}); + ArrayList arrayList3 = new ArrayList<>(); + arrayList3.add(bundle.deepCopy()); + bundle.putParcelableArrayList("plist", arrayList3); + SparseArray sa = new SparseArray<>(); + sa.append(100, bundle.deepCopy()); + bundle.putSparseParcelableArray("ps", sa); + + bundle.putSerializable("serial", "cpacm"); + + bundle.putBundle("bundle", deepBundle); + + FirebaseAnalyticsAdapter adapter = FirebaseAnalyticsAdapter.get(); + Map attr = adapter.parseBundle(bundle); + + Assert.assertEquals(attr.toString().length(), BUNDLE_RESULT.length()); + Assert.assertEquals(attr.toString(), BUNDLE_RESULT); + } + + private static final String BUNDLE_RESULT = "{ps_100_plist_0_i=1, ps_100_plist_0_f=1.0, ps_100_plist_0_p_cs[]_1=s2, ps_100_plist_0_d=1.0, ps_100_plist_0_p_cs[]_0=s1, ps_100_plist_0_c=a, ps_100_plist_0_b=99, bundle_ilist_1=2, ps_100_p[]_0_bool=false, ps_100_plist_0_p_bool=false, p[]_0_cslist_1=cpacm, p[]_0_cslist_0=name, bundle_ilist_0=1, ps_100_bool[]_2=true, ps_100_plist_0_p[]_0_c[]_4=m, ps_100_bool[]_1=false, ps_100_d[]_1=2.0, ps_100_plist_0_p[]_0_c[]_0=c, plist_0_slist_0=name, ps_100_plist_0_p[]_0_c[]_1=p, plist_0_slist_1=cpacm, ps_100_plist_0_p[]_0_c[]_2=a, ps_100_d[]_0=1.0, ps_100_plist_0_p[]_0_c[]_3=c, ps_100_bool[]_0=false, ps_100_p[]_0_sizeF=100.0x200.0, plist_0_p[]_0_ilist_0=1, plist_0_p[]_0_ilist_1=2, plist_0_p[]_0_cs=CharSequence, plist_0_bool=false, ps_100_bool=false, ps_100_cs[]_0=s1, size=100x200, ps_100_plist_0_s=String, ps_100_cs[]_1=s2, ps_100_plist_0_p[]_0_bool=false, ps_100_p_cslist_1=cpacm, ps_100_plist_0_p[]_0_ilist_0=1, ps_100_p_cslist_0=name, ps_100_plist_0_p[]_0_ilist_1=2, ps_100_plist_0_s[]_1=s2, ps_100_plist_0_s[]_0=s1, p_b=99, p_d=1.0, ps_100_p_c[]_3=c, p_c=a, ps_100_p_c[]_4=m, p_f=1.0, p_i=1, plist_0_ilist_0=1, plist_0_ilist_1=2, b=99, plist_0_d[]_0=1.0, c=a, d=1.0, p_s=String, f=1.0, i=1, ps_100_p_c[]_0=c, ps_100_p_c[]_1=p, ps_100_p_c[]_2=a, cs[]_1=s2, ps_100_plist_0_p_cslist_0=name, cs[]_0=s1, ps_100_plist_0_p_cslist_1=cpacm, plist_0_d[]_1=2.0, cs=CharSequence, s=String, b[]_4=109, b[]_3=99, b[]_2=97, b[]_1=112, b[]_0=99, plist_0_cs=CharSequence, plist_0_p_cs=CharSequence, ps_100_p[]_0_ilist_1=2, ps_100_plist_0_p[]_0_d[]_1=2.0, ps_100_p[]_0_ilist_0=1, ps_100_plist_0_p[]_0_d[]_0=1.0, plist_0_p[]_0_i=1, plist_0_p[]_0_f=1.0, plist_0_p[]_0_d=1.0, plist_0_p[]_0_b=99, plist_0_p[]_0_c=a, cslist_1=cpacm, p[]_0_i[]_3=4, p[]_0_i[]_2=3, p[]_0_i[]_1=2, p[]_0_i[]_0=1, ps_100_p[]_0_c=a, ps_100_p[]_0_b=99, p_c[]_0=c, ps_100_p[]_0_d=1.0, bundle_d[]_1=2.0, bundle_d[]_0=1.0, plist_0_p[]_0_bool=false, plist_0_p[]_0_s=String, p_c[]_1=p, p_c[]_2=a, p_c[]_3=c, p_c[]_4=m, ps_100_p[]_0_s=String, plist_0_p_b[]_1=112, plist_0_p_b[]_0=99, plist_0_p[]_0_bool[]_0=false, plist_0_p[]_0_bool[]_1=false, plist_0_p[]_0_bool[]_2=true, p_st=-32768, p[]_0_bool=false, ps_100_plist_0_p_cs=CharSequence, ps_100_p[]_0_f=1.0, plist_0_p_b[]_4=109, ps_100_p[]_0_i=1, plist_0_p_b[]_3=99, plist_0_p_b[]_2=97, ps_100_plist_0_d[]_1=2.0, ps_100_s[]_0=s1, plist_0_p[]_0_d[]_0=1.0, ps_100_s[]_1=s2, ps_100_plist_0_d[]_0=1.0, plist_0_p[]_0_d[]_1=2.0, ps_100_plist_0_cs=CharSequence, p[]_0_st[]_0=-32768, p[]_0_st[]_1=32767, plist_0_p_size=100x200, ps_100_p_b[]_4=109, bundle_s[]_0=s1, bundle_s[]_1=s2, plist_0_p[]_0_sizeF=100.0x200.0, ps_100_p[]_0_st=-32768, ps_100_plist_0_p_f[]_1=2.0, p[]_0_ilist_0=1, ps_100_plist_0_p_f[]_0=1.0, p[]_0_ilist_1=2, ps_100_cs=CharSequence, ps_100_plist_0_p[]_0_bool[]_0=false, c[]_3=c, c[]_2=a, ps_100_plist_0_p[]_0_bool[]_1=false, ps_100_plist_0_p[]_0_bool[]_2=true, c[]_4=m, p_d[]_0=1.0, c[]_1=p, p_d[]_1=2.0, c[]_0=c, bundle_st[]_1=32767, plist_0_s[]_0=s1, bundle_st[]_0=-32768, plist_0_s[]_1=s2, ps_100_plist_0_p[]_0_st[]_1=32767, bundle_st=-32768, bundle_slist_0=name, ps_100_plist_0_p[]_0_st[]_0=-32768, bundle_slist_1=cpacm, cslist_0=name, ps_100_p_b[]_2=97, ps_100_p_b[]_3=99, ps_100_p_b[]_0=99, bundle_size=100x200, ps_100_p_b[]_1=112, p_b[]_0=99, p_b[]_1=112, ps_100_plist_0_p_i[]_0=1, plist_0_p[]_0_cs[]_0=s1, ps_100_plist_0_p_i[]_3=4, ps_100_plist_0_p_i[]_1=2, ps_100_plist_0_p_i[]_2=3, ps_100_plist_0_p_size=100x200, p_b[]_4=109, p_b[]_2=97, ps_100_p[]_0_slist_0=name, p_b[]_3=99, ps_100_p[]_0_slist_1=cpacm, p[]_0_f[]_0=1.0, ps_100_p[]_0_bool[]_2=true, ps_100_p[]_0_bool[]_1=false, p[]_0_f[]_1=2.0, ps_100_p[]_0_bool[]_0=false, ps_100_plist_0_c[]_4=m, bundle_c[]_4=m, bundle_s=String, bundle_c[]_3=c, bundle_c[]_2=a, bundle_c[]_1=p, p_i[]_0=1, bundle_c[]_0=c, p_i[]_1=2, p_i[]_2=3, plist_0_p_slist_1=cpacm, plist_0_p_slist_0=name, bundle_sizeF=100.0x200.0, bundle_b=99, ps_100_p_bool=false, bundle_d=1.0, ps_100_i[]_1=2, bundle_c=a, ps_100_i[]_0=1, ps_100_i[]_3=4, ps_100_i[]_2=3, p_i[]_3=4, bundle_i=1, bundle_f=1.0, ps_100_plist_0_c[]_0=c, ps_100_plist_0_c[]_1=p, ps_100_plist_0_c[]_2=a, ps_100_plist_0_c[]_3=c, ps_100_plist_0_p[]_0_i[]_2=3, ps_100_p_slist_1=cpacm, ps_100_plist_0_p[]_0_i[]_3=4, ps_100_p_slist_0=name, p[]_0_st=-32768, ps_100_plist_0_p[]_0_s[]_1=s2, ps_100_plist_0_p[]_0_i=1, ps_100_plist_0_p[]_0_s[]_0=s1, ps_100_plist_0_p[]_0_f=1.0, plist_0_f[]_0=1.0, ps_100_plist_0_p[]_0_s=String, plist_0_f[]_1=2.0, ps_100_plist_0_p[]_0_i[]_0=1, ps_100_plist_0_p[]_0_i[]_1=2, plist_0_p_cslist_0=name, plist_0_p_cslist_1=cpacm, ps_100_plist_0_st[]_0=-32768, ps_100_plist_0_st[]_1=32767, d[]_1=2.0, d[]_0=1.0, ps_100_plist_0_sizeF=100.0x200.0, ps_100_p_st[]_1=32767, ps_100_p_st[]_0=-32768, ps_100_p[]_0_s[]_1=s2, ps_100_p[]_0_s[]_0=s1, ps_100_p_s[]_1=s2, ps_100_plist_0_p[]_0_d=1.0, ps_100_plist_0_p[]_0_b=99, ps_100_p_s[]_0=s1, ps_100_plist_0_p[]_0_c=a, plist_0_p[]_0_cs[]_1=s2, ps_100_plist_0_p[]_0_cs=CharSequence, ps_100_p[]_0_st[]_1=32767, ps_100_p[]_0_st[]_0=-32768, p[]_0_cs[]_0=s1, ps_100_ilist_1=2, plist_0_p[]_0_f[]_0=1.0, ps_100_p[]_0_cs[]_0=s1, ps_100_ilist_0=1, p_st[]_1=32767, ps_100_p[]_0_cs[]_1=s2, plist_0_p[]_0_f[]_1=2.0, p_st[]_0=-32768, plist_0_p_bool=false, p_s[]_0=s1, ps_100_plist_0_p[]_0_b[]_2=97, ps_100_plist_0_p[]_0_b[]_1=112, ps_100_plist_0_p[]_0_b[]_4=109, ps_100_plist_0_p[]_0_b[]_3=99, bundle_b[]_1=112, bundle_b[]_0=99, ps_100_plist_0_b[]_0=99, bundle_b[]_3=99, bundle_b[]_2=97, ps_100_plist_0_b[]_3=99, plist_0_p_cs[]_1=s2, bundle_b[]_4=109, p_s[]_1=s2, ps_100_plist_0_b[]_4=109, plist_0_p_cs[]_0=s1, ps_100_plist_0_b[]_1=112, ps_100_plist_0_b[]_2=97, p[]_0_size=100x200, ps_100_plist_0_p[]_0_b[]_0=99, ps_100_plist_0_ilist_0=1, ps_100_plist_0_ilist_1=2, plist_0_p_i[]_0=1, plist_0_p_i[]_2=3, plist_0_p_i[]_1=2, ps_100_plist_0_p[]_0_size=100x200, ps_100_plist_0_p_ilist_1=2, plist_0_p[]_0_slist_0=name, plist_0_p[]_0_slist_1=cpacm, ps_100_plist_0_p[]_0_cslist_1=cpacm, plist_0_p_i[]_3=4, bundle_bool=false, ps_100_plist_0_p[]_0_cslist_0=name, p_bool=false, ps_100_p_cs=CharSequence, ps_100_plist_0_cslist_0=name, ps_100_p_i[]_0=1, ps_100_plist_0_cslist_1=cpacm, ps_100_p_i[]_2=3, ps_100_p_i[]_1=2, ps_100_p[]_0_b[]_0=99, p[]_0_cs[]_1=s2, ps_100_p_i[]_3=4, ps_100_p[]_0_b[]_3=99, ps_100_p[]_0_b[]_4=109, ps_100_p[]_0_b[]_1=112, ps_100_p[]_0_b[]_2=97, ps_100_plist_0_p_ilist_0=1, p_slist_1=cpacm, plist_0_p[]_0_st=-32768, ps_100_plist_0_p_s=String, p_slist_0=name, ps_100_plist_0_p_i=1, ps_100_plist_0_size=100x200, plist_0_p[]_0_i[]_3=4, plist_0_p[]_0_i[]_2=3, plist_0_p[]_0_i[]_1=2, plist_0_p[]_0_i[]_0=1, ps_100_plist_0_p_b=99, ps_100_plist_0_p_c=a, ps_100_plist_0_p_d=1.0, ps_100_plist_0_p[]_0_sizeF=100.0x200.0, ps_100_plist_0_p_f=1.0, p[]_0_s[]_0=s1, p[]_0_s[]_1=s2, ps_100_p_size=100x200, ps_100_plist_0_p[]_0_cs[]_1=s2, ps_100_plist_0_p[]_0_cs[]_0=s1, plist_0_p[]_0_cslist_1=cpacm, plist_0_p_bool[]_1=false, plist_0_p_bool[]_0=false, plist_0_p[]_0_cslist_0=name, plist_0_p_bool[]_2=true, f[]_0=1.0, f[]_1=2.0, p[]_0_d[]_0=1.0, bundle_i[]_1=2, p[]_0_d[]_1=2.0, plist_0_bool[]_1=false, bundle_i[]_2=3, plist_0_bool[]_2=true, bundle_i[]_3=4, plist_0_bool[]_0=false, ps_100_plist_0_p_st[]_0=-32768, ps_100_plist_0_p_st[]_1=32767, plist_0_p_s[]_0=s1, plist_0_p_s[]_1=s2, ps_100_p_sizeF=100.0x200.0, ps_100_plist_0_p_c[]_0=c, plist_0_p[]_0_b[]_4=109, plist_0_p[]_0_b[]_3=99, ps_100_plist_0_p_c[]_2=a, ps_100_plist_0_p_c[]_1=p, plist_0_p[]_0_b[]_0=99, plist_0_p[]_0_b[]_2=97, plist_0_p[]_0_b[]_1=112, plist_0_p_st[]_0=-32768, plist_0_p_st[]_1=32767, ps_100_p[]_0_c[]_0=c, ps_100_plist_0_p_bool[]_1=false, ps_100_p[]_0_c[]_1=p, ps_100_plist_0_p_bool[]_0=false, st=-32768, ps_100_p[]_0_c[]_2=a, ps_100_p[]_0_c[]_3=c, ps_100_p[]_0_c[]_4=m, ps_100_st[]_1=32767, ps_100_st[]_0=-32768, ps_100_plist_0_p_c[]_4=m, ps_100_plist_0_p_c[]_3=c, plist_0_st=-32768, ps_100_plist_0_p_bool[]_2=true, plist_0_p_st=-32768, p_bool[]_0=false, p_bool[]_1=false, p_bool[]_2=true, p[]_0_bool[]_1=false, ps_100_plist_0_p_s[]_1=s2, p[]_0_bool[]_2=true, bundle_cs=CharSequence, ps_100_plist_0_p_s[]_0=s1, p[]_0_bool[]_0=false, ps_100_f=1.0, p_sizeF=100.0x200.0, ps_100_i=1, ps_100_c=a, ps_100_b=99, ps_100_d=1.0, ps_100_p[]_0_i[]_1=2, ps_100_p[]_0_i[]_0=1, plist_0_p_f[]_1=2.0, plist_0_p_f[]_0=1.0, ps_100_plist_0_p_st=-32768, ps_100_cslist_1=cpacm, ps_100_p[]_0_i[]_3=4, p_ilist_1=2, ps_100_p[]_0_i[]_2=3, p_ilist_0=1, ps_100_cslist_0=name, plist_0_i[]_3=4, plist_0_i[]_2=3, plist_0_i[]_1=2, plist_0_i[]_0=1, plist_0_cs[]_1=s2, ps_100_plist_0_st=-32768, p_cs=CharSequence, plist_0_cs[]_0=s1, ps_100_p_bool[]_2=true, slist_1=cpacm, slist_0=name, ps_100_p_bool[]_0=false, ps_100_s=String, ps_100_p_bool[]_1=false, ps_100_p_f[]_0=1.0, st[]_0=-32768, ps_100_p_f[]_1=2.0, st[]_1=32767, plist_0_p[]_0_c[]_1=p, plist_0_p[]_0_c[]_0=c, bool=false, plist_0_p[]_0_c[]_4=m, plist_0_p[]_0_c[]_3=c, plist_0_p[]_0_c[]_2=a, bundle_i[]_0=1, ps_100_st=-32768, ilist_1=2, ilist_0=1, p_cs[]_0=s1, ps_100_plist_0_i[]_3=4, p_cs[]_1=s2, ps_100_plist_0_i[]_2=3, ps_100_plist_0_i[]_1=2, ps_100_plist_0_i[]_0=1, ps_100_p[]_0_cs=CharSequence, ps_100_plist_0_cs[]_0=s1, ps_100_plist_0_cs[]_1=s2, ps_100_p_s=String, plist_0_size=100x200, sizeF=100.0x200.0, ps_100_plist_0_bool[]_0=false, ps_100_f[]_1=2.0, ps_100_p_i=1, ps_100_plist_0_bool[]_2=true, ps_100_plist_0_bool[]_1=false, bundle_cslist_1=cpacm, ps_100_p[]_0_d[]_1=2.0, bundle_cslist_0=name, ps_100_p[]_0_d[]_0=1.0, ps_100_p_c=a, ps_100_p_d=1.0, ps_100_p_b=99, ps_100_p_f=1.0, ps_100_f[]_0=1.0, p_size=100x200, ps_100_p[]_0_size=100x200, ps_100_plist_0_bool=false, plist_0_sizeF=100.0x200.0, ps_100_slist_0=name, ps_100_slist_1=cpacm, ps_100_plist_0_p_b[]_4=109, ps_100_plist_0_p_b[]_3=99, ps_100_plist_0_p_b[]_2=97, ps_100_plist_0_p_b[]_1=112, ps_100_plist_0_p_b[]_0=99, plist_0_p[]_0_st[]_0=-32768, plist_0_p[]_0_st[]_1=32767, p[]_0_slist_0=name, p[]_0_slist_1=cpacm, ps_100_b[]_3=99, ps_100_b[]_4=109, ps_100_b[]_1=112, plist_0_p_c[]_0=c, ps_100_b[]_2=97, ps_100_b[]_0=99, ps_100_plist_0_slist_1=cpacm, ps_100_plist_0_slist_0=name, plist_0_p_c[]_2=a, plist_0_p_c[]_1=p, plist_0_p_c[]_4=m, plist_0_p_c[]_3=c, ps_100_plist_0_p_slist_0=name, p[]_0_c[]_0=c, plist_0_i=1, p[]_0_c[]_1=p, ps_100_plist_0_p_slist_1=cpacm, ps_100_size=100x200, p[]_0_c[]_4=m, p[]_0_c[]_2=a, p[]_0_c[]_3=c, p[]_0_sizeF=100.0x200.0, plist_0_c=a, plist_0_b=99, plist_0_d=1.0, plist_0_f=1.0, ps_100_p_cs[]_0=s1, ps_100_p_cs[]_1=s2, plist_0_s=String, p[]_0_i=1, p[]_0_d=1.0, p[]_0_f=1.0, p[]_0_c=a, p[]_0_b=99, plist_0_p_sizeF=100.0x200.0, plist_0_st[]_1=32767, p[]_0_cs=CharSequence, plist_0_st[]_0=-32768, bundle_f[]_1=2.0, bundle_f[]_0=1.0, p[]_0_s=String, p_cslist_0=name, p_cslist_1=cpacm, ps_100_c[]_0=c, plist_0_b[]_3=99, ps_100_c[]_1=p, plist_0_b[]_4=109, bundle_cs[]_0=s1, ps_100_c[]_2=a, bundle_cs[]_1=s2, ps_100_c[]_3=c, plist_0_p[]_0_size=100x200, plist_0_p_ilist_0=1, ps_100_plist_0_f[]_1=2.0, plist_0_p_d[]_1=2.0, plist_0_p_ilist_1=2, plist_0_p_d[]_0=1.0, i[]_2=3, i[]_3=4, plist_0_b[]_0=99, i[]_0=1, plist_0_b[]_1=112, ps_100_sizeF=100.0x200.0, i[]_1=2, plist_0_b[]_2=97, ps_100_plist_0_p[]_0_st=-32768, ps_100_plist_0_f[]_0=1.0, plist_0_p[]_0_s[]_0=s1, plist_0_p[]_0_s[]_1=s2, ps_100_p[]_0_cslist_0=name, ps_100_p[]_0_cslist_1=cpacm, ps_100_p_d[]_0=1.0, ps_100_c[]_4=m, ps_100_p_d[]_1=2.0, ps_100_plist_0_p[]_0_slist_0=name, ps_100_plist_0_p[]_0_slist_1=cpacm, plist_0_cslist_0=name, ps_100_plist_0_p_sizeF=100.0x200.0, ps_100_plist_0_p_d[]_1=2.0, ps_100_plist_0_p_d[]_0=1.0, plist_0_cslist_1=cpacm, ps_100_p[]_0_f[]_0=1.0, ps_100_p_ilist_1=2, ps_100_p[]_0_f[]_1=2.0, p[]_0_b[]_3=99, plist_0_p_b=99, p[]_0_b[]_4=109, plist_0_p_f=1.0, p[]_0_b[]_0=99, p[]_0_b[]_1=112, plist_0_p_d=1.0, ps_100_p_st=-32768, p[]_0_b[]_2=97, plist_0_p_c=a, plist_0_p_i=1, plist_0_p_s=String, bundle_bool[]_2=true, bundle_bool[]_0=false, bundle_bool[]_1=false, bool[]_0=false, plist_0_c[]_1=p, plist_0_c[]_0=c, bool[]_2=true, bool[]_1=false, ps_100_p_ilist_0=1, p_f[]_0=1.0, serial=cpacm, p_f[]_1=2.0, s[]_1=s2, s[]_0=s1, ps_100_plist_0_p[]_0_f[]_1=2.0, ps_100_plist_0_p[]_0_f[]_0=1.0, plist_0_c[]_4=m, plist_0_c[]_3=c, plist_0_c[]_2=a}"; + +} diff --git a/inject-annotation/compiler/.gitignore b/growingio-adapter/analytics-ga/.gitignore similarity index 100% rename from inject-annotation/compiler/.gitignore rename to growingio-adapter/analytics-ga/.gitignore diff --git a/growingio-adapter/analytics-ga/build.gradle b/growingio-adapter/analytics-ga/build.gradle new file mode 100644 index 00000000..3eab4154 --- /dev/null +++ b/growingio-adapter/analytics-ga/build.gradle @@ -0,0 +1,55 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdkVersion buildConfiguration.compileVersion + defaultConfig { + minSdkVersion buildConfiguration.minSdkVersion + targetSdkVersion buildConfiguration.targetSdkVersion + versionName releaseConfiguration.releaseVersion + versionCode releaseConfiguration.releaseVersionCode + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility buildConfiguration.sourceCompatibility + targetCompatibility buildConfiguration.targetCompatibility + } + + testOptions { + unitTests.all { + jacoco { + includeNoLocationClasses = true + excludes = ['jdk.internal.*'] + } + } + unitTests { + returnDefaultValues = true + includeAndroidResources = true + } + } +} + + +dependencies { + testImplementation libraries.test.junit + testImplementation libraries.test.truth + testImplementation libraries.test.androidx_core + testImplementation libraries.test.robolectric + + implementation project(':growingio-tracker-core') + + implementation project(":growingio-annotation") + annotationProcessor project(":growingio-annotation:compiler") + + compileOnly "com.google.android.gms:play-services-analytics:18.0.1" +} +apply from: "${rootProject.projectDir}/gradle/publishMaven.gradle" +apply from: "${rootProject.projectDir}/gradle/jacocoModule.gradle" \ No newline at end of file diff --git a/growingio-adapter/analytics-ga/consumer-rules.pro b/growingio-adapter/analytics-ga/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/growingio-adapter/analytics-ga/gradle.properties b/growingio-adapter/analytics-ga/gradle.properties new file mode 100644 index 00000000..ac79748b --- /dev/null +++ b/growingio-adapter/analytics-ga/gradle.properties @@ -0,0 +1,4 @@ +POM_NAME=analytics-ga +POM_ARTIFACT_ID=analytics-ga +POM_PACKAGING=aar +POM_DESCRIPTION=Adapter Google Analytics data to Growingio's sdk. \ No newline at end of file diff --git a/growingio-adapter/analytics-ga/proguard-rules.pro b/growingio-adapter/analytics-ga/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/growingio-adapter/analytics-ga/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/growingio-adapter/analytics-ga/src/main/AndroidManifest.xml b/growingio-adapter/analytics-ga/src/main/AndroidManifest.xml new file mode 100644 index 00000000..708d5d3a --- /dev/null +++ b/growingio-adapter/analytics-ga/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsAdapter.java b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsAdapter.java new file mode 100644 index 00000000..a4163fc4 --- /dev/null +++ b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsAdapter.java @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.analytics.google; + +import android.content.res.XmlResourceParser; +import android.text.TextUtils; + +import com.google.android.gms.analytics.GoogleAnalytics; +import com.google.android.gms.analytics.Tracker; +import com.growingio.android.analytics.google.model.AnalyticsEvent; +import com.growingio.android.analytics.google.model.TrackerInfo; +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.track.TrackMainThread; +import com.growingio.android.sdk.track.events.AutotrackEventType; +import com.growingio.android.sdk.track.events.CustomEvent; +import com.growingio.android.sdk.track.events.EventBuildInterceptor; +import com.growingio.android.sdk.track.events.LoginUserAttributesEvent; +import com.growingio.android.sdk.track.events.TrackEventType; +import com.growingio.android.sdk.track.events.VisitEvent; +import com.growingio.android.sdk.track.events.base.BaseEvent; +import com.growingio.android.sdk.track.ipc.PersistentDataProvider; +import com.growingio.android.sdk.track.listener.IActivityLifecycle; +import com.growingio.android.sdk.track.listener.TrackThread; +import com.growingio.android.sdk.track.listener.event.ActivityLifecycleEvent; +import com.growingio.android.sdk.track.log.Logger; +import com.growingio.android.sdk.track.middleware.GEvent; +import com.growingio.android.sdk.track.providers.ActivityStateProvider; +import com.growingio.android.sdk.track.providers.ConfigurationProvider; +import com.growingio.android.sdk.track.providers.SessionProvider; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * 不支持多进程 + */ +public class GoogleAnalyticsAdapter implements IActivityLifecycle { + private static final String TAG = "GoogleAnalyticsAdapter"; + private static final String USER_ID_KEY = "&uid"; + private static final String CLIENT_ID_KEY = "&cid"; + private static final String MEASUREMENT_ID_KEY = "&tid"; + + private final Map mTrackers = new HashMap<>(); + private final GoogleAnalyticsConfiguration mGoogleAnalyticsConfiguration; + + private long mSessionInterval = 30 * 1000L; + private boolean mEnterBackground = true; + + // true 为关闭采集,false 为开启采集 + private boolean mOptOut; + + private static class SingleInstance { + private static final GoogleAnalyticsAdapter INSTANCE = new GoogleAnalyticsAdapter(); + } + + // 注意两个时机 + // 1. cdp的gioId事件拦截必定在newTracker,但是需要给新构建的事件增加gioId以及通用属性读取(不会被拦截器处理) + // 2. activity的生命周期注册先于SessionProvider + private GoogleAnalyticsAdapter() { + // 初始化 使用 GA的 开关配置,忽略本身的配置项 + // TODO: 初始化前 在 子线程修改 AppOptOut 可能导致状态异常, GA中仅保证optOut的可见性(volatile) + mOptOut = GoogleAnalytics.getInstance(TrackerContext.get()).getAppOptOut(); + // AppOptOut true/false 与 dataCollectionEnabled 相反 + ConfigurationProvider.core().setDataCollectionEnabled(!mOptOut); + mGoogleAnalyticsConfiguration = ConfigurationProvider.get().getConfiguration(GoogleAnalyticsConfiguration.class); + mSessionInterval = ConfigurationProvider.core().getSessionInterval() * 1000L; + ActivityStateProvider.get().registerActivityLifecycleListener(this); + } + + public static GoogleAnalyticsAdapter get() { + return SingleInstance.INSTANCE; + } + + @Override + public void onActivityLifecycle(ActivityLifecycleEvent event) { + // 注意 该函数与SessionProvider中 latestPauseTime 与 activityCount的关系 + // SessionProvider#init 先于 模块注册,即先执行SessionProvider中设置 + if (event.eventType == ActivityLifecycleEvent.EVENT_TYPE.ON_STARTED) { + if (mEnterBackground) { + mEnterBackground = false; + long latestPauseTime = PersistentDataProvider.get().getLatestPauseTime(); + if (latestPauseTime != 0 && (System.currentTimeMillis() - latestPauseTime >= mSessionInterval)) { + TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { + @Override + public void run() { + // 更新所有 Tracker 的 session,并补发相应vst事件 + for (TrackerInfo trackerInfo : mTrackers.values()) { + trackerInfo.setSessionId(UUID.randomUUID().toString()); + newAnalyticsEvent(new VisitEvent.Builder(), trackerInfo); + } + } + }); + } + } + } else if (event.eventType == ActivityLifecycleEvent.EVENT_TYPE.ON_STOPPED) { + // SessionProvider 先执行已经将对应count减去相关值 并设置对应latestPauseTime + if (PersistentDataProvider.get().getActivityCount() == 0) { + mEnterBackground = true; + } + } + } + + // 解析 GA3 配置xml + void newTracker(Tracker tracker, int resId) { + try { + XmlResourceParser parser = TrackerContext.get().getResources().getXml(resId); + boolean foundTag = false; + while (parser.getEventType() != XmlResourceParser.END_DOCUMENT) { + if (parser.getEventType() == XmlResourceParser.START_TAG) { + String tagName = parser.getName(); + String nameAttr = parser.getAttributeValue(null, "name"); + foundTag = "string".equals(tagName) && "ga_trackingId".equals(nameAttr); + } + if (parser.getEventType() == XmlResourceParser.TEXT) { + if (foundTag) { + String measurementId = parser.getText(); + if (!TextUtils.isEmpty(measurementId)) { + newTracker(tracker, measurementId); + return; + } + } + } + parser.next(); + } + } catch (Exception ignored) { + } + } + + void newTracker(Tracker tracker, String measurementId) { + TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { + @Override + public void run() { + String datasourceId = mGoogleAnalyticsConfiguration.getDatasourceIds().get(measurementId); + if (measurementId != null && !TextUtils.isEmpty(datasourceId) && !mTrackers.containsKey(measurementId)) { + TrackerInfo trackerInfo = new TrackerInfo(datasourceId, UUID.randomUUID().toString()); + trackerInfo.setEventBuildInterceptor(new EventBuildInterceptor() { + @Override + public void eventWillBuild(BaseEvent.BaseBuilder eventBuilder) { + } + + @Override + public void eventDidBuild(GEvent event) { + // 转发所有无埋点事件, VST不进行再次转发 + if (TrackEventType.APP_CLOSED.equals(event.getEventType()) || + TrackEventType.FORM_SUBMIT.equals(event.getEventType()) || + AutotrackEventType.PAGE.equals(event.getEventType()) || + AutotrackEventType.PAGE_ATTRIBUTES.equals(event.getEventType()) || + AutotrackEventType.VIEW_CHANGE.equals(event.getEventType()) || + AutotrackEventType.VIEW_CLICK.equals(event.getEventType())) { + if (event instanceof BaseEvent) { + transformAnalyticsEvent((BaseEvent) event, trackerInfo); + } + } + } + }); + // 增加对应Tracker拦截器 + TrackMainThread.trackMain().addEventBuildInterceptor(trackerInfo.getEventBuildInterceptor()); + + // 发送 用户属性事件 用于关联历史数据 + String clientId = getClientId(tracker); + if (!TextUtils.isEmpty(clientId)) { + trackerInfo.setClientId(clientId); + } + + sendNewTrackEvent(trackerInfo); + + mTrackers.put(measurementId, trackerInfo); + } + } + }); + } + +// void setClientId(Tracker tracker, String clientId) { +// TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { +// @Override +// public void run() { +// TrackerInfo trackerInfo = mTrackers.get(getMeasurementId(tracker)); +// if (trackerInfo != null) { +// trackerInfo.setClientId(clientId); +// sendClientIdEvent(trackerInfo); +// } +// } +// }); +// } + + void send(Tracker tracker, Map params) { + TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { + @Override + public void run() { + TrackerInfo trackerInfo = mTrackers.get(getMeasurementId(tracker)); + if (trackerInfo != null) { + newAnalyticsEvent(new CustomEvent.Builder() + .setEventName("GAEvent") + .setAttributes(params), trackerInfo); + } + } + }); + } + + void set(Tracker tracker, String key, String value) { + TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { + @Override + public void run() { + TrackerInfo trackerInfo = mTrackers.get(getMeasurementId(tracker)); + if (trackerInfo != null) { + if (USER_ID_KEY.equals(key)) { + setUserId(trackerInfo, value); + return; + } else if (CLIENT_ID_KEY.equals(key)) { + // setClientId 内部调用 set 方法 + trackerInfo.setClientId(value); + sendClientIdEvent(trackerInfo); + return; + } + setDefaultParam(trackerInfo, key, value); + } + } + }); + } + + void setAppOptOut(boolean optOut) { + TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { + @Override + public void run() { + // GA3 全局控制 控制原生部分开关 + // 考虑 使用运行时 API 进行开关控制,可能导致与 GA 全局控制开关不同 + setDataCollectionEnabled(!optOut); + + // GA3 全局控制 控制Tracker部分开关 + if (optOut == mOptOut) { + Logger.e(TAG, "当前GA3数据采集开关 = " + optOut + ", 请勿重复操作"); + } else { + mOptOut = optOut; + // 关 -> 开 + if (!optOut) { + for (TrackerInfo trackerInfo : mTrackers.values()) { + sendNewTrackEvent(trackerInfo); + } + } + } + } + }); + } + + @TrackThread + private void setDataCollectionEnabled(boolean enabled) { + if (enabled == ConfigurationProvider.core().isDataCollectionEnabled()) { + Logger.e(TAG, "当前数据采集开关 = " + enabled + ", 请勿重复操作"); + } else { + ConfigurationProvider.core().setDataCollectionEnabled(enabled); + if (enabled) { + SessionProvider.get().generateVisit(); + } + } + } + + @TrackThread + private void sendNewTrackEvent(TrackerInfo trackerInfo) { + // 补发vst + // 直接入库,不经过Interceptor + newAnalyticsEvent(new VisitEvent.Builder(), trackerInfo); + + sendClientIdEvent(trackerInfo); + } + + @TrackThread + private void sendClientIdEvent(TrackerInfo trackerInfo) { + // 发送 用户属性事件 用于关联历史数据 + if (!TextUtils.isEmpty(trackerInfo.getClientId())) { + Map attributes = new HashMap<>(); + attributes.put(CLIENT_ID_KEY, trackerInfo.getClientId()); + newAnalyticsEvent(new LoginUserAttributesEvent.Builder() + .setAttributes(attributes), trackerInfo); + } + } + + @TrackThread + private void setUserId(TrackerInfo trackerInfo, String userId) { + if (TextUtils.isEmpty(userId)) { + trackerInfo.setUserId(null); + return; + } + + String oldUserId = trackerInfo.getUserId(); + // A -> A 直接返回 + if (userId.equals(oldUserId)) { + return; + } + trackerInfo.setUserId(userId); + + String lastUserId = trackerInfo.getLastUserId(); + trackerInfo.setLastUserId(userId); + // null -> A 补发vst + // A -> null -> A 不做session变更, 与3.0保持一致,不补发vst + if (TextUtils.isEmpty(lastUserId)) { + newAnalyticsEvent(new VisitEvent.Builder(), trackerInfo); + } else { + if (!userId.equals(lastUserId)) { + // 更新session, 补发vst事件 + trackerInfo.setSessionId(UUID.randomUUID().toString()); + newAnalyticsEvent(new VisitEvent.Builder(), trackerInfo); + } + } + } + + @TrackThread + private void setDefaultParam(TrackerInfo trackerInfo, String key, String value) { + trackerInfo.addParam(key, value); + } + + @TrackThread + private String getMeasurementId(Tracker tracker) { + try { + // GA 未初始化完成可能抛出IllegalStateException + return tracker.get(MEASUREMENT_ID_KEY); + } catch (Exception e) { + } + + return null; + } + + @TrackThread + private String getClientId(Tracker tracker) { + try { + return tracker.get(CLIENT_ID_KEY); + } catch (Exception e) { + } + + return null; + } + + // 主动构造的事件需要执行readPropertyInTrackThread读取通用参数 + // 不通过readPropertyInTrackThread方法直接读取参数,避免导致esid、gesid自增 + @TrackThread + private void newAnalyticsEvent(BaseEvent.BaseBuilder baseBuilder, TrackerInfo trackerInfo) { + postAnalyticsEvent(new AnalyticsEvent(baseBuilder.build(), trackerInfo, true)); + } + + // 转发事件已经执行过readPropertyInTrackThread + @TrackThread + private void transformAnalyticsEvent(BaseEvent event, TrackerInfo trackerInfo, long timestamp) { + postAnalyticsEvent(new AnalyticsEvent(event, trackerInfo, timestamp)); + } + + @TrackThread + private void transformAnalyticsEvent(BaseEvent event, TrackerInfo trackerInfo) { + postAnalyticsEvent(new AnalyticsEvent(event, trackerInfo)); + } + + @TrackThread + private void postAnalyticsEvent(AnalyticsEvent analyticsEvent) { + if (!mOptOut) { + // 转发给 MobileDebugger 的 EventBuildInterceptor + // MobileDebugger 默认 在 Tracker中 先于 第三方模块加载 直接调用 DebuggerEventWrapper 发送数据 / 缓存数据 + sendToDebugger(analyticsEvent); + + TrackMainThread.trackMain().postGEventToTrackMain(analyticsEvent); + } + } + + private Object mDebuggerEventWrapper; + private Method mEventDidBuildMethod; + private boolean mDebuggerNotFind = false; + + @TrackThread + private void sendToDebugger(AnalyticsEvent analyticsEvent) { + if (mDebuggerNotFind) return; + + try { + if (mDebuggerEventWrapper == null || mEventDidBuildMethod == null) { + Class clazz = Class.forName("com.growingio.android.debugger.DebuggerEventWrapper"); + Method getMethod = clazz.getDeclaredMethod("get"); + mDebuggerEventWrapper = getMethod.invoke(null); + mEventDidBuildMethod = clazz.getDeclaredMethod("eventDidBuild", Class.forName("com.growingio.android.sdk.track.middleware.GEvent")); + } + mEventDidBuildMethod.invoke(mDebuggerEventWrapper, analyticsEvent); + + return; + } catch (Exception ignored) { + } + + mDebuggerNotFind = true; + } +} diff --git a/inject-annotation/compiler/src/test/java/com/growingio/sdk/sample/TestOnClickListener.java b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsConfiguration.java similarity index 51% rename from inject-annotation/compiler/src/test/java/com/growingio/sdk/sample/TestOnClickListener.java rename to growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsConfiguration.java index e21b4a02..896de3a2 100644 --- a/inject-annotation/compiler/src/test/java/com/growingio/sdk/sample/TestOnClickListener.java +++ b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsConfiguration.java @@ -14,40 +14,25 @@ * limitations under the License. */ -package com.growingio.sdk.sample; +package com.growingio.android.analytics.google; +import com.growingio.android.sdk.Configurable; -import java.util.List; +import java.util.HashMap; +import java.util.Map; -public class TestOnClickListener { - public void onClick(int obj) { - } - - public void show() { - } - - public boolean onOptionsItemSelected() { - return false; - } - - public boolean onOptionsItemSelected2() { - return true; - } - - public void loadUrl(String url) { - } +public class GoogleAnalyticsConfiguration implements Configurable { - public void onResume() { - } - - public void onResume2() { - } + private Map mDatasourceIds = new HashMap<>(); - public String types(float type1, double type2, char type3, short type4, boolean type5, byte type6) { - return ""; + public GoogleAnalyticsConfiguration setDatasourceIds(Map map) { + if (map != null) { + this.mDatasourceIds.putAll(map); + } + return this; } - public Object arrays(List params) { - return ""; + public Map getDatasourceIds() { + return this.mDatasourceIds; } } diff --git a/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsInjector.java b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsInjector.java new file mode 100644 index 00000000..b136ae36 --- /dev/null +++ b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsInjector.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.analytics.google; + +import com.google.android.gms.analytics.GoogleAnalytics; +import com.google.android.gms.analytics.Tracker; +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.track.log.Logger; + +import java.util.Map; + +public class GoogleAnalyticsInjector { + private static final String TAG = "GoogleAnalyticsInjector"; + + private GoogleAnalyticsInjector() { + } + + public static void newTracker(Tracker tracker, GoogleAnalytics googleAnalytics, int resId) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Tracker do not initialized successfully"); + return; + } + + GoogleAnalyticsAdapter.get().newTracker(tracker, resId); + } + + public static void newTracker(Tracker tracker, GoogleAnalytics googleAnalytics, String measurementId) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Tracker do not initialized successfully"); + return; + } + + GoogleAnalyticsAdapter.get().newTracker(tracker, measurementId); + } + + public static void setAppOptOut(GoogleAnalytics googleAnalytics, boolean optOut) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Tracker do not initialized successfully"); + return; + } + + GoogleAnalyticsAdapter.get().setAppOptOut(optOut); + } + + public static void setClientId(Tracker tracker, String clientId) { + // setClientId 内部调用 set("&cid", clientId); +// if (!TrackerContext.initializedSuccessfully()) { +// Logger.e(TAG, "Tracker do not initialized successfully"); +// return; +// } +// +// GoogleAnalyticsAdapter.get().setClientId(tracker, clientId); + } + + public static void send(Tracker tracker, Map params) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Tracker do not initialized successfully"); + return; + } + + GoogleAnalyticsAdapter.get().send(tracker, params); + } + + public static void set(Tracker tracker, String key, String value) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Tracker do not initialized successfully"); + return; + } + + GoogleAnalyticsAdapter.get().set(tracker, key, value); + } +} diff --git a/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsLibraryModule.java b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsLibraryModule.java new file mode 100644 index 00000000..18e1c064 --- /dev/null +++ b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/GoogleAnalyticsLibraryModule.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.analytics.google; + +import android.content.Context; + +import com.growingio.android.sdk.LibraryGioModule; +import com.growingio.android.sdk.track.modelloader.TrackerRegistry; +import com.growingio.sdk.annotation.GIOLibraryModule; + +@GIOLibraryModule(config = GoogleAnalyticsConfiguration.class) +public class GoogleAnalyticsLibraryModule extends LibraryGioModule { + + @Override + public void registerComponents(Context context, TrackerRegistry registry) { + // 提前初始化 + GoogleAnalyticsAdapter.get(); + } +} \ No newline at end of file diff --git a/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/model/AnalyticsEvent.java b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/model/AnalyticsEvent.java new file mode 100644 index 00000000..7a4f381a --- /dev/null +++ b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/model/AnalyticsEvent.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.analytics.google.model; + +import android.content.Context; +import android.text.TextUtils; + +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.track.SDKConfig; +import com.growingio.android.sdk.track.events.TrackEventType; +import com.growingio.android.sdk.track.events.base.BaseEvent; +import com.growingio.android.sdk.track.events.helper.FieldIgnoreFilter; +import com.growingio.android.sdk.track.providers.AppInfoProvider; +import com.growingio.android.sdk.track.providers.DeviceInfoProvider; +import com.growingio.android.sdk.track.providers.SessionProvider; +import com.growingio.android.sdk.track.utils.NetworkUtil; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Locale; +import java.util.Map; + +/** + * 当前仅支持 JSON模块上报,PB模块不依赖 toJSONObject方法 + */ +public class AnalyticsEvent extends BaseEvent { + private static final String REPLACE_USER_KEY = "userKey"; + private static final String REPLACE_SESSION_ID = "sessionId"; + private static final String REPLACE_DATASOURCE_ID = "dataSourceId"; + private static final String REPLACE_USER_ID = "userId"; + private static final String REPLACE_GIO_ID = "gioId"; + private static final String REPLACE_ATTRIBUTES = "attributes"; + private static final String REPLACE_GLOBAL_SEQUENCE_ID = "globalSequenceId"; + private static final String REPLACE_EVENT_SEQUENCE_ID = "eventSequenceId"; + + private static final String READ_DEVICE_ID = "deviceId"; + private static final String READ_NETWORK_STATE = "networkState"; + private static final String READ_SCREEN_HEIGHT = "screenHeight"; + private static final String READ_SCREEN_WIDTH = "screenWidth"; + private static final String READ_DEVICE_BRAND = "deviceBrand"; + private static final String READ_DEVICE_MODEL = "deviceModel"; + private static final String READ_DEVICE_TYPE = "deviceType"; + private static final String READ_APP_CHANNEL = "appChannel"; + private static final String READ_APP_NAME = "appName"; + private static final String READ_APP_VERSION = "appVersion"; + private static final String READ_LATITUDE = "latitude"; + private static final String READ_LONGITUDE = "longitude"; + private static final String READ_SDK_VERSION = "sdkVersion"; + private static final String READ_LANGUAGE = "language"; + + private static final String READ_VISIT_IMEI = "imei"; + private static final String READ_VISIT_ANDROID_ID = "androidId"; + private static final String READ_VISIT_OAID = "oaid"; + private static final String READ_VISIT_GOOGLE_ADVERTISING_ID = "googleAdvertisingId"; + + private static final String READ_AND_REPLACE_TIMESTAMP = "timestamp"; + + private final TrackerInfo mTrackerInfo; + private final long mTimestamp; + private final boolean mReadProperty; + + private final String mEventType; + private final int mSendPolicy; + + private JSONObject mJsonObject; + + public AnalyticsEvent(final BaseEvent baseEvent, final TrackerInfo trackerInfo) { + this(baseEvent, trackerInfo, 0L, false); + } + + public AnalyticsEvent(final BaseEvent baseEvent, final TrackerInfo trackerInfo, final boolean readProperty) { + this(baseEvent, trackerInfo, 0L, readProperty); + } + + public AnalyticsEvent(final BaseEvent baseEvent, final TrackerInfo trackerInfo, final long timestamp) { + this(baseEvent, trackerInfo, timestamp, false); + } + + public AnalyticsEvent(final BaseEvent baseEvent, final TrackerInfo trackerInfo, final long timestamp, final boolean readProperty) { + // 空实现 + super(new BaseBuilder() { + @Override + public String getEventType() { + return null; + } + + @Override + public BaseEvent build() { + return null; + } + }); + + this.mTrackerInfo = trackerInfo; + this.mTimestamp = timestamp; + this.mReadProperty = readProperty; + + this.mEventType = baseEvent.getEventType(); + this.mSendPolicy = baseEvent.getSendPolicy(); + this.mJsonObject = baseEvent.toJSONObject(); + + if (mReadProperty) { + readProperty(); + } + } + + private void readProperty() { + try { + readBaseProperty(); + + if (TrackEventType.VISIT.equals(mEventType)) { + DeviceInfoProvider deviceInfo = DeviceInfoProvider.get(); + String imei = deviceInfo.getImei(); + if (!TextUtils.isEmpty(imei)) { + mJsonObject.put(READ_VISIT_IMEI, imei); + } + String androidId = deviceInfo.getAndroidId(); + if (!TextUtils.isEmpty(androidId)) { + mJsonObject.put(READ_VISIT_ANDROID_ID, androidId); + } + String oaid = deviceInfo.getOaid(); + if (!TextUtils.isEmpty(oaid)) { + mJsonObject.put(READ_VISIT_OAID, oaid); + } +// String googleAdvertisingId = ""; +// if (!TextUtils.isEmpty(googleAdvertisingId)) { +// mJsonObject.put(READ_VISIT_GOOGLE_ADVERTISING_ID, googleAdvertisingId); +// } + } + } catch (JSONException ignored) { + + } + } + + private void readBaseProperty() throws JSONException { + mJsonObject.put(READ_AND_REPLACE_TIMESTAMP, System.currentTimeMillis()); + mJsonObject.put(READ_DEVICE_ID, DeviceInfoProvider.get().getDeviceId()); + + Context context = TrackerContext.get().getApplicationContext(); + String netWorkState = FieldIgnoreFilter.isFieldFilter("networkState") ? "" : NetworkUtil.getActiveNetworkState(context).getNetworkName(); + if (!TextUtils.isEmpty(netWorkState)) { + mJsonObject.put(READ_NETWORK_STATE, netWorkState); + } + + DeviceInfoProvider deviceInfo = DeviceInfoProvider.get(); + int screenHeight = FieldIgnoreFilter.isFieldFilter("screenHeight") ? 0 : deviceInfo.getScreenHeight(); + if (screenHeight > 0) { + mJsonObject.put(READ_SCREEN_HEIGHT, screenHeight); + } + int screenWidth = FieldIgnoreFilter.isFieldFilter("screenWidth") ? 0 : deviceInfo.getScreenWidth(); + if (screenWidth > 0) { + mJsonObject.put(READ_SCREEN_WIDTH, screenWidth); + } + String deviceBrand = FieldIgnoreFilter.isFieldFilter("deviceBrand") ? "" : deviceInfo.getDeviceBrand(); + if (!TextUtils.isEmpty(deviceBrand)) { + mJsonObject.put(READ_DEVICE_BRAND, deviceBrand); + } + String deviceModel = FieldIgnoreFilter.isFieldFilter("deviceModel") ? "" : deviceInfo.getDeviceModel(); + if (!TextUtils.isEmpty(deviceModel)) { + mJsonObject.put(READ_DEVICE_MODEL, deviceModel); + } + String deviceType = FieldIgnoreFilter.isFieldFilter("deviceType") ? "" : deviceInfo.getDeviceType(); + if (!TextUtils.isEmpty(deviceType)) { + mJsonObject.put(READ_DEVICE_TYPE, deviceType); + } + + AppInfoProvider appInfo = AppInfoProvider.get(); + String appChannel = appInfo.getAppChannel(); + if (!TextUtils.isEmpty(appChannel)) { + mJsonObject.put(READ_APP_CHANNEL, appChannel); + } + mJsonObject.put(READ_APP_NAME, appInfo.getAppName()); + mJsonObject.put(READ_APP_VERSION, appInfo.getAppVersion()); + + SessionProvider session = SessionProvider.get(); + double latitude = session.getLatitude(); + double longitude = session.getLongitude(); + if (latitude != 0 || longitude != 0) { + mJsonObject.put(READ_LATITUDE, latitude); + mJsonObject.put(READ_LONGITUDE, longitude); + } + + mJsonObject.put(READ_SDK_VERSION, SDKConfig.SDK_VERSION); + mJsonObject.put(READ_LANGUAGE, Locale.getDefault().getLanguage()); + } + + @Override + public String getEventType() { + return mEventType; + } + + @Override + public int getSendPolicy() { + return mSendPolicy; + } + + @Override + public JSONObject toJSONObject() { + try { + // 如果存在则移除 userKey 字段 + mJsonObject.remove(REPLACE_USER_KEY); + // 如果存在则移除 esid、gesid 字段 + mJsonObject.remove(REPLACE_GLOBAL_SEQUENCE_ID); + mJsonObject.remove(REPLACE_EVENT_SEQUENCE_ID); + + // 替换 / 增加 gioId + mJsonObject.put(REPLACE_GIO_ID, mTrackerInfo.getLastUserId()); + // 替换 / 增加 dataSourceId + mJsonObject.put(REPLACE_DATASOURCE_ID, mTrackerInfo.getDatasourceId()); + // 替换 / 增加 sessionId + mJsonObject.put(REPLACE_SESSION_ID, mTrackerInfo.getSessionId()); + // 替换 / 增加 userId + mJsonObject.put(REPLACE_USER_ID, mTrackerInfo.getUserId()); + // 如果 timestamp 不为0L,替换 / 增加 timestamp + if (mTimestamp != 0L) { + mJsonObject.put(READ_AND_REPLACE_TIMESTAMP, mTimestamp); + } + + // custom需要处理 通用参数 + if (TrackEventType.CUSTOM.equals(mEventType)) { + JSONObject attributes = mJsonObject.optJSONObject(REPLACE_ATTRIBUTES); + if (attributes == null) { + attributes = new JSONObject(); + } + + for (Map.Entry attr : mTrackerInfo.getParams().entrySet()) { + // 如果与send设置的字段冲突,优先使用send方法中设置的字段值 + String attrKey = attr.getKey(); + if (attrKey != null && !attributes.has(attrKey)) { + attributes.put(attr.getKey(), attr.getValue()); + } + } + } + + // 不直接返回 jsonObject, 避免 被 拦截器修改 mobile debugger + return new JSONObject(mJsonObject.toString()); + } catch (JSONException ignored) { + } + + return new JSONObject(); + } +} diff --git a/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/model/TrackerInfo.java b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/model/TrackerInfo.java new file mode 100644 index 00000000..456b785a --- /dev/null +++ b/growingio-adapter/analytics-ga/src/main/java/com/growingio/android/analytics/google/model/TrackerInfo.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.analytics.google.model; + +import android.text.TextUtils; + +import com.growingio.android.sdk.track.events.EventBuildInterceptor; + +import java.util.HashMap; +import java.util.Map; + +public class TrackerInfo { + private String mSessionId; + private String mDataSourceId; + private String mUserId; + private String mLastUserId; + private String mClientId; + private Map extraParams; + private EventBuildInterceptor mEventBuildInterceptor; + + public TrackerInfo(String datasourceId, String sessionId) { + this.mDataSourceId = datasourceId; + this.mSessionId = sessionId; + this.extraParams = new HashMap<>(); + } + + public String getSessionId() { + return mSessionId; + } + + public void setSessionId(String sessionId) { + this.mSessionId = sessionId; + } + + public String getDatasourceId() { + return mDataSourceId; + } + + public void setDatasourceId(String datasource) { + this.mDataSourceId = datasource; + } + + public String getUserId() { + return mUserId; + } + + public void setUserId(String userId) { + this.mUserId = userId; + } + + public String getLastUserId() { + return mLastUserId; + } + + public void setLastUserId(String mLastUserId) { + this.mLastUserId = mLastUserId; + } + + public String getClientId() { + return mClientId; + } + + public void setClientId(String clientId) { + this.mClientId = clientId; + } + + public EventBuildInterceptor getEventBuildInterceptor() { + return mEventBuildInterceptor; + } + + public void setEventBuildInterceptor(EventBuildInterceptor mEventBuildInterceptor) { + this.mEventBuildInterceptor = mEventBuildInterceptor; + } + + public void addParam(String key, String value) { + if (TextUtils.isEmpty(key)) { + return; + } + if (value == null) { + extraParams.remove(key); + return; + } + extraParams.put(key, value); + } + + public Map getParams() { + return extraParams; + } +} diff --git a/growingio-adapter/build.gradle b/growingio-adapter/build.gradle new file mode 100644 index 00000000..d4e8437e --- /dev/null +++ b/growingio-adapter/build.gradle @@ -0,0 +1 @@ +// keep an empty file to make sure Gradle recognizes the properties diff --git a/growingio-autotracker-core/build.gradle b/growingio-autotracker-core/build.gradle index 25a0df66..610dfa31 100644 --- a/growingio-autotracker-core/build.gradle +++ b/growingio-autotracker-core/build.gradle @@ -42,16 +42,6 @@ android { lintOptions { abortOnError false } - - defaultConfig { - javaCompileOptions { - annotationProcessorOptions { - arguments = [ - GRADLE_PLUGIN_DIR : ("$rootDir/growingio-autotracker-gradle-plugin".toString()) - ] - } - } - } } dependencies { @@ -72,10 +62,8 @@ dependencies { debugApi project(':growingio-tracker-core') releaseApi libraries.growingio.tracker_core - implementation project(':inject-annotation') - annotationProcessor project(':inject-annotation:compiler') - compileOnly libraries.androidx.appcompat + compileOnly libraries.androidx.material compileOnly libraries.androidx.recyclerview compileOnly libraries.android.appcompat compileOnly libraries.android.recyclerview diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/click/ViewClickInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/click/ViewClickInjector.java deleted file mode 100644 index 39f2a3fa..00000000 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/click/ViewClickInjector.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.android.sdk.autotrack.click; - -import android.accounts.AccountAuthenticatorActivity; -import android.app.Activity; -import android.app.ActivityGroup; -import android.app.AlertDialog; -import android.app.AliasActivity; -import android.app.ExpandableListActivity; -import android.app.LauncherActivity; -import android.app.ListActivity; -import android.app.NativeActivity; -import android.app.TabActivity; -import android.content.DialogInterface; -import android.preference.PreferenceActivity; -import android.view.MenuItem; -import android.view.View; -import android.widget.ActionMenuView; -import android.widget.AdapterView; -import android.widget.CompoundButton; -import android.widget.ExpandableListView; -import android.widget.ListView; -import android.widget.PopupMenu; -import android.widget.RadioGroup; -import android.widget.RatingBar; -import android.widget.SeekBar; -import android.widget.Spinner; -import android.widget.Toolbar; - -import com.growingio.sdk.inject.annotation.After; -import com.growingio.sdk.inject.annotation.BeforeSuper; - -public class ViewClickInjector { - private static final String TAG = "ViewClickInjector"; - - private ViewClickInjector() { - } - - @BeforeSuper(clazz = View.OnClickListener.class, method = "onClick", parameterTypes = {View.class}) - public static void viewOnClick(View.OnClickListener listener, View view) { - ViewClickProvider.viewOnClick(view); - } - - @After(clazz = AlertDialog.class, method = "show") - public static void alertDialogShow(AlertDialog alertDialog) { - ViewClickProvider.alertDialogShow(alertDialog); - } - - @BeforeSuper(clazz = DialogInterface.OnClickListener.class, method = "onClick", parameterTypes = {DialogInterface.class, int.class}) - public static void dialogOnClick(DialogInterface.OnClickListener listener, DialogInterface dialogInterface, int which) { - if (dialogInterface instanceof AlertDialog) { - ViewClickProvider.alertDialogOnClick((AlertDialog) dialogInterface, which); - } - } - - @BeforeSuper(clazz = AdapterView.OnItemClickListener.class, method = "onItemClick", parameterTypes = {AdapterView.class, View.class, int.class, long.class}) - public static void adapterViewOnItemClick(AdapterView.OnItemClickListener listener, AdapterView adapterView, View view, int position, long id) { - ViewClickProvider.viewOnClick(view); - } - - @BeforeSuper(clazz = AdapterView.OnItemSelectedListener.class, method = "onItemSelected", parameterTypes = {AdapterView.class, View.class, int.class, long.class}) - public static void adapterViewOnItemSelected(AdapterView.OnItemSelectedListener listener, AdapterView adapterView, View view, int position, long id) { - if (adapterView instanceof Spinner) { - // 目前只需要将Spinner的onItemSelected回调触发点击事件,因为Spinner的元素点击只会触发onItemSelected回调 - ViewClickProvider.viewOnClick(view); - } - } - - @BeforeSuper(clazz = ExpandableListView.OnGroupClickListener.class, method = "onGroupClick", parameterTypes = {ExpandableListView.class, View.class, int.class, long.class}, returnType = boolean.class) - public static void expandableListViewOnGroupClick(ExpandableListView.OnGroupClickListener listener, ExpandableListView parent, View v, int groupPosition, long id) { - ViewClickProvider.viewOnClick(v); - } - - @BeforeSuper(clazz = ExpandableListView.OnChildClickListener.class, method = "onChildClick", parameterTypes = {ExpandableListView.class, View.class, int.class, int.class, long.class}, returnType = boolean.class) - public static void expandableListViewOnChildClick(ExpandableListView.OnChildClickListener listener, ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - ViewClickProvider.viewOnClick(v); - } - - @BeforeSuper(clazz = ExpandableListActivity.class, method = "onChildClick", parameterTypes = {ExpandableListView.class, View.class, int.class, int.class, long.class}, returnType = boolean.class) - public static void expandableListActivityOnChildClick(ExpandableListActivity activity, ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - ViewClickProvider.viewOnClick(v); - } - - @BeforeSuper(clazz = ListActivity.class, method = "onListItemClick", parameterTypes = {ListView.class, View.class, int.class, long.class}) - public static void listActivityOnListItemClick(ListActivity activity, ListView listView, View view, int position, long id) { - ViewClickProvider.viewOnClick(view); - } - - @BeforeSuper(clazz = CompoundButton.OnCheckedChangeListener.class, method = "onCheckedChanged", parameterTypes = {CompoundButton.class, boolean.class}) - public static void compoundButtonOnChecked(CompoundButton.OnCheckedChangeListener listener, CompoundButton button, boolean checked) { - ViewClickProvider.viewOnClick(button); - } - - @BeforeSuper(clazz = RadioGroup.OnCheckedChangeListener.class, method = "onCheckedChanged", parameterTypes = {RadioGroup.class, int.class}) - public static void radioGroupOnChecked(RadioGroup.OnCheckedChangeListener listener, RadioGroup radioGroup, int i) { - ViewClickProvider.viewOnClick(radioGroup.findViewById(radioGroup.getCheckedRadioButtonId())); - } - - @BeforeSuper(clazz = RatingBar.OnRatingBarChangeListener.class, method = "onRatingChanged", parameterTypes = {RatingBar.class, float.class, boolean.class}) - public static void ratingBarOnRatingBarChange(RatingBar.OnRatingBarChangeListener listener, RatingBar ratingBar, float rating, boolean fromUser) { - if (fromUser) { - ViewClickProvider.viewOnClick(ratingBar); - } - } - - @BeforeSuper(clazz = SeekBar.OnSeekBarChangeListener.class, method = "onStopTrackingTouch", parameterTypes = {SeekBar.class}) - public static void seekBarOnSeekBarChange(SeekBar.OnSeekBarChangeListener listener, SeekBar seekBar) { - ViewClickProvider.viewOnClick(seekBar); - } - - @BeforeSuper(clazz = Toolbar.OnMenuItemClickListener.class, method = "onMenuItemClick", parameterTypes = {MenuItem.class}, returnType = boolean.class) - public static void toolbarOnMenuItemClick(Toolbar.OnMenuItemClickListener listener, MenuItem item) { - ViewClickProvider.menuItemOnClick(item); - } - - @BeforeSuper(clazz = ActionMenuView.OnMenuItemClickListener.class, method = "onMenuItemClick", parameterTypes = {MenuItem.class}, returnType = boolean.class) - public static void actionMenuViewOnMenuItemClick(ActionMenuView.OnMenuItemClickListener listener, MenuItem item) { - ViewClickProvider.menuItemOnClick(item); - } - - @BeforeSuper(clazz = PopupMenu.OnMenuItemClickListener.class, method = "onMenuItemClick", parameterTypes = {MenuItem.class}, returnType = boolean.class) - public static void popupMenuOnMenuItemClick(PopupMenu.OnMenuItemClickListener listener, MenuItem item) { - ViewClickProvider.menuItemOnClick(item); - } - - @BeforeSuper(clazz = Activity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = AccountAuthenticatorActivity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = ActivityGroup.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = AliasActivity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = ExpandableListActivity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = LauncherActivity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = ListActivity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = NativeActivity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = TabActivity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - @BeforeSuper(clazz = PreferenceActivity.class, method = "onOptionsItemSelected", parameterTypes = {MenuItem.class}, returnType = boolean.class) - public static void menuItemOnOptionsItemSelected(Activity activity, MenuItem item) { - ViewClickProvider.menuItemOnClick(activity, item); - } -} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/click/ViewClickProvider.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/click/ViewClickProvider.java deleted file mode 100644 index 05dec5b0..00000000 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/click/ViewClickProvider.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.android.sdk.autotrack.click; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.text.TextUtils; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.ListView; - -import com.growingio.android.sdk.TrackerContext; -import com.growingio.android.sdk.track.events.AutotrackEventType; -import com.growingio.android.sdk.track.events.ViewElementEvent; -import com.growingio.android.sdk.autotrack.page.Page; -import com.growingio.android.sdk.autotrack.page.PageProvider; -import com.growingio.android.sdk.autotrack.shadow.AlertControllerShadow; -import com.growingio.android.sdk.autotrack.util.ClassUtil; -import com.growingio.android.sdk.autotrack.view.ViewAttributeUtil; -import com.growingio.android.sdk.autotrack.view.ViewHelper; -import com.growingio.android.sdk.autotrack.view.ViewNode; -import com.growingio.android.sdk.track.TrackMainThread; -import com.growingio.android.sdk.track.log.Logger; -import com.growingio.android.sdk.track.providers.ActivityStateProvider; -import com.growingio.android.sdk.track.utils.ThreadUtils; - -class ViewClickProvider { - private static final String TAG = "ViewClickProvider"; - private static final int[] DIALOG_BUTTON_IDS = new int[]{DialogInterface.BUTTON_NEUTRAL, DialogInterface.BUTTON_NEGATIVE, DialogInterface.BUTTON_POSITIVE}; - private static final String[] DIALOG_BUTTON_NAMES = new String[]{"BUTTON_NEUTRAL", "BUTTON_NEGATIVE", "BUTTON_POSITIVE"}; - - private ViewClickProvider() { - } - - public static void alertDialogOnClick(AlertDialog dialog, int which) { - Logger.d(TAG, "alertDialogOnClick: which = " + which); - if (which < 0) { - Button button = dialog.getButton(which); - if (button != null) { - viewOnClick(button); - } - } else { - ListView listView = dialog.getListView(); - if (listView != null) { - viewOnClick(listView.getChildAt(which - listView.getFirstVisiblePosition())); - } - } - } - - /** - * 由于Android的不同版本的AlertDialog实现机制不一样,导致view xpath也不一样,如 - * Android 7.0之前 /DialogWindow/DecorView/FrameLayout[0]/FrameLayout[0]/LinearLayout[0]/LinearLayout[2]/LinearLayout[0]/Button[2] - * Android 7,0及其之后 /DialogWindow/DecorView/FrameLayout[0]/FrameLayout[0]/AlertDialogLayout[0]/ScrollView[0]/ButtonBarLayout[0]/Button[2] - * 所以这里人为的给view定义一个id - */ - public static void alertDialogShow(AlertDialog dialog) { - if (!TrackerContext.initializedSuccessfully()) { - Logger.e(TAG, "Autotracker do not initialized successfully"); - return; - } - - if (dialog == null) { - Logger.d(TAG, "alertDialogShow: dialog is NULL"); - return; - } - - Logger.d(TAG, "alertDialogShow: " + dialog); - for (int i = 0; i < DIALOG_BUTTON_IDS.length; i++) { - Button button = dialog.getButton(DIALOG_BUTTON_IDS[i]); - if (button != null && TextUtils.isEmpty(ViewAttributeUtil.getCustomId(button))) { - String dialogButtonName = DIALOG_BUTTON_NAMES[i]; - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - ViewAttributeUtil.setCustomId(button, getAlertDialogName(dialog) + "/" + dialogButtonName); - } - }); - } - } - - // TODO: 2020/10/10 list dialog等也要处理 - } - - private static String getAlertDialogName(AlertDialog dialog) { - String className = ClassUtil.getSimpleClassName(dialog.getClass()); - try { - AlertControllerShadow alertControllerShadow = new AlertControllerShadow(dialog); - CharSequence title = alertControllerShadow.getTitle(); - if (!TextUtils.isEmpty(title)) { - return className + "/" + title; - } - - CharSequence message = alertControllerShadow.getMessage(); - if (!TextUtils.isEmpty(message)) { - return className + "/" + message; - } - } catch (Exception e) { - Logger.e(TAG, e); - } - return className; - } - - public static void viewOnClick(View view) { - if (!TrackerContext.initializedSuccessfully()) { - Logger.e(TAG, "Autotracker do not initialized successfully"); - return; - } - - ViewNode viewNode = ViewHelper.getClickViewNode(view); - if (viewNode != null) { - Page page = PageProvider.get().findPage(view); - sendClickEvent(page, viewNode); - } else { - Logger.e(TAG, "ViewNode is NULL"); - } - } - - public static void menuItemOnClick(Activity activity, MenuItem menuItem) { - if (!TrackerContext.initializedSuccessfully()) { - Logger.e(TAG, "Autotracker do not initialized successfully"); - return; - } - if (activity == null || menuItem == null) { - Logger.e(TAG, "menuItemOnClick: activity or menuItem is NULL"); - return; - } - - Page page = PageProvider.get().findPage(activity); - ViewNode viewNode = ViewHelper.getMenuItemViewNode(page, menuItem); - if (viewNode != null) { - sendClickEvent(page, viewNode); - } else { - Logger.e(TAG, "MenuItem ViewNode is NULL"); - } - } - - public static void menuItemOnClick(MenuItem menuItem) { - if (!TrackerContext.initializedSuccessfully()) { - Logger.e(TAG, "Autotracker do not initialized successfully"); - return; - } - - Activity activity = ActivityStateProvider.get().getForegroundActivity(); - menuItemOnClick(activity, menuItem); - } - - private static void sendClickEvent(Page page, ViewNode viewNode) { - if (page == null) { - Logger.e(TAG, "sendClickEvent page Activity is NULL"); - return; - } - TrackMainThread.trackMain().postEventToTrackMain( - new ViewElementEvent.Builder() - .setEventType(AutotrackEventType.VIEW_CLICK) - .setPath(page.path()) - .setPageShowTimestamp(page.getShowTimestamp()) - .setXpath(viewNode.getXPath()) - .setIndex(viewNode.getIndex()) - .setTextValue(viewNode.getViewContent()) - ); - } -} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ActivityInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ActivityInjector.java index a86d1af0..161a057c 100644 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ActivityInjector.java +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ActivityInjector.java @@ -16,36 +16,34 @@ package com.growingio.android.sdk.autotrack.inject; -import android.accounts.AccountAuthenticatorActivity; import android.app.Activity; -import android.app.ActivityGroup; -import android.app.AliasActivity; import android.app.ExpandableListActivity; -import android.app.LauncherActivity; import android.app.ListActivity; -import android.app.NativeActivity; -import android.app.TabActivity; import android.content.Intent; -import android.preference.PreferenceActivity; +import android.view.MenuItem; +import android.view.View; +import android.widget.ExpandableListView; +import android.widget.ListView; import com.growingio.android.sdk.track.providers.ActivityStateProvider; -import com.growingio.sdk.inject.annotation.BeforeSuper; public class ActivityInjector { private ActivityInjector() { } - @BeforeSuper(clazz = Activity.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = AccountAuthenticatorActivity.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = ActivityGroup.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = AliasActivity.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = ExpandableListActivity.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = LauncherActivity.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = ListActivity.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = NativeActivity.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = TabActivity.class, method = "onNewIntent", parameterTypes = {Intent.class}) - @BeforeSuper(clazz = PreferenceActivity.class, method = "onNewIntent", parameterTypes = {Intent.class}) public static void onActivityNewIntent(Activity activity, Intent intent) { ActivityStateProvider.get().onActivityNewIntent(activity, intent); } + + public static void menuItemOnOptionsItemSelected(Activity activity, MenuItem item) { + ViewClickProvider.menuItemOnClick(activity, item); + } + + public static void expandableListActivityOnChildClick(ExpandableListActivity activity, ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { + ViewClickProvider.viewOnClick(v); + } + + public static void listActivityOnListItemClick(ListActivity activity, ListView listView, View view, int position, long id) { + ViewClickProvider.viewOnClick(view); + } } diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/DialogClickProvider.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/DialogClickProvider.java new file mode 100644 index 00000000..dbb16e5d --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/DialogClickProvider.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.text.TextUtils; +import android.widget.Button; +import android.widget.ListView; + +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.autotrack.shadow.AlertControllerShadow; +import com.growingio.android.sdk.autotrack.util.ClassUtil; +import com.growingio.android.sdk.autotrack.view.ViewAttributeUtil; +import com.growingio.android.sdk.track.log.Logger; +import com.growingio.android.sdk.track.utils.ThreadUtils; + +class DialogClickProvider { + private static final String TAG = "DialogClickProvider"; + private static final int[] DIALOG_BUTTON_IDS = new int[]{DialogInterface.BUTTON_NEUTRAL, DialogInterface.BUTTON_NEGATIVE, DialogInterface.BUTTON_POSITIVE}; + private static final String[] DIALOG_BUTTON_NAMES = new String[]{"BUTTON_NEUTRAL", "BUTTON_NEGATIVE", "BUTTON_POSITIVE"}; + + private DialogClickProvider() { + } + + /** + * 同版本下appcompat 包下的xpath应该也会一样。 + */ + public static void alertDialogXOnClick(androidx.appcompat.app.AlertDialog dialog, int which) { + Logger.d(TAG, "alertDialogXOnClick: which = " + which); + if (which < 0) { + Button button = dialog.getButton(which); + if (button != null) { + ViewClickProvider.viewOnClick(button); + } + } else { + ListView listView = dialog.getListView(); + if (listView != null) { + ViewClickProvider.viewOnClick(listView.getChildAt(which - listView.getFirstVisiblePosition())); + } + } + } + + public static void alertDialogSupportOnClick(android.support.v7.app.AlertDialog dialog, int which) { + Logger.d(TAG, "alertDialogSupportOnClick: which = " + which); + if (which < 0) { + Button button = dialog.getButton(which); + if (button != null) { + ViewClickProvider.viewOnClick(button); + } + } else { + ListView listView = dialog.getListView(); + if (listView != null) { + ViewClickProvider.viewOnClick(listView.getChildAt(which - listView.getFirstVisiblePosition())); + } + } + } + + public static void alertDialogOnClick(AlertDialog dialog, int which) { + Logger.d(TAG, "alertDialogOnClick: which = " + which); + if (which < 0) { + Button button = dialog.getButton(which); + if (button != null) { + ViewClickProvider.viewOnClick(button); + } + } else { + ListView listView = dialog.getListView(); + if (listView != null) { + ViewClickProvider.viewOnClick(listView.getChildAt(which - listView.getFirstVisiblePosition())); + } + } + } + + /** + * 由于Android的不同版本的AlertDialog实现机制不一样,导致view xpath也不一样,如 + * Android 7.0之前 /DialogWindow/DecorView/FrameLayout[0]/FrameLayout[0]/LinearLayout[0]/LinearLayout[2]/LinearLayout[0]/Button[2] + * Android 7,0及其之后 /DialogWindow/DecorView/FrameLayout[0]/FrameLayout[0]/AlertDialogLayout[0]/ScrollView[0]/ButtonBarLayout[0]/Button[2] + * 所以这里人为的给view定义一个id + */ + public static void alertDialogShow(AlertDialog dialog) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Autotracker do not initialized successfully"); + return; + } + + if (dialog == null) { + Logger.d(TAG, "alertDialogShow: dialog is NULL"); + return; + } + + Logger.d(TAG, "alertDialogShow: " + dialog); + for (int i = 0; i < DIALOG_BUTTON_IDS.length; i++) { + Button button = dialog.getButton(DIALOG_BUTTON_IDS[i]); + if (button != null && TextUtils.isEmpty(ViewAttributeUtil.getCustomId(button))) { + String dialogButtonName = DIALOG_BUTTON_NAMES[i]; + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + ViewAttributeUtil.setCustomId(button, getAlertDialogName(dialog) + "/" + dialogButtonName); + } + }); + } + } + + // TODO: 2020/10/10 list dialog等也要处理 + } + + private static String getAlertDialogName(AlertDialog dialog) { + String className = ClassUtil.getSimpleClassName(dialog.getClass()); + try { + AlertControllerShadow alertControllerShadow = new AlertControllerShadow(dialog); + CharSequence title = alertControllerShadow.getTitle(); + if (!TextUtils.isEmpty(title)) { + return className + "/" + title; + } + + CharSequence message = alertControllerShadow.getMessage(); + if (!TextUtils.isEmpty(message)) { + return className + "/" + message; + } + } catch (Exception e) { + Logger.e(TAG, e); + } + return className; + } +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/DialogInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/DialogInjector.java new file mode 100644 index 00000000..4e9d32a6 --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/DialogInjector.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + + +import android.app.AlertDialog; +import android.content.DialogInterface; + +import com.growingio.android.sdk.track.utils.ClassExistHelper; + + +public class DialogInjector { + + private DialogInjector() { + } + + public static void alertDialogShow(AlertDialog alertDialog) { + DialogClickProvider.alertDialogShow(alertDialog); + } + + public static void dialogOnClick(DialogInterface.OnClickListener listener, DialogInterface dialogInterface, int which) { + if (dialogInterface instanceof AlertDialog) { + DialogClickProvider.alertDialogOnClick((AlertDialog) dialogInterface, which); + } else if (ClassExistHelper.instanceOfAndroidXAlertDialog(dialogInterface)) { + DialogClickProvider.alertDialogXOnClick((androidx.appcompat.app.AlertDialog) dialogInterface, which); + } else if (ClassExistHelper.instanceOfSupportAlertDialog(dialogInterface)) { + DialogClickProvider.alertDialogSupportOnClick((android.support.v7.app.AlertDialog) dialogInterface, which); + } + } +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/FragmentInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/FragmentInjector.java new file mode 100644 index 00000000..26063335 --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/FragmentInjector.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + +import com.growingio.android.sdk.autotrack.page.PageProvider; +import com.growingio.android.sdk.autotrack.page.SuperFragment; +import com.growingio.android.sdk.track.log.Logger; + +public class FragmentInjector { + private static final String TAG = "FragmentInjector"; + + private FragmentInjector() { + } + + public static void systemFragmentOnResume(android.app.Fragment fragment) { + Logger.d(TAG, "systemFragmentOnResume: fragment = " + fragment.getClass().getName()); + PageProvider.get().createOrResumePage(SuperFragment.make(fragment)); + } + + public static void systemFragmentSetUserVisibleHint(android.app.Fragment fragment, boolean isVisibleToUser) { + Logger.d(TAG, "systemFragmentSetUserVisibleHint: fragment = " + fragment.getClass().getName() + ", isVisibleToUser = " + isVisibleToUser); + if (isVisibleToUser) { + PageProvider.get().createOrResumePage(SuperFragment.make(fragment)); + } + } + + public static void systemFragmentOnHiddenChanged(android.app.Fragment fragment, boolean hidden) { + Logger.d(TAG, "systemFragmentOnHiddenChanged: fragment = " + fragment.getClass().getName() + ", hidden" + hidden); + PageProvider.get().fragmentOnHiddenChanged(SuperFragment.make(fragment), hidden); + } + + public static void systemFragmentOnDestroyView(android.app.Fragment fragment) { + Logger.d(TAG, "systemFragmentOnDestroyView: fragment = " + fragment.getClass().getName()); + PageProvider.get().removePage(SuperFragment.make(fragment)); + } + + public static void androidxFragmentOnResume(androidx.fragment.app.Fragment fragment) { + Logger.d(TAG, "androidxFragmentOnResume: fragment = " + fragment.getClass().getName()); + PageProvider.get().createOrResumePage(SuperFragment.makeX(fragment)); + } + + /** + * 新版本的AndroidX Fragment setUserVisibleHint 将通过 FragmentTransaction setMaxLifecycle 来控制生命周期实现 + */ + @Deprecated + public static void androidxFragmentSetUserVisibleHint(androidx.fragment.app.Fragment fragment, boolean isVisibleToUser) { + Logger.d(TAG, "androidxFragmentSetUserVisibleHint: fragment = " + fragment.getClass().getName() + ", isVisibleToUser = " + isVisibleToUser); + if (isVisibleToUser) { + PageProvider.get().createOrResumePage(SuperFragment.makeX(fragment)); + } + } + + public static void androidxFragmentOnHiddenChanged(androidx.fragment.app.Fragment fragment, boolean hidden) { + Logger.d(TAG, "androidxFragmentOnHiddenChanged: fragment = " + fragment.getClass().getName() + ", hidden" + hidden); + PageProvider.get().fragmentOnHiddenChanged(SuperFragment.makeX(fragment), hidden); + } + + public static void androidxFragmentOnDestroyView(androidx.fragment.app.Fragment fragment) { + Logger.d(TAG, "androidxFragmentOnDestroyView: fragment = " + fragment.getClass().getName()); + PageProvider.get().removePage(SuperFragment.makeX(fragment)); + } + +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/FragmentV4Injector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/FragmentV4Injector.java new file mode 100644 index 00000000..42669767 --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/FragmentV4Injector.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + +import com.growingio.android.sdk.autotrack.page.PageProvider; +import com.growingio.android.sdk.autotrack.page.SuperFragment; +import com.growingio.android.sdk.track.log.Logger; + +public class FragmentV4Injector { + private static final String TAG = "FragmentV4Injector"; + + private FragmentV4Injector() { + } + + public static void v4FragmentOnResume(android.support.v4.app.Fragment fragment) { + Logger.d(TAG, "v4FragmentOnResume: fragment = " + fragment.getClass().getName()); + PageProvider.get().createOrResumePage(SuperFragment.makeSupport(fragment)); + } + + public static void v4FragmentSetUserVisibleHint(android.support.v4.app.Fragment fragment, boolean isVisibleToUser) { + Logger.d(TAG, "v4FragmentSetUserVisibleHint: fragment = " + fragment.getClass().getName() + ", isVisibleToUser = " + isVisibleToUser); + if (isVisibleToUser) { + PageProvider.get().createOrResumePage(SuperFragment.makeSupport(fragment)); + } + } + + public static void v4FragmentOnHiddenChanged(android.support.v4.app.Fragment fragment, boolean hidden) { + Logger.d(TAG, "v4FragmentOnHiddenChanged: fragment = " + fragment.getClass().getName() + ", hidden = " + hidden); + PageProvider.get().fragmentOnHiddenChanged(SuperFragment.makeSupport(fragment), hidden); + } + + public static void v4FragmentOnDestroyView(android.support.v4.app.Fragment fragment) { + Logger.d(TAG, "v4FragmentOnDestroyView: fragment = " + fragment.getClass().getName()); + PageProvider.get().removePage(SuperFragment.makeSupport(fragment)); + } +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/MenuItemInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/MenuItemInjector.java new file mode 100644 index 00000000..140a758d --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/MenuItemInjector.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + +import android.view.MenuItem; +import android.widget.ActionMenuView; +import android.widget.PopupMenu; +import android.widget.Toolbar; + +public class MenuItemInjector { + private static final String TAG = "MenuItemInjector"; + + private MenuItemInjector() { + } + + public static void toolbarOnMenuItemClick(Toolbar.OnMenuItemClickListener listener, MenuItem item) { + ViewClickProvider.menuItemOnClick(item); + } +/* + public static void toolbarXOnMenuItemClick(androidx.appcompat.widget.Toolbar.OnMenuItemClickListener listener, MenuItem item) { + ViewClickProvider.menuItemOnClick(item); + } + + public static void toolbarSupportOnMenuItemClick(android.support.v7.widget.Toolbar.OnMenuItemClickListener listener, MenuItem item) { + ViewClickProvider.menuItemOnClick(item); + } +*/ + + public static void actionMenuViewOnMenuItemClick(ActionMenuView.OnMenuItemClickListener listener, MenuItem item) { + ViewClickProvider.menuItemOnClick(item); + } + + public static void popupMenuOnMenuItemClick(PopupMenu.OnMenuItemClickListener listener, MenuItem item) { + ViewClickProvider.menuItemOnClick(item); + } + +/* + public static void popupMenuXOnMenuItemClick(androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener listener, MenuItem item) { + ViewClickProvider.menuItemOnClick(item); + } + + public static void popupMenuSupportOnMenuItemClick(android.support.v7.widget.PopupMenu.OnMenuItemClickListener listener, MenuItem item) { + ViewClickProvider.menuItemOnClick(item); + } +*/ + +/* + public static void naviBarViewOnMenuItemClick(com.google.android.material.navigation.NavigationBarView.OnItemSelectedListener listener, MenuItem item) { + ViewClickProvider.menuItemOnClick(item); + } + + public static void tabLayoutSelected(TabLayout.Tab tab) { + ViewClickProvider.viewOnClick(tab.view); + } +*/ + +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/UcWebViewInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/UcWebViewInjector.java new file mode 100644 index 00000000..22d8a2cc --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/UcWebViewInjector.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.track.log.Logger; +import com.growingio.android.sdk.track.modelloader.ModelLoader; +import com.growingio.android.sdk.track.middleware.hybrid.HybridBridge; +import com.uc.webview.export.WebView; + +import java.util.Map; + +public class UcWebViewInjector { + private static final String TAG = "UCWebViewInjector"; + + private static void bridgeForWebView(WebView view) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Autotracker do not initialized successfully"); + return; + } + + boolean result = false; + ModelLoader modelLoader = TrackerContext.get().getRegistry().getModelLoader(HybridBridge.class, Boolean.class); + if (modelLoader != null) { + result = modelLoader.buildLoadData(new HybridBridge(view)).fetcher.executeData(); + } + Logger.d(TAG, "bridgeForWebView: webView = " + view.getClass().getName() + ", result = " + result); + } + + private UcWebViewInjector() { + } + + public static void ucWebViewLoadUrl(WebView webView, String url) { + Logger.d(TAG, "ucWebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url); + bridgeForWebView(webView); + } + + public static void ucWebViewLoadUrl(WebView webView, String url, Map additionalHttpHeaders) { + Logger.d(TAG, "ucWebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url + ", additionalHttpHeaders = " + additionalHttpHeaders); + bridgeForWebView(webView); + } + + public static void ucWebViewLoadData(WebView webView, String data, String mimeType, String encoding) { + Logger.d(TAG, "ucWebViewLoadData: webView = " + webView.getClass().getName()); + bridgeForWebView(webView); + } + + public static void ucWebViewLoadDataWithBaseURL(WebView webView, String baseUrl, String data, String mimeType, String encoding, String historyUrl) { + Logger.d(TAG, "ucWebViewLoadDataWithBaseURL: webView = " + webView.getClass().getName()); + bridgeForWebView(webView); + } + + public static void ucWebViewPostUrl(WebView webView, String url, byte[] postData) { + Logger.d(TAG, "ucWebViewPostUrl: webView = " + webView.getClass().getName()); + bridgeForWebView(webView); + } + +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ViewClickInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ViewClickInjector.java new file mode 100644 index 00000000..f63996bb --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ViewClickInjector.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + +import android.view.View; +import android.widget.AdapterView; +import android.widget.CompoundButton; +import android.widget.ExpandableListView; +import android.widget.RadioGroup; +import android.widget.RatingBar; +import android.widget.SeekBar; +import android.widget.Spinner; + + +public class ViewClickInjector { + private static final String TAG = "ViewClickInjector"; + + private ViewClickInjector() { + } + + public static void viewOnClick(View.OnClickListener listener, View view) { + ViewClickProvider.viewOnClick(view); + } + + public static void seekBarOnSeekBarChange(SeekBar.OnSeekBarChangeListener listener, SeekBar seekBar) { + ViewClickProvider.viewOnClick(seekBar); + } + + public static void adapterViewOnItemClick(AdapterView.OnItemClickListener listener, AdapterView adapterView, View view, int position, long id) { + ViewClickProvider.viewOnClick(view); + } + + public static void adapterViewOnItemSelected(AdapterView.OnItemSelectedListener listener, AdapterView adapterView, View view, int position, long id) { + if (adapterView instanceof Spinner) { + // 目前只需要将Spinner的onItemSelected回调触发点击事件,因为Spinner的元素点击只会触发onItemSelected回调 + ViewClickProvider.viewOnClick(view); + } + } + + public static void expandableListViewOnGroupClick(ExpandableListView.OnGroupClickListener listener, ExpandableListView parent, View v, int groupPosition, long id) { + ViewClickProvider.viewOnClick(v); + } + + public static void expandableListViewOnChildClick(ExpandableListView.OnChildClickListener listener, ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { + ViewClickProvider.viewOnClick(v); + } + + + public static void compoundButtonOnChecked(CompoundButton.OnCheckedChangeListener listener, CompoundButton button, boolean checked) { + ViewClickProvider.viewOnClick(button); + } + + public static void radioGroupOnChecked(RadioGroup.OnCheckedChangeListener listener, RadioGroup radioGroup, int i) { + ViewClickProvider.viewOnClick(radioGroup.findViewById(radioGroup.getCheckedRadioButtonId())); + } + + public static void ratingBarOnRatingBarChange(RatingBar.OnRatingBarChangeListener listener, RatingBar ratingBar, float rating, boolean fromUser) { + if (fromUser) { + ViewClickProvider.viewOnClick(ratingBar); + } + } +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ViewClickProvider.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ViewClickProvider.java new file mode 100644 index 00000000..e604b222 --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/ViewClickProvider.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + +import android.app.Activity; +import android.view.MenuItem; +import android.view.View; + +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.autotrack.util.ClassUtil; +import com.growingio.android.sdk.track.events.AutotrackEventType; +import com.growingio.android.sdk.track.events.ViewElementEvent; +import com.growingio.android.sdk.autotrack.page.Page; +import com.growingio.android.sdk.autotrack.page.PageProvider; +import com.growingio.android.sdk.autotrack.view.ViewHelper; +import com.growingio.android.sdk.autotrack.view.ViewNode; +import com.growingio.android.sdk.track.TrackMainThread; +import com.growingio.android.sdk.track.log.Logger; +import com.growingio.android.sdk.track.providers.ActivityStateProvider; + +class ViewClickProvider { + private static final String TAG = "ViewClickProvider"; + + private ViewClickProvider() { + } + + public static void viewOnClick(View view) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Autotracker do not initialized successfully"); + return; + } + + // 为了防止click事件重复发送 + if (ClassUtil.isDuplicateClick(view)) { + view.hasOnClickListeners(); + Logger.e(TAG, "Duplicate Click"); + return; + } + + ViewNode viewNode = ViewHelper.getClickViewNode(view); + if (viewNode != null) { + Page page = PageProvider.get().findPage(view); + sendClickEvent(page, viewNode); + } else { + Logger.e(TAG, "ViewNode is NULL"); + } + } + + public static void menuItemOnClick(Activity activity, MenuItem menuItem) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Autotracker do not initialized successfully"); + return; + } + if (activity == null || menuItem == null) { + Logger.e(TAG, "menuItemOnClick: activity or menuItem is NULL"); + return; + } + + Page page = PageProvider.get().findPage(activity); + ViewNode viewNode = ViewHelper.getMenuItemViewNode(page, menuItem); + if (viewNode != null) { + sendClickEvent(page, viewNode); + } else { + Logger.e(TAG, "MenuItem ViewNode is NULL"); + } + } + + public static void menuItemOnClick(MenuItem menuItem) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Autotracker do not initialized successfully"); + return; + } + + Activity activity = ActivityStateProvider.get().getForegroundActivity(); + menuItemOnClick(activity, menuItem); + } + + private static void sendClickEvent(Page page, ViewNode viewNode) { + if (page == null) { + Logger.e(TAG, "sendClickEvent page Activity is NULL"); + return; + } + TrackMainThread.trackMain().postEventToTrackMain( + new ViewElementEvent.Builder() + .setEventType(AutotrackEventType.VIEW_CLICK) + .setPath(page.path()) + .setPageShowTimestamp(page.getShowTimestamp()) + .setXpath(viewNode.getXPath()) + .setIndex(viewNode.getIndex()) + .setTextValue(viewNode.getViewContent()) + ); + } +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/WebViewInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/WebViewInjector.java index 367fd479..4bb0ab28 100644 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/WebViewInjector.java +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/WebViewInjector.java @@ -22,8 +22,7 @@ import com.growingio.android.sdk.TrackerContext; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.modelloader.ModelLoader; -import com.growingio.android.sdk.track.modelloader.data.HybridBridge; -import com.growingio.sdk.inject.annotation.Before; +import com.growingio.android.sdk.track.middleware.hybrid.HybridBridge; import java.util.Map; @@ -47,93 +46,28 @@ private static void bridgeForWebView(View view) { private WebViewInjector() { } - @Before(clazz = WebView.class, method = "loadUrl", parameterTypes = {String.class}) public static void webkitWebViewLoadUrl(WebView webView, String url) { Logger.d(TAG, "webkitWebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url); bridgeForWebView(webView); } - @Before(clazz = WebView.class, method = "loadUrl", parameterTypes = {String.class, Map.class}) public static void webkitWebViewLoadUrl(WebView webView, String url, Map additionalHttpHeaders) { Logger.d(TAG, "webkitWebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url + ", additionalHttpHeaders = " + additionalHttpHeaders); bridgeForWebView(webView); } - @Before(clazz = WebView.class, method = "loadData", parameterTypes = {String.class, String.class, String.class}) public static void webkitWebViewLoadData(WebView webView, String data, String mimeType, String encoding) { Logger.d(TAG, "webkitWebViewLoadData: webView = " + webView.getClass().getName()); bridgeForWebView(webView); } - @Before(clazz = WebView.class, method = "loadDataWithBaseURL", parameterTypes = {String.class, String.class, String.class, String.class, String.class}) public static void webkitWebViewLoadDataWithBaseURL(WebView webView, String baseUrl, String data, String mimeType, String encoding, String historyUrl) { Logger.d(TAG, "webkitWebViewLoadDataWithBaseURL: webView = " + webView.getClass().getName()); bridgeForWebView(webView); } - @Before(clazz = WebView.class, method = "postUrl", parameterTypes = {String.class, byte[].class}) public static void webkitWebViewPostUrl(WebView webView, String url, byte[] postData) { Logger.d(TAG, "webkitWebViewPostUrl: webView = " + webView.getClass().getName()); bridgeForWebView(webView); } - - @Before(clazz = com.tencent.smtt.sdk.WebView.class, method = "loadUrl", parameterTypes = {String.class}) - public static void x5WebViewLoadUrl(View webView, String url) { - Logger.d(TAG, "x5WebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url); - bridgeForWebView(webView); - } - - @Before(clazz = com.tencent.smtt.sdk.WebView.class, method = "loadUrl", parameterTypes = {String.class, Map.class}) - public static void x5WebViewLoadUrl(View webView, String url, Map additionalHttpHeaders) { - Logger.d(TAG, "x5WebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url + ", additionalHttpHeaders = " + additionalHttpHeaders); - bridgeForWebView(webView); - } - - @Before(clazz = com.tencent.smtt.sdk.WebView.class, method = "loadData", parameterTypes = {String.class, String.class, String.class}) - public static void x5WebViewLoadData(View webView, String data, String mimeType, String encoding) { - Logger.d(TAG, "x5WebViewLoadData: webView = " + webView.getClass().getName()); - bridgeForWebView(webView); - } - - @Before(clazz = com.tencent.smtt.sdk.WebView.class, method = "loadDataWithBaseURL", parameterTypes = {String.class, String.class, String.class, String.class, String.class}) - public static void x5WebViewLoadDataWithBaseURL(View webView, String baseUrl, String data, String mimeType, String encoding, String historyUrl) { - Logger.d(TAG, "x5WebViewLoadDataWithBaseURL: webView = " + webView.getClass().getName()); - bridgeForWebView(webView); - } - - @Before(clazz = com.tencent.smtt.sdk.WebView.class, method = "postUrl", parameterTypes = {String.class, byte[].class}) - public static void x5WebViewPostUrl(View webView, String url, byte[] postData) { - Logger.d(TAG, "x5WebViewPostUrl: webView = " + webView.getClass().getName()); - bridgeForWebView(webView); - } - - @Before(clazz = com.uc.webview.export.WebView.class, method = "loadUrl", parameterTypes = {String.class}) - public static void ucWebViewLoadUrl(View webView, String url) { - Logger.d(TAG, "ucWebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url); - bridgeForWebView(webView); - } - - @Before(clazz = com.uc.webview.export.WebView.class, method = "loadUrl", parameterTypes = {String.class, Map.class}) - public static void ucWebViewLoadUrl(View webView, String url, Map additionalHttpHeaders) { - Logger.d(TAG, "ucWebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url + ", additionalHttpHeaders = " + additionalHttpHeaders); - bridgeForWebView(webView); - } - - @Before(clazz = com.uc.webview.export.WebView.class, method = "loadData", parameterTypes = {String.class, String.class, String.class}) - public static void ucWebViewLoadData(View webView, String data, String mimeType, String encoding) { - Logger.d(TAG, "ucWebViewLoadData: webView = " + webView.getClass().getName()); - bridgeForWebView(webView); - } - - @Before(clazz = com.uc.webview.export.WebView.class, method = "loadDataWithBaseURL", parameterTypes = {String.class, String.class, String.class, String.class, String.class}) - public static void ucWebViewLoadDataWithBaseURL(View webView, String baseUrl, String data, String mimeType, String encoding, String historyUrl) { - Logger.d(TAG, "ucWebViewLoadDataWithBaseURL: webView = " + webView.getClass().getName()); - bridgeForWebView(webView); - } - - @Before(clazz = com.uc.webview.export.WebView.class, method = "postUrl", parameterTypes = {String.class, byte[].class}) - public static void ucWebViewPostUrl(View webView, String url, byte[] postData) { - Logger.d(TAG, "ucWebViewPostUrl: webView = " + webView.getClass().getName()); - bridgeForWebView(webView); - } } diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/X5WebViewInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/X5WebViewInjector.java new file mode 100644 index 00000000..4bb0a492 --- /dev/null +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/inject/X5WebViewInjector.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.autotrack.inject; + + +import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.track.log.Logger; +import com.growingio.android.sdk.track.modelloader.ModelLoader; +import com.growingio.android.sdk.track.middleware.hybrid.HybridBridge; +import com.tencent.smtt.sdk.WebView; + +import java.util.Map; + +public class X5WebViewInjector { + private static final String TAG = "X5WebViewInjector"; + + private static void bridgeForWebView(WebView view) { + if (!TrackerContext.initializedSuccessfully()) { + Logger.e(TAG, "Autotracker do not initialized successfully"); + return; + } + + boolean result = false; + ModelLoader modelLoader = TrackerContext.get().getRegistry().getModelLoader(HybridBridge.class, Boolean.class); + if (modelLoader != null) { + result = modelLoader.buildLoadData(new HybridBridge(view)).fetcher.executeData(); + } + Logger.d(TAG, "bridgeForWebView: webView = " + view.getClass().getName() + ", result = " + result); + } + + private X5WebViewInjector() { + } + + public static void x5WebViewLoadUrl(WebView webView, String url) { + Logger.d(TAG, "x5WebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url); + bridgeForWebView(webView); + } + + public static void x5WebViewLoadUrl(WebView webView, String url, Map additionalHttpHeaders) { + Logger.d(TAG, "x5WebViewLoadUrl: webView = " + webView.getClass().getName() + ", url = " + url + ", additionalHttpHeaders = " + additionalHttpHeaders); + bridgeForWebView(webView); + } + + public static void x5WebViewLoadData(WebView webView, String data, String mimeType, String encoding) { + Logger.d(TAG, "x5WebViewLoadData: webView = " + webView.getClass().getName()); + bridgeForWebView(webView); + } + + public static void x5WebViewLoadDataWithBaseURL(WebView webView, String baseUrl, String data, String mimeType, String encoding, String historyUrl) { + Logger.d(TAG, "x5WebViewLoadDataWithBaseURL: webView = " + webView.getClass().getName()); + bridgeForWebView(webView); + } + + public static void x5WebViewPostUrl(WebView webView, String url, byte[] postData) { + Logger.d(TAG, "x5WebViewPostUrl: webView = " + webView.getClass().getName()); + bridgeForWebView(webView); + } +} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/FragmentInjector.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/FragmentInjector.java deleted file mode 100644 index 0a1957ac..00000000 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/FragmentInjector.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.android.sdk.autotrack.page; - -import com.growingio.android.sdk.track.log.Logger; -import com.growingio.sdk.inject.annotation.AfterSuper; - -public class FragmentInjector { - private static final String TAG = "FragmentInjector"; - - private FragmentInjector() { - } - - @AfterSuper(clazz = android.app.Fragment.class, method = "onResume") - @AfterSuper(clazz = android.app.DialogFragment.class, method = "onResume") - @AfterSuper(clazz = android.app.ListFragment.class, method = "onResume") - @AfterSuper(clazz = android.preference.PreferenceFragment.class, method = "onResume") - @AfterSuper(clazz = android.webkit.WebViewFragment.class, method = "onResume") - public static void systemFragmentOnResume(android.app.Fragment fragment) { - Logger.d(TAG, "systemFragmentOnResume: fragment = " + fragment.getClass().getName()); - PageProvider.get().createOrResumePage(SuperFragment.make(fragment)); - } - - @AfterSuper(clazz = android.app.Fragment.class, method = "setUserVisibleHint", parameterTypes = {boolean.class}) - @AfterSuper(clazz = android.app.DialogFragment.class, method = "setUserVisibleHint", parameterTypes = {boolean.class}) - @AfterSuper(clazz = android.app.ListFragment.class, method = "setUserVisibleHint", parameterTypes = {boolean.class}) - @AfterSuper(clazz = android.preference.PreferenceFragment.class, method = "setUserVisibleHint", parameterTypes = {boolean.class}) - @AfterSuper(clazz = android.webkit.WebViewFragment.class, method = "setUserVisibleHint", parameterTypes = {boolean.class}) - public static void systemFragmentSetUserVisibleHint(android.app.Fragment fragment, boolean isVisibleToUser) { - Logger.d(TAG, "systemFragmentSetUserVisibleHint: fragment = " + fragment.getClass().getName() + ", isVisibleToUser = " + isVisibleToUser); - if (isVisibleToUser) { - PageProvider.get().createOrResumePage(SuperFragment.make(fragment)); - } - } - - @AfterSuper(clazz = android.app.Fragment.class, method = "onHiddenChanged", parameterTypes = {boolean.class}) - @AfterSuper(clazz = android.app.DialogFragment.class, method = "onHiddenChanged", parameterTypes = {boolean.class}) - @AfterSuper(clazz = android.app.ListFragment.class, method = "onHiddenChanged", parameterTypes = {boolean.class}) - @AfterSuper(clazz = android.preference.PreferenceFragment.class, method = "onHiddenChanged", parameterTypes = {boolean.class}) - @AfterSuper(clazz = android.webkit.WebViewFragment.class, method = "onHiddenChanged", parameterTypes = {boolean.class}) - public static void systemFragmentOnHiddenChanged(android.app.Fragment fragment, boolean hidden) { - Logger.d(TAG, "systemFragmentOnHiddenChanged: fragment = " + fragment.getClass().getName() + ", hidden" + hidden); - PageProvider.get().fragmentOnHiddenChanged(SuperFragment.make(fragment), hidden); - } - - @AfterSuper(clazz = android.app.Fragment.class, method = "onDestroyView") - @AfterSuper(clazz = android.app.DialogFragment.class, method = "onDestroyView") - @AfterSuper(clazz = android.app.ListFragment.class, method = "onDestroyView") - @AfterSuper(clazz = android.preference.PreferenceFragment.class, method = "onDestroyView") - @AfterSuper(clazz = android.webkit.WebViewFragment.class, method = "onDestroyView") - public static void systemFragmentOnDestroyView(android.app.Fragment fragment) { - Logger.d(TAG, "systemFragmentOnDestroyView: fragment = " + fragment.getClass().getName()); - PageProvider.get().removePage(SuperFragment.make(fragment)); - } - - @AfterSuper(clazz = android.support.v4.app.Fragment.class, method = "onResume") - public static void v4FragmentOnResume(android.support.v4.app.Fragment fragment) { - Logger.d(TAG, "v4FragmentOnResume: fragment = " + fragment.getClass().getName()); - PageProvider.get().createOrResumePage(SuperFragment.makeSupport(fragment)); - } - - @AfterSuper(clazz = android.support.v4.app.Fragment.class, method = "setUserVisibleHint", parameterTypes = {boolean.class}) - public static void v4FragmentSetUserVisibleHint(android.support.v4.app.Fragment fragment, boolean isVisibleToUser) { - Logger.d(TAG, "v4FragmentSetUserVisibleHint: fragment = " + fragment.getClass().getName() + ", isVisibleToUser = " + isVisibleToUser); - if (isVisibleToUser) { - PageProvider.get().createOrResumePage(SuperFragment.makeSupport(fragment)); - } - } - - @AfterSuper(clazz = android.support.v4.app.Fragment.class, method = "onHiddenChanged", parameterTypes = {boolean.class}) - public static void v4FragmentOnHiddenChanged(android.support.v4.app.Fragment fragment, boolean hidden) { - Logger.d(TAG, "v4FragmentOnHiddenChanged: fragment = " + fragment.getClass().getName() + ", hidden = " + hidden); - PageProvider.get().fragmentOnHiddenChanged(SuperFragment.makeSupport(fragment), hidden); - } - - @AfterSuper(clazz = android.support.v4.app.Fragment.class, method = "onDestroyView") - public static void v4FragmentOnDestroyView(android.support.v4.app.Fragment fragment) { - Logger.d(TAG, "v4FragmentOnDestroyView: fragment = " + fragment.getClass().getName()); - PageProvider.get().removePage(SuperFragment.makeSupport(fragment)); - } - - @AfterSuper(clazz = androidx.fragment.app.Fragment.class, method = "onResume") - public static void androidxFragmentOnResume(androidx.fragment.app.Fragment fragment) { - Logger.d(TAG, "androidxFragmentOnResume: fragment = " + fragment.getClass().getName()); - PageProvider.get().createOrResumePage(SuperFragment.makeX(fragment)); - } - - @AfterSuper(clazz = androidx.fragment.app.Fragment.class, method = "setUserVisibleHint", parameterTypes = {boolean.class}) - public static void androidxFragmentSetUserVisibleHint(androidx.fragment.app.Fragment fragment, boolean isVisibleToUser) { - Logger.d(TAG, "androidxFragmentSetUserVisibleHint: fragment = " + fragment.getClass().getName() + ", isVisibleToUser = " + isVisibleToUser); - if (isVisibleToUser) { - PageProvider.get().createOrResumePage(SuperFragment.makeX(fragment)); - } - } - - @AfterSuper(clazz = androidx.fragment.app.Fragment.class, method = "onHiddenChanged", parameterTypes = {boolean.class}) - public static void androidxFragmentOnHiddenChanged(androidx.fragment.app.Fragment fragment, boolean hidden) { - Logger.d(TAG, "androidxFragmentOnHiddenChanged: fragment = " + fragment.getClass().getName() + ", hidden" + hidden); - PageProvider.get().fragmentOnHiddenChanged(SuperFragment.makeX(fragment), hidden); - } - - @AfterSuper(clazz = androidx.fragment.app.Fragment.class, method = "onDestroyView") - public static void androidxFragmentOnDestroyView(androidx.fragment.app.Fragment fragment) { - Logger.d(TAG, "androidxFragmentOnDestroyView: fragment = " + fragment.getClass().getName()); - PageProvider.get().removePage(SuperFragment.makeX(fragment)); - } - -} diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/util/ClassUtil.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/util/ClassUtil.java index bb2eebd0..b2fa7bbf 100644 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/util/ClassUtil.java +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/util/ClassUtil.java @@ -18,7 +18,11 @@ import android.annotation.TargetApi; import android.os.Build; +import android.os.SystemClock; import android.text.TextUtils; +import android.view.View; + +import com.growingio.android.sdk.autotrack.R; @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) @@ -35,5 +39,23 @@ public static String getSimpleClassName(Class clazz) { } return name; } + + public static boolean isDuplicateClick(View view) { + if (view == null) { + return false; + } + try { + String timeStamp = (String) view.getTag(R.id.growing_tracker_duplicate_click_timestamp); + if (!TextUtils.isEmpty(timeStamp)) { + long lastTime = Long.parseLong(timeStamp); + if (SystemClock.elapsedRealtime() - lastTime <= 200) { + return true; + } + } + view.setTag(R.id.growing_tracker_duplicate_click_timestamp, String.valueOf(SystemClock.elapsedRealtime())); + } catch (Exception ignored) { + } + return false; + } } diff --git a/growingio-autotracker-core/src/main/res/values/ids.xml b/growingio-autotracker-core/src/main/res/values/ids.xml index a82a805d..7baf211f 100644 --- a/growingio-autotracker-core/src/main/res/values/ids.xml +++ b/growingio-autotracker-core/src/main/res/values/ids.xml @@ -7,4 +7,5 @@ + \ No newline at end of file diff --git a/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/click/ViewClickTest.java b/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/click/ViewClickTest.java index 95f7962d..3f215795 100644 --- a/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/click/ViewClickTest.java +++ b/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/click/ViewClickTest.java @@ -25,6 +25,8 @@ import com.google.common.truth.Truth; import com.growingio.android.sdk.TrackerContext; import com.growingio.android.sdk.autotrack.RobolectricActivity; +import com.growingio.android.sdk.autotrack.inject.DialogInjector; +import com.growingio.android.sdk.autotrack.inject.ViewClickInjector; import com.growingio.android.sdk.track.events.ViewElementEvent; import com.growingio.android.sdk.track.providers.ActivityStateProvider; @@ -78,9 +80,8 @@ public void injectTest() { }) .create(); testDialog.show(); - ViewClickInjector.alertDialogShow(testDialog); - ViewClickInjector.dialogOnClick((dialog, which) -> { - + DialogInjector.alertDialogShow(testDialog); + DialogInjector.dialogOnClick((dialog, which) -> { }, testDialog, -1); } } diff --git a/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/hybrid/HybridTest.java b/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/hybrid/HybridTest.java index 4ea18f2e..f87abc80 100644 --- a/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/hybrid/HybridTest.java +++ b/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/hybrid/HybridTest.java @@ -24,7 +24,9 @@ import com.growingio.android.sdk.TrackerContext; import com.growingio.android.sdk.autotrack.RobolectricActivity; +import com.growingio.android.sdk.autotrack.inject.UcWebViewInjector; import com.growingio.android.sdk.autotrack.inject.WebViewInjector; +import com.growingio.android.sdk.autotrack.inject.X5WebViewInjector; import org.junit.Before; import org.junit.Test; @@ -58,18 +60,18 @@ public void webInjectTest() { WebViewInjector.webkitWebViewPostUrl(webView, "https://www.baidu.com/", null); com.uc.webview.export.WebView ucWebView = new com.uc.webview.export.WebView(activity); - WebViewInjector.ucWebViewLoadUrl(ucWebView, "https://www.baidu.com/"); - WebViewInjector.ucWebViewLoadUrl(ucWebView, "https://www.baidu.com/", new HashMap<>()); - WebViewInjector.ucWebViewLoadData(ucWebView, "", "text", "UTF8"); - WebViewInjector.ucWebViewLoadDataWithBaseURL(ucWebView, "https://www.baidu.com/", "

", "text", "UTF8", "https://www/growingio.com/"); - WebViewInjector.ucWebViewPostUrl(ucWebView, "https://www.baidu.com/", null); + UcWebViewInjector.ucWebViewLoadUrl(ucWebView, "https://www.baidu.com/"); + UcWebViewInjector.ucWebViewLoadUrl(ucWebView, "https://www.baidu.com/", new HashMap<>()); + UcWebViewInjector.ucWebViewLoadData(ucWebView, "", "text", "UTF8"); + UcWebViewInjector.ucWebViewLoadDataWithBaseURL(ucWebView, "https://www.baidu.com/", "

", "text", "UTF8", "https://www/growingio.com/"); + UcWebViewInjector.ucWebViewPostUrl(ucWebView, "https://www.baidu.com/", null); com.tencent.smtt.sdk.WebView x5WebView = new com.tencent.smtt.sdk.WebView(activity); - WebViewInjector.x5WebViewLoadUrl(x5WebView, "https://www.baidu.com/"); - WebViewInjector.x5WebViewLoadUrl(x5WebView, "https://www.baidu.com/", new HashMap<>()); - WebViewInjector.x5WebViewLoadData(x5WebView, "", "text", "UTF8"); - WebViewInjector.x5WebViewLoadDataWithBaseURL(x5WebView, "https://www.baidu.com/", "

", "text", "UTF8", "https://www/growingio.com/"); - WebViewInjector.x5WebViewPostUrl(x5WebView, "https://www.baidu.com/", null); + X5WebViewInjector.x5WebViewLoadUrl(x5WebView, "https://www.baidu.com/"); + X5WebViewInjector.x5WebViewLoadUrl(x5WebView, "https://www.baidu.com/", new HashMap<>()); + X5WebViewInjector.x5WebViewLoadData(x5WebView, "", "text", "UTF8"); + X5WebViewInjector.x5WebViewLoadDataWithBaseURL(x5WebView, "https://www.baidu.com/", "

", "text", "UTF8", "https://www/growingio.com/"); + X5WebViewInjector.x5WebViewPostUrl(x5WebView, "https://www.baidu.com/", null); } } diff --git a/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/page/PageTest.java b/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/page/PageTest.java index bd2948ad..e0dd4c5e 100644 --- a/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/page/PageTest.java +++ b/growingio-autotracker-core/src/test/java/com/growingio/android/sdk/autotrack/page/PageTest.java @@ -32,6 +32,7 @@ import com.growingio.android.sdk.TrackerContext; import com.growingio.android.sdk.autotrack.IgnorePolicy; import com.growingio.android.sdk.autotrack.RobolectricActivity; +import com.growingio.android.sdk.autotrack.inject.FragmentInjector; import com.growingio.android.sdk.track.providers.ActivityStateProvider; import com.growingio.android.sdk.track.providers.SessionProvider; diff --git a/growingio-autotracker-gradle-plugin/.gitignore b/growingio-autotracker-gradle-plugin/.gitignore deleted file mode 100644 index d849a609..00000000 --- a/growingio-autotracker-gradle-plugin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -generate/ diff --git a/growingio-autotracker-gradle-plugin/build.gradle b/growingio-autotracker-gradle-plugin/build.gradle deleted file mode 100644 index cddca44d..00000000 --- a/growingio-autotracker-gradle-plugin/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -apply plugin: 'java-gradle-plugin' -apply plugin: 'jacoco' - -jar { - manifest { - attributes( - "Manifest-Version": "1.0", - "Gradle-Plugin-Version": releaseConfiguration.releaseVersion - ) - } -} - -test { - finalizedBy jacocoTestReport // report is always generated after tests run -} - -dependencies { - testImplementation libraries.test.junit - testImplementation libraries.test.mockito_core - testImplementation libraries.test.powermock_api_mockito2 - testImplementation libraries.test.powermock_module_junit4 - testImplementation libraries.test.powermock_module_junit4_rule - testImplementation libraries.test.truth - testImplementation libraries.asm.asm - testImplementation libraries.asm.asm_commons - testImplementation libraries.asm.asm_util - testImplementation libraries.asm.asm_tree - testImplementation libraries.android.gradle_plugin - - compileOnly gradleApi() - compileOnly libraries.android.gradle_plugin - //implementation "com.android.tools.build:gradle:7.0.3" -} - -apply from: "${rootProject.projectDir}/gradle/publishMaven.gradle" - - diff --git a/growingio-autotracker-gradle-plugin/gradle.properties b/growingio-autotracker-gradle-plugin/gradle.properties deleted file mode 100644 index 13537636..00000000 --- a/growingio-autotracker-gradle-plugin/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -POM_NAME=autotracker-gradle-plugin -POM_ARTIFACT_ID=autotracker-gradle-plugin -POM_PACKAGING=jar -POM_DESCRIPTION=GrowingIO Android SDK Gradle Plugin. \ No newline at end of file diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/AutotrackExtension.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/AutotrackExtension.java deleted file mode 100644 index c906dc4c..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/AutotrackExtension.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack; - -public class AutotrackExtension { - private boolean mIsLogEnabled = false; - private boolean mIsDevelopment = true; - private boolean mExcludeOfficialPackages = true; - private String[] mExcludePackages; - - public boolean isLogEnabled() { - return mIsLogEnabled; - } - - public void setLogEnabled(boolean logEnabled) { - mIsLogEnabled = logEnabled; - } - - public boolean isDevelopment() { - return mIsDevelopment; - } - - public void setDevelopment(boolean development) { - mIsDevelopment = development; - } - - public String[] getExcludePackages() { - return mExcludePackages; - } - - public void setExcludePackages(String[] excludePackages) { - mExcludePackages = excludePackages; - } - - public boolean isExcludeOfficialPackages() { - return mExcludeOfficialPackages; - } - - public void setExcludeOfficialPackages(boolean mExcludeOfficialPackages) { - this.mExcludeOfficialPackages = mExcludeOfficialPackages; - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/AutotrackPlugin.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/AutotrackPlugin.java deleted file mode 100644 index be65b618..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/AutotrackPlugin.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack; - -import com.android.build.gradle.AppExtension; -import com.growingio.sdk.plugin.autotrack.compile.AutotrackBuildException; -import com.growingio.sdk.plugin.autotrack.compile.AutotrackTransform; -import com.growingio.sdk.plugin.autotrack.compile.ClassRewriter; -import com.growingio.sdk.plugin.autotrack.utils.ReflectUtil; - -import org.gradle.api.Action; -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.result.DependencyResult; -import org.gradle.api.artifacts.result.ResolvedDependencyResult; -import org.gradle.api.logging.Logger; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.List; -import java.util.jar.JarInputStream; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class AutotrackPlugin implements Plugin { - private Logger mLogger; - - @Override - public void apply(Project project) { - mLogger = project.getLogger(); - AutotrackExtension extension = project.getExtensions().create("growingAutotracker", AutotrackExtension.class); - final AppExtension android = project.getExtensions().findByType(AppExtension.class); - final AutotrackTransform transform = new AutotrackTransform(project); - android.registerTransform(transform); - - project.afterEvaluate(new Action() { - @Override - public void execute(Project project) { - checkJavaVersion(); - if (!extension.isDevelopment()) { - checkAutotrackDependency(project); - } - onGotAndroidJarFiles(android, transform); - } - }); - } - - private void checkJavaVersion() { - String version = System.getProperty("java.version"); - Matcher matcher = Pattern.compile("^(1\\.[0-9]+)\\..*").matcher(version); - if (matcher.find()) { - String versionNum = matcher.group(1); - try { - int num = (int) (Float.parseFloat(versionNum) * 10); - if (num < 18) { - throw new RuntimeException("GrowingIO autotracker gradle plugin 要求编译环境的JDK为1.8及以上"); - } - } catch (NumberFormatException e) { - // ignore - } - return; - } - mLogger.info("GIO: check java version failed"); - } - - private void checkAutotrackDependency(Project project) { - for (Configuration configuration : project.getConfigurations()) { - if ("releaseRuntimeClasspath".equals(configuration.getName())) { - for (DependencyResult dependency : configuration.getIncoming().getResolutionResult().getRoot().getDependencies()) { - if (findAutotrackDependency(dependency)) { - return; - } - } - } - } - throw new RuntimeException("未发现autotrack依赖,请参考官方文档添加依赖"); - } - - private boolean findAutotrackDependency(DependencyResult dependency) { - String autotrackDependency = "com.growingio.android:autotracker-core:"; - if (dependency.getRequested().getDisplayName().startsWith(autotrackDependency)) { - String sdkVersion = dependency.getRequested().getDisplayName().split(":")[2]; - String pluginVersion = getPluginVersion(); - if (sdkVersion.equals(pluginVersion)) { - return true; - } else { - throw new AutotrackBuildException("您的autotracker-gradle-plugin版本号[" + pluginVersion + "]和autotracker版本号[" + sdkVersion + "]不一致,请在build.gradle文件中修改"); - } - } - - if (dependency instanceof ResolvedDependencyResult) { - for (DependencyResult result : ((ResolvedDependencyResult) dependency).getSelected().getDependencies()) { - if (findAutotrackDependency(result)) { - return true; - } - } - } - return false; - } - - public String getPluginVersion() { - try { - String jarPath = URLDecoder.decode(new File(ClassRewriter.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getCanonicalPath()); - try (JarInputStream inputStream = new JarInputStream(new FileInputStream(jarPath))) { - String pluginVersion = inputStream.getManifest().getMainAttributes().getValue("Gradle-Plugin-Version"); - if (pluginVersion == null) { - throw new AutotrackBuildException("Cannot find GrowingIO autotrack gradle plugin version"); - } - return pluginVersion; - } - } catch (IOException e) { - throw new AutotrackBuildException("Cannot find GrowingIO autotrack gradle plugin version"); - } - } - - private void onGotAndroidJarFiles(AppExtension appExtension, AutotrackTransform transform) { - checkJackStatus(appExtension); - try { - List files = appExtension.getBootClasspath(); - if (files == null || files.isEmpty()) { - throw new RuntimeException("GIO: get android.jar failed"); - } - List androidJars = new ArrayList<>(); - for (File file : files) { - androidJars.add(file.toURL()); - } - transform.setAndroidJars(androidJars); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("GIO: get android.jar failed"); - } - } - - private void checkJackStatus(AppExtension appExtension) { - // 高版本Gradle没有这个特性了 - // config.getJackOptions().isEnabled(); - String errorMessage = null; - try { - Method configMethod = ReflectUtil.getMethod(AppExtension.class, "getDefaultConfig"); - if (configMethod == null) - return; - Object config = configMethod.invoke(appExtension); - Object jackOptions = ReflectUtil.findField(config, "jackOptions"); - if (jackOptions == null) - return; - java.lang.reflect.Method isEnable = ReflectUtil.getMethod(jackOptions.getClass(), "isEnabled"); - if (isEnable == null) - return; - boolean jackEnabled = (boolean) isEnable.invoke(jackOptions); - if (jackEnabled) { - errorMessage = "\n========= GIO无埋点SDK不支持Jack编译器\n" - + "========= 由于TransformApi不支持Jack编译器且Jack项目已被Google废弃。请确保没有以下配置:\n" - + "========= jackOptions {\n" - + "========= enabled true\n" - + "========= }\n"; - } - } catch (Exception e) { - // ignore - System.out.println(e.getMessage()); - } - if (errorMessage != null) { - throw new IllegalStateException(errorMessage); - } - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackBuildException.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackBuildException.java deleted file mode 100644 index 033b2da4..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackBuildException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile; - -public class AutotrackBuildException extends RuntimeException { - public AutotrackBuildException(String message) { - super(message); - } - - public AutotrackBuildException(Exception e) { - super(e); - } - - public AutotrackBuildException(String message, Exception e) { - super(message, e); - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackTransform.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackTransform.java deleted file mode 100644 index 9c8f9b95..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackTransform.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile; - -import com.android.build.api.transform.Context; -import com.android.build.api.transform.DirectoryInput; -import com.android.build.api.transform.Format; -import com.android.build.api.transform.JarInput; -import com.android.build.api.transform.QualifiedContent; -import com.android.build.api.transform.Status; -import com.android.build.api.transform.Transform; -import com.android.build.api.transform.TransformInput; -import com.android.build.api.transform.TransformOutputProvider; -import com.android.build.gradle.internal.pipeline.TransformManager; -import com.growingio.sdk.plugin.autotrack.AutotrackExtension; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.gradle.api.Project; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; - -@SuppressWarnings("ResultOfMethodCallIgnored") -public class AutotrackTransform extends Transform { - - private Log mLog; - private List mAndroidJars; - - private TransformOutputProvider mOutputProvider; - private DirectoryInput mDirectoryInput; - private ClassRewriter mClassRewriter; - private BuildExecutor mExecutor; - private final AutotrackExtension mAutotrackExtension; - - public AutotrackTransform(final Project project) { - mAutotrackExtension = project.getExtensions().getByType(AutotrackExtension.class); - } - - public void setAndroidJars(List androidJars) { - this.mAndroidJars = androidJars; - } - - @Override - public String getName() { - return "growingAutotracker"; - } - - @Override - public Set getInputTypes() { - return TransformManager.CONTENT_CLASS; - } - - @Override - public Set getScopes() { - return TransformManager.SCOPE_FULL_PROJECT; - } - - @Override - public boolean isIncremental() { - return true; - } - - private void log(String msg) { - mLog.info(msg); - } - - @Override - public void transform(Context context, Collection inputs, Collection referencedInputs, final TransformOutputProvider outputProvider, final boolean isIncremental) throws IOException, InterruptedException { - if (mAutotrackExtension.isLogEnabled()) { - mLog = new SystemLog(); - } else { - mLog = new ErrorLog(); - } - - mLog.info("transform task start: isIncremental = " + isIncremental); - mExecutor = BuildExecutor.createExecutor(); - ArrayList urlList = new ArrayList<>(); - for (TransformInput input : inputs) { - for (DirectoryInput directoryInput : input.getDirectoryInputs()) { - urlList.add(directoryInput.getFile().toURL()); - } - - for (JarInput jarInput : input.getJarInputs()) { - urlList.add(jarInput.getFile().toURL()); - } - } - urlList.addAll(mAndroidJars); - URL[] urlArray = new URL[urlList.size()]; - urlList.toArray(urlArray); - URLClassLoader classLoader = new URLClassLoader(urlArray); - mOutputProvider = outputProvider; - mClassRewriter = new ClassRewriter(mLog, classLoader, mAutotrackExtension.getExcludePackages(), mAutotrackExtension.isExcludeOfficialPackages()); - - if (!isIncremental) { - // 1. 非增量模式下删除上次所有的编译产物 - try { - outputProvider.deleteAll(); - } catch (IOException e) { - mLog.error("删除上次的编译产物失败: " + e.getMessage()); - throw e; - } - } - for (TransformInput transformInput : inputs) { - for (DirectoryInput directoryInput : transformInput.getDirectoryInputs()) { - mDirectoryInput = directoryInput; - if (isIncremental) { - // 2. 增量模式下处理directory - transformInputDirectoryIncrement(); - } else { - // 3. 非增量模式处理directory - transformInputDirectoryNoIncrement(); - } - } - mDirectoryInput = null; - for (final JarInput jarInput : transformInput.getJarInputs()) { - mExecutor.execute(new Runnable() { - @Override - public void run() { - // 4. 处理jar包, 整个jar包暂时在同一个线程中处理, jar包更改的概率很小, 不会影响instant run - transformJar(jarInput, isIncremental); - } - }); - } - } - - mLog.info("has submit all gio task, and wait for all task complete"); - mExecutor.waitAllTaskComplete(); - mLog.info("transform task completed"); - - // reset tmp variable - if (classLoader != null) { - classLoader.close(); - } - this.mOutputProvider = null; - this.mDirectoryInput = null; - this.mClassRewriter = null; - this.mExecutor = null; - } - - private void transformJar(JarInput jarInput, boolean isIncremental) { - File out = mOutputProvider.getContentLocation( - jarInput.getName(), jarInput.getContentTypes(), jarInput.getScopes(), Format.JAR); - out.getParentFile().mkdirs(); - if (isIncremental && jarInput.getStatus() == Status.NOTCHANGED) { - return; - } - if (out.exists()) { - FileUtils.deleteQuietly(out); - } - if (isIncremental && jarInput.getStatus() == Status.REMOVED) { - return; - } - log("transforming " + jarInput.getFile() + " to jar: " + out); - try (ZipOutputStream outJar = new ZipOutputStream(new FileOutputStream(out))) { - try (ZipInputStream jar = new ZipInputStream(new FileInputStream(jarInput.getFile()))) { - ZipEntry entry; - while ((entry = jar.getNextEntry()) != null) { - ZipEntry outEntry = copyEntry(entry); - outJar.putNextEntry(outEntry); - if (!entry.isDirectory() - && !entry.getName().equals("module-info.class") - && entry.getName().endsWith(".class")) { - if (mClassRewriter.transformClass(jar, outJar)) { - log("transforming jar entry: " + entry.getName()); - } - } else { - IOUtils.copy(jar, outJar); - } - } - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void transformInputDirectoryIncrement() { - Map changedFiles = mDirectoryInput.getChangedFiles(); - for (File file : changedFiles.keySet()) { - Status status = changedFiles.get(file); - actionOnFile(file, status); - } - } - - // 5. 处理directoryInput中的文件, 可以单个在子线程中处理 - private void actionOnFile(final File file, Status status) { - File outDir = mOutputProvider.getContentLocation(mDirectoryInput.getName(), - mDirectoryInput.getContentTypes(), mDirectoryInput.getScopes(), Format.DIRECTORY); - outDir.mkdirs(); - final String outDirPath = outDir.getAbsolutePath(); - final String inputDirPath = mDirectoryInput.getFile().getAbsolutePath(); - final String relativeClassPath = file.getAbsolutePath().substring(inputDirPath.length()); - mExecutor.execute(() -> { - File outFile = new File(outDirPath, relativeClassPath); - if (status == Status.REMOVED) { - FileUtils.deleteQuietly(outFile); - } else if (status != Status.NOTCHANGED) { - if (relativeClassPath.endsWith(".class")) { - if (mClassRewriter.transformClassFile(file, outFile)) { - log("transformed class file " + file + " to " + outFile); - return; - } - } - try { - FileUtils.copyFile(file, outFile); - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - } - - private void transformInputDirectoryNoIncrement() { - for (File classFile : com.android.utils.FileUtils.getAllFiles(mDirectoryInput.getFile())) { - actionOnFile(classFile, Status.ADDED); - } - } - - private ZipEntry copyEntry(ZipEntry entry) { - ZipEntry newEntry = new ZipEntry(entry.getName()); - newEntry.setComment(entry.getComment()); - newEntry.setExtra(entry.getExtra()); - return newEntry; - } - -} \ No newline at end of file diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/BuildExecutor.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/BuildExecutor.java deleted file mode 100644 index 09fab1c9..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/BuildExecutor.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile; - -import com.android.annotations.VisibleForTesting; -import com.android.ide.common.internal.WaitableExecutor; - -import org.jetbrains.annotations.NotNull; - -import java.lang.reflect.Method; -import java.util.concurrent.Callable; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.ForkJoinTask; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -abstract public class BuildExecutor implements Executor { - - private static boolean sHasWaitableExecutor; - - static { - try { - // 2.3.3版本下execute(Ljava/util/concurrent/Callable;)不是ForkJoinTask - Class waitableExecutorClazz = Class.forName("com.android.ide.common.internal.WaitableExecutor"); - Method method = waitableExecutorClazz.getMethod("execute", Callable.class); - sHasWaitableExecutor = method.getReturnType() == ForkJoinTask.class; - } catch (Throwable e) { - sHasWaitableExecutor = false; - } - } - - - public abstract void waitAllTaskComplete() throws InterruptedException; - - public static BuildExecutor createExecutor() { - return sHasWaitableExecutor ? new BuildWaitableExecutor() : new CacheWaitableExecutor(); - } - - @VisibleForTesting - static class CacheWaitableExecutor extends BuildExecutor { - private final ThreadPoolExecutor mPoolExecutor; - private final AtomicInteger mWaitingTaskCount = new AtomicInteger(0); - private ThreadFactory mDefaultThreadFactory = Executors.defaultThreadFactory(); - private Throwable mThrowable; - private final Object mLock = new Object(); - - CacheWaitableExecutor() { - int processorsNum = Runtime.getRuntime().availableProcessors(); - mPoolExecutor = new ThreadPoolExecutor(processorsNum, - processorsNum * 2, - 60L, - TimeUnit.SECONDS, - new LinkedBlockingQueue<>()) { - @Override - protected void afterExecute(Runnable runnable, Throwable th) { - if (mThrowable != null) { - return; - } - if (th != null || mWaitingTaskCount.decrementAndGet() == 0) { - synchronized (mLock) { - if (mThrowable != null) { - return; - } - if (th != null) { - getQueue().clear(); - mThrowable = th; - } - mLock.notifyAll(); - } - } - } - }; - mPoolExecutor.setThreadFactory(runnable -> { - Thread result = mDefaultThreadFactory.newThread(runnable); - result.setUncaughtExceptionHandler((thread, th) -> { - // ignore: 仅仅为了消除默认handler的日志 - }); - return result; - }); - } - - @Override - public void waitAllTaskComplete() throws InterruptedException { - checkAndThrow(); - synchronized (mLock) { - checkAndThrow(); - mPoolExecutor.shutdown(); - if (mWaitingTaskCount.get() != 0) { - mLock.wait(); - checkAndThrow(); - } - } - mPoolExecutor.awaitTermination(0, TimeUnit.MILLISECONDS); - } - - private void checkAndThrow() { - if (mThrowable instanceof RuntimeException) { - throw (RuntimeException) mThrowable; - } else if (mThrowable != null) { - throw new RuntimeException(mThrowable); - } - } - - @Override - public void execute(@NotNull Runnable runnable) { - mWaitingTaskCount.incrementAndGet(); - mPoolExecutor.execute(runnable); - } - } - - - @VisibleForTesting - static class BuildWaitableExecutor extends BuildExecutor { - - private final WaitableExecutor mExecutor = WaitableExecutor.useGlobalSharedThreadPool(); - - @Override - public void waitAllTaskComplete() throws InterruptedException { - mExecutor.waitForTasksWithQuickFail(true); - } - - @Override - public void execute(@NotNull final Runnable runnable) { - mExecutor.execute(() -> { - runnable.run(); - return null; - }); - } - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/ClassRewriter.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/ClassRewriter.java deleted file mode 100644 index 9807109e..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/ClassRewriter.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile; - -import com.growingio.sdk.plugin.autotrack.compile.visitor.ContextClassVisitor; -import com.growingio.sdk.plugin.autotrack.compile.visitor.DesugaredClassVisitor; -import com.growingio.sdk.plugin.autotrack.compile.visitor.DesugaringClassVisitor; -import com.growingio.sdk.plugin.autotrack.compile.visitor.InjectAroundClassVisitor; -import com.growingio.sdk.plugin.autotrack.compile.visitor.InjectSuperClassVisitor; - -import org.apache.commons.io.IOUtils; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class ClassRewriter { - private final Log mLog; - private final ClassLoader mClassLoader; - private final String[] mUserExcludePackages; - private final boolean mExcludeOfficial; - private static final String[] EXCLUDED_PACKAGES = new String[]{ - "com/growingio/android/", - "com/growingio/giokit/", - "com/alibaba/mobileim/extra/xblink/webview", - "com/alibaba/sdk/android/feedback/xblink", - "com/tencent/smtt", - "com/baidu/location", - "com/blueware/agent/android", - "com/oneapm/agent/android", - "com/networkbench/agent", - "android/taobao/windvane/webview", - }; - - private static final String[] OFFICIAL_PACKAGES = new String[]{ - "android/arch/", - "com/google/", - "javax/", - "io/rectivex/rxjava", - "org/jetbrains/kotlin", - -// "com/squareup/", -// "org/apache", - }; - - - public ClassRewriter(final Log log, ClassLoader classLoader, String[] userExcludePackages, boolean excludeOfficial) { - mLog = log; - mClassLoader = classLoader; - mExcludeOfficial = excludeOfficial; - if (userExcludePackages == null) { - mUserExcludePackages = new String[0]; - } else { - mUserExcludePackages = new String[userExcludePackages.length]; - for (int i = 0; i < userExcludePackages.length; i++) { - mUserExcludePackages[i] = userExcludePackages[i].replace(".", "/"); - } - } - } - - private boolean isExcludedPackage(String packageName) { - for (String exPackage : EXCLUDED_PACKAGES) { - if (packageName.startsWith(exPackage)) { - return true; - } - } - - for (String exPackage : mUserExcludePackages) { - if (packageName.startsWith(exPackage)) { - return true; - } - } - - if (!mExcludeOfficial) return false; - - for (String exPackage : OFFICIAL_PACKAGES) { - if (packageName.startsWith(exPackage)) { - return true; - } - } - return false; - } - - public boolean transformClass(InputStream from, OutputStream to) { - try { - byte[] bytes = IOUtils.toByteArray(from); - byte[] modifiedClass = visitClassBytes(bytes); - if (modifiedClass != null) { - IOUtils.write(modifiedClass, to); - return true; - } else { - IOUtils.write(bytes, to); - } - } catch (IOException e) { - mLog.error(e.getMessage(), e); - } - return false; - } - - public boolean transformClassFile(File from, File to) { - boolean result; - File toParent = to.getParentFile(); - toParent.mkdirs(); - try (FileInputStream fileInputStream = new FileInputStream(from); FileOutputStream fileOutputStream = new FileOutputStream(to)) { - result = transformClass(fileInputStream, fileOutputStream); - } catch (Exception e) { - mLog.error(e.getMessage(), e); - result = false; - } - return result; - } - - private byte[] visitClassBytes(byte[] bytes) { - String className = null; - try { - ClassReader classReader = new ClassReader(bytes); - AutotrackClassWriter classWriter = new AutotrackClassWriter(classReader, ClassWriter.COMPUTE_MAXS); - Context context = new Context(mLog, mClassLoader); - classReader.accept(new ContextClassVisitor(classWriter.getApi(), context), ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE); - className = context.getClassName(); - ClassVisitor classVisitor; - if (className == null || this.isExcludedPackage(context.getClassName())) { - return null; - } - DesugaringClassVisitor desugaringClassVisitor = new DesugaringClassVisitor(classWriter.getApi(), - new InjectAroundClassVisitor(classWriter.getApi(), - new InjectSuperClassVisitor(classWriter.getApi(), classWriter, context), - context), - context); - classVisitor = desugaringClassVisitor; - classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES); - if (!desugaringClassVisitor.getNeedInjectTargetMethods().isEmpty()) { - // lambda 表达式需要特殊处理两次 - mLog.debug(String.format("GIO: deal with lambda second time: %s", className)); - ClassReader lambdaReader = new ClassReader(classWriter.toByteArray()); - classWriter = new AutotrackClassWriter(lambdaReader, ClassWriter.COMPUTE_MAXS); - lambdaReader.accept(new DesugaredClassVisitor(classWriter.getApi(), classWriter, context, desugaringClassVisitor.getNeedInjectTargetMethods()), ClassReader.EXPAND_FRAMES); - } - if (context.isClassModified()) { - return classWriter.toByteArray(); - } - } catch (AutotrackBuildException e) { - throw new RuntimeException(e); - } catch (Throwable t) { - this.mLog.error("Unfortunately, an error has occurred while processing " + className + ". Please copy your build logs and the jar containing this class and visit https://www.growingio.com, thanks!\n" + t.getMessage(), t); - } - return null; - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/Context.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/Context.java deleted file mode 100644 index 3a469f13..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/Context.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile; - -public class Context { - private final Log mLog; - private final ClassLoader mClassLoader; - - private String mClassName; - private String mSuperClassName; - private boolean mClassModified; - private boolean mIsAbstract; - - public Context(Log log, ClassLoader classLoader) { - mLog = log; - mClassLoader = classLoader; - } - - public ClassLoader getClassLoader() { - return mClassLoader; - } - - public Log getLog() { - return mLog; - } - - public String getClassName() { - return mClassName; - } - - public void setClassName(String className) { - mClassName = className; - } - - public String getSuperClassName() { - return mSuperClassName; - } - - public void setSuperClassName(String superClassName) { - mSuperClassName = superClassName; - } - - public boolean isClassModified() { - return mClassModified; - } - - public void markModified() { - mClassModified = true; - } - - public boolean isAbstract() { - return mIsAbstract; - } - - public void setAbstract(boolean anAbstract) { - mIsAbstract = anAbstract; - } - - public boolean isAssignable(String subClassName, String superClassName) { - if (subClassName.contains("/")) { - subClassName = subClassName.replace("/", "."); - } - if (superClassName.contains("/")) { - superClassName = superClassName.replace("/", "."); - } - try { - Class subClass = getClassLoader().loadClass(subClassName); - Class superClass = getClassLoader().loadClass(superClassName); - return superClass.isAssignableFrom(subClass); - } catch (ClassNotFoundException ignored) { - } - return false; - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/Log.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/Log.java deleted file mode 100644 index 5312457f..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/Log.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile; - -public interface Log { - void debug(String str); - - void error(String str); - - void error(String str, Throwable th); - - void info(String str); - - void warning(String str); - - void warning(String str, Throwable th); -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/SystemLog.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/SystemLog.java deleted file mode 100644 index 70313471..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/SystemLog.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile; - -public class SystemLog implements Log { - - @Override - public void info(String message) { - System.out.println("[Autotrack.info] " + message); - } - - @Override - public void debug(String message) { - System.out.println("[Autotrack.debug] " + message); - } - - @Override - public void warning(String message) { - System.err.println("[Autotrack.warn] " + message); - } - - @Override - public void warning(String message, Throwable cause) { - System.err.println("[Autotrack.warn] " + message); - cause.printStackTrace(System.err); - } - - @Override - public void error(String message) { - System.err.println("[Autotrack.error] " + message); - } - - @Override - public void error(String message, Throwable cause) { - System.err.println("[Autotrack.error] " + message); - cause.printStackTrace(System.err); - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/ContextClassVisitor.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/ContextClassVisitor.java deleted file mode 100644 index 47a2466f..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/ContextClassVisitor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile.visitor; - -import com.growingio.sdk.plugin.autotrack.compile.Context; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.Opcodes; - -public class ContextClassVisitor extends ClassVisitor { - private final Context mContext; - - public ContextClassVisitor(int api, Context context) { - super(api); - mContext = context; - } - - public void visit(int version, int access, String name, String sig, String superName, String[] interfaces) { - mContext.setClassName(name); - mContext.setSuperClassName(superName); - mContext.setAbstract((access & Opcodes.ACC_ABSTRACT) != 0); - super.visit(version, access, name, sig, superName, interfaces); - } - -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/DesugaredClassVisitor.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/DesugaredClassVisitor.java deleted file mode 100644 index 9ec2b650..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/DesugaredClassVisitor.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile.visitor; - -import com.growingio.sdk.plugin.autotrack.compile.Context; -import com.growingio.sdk.plugin.autotrack.compile.Log; -import com.growingio.sdk.plugin.autotrack.hook.InjectMethod; -import com.growingio.sdk.plugin.autotrack.hook.TargetMethod; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.AdviceAdapter; -import org.objectweb.asm.commons.Method; - -import java.util.Set; - -public class DesugaredClassVisitor extends ClassVisitor { - private final Context mContext; - private final Log mLog; - private final Set mNeedInjectTargetMethods; - - public DesugaredClassVisitor(int api, ClassVisitor cv, Context context, Set needInjectTargetMethods) { - super(api, cv); - mContext = context; - mLog = context.getLog(); - mNeedInjectTargetMethods = needInjectTargetMethods; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); - return new DesugaredMethodVisitor(api, methodVisitor, access, name, desc); - } - - private TargetMethod findTargetMethod(String name, String desc) { - if (mNeedInjectTargetMethods.isEmpty()) { - return null; - } - - for (TargetMethod targetMethod : mNeedInjectTargetMethods) { - if (name.equals(targetMethod.getName()) && desc.equals(targetMethod.getDesc())) { - return targetMethod; - } - } - return null; - } - - private final class DesugaredMethodVisitor extends AdviceAdapter { - private final String mName; - private final String mDesc; - - protected DesugaredMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc) { - super(api, mv, access, name, desc); - mName = name; - mDesc = desc; - } - - @Override - protected void onMethodEnter() { - TargetMethod targetMethod = findTargetMethod(mName, mDesc); - if (targetMethod == null) { - return; - } - - for (InjectMethod injectMethod : targetMethod.getInjectMethods()) { - if (!injectMethod.isAfter()) { - visitInsn(ACONST_NULL); - int injectArgsLen = Type.getArgumentTypes(injectMethod.getMethodDesc()).length - 1; - int originArgsLen = Type.getArgumentTypes(mDesc).length; - if (injectArgsLen != 0) { - loadArgs(originArgsLen - injectArgsLen, injectArgsLen); - } - invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - } - } - mContext.markModified(); - } - - @Override - protected void onMethodExit(int opcode) { - TargetMethod targetMethod = findTargetMethod(mName, mDesc); - if (targetMethod == null) { - return; - } - for (InjectMethod injectMethod : targetMethod.getInjectMethods()) { - if (injectMethod.isAfter()) { - visitInsn(ACONST_NULL); - int injectArgsLen = Type.getArgumentTypes(injectMethod.getMethodDesc()).length - 1; - int originArgsLen = Type.getArgumentTypes(mDesc).length; - if (injectArgsLen != 0) { - loadArgs(originArgsLen - injectArgsLen, injectArgsLen); - } - invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - } - } - mNeedInjectTargetMethods.remove(targetMethod); - mContext.markModified(); - } - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/DesugaringClassVisitor.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/DesugaringClassVisitor.java deleted file mode 100644 index 254c61ba..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/DesugaringClassVisitor.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile.visitor; - -import com.growingio.sdk.plugin.autotrack.compile.Context; -import com.growingio.sdk.plugin.autotrack.compile.Log; -import com.growingio.sdk.plugin.autotrack.hook.HookClassesConfig; -import com.growingio.sdk.plugin.autotrack.hook.InjectMethod; -import com.growingio.sdk.plugin.autotrack.hook.TargetClass; -import com.growingio.sdk.plugin.autotrack.hook.TargetMethod; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.Handle; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.AdviceAdapter; -import org.objectweb.asm.commons.GeneratorAdapter; -import org.objectweb.asm.commons.Method; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -import static org.objectweb.asm.Opcodes.ACONST_NULL; - -public class DesugaringClassVisitor extends ClassVisitor { - private static final String TAG = "DesugaringClassVisitor"; - - private final Context mContext; - private final Log mLog; - - private final Set mNeedInjectTargetMethods = new HashSet<>(); - private final HashMap mGenerateMethodBlocks = new HashMap<>(); - private int mGenerateMethodIndex = 0; - - public DesugaringClassVisitor(int api, ClassVisitor cv, Context context) { - super(api, cv); - mContext = context; - mLog = context.getLog(); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); - return new DesugaringMethodVisitor(api, methodVisitor, access, name, desc); - } - - @Override - public void visitEnd() { - if (mGenerateMethodBlocks.isEmpty()) { - super.visitEnd(); - return; - } - - for (GenerateMethodBlock methodBlock : mGenerateMethodBlocks.values()) { - generateMethod(methodBlock); - } - - super.visitEnd(); - } - - public Set getNeedInjectTargetMethods() { - return mNeedInjectTargetMethods; - } - - private void generateMethod(GenerateMethodBlock methodBlock) { - mLog.debug(TAG + ": generateMethod: " + methodBlock.mMethodName + "#" + methodBlock.mMethodDesc); - int access = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC; - MethodVisitor visitor = super.visitMethod(access, methodBlock.mMethodName, methodBlock.mMethodDesc, null, null); - GeneratorAdapter adapter = new GeneratorAdapter(visitor, access, methodBlock.mMethodName, methodBlock.mMethodDesc); - adapter.visitCode(); - Type[] arguments = Type.getArgumentTypes(methodBlock.mMethodDesc); - boolean isStaticOrigin = methodBlock.mOriginHandle.getTag() == Opcodes.H_INVOKESTATIC; - for (InjectMethod injectMethod : methodBlock.mTargetMethod.getInjectMethods()) { - if (!injectMethod.isAfter()) { - adapter.visitInsn(ACONST_NULL); - if (isStaticOrigin) { - adapter.loadArgs(); - } else { - if (arguments.length > 1) { - adapter.loadArgs(1, arguments.length - 1); - } - } - adapter.invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - } - } - - adapter.loadArgs(); - Type owner = Type.getObjectType(methodBlock.mOriginHandle.getOwner()); - Method method = new Method(methodBlock.mOriginHandle.getName(), methodBlock.mOriginHandle.getDesc()); - switch (methodBlock.mOriginHandle.getTag()) { - case Opcodes.H_INVOKEINTERFACE: - adapter.invokeInterface(owner, method); - break; - case Opcodes.H_INVOKESPECIAL: - throw new RuntimeException("should not has invoke special: " + methodBlock.mMethodName + "#" + methodBlock.mMethodDesc); - case Opcodes.H_INVOKESTATIC: - adapter.invokeStatic(owner, method); - break; - case Opcodes.H_INVOKEVIRTUAL: - adapter.invokeVirtual(owner, method); - break; - default: - break; - } - - for (InjectMethod injectMethod : methodBlock.mTargetMethod.getInjectMethods()) { - if (injectMethod.isAfter()) { - adapter.visitInsn(ACONST_NULL); - if (isStaticOrigin) { - adapter.loadArgs(); - } else { - if (arguments.length > 1) { - adapter.loadArgs(1, arguments.length - 1); - } - } - adapter.invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - } - } - - adapter.returnValue(); - adapter.visitMaxs(arguments.length, arguments.length); - adapter.visitEnd(); - } - - private final class DesugaringMethodVisitor extends AdviceAdapter { - private final String mName; - - private DesugaringMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc) { - super(api, mv, access, name, desc); - mName = name; - } - - @Override - public void visitInvokeDynamicInsn(String lambdaMethodName, String desc, Handle bsm, Object... bsmArgs) { - mLog.debug(String.format("DesugaringMethodVisitor(%s): on method %s", mContext.getClassName(), mName)); - int index = desc.lastIndexOf(")L"); - if (index == -1) { - super.visitInvokeDynamicInsn(lambdaMethodName, desc, bsm, bsmArgs); - return; - } - String interfaceClazzName = desc.substring(index + 2, desc.length() - 1); - TargetClass targetClass = HookClassesConfig.getSuperHookClasses().get(interfaceClazzName); - if (targetClass == null) { - super.visitInvokeDynamicInsn(lambdaMethodName, desc, bsm, bsmArgs); - return; - } - String lambdaMethodDesc = ((Type) bsmArgs[0]).getDescriptor(); - TargetMethod targetMethod = targetClass.getTargetMethod(lambdaMethodName, lambdaMethodDesc); - if (targetMethod == null) { - super.visitInvokeDynamicInsn(lambdaMethodName, desc, bsm, bsmArgs); - return; - } - - Handle handle = (Handle) bsmArgs[1]; - if (lambdaMethodName.equals(handle.getName())) { - // 校验实现方法是不是实现了对应接口的实现方法, 如果是则过滤,交给 InjectSuperClassVisitor 进行处理 - if (mContext.isAssignable(handle.getOwner(), interfaceClazzName)) { - mLog.debug(String.format("DesugaringClassVisitor(%s): skipped on method %s", mContext.getClassName(), mName)); - super.visitInvokeDynamicInsn(lambdaMethodName, desc, bsm, bsmArgs); - return; - } - } - - if (handle.getOwner().equals(mContext.getClassName())) { - // 实现方法在此类中 - super.visitInvokeDynamicInsn(lambdaMethodName, desc, bsm, bsmArgs); - TargetMethod needInjectMethod = new TargetMethod(handle.getName(), handle.getDesc()); - needInjectMethod.addInjectMethods(targetMethod.getInjectMethods()); - mNeedInjectTargetMethods.add(needInjectMethod); - } else { - String key = interfaceClazzName + handle.getOwner() + handle.getName() + handle.getDesc(); - GenerateMethodBlock methodBlock = mGenerateMethodBlocks.get(key); - if (methodBlock == null) { - String methodDesc; - if (handle.getTag() == Opcodes.H_INVOKESTATIC) { - methodDesc = "(" + handle.getDesc().replace("(", ""); - } else { - methodDesc = "(L" + handle.getOwner() + ";" + handle.getDesc().replace("(", ""); - } - methodBlock = new GenerateMethodBlock("lambda$GIO$" + mGenerateMethodIndex, methodDesc, targetMethod, handle); - mGenerateMethodBlocks.put(key, methodBlock); - mGenerateMethodIndex++; - } - - bsmArgs[1] = new Handle(Opcodes.H_INVOKESTATIC, mContext.getClassName(), methodBlock.mMethodName, methodBlock.mMethodDesc); - String newDesc; - // Check for exact match on non-receiver captured arguments - // (实例方法中this是receiver, 这里进行更改, 防止改为invoke_static 后Lambda Runtime校验失败 ) - if (handle.getTag() == Opcodes.H_INVOKESTATIC) { - newDesc = desc; - } else { - newDesc = newDesc(desc, handle.getOwner()); - } - mContext.markModified(); - super.visitInvokeDynamicInsn(lambdaMethodName, newDesc, bsm, bsmArgs); - } - } - - private String newDesc(String oldDesc, String realOwner) { - int firstSemiColon = oldDesc.indexOf(';'); - return "(L" + realOwner + oldDesc.substring(firstSemiColon); - } - } - - private static final class GenerateMethodBlock { - final String mMethodName; - final String mMethodDesc; - final TargetMethod mTargetMethod; - final Handle mOriginHandle; - - GenerateMethodBlock(String methodName, String methodDesc, TargetMethod targetMethod, Handle originHandle) { - this.mMethodName = methodName; - this.mMethodDesc = methodDesc; - this.mTargetMethod = targetMethod; - this.mOriginHandle = originHandle; - } - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectAroundClassVisitor.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectAroundClassVisitor.java deleted file mode 100644 index 62e63a11..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectAroundClassVisitor.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile.visitor; - -import com.growingio.sdk.plugin.autotrack.compile.Context; -import com.growingio.sdk.plugin.autotrack.compile.Log; -import com.growingio.sdk.plugin.autotrack.hook.HookClassesConfig; -import com.growingio.sdk.plugin.autotrack.hook.InjectMethod; -import com.growingio.sdk.plugin.autotrack.hook.TargetClass; -import com.growingio.sdk.plugin.autotrack.hook.TargetMethod; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.GeneratorAdapter; -import org.objectweb.asm.commons.Method; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class InjectAroundClassVisitor extends ClassVisitor { - private final Context mContext; - private final Log mLog; - private String mCurrentClass; - - public InjectAroundClassVisitor(int api, ClassVisitor classVisitor, Context context) { - super(api, classVisitor); - mContext = context; - mLog = mContext.getLog(); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - mCurrentClass = name; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); - return new AroundMethodVisitor(api, mv, access, name, desc); - } - - private final class AroundMethodVisitor extends GeneratorAdapter { - - AroundMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc) { - super(api, mv, access, name, desc); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - TargetMethod targetMethod = findTargetMethod(owner, name, desc); - - if (targetMethod != null) { - Method originalMethod = new Method(name, desc); - int callObject = -1; - int[] locals = new int[originalMethod.getArgumentTypes().length]; - for (int i = locals.length - 1; i >= 0; i--) { - locals[i] = newLocal(originalMethod.getArgumentTypes()[i]); - storeLocal(locals[i]); - } - if (opcode != Opcodes.INVOKESTATIC) { - callObject = newLocal(Type.getObjectType(owner)); - storeLocal(callObject); - } - for (InjectMethod injectMethod : targetMethod.getInjectMethods()) { - if (!injectMethod.isAfter()) { - if (callObject >= 0) { - loadLocal(callObject); - } - for (int tmpLocal : locals) { - loadLocal(tmpLocal); - } - invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - mLog.debug(mCurrentClass + ": " + injectMethod.getClassName() + "#" + injectMethod.getMethodName() + injectMethod.getMethodDesc() + " ===Before===> " + owner + "#" + name + desc); - } - } - - if (callObject >= 0) { - loadLocal(callObject); - } - - for (int tmpLocal : locals) { - loadLocal(tmpLocal); - } - super.visitMethodInsn(opcode, owner, name, desc, itf); - - for (InjectMethod injectMethod : targetMethod.getInjectMethods()) { - if (injectMethod.isAfter()) { - if (callObject >= 0) { - loadLocal(callObject); - } - for (int tmpLocal : locals) { - loadLocal(tmpLocal); - } - invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - mLog.debug(mCurrentClass + ": " + injectMethod.getClassName() + "#" + injectMethod.getMethodName() + injectMethod.getMethodDesc() + " ===After===> " + owner + "#" + name + desc); - } - } - mContext.markModified(); - } else { - super.visitMethodInsn(opcode, owner, name, desc, itf); - } - } - } - - private TargetMethod findTargetMethod(String className, String methodName, String methodDesc) { - List targetClass = findTargetClass(className); - for (TargetClass tClass : targetClass) { - if (tClass != null) { - TargetMethod method = tClass.getTargetMethod(methodName, methodDesc); - if (method != null) { - return method; - } - } - } - return null; - } - - private List findTargetClass(String className) { - List list = new ArrayList<>(); - Map aroundHookClasses = HookClassesConfig.getAroundHookClasses(); - for (String clazz : aroundHookClasses.keySet()) { - if (isAssignable(className, clazz)) { - list.add(aroundHookClasses.get(clazz)); - } - } - return list; - } - - private boolean isAssignable(String subClassName, String superClassName) { - if (subClassName.contains("/")) { - subClassName = subClassName.replace("/", "."); - } - if (superClassName.contains("/")) { - superClassName = superClassName.replace("/", "."); - } - try { - Class subClass = mContext.getClassLoader().loadClass(subClassName); - Class superClass = mContext.getClassLoader().loadClass(superClassName); - return superClass.isAssignableFrom(subClass); - } catch (ClassNotFoundException | NoClassDefFoundError | SecurityException ignored) { - } - return false; - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectSuperClassVisitor.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectSuperClassVisitor.java deleted file mode 100644 index 83452aa1..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectSuperClassVisitor.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile.visitor; - -import com.growingio.sdk.plugin.autotrack.compile.Context; -import com.growingio.sdk.plugin.autotrack.compile.Log; -import com.growingio.sdk.plugin.autotrack.hook.HookClassesConfig; -import com.growingio.sdk.plugin.autotrack.hook.InjectMethod; -import com.growingio.sdk.plugin.autotrack.hook.TargetClass; -import com.growingio.sdk.plugin.autotrack.hook.TargetMethod; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.AdviceAdapter; -import org.objectweb.asm.commons.GeneratorAdapter; -import org.objectweb.asm.commons.Method; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import static org.objectweb.asm.Opcodes.ACC_PUBLIC; - -public class InjectSuperClassVisitor extends ClassVisitor { - private final Context mContext; - private final Log mLog; - private final List mTargetClasses = new ArrayList<>(); - private final Set mOverrideMethods = new HashSet<>(); - private String mCurrentClass; - - public InjectSuperClassVisitor(int api, ClassVisitor classVisitor, Context context) { - super(api, classVisitor); - mContext = context; - mLog = context.getLog(); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - mCurrentClass = name; - TargetClass targetClass = HookClassesConfig.getSuperHookClasses().get(superName); - if (targetClass != null) { - mTargetClasses.add(targetClass); - } - for (String i : interfaces) { - TargetClass targetInterface = HookClassesConfig.getSuperHookClasses().get(i); - if (targetInterface != null) { - targetInterface.setInterface(true); - mTargetClasses.add(targetInterface); - } - } - - if (!mTargetClasses.isEmpty()) { - mContext.markModified(); - } - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); - for (TargetClass targetClass : mTargetClasses) { - TargetMethod targetMethod = targetClass.getTargetMethod(name, desc); - if (targetMethod != null) { - mOverrideMethods.add(targetMethod); - return new InjectSuperMethodVisitor(api, mv, access, name, desc, targetMethod.getInjectMethods()); - } - } - return mv; - } - - @Override - public void visitEnd() { - for (TargetClass targetClass : mTargetClasses) { - for (TargetMethod targetMethod : targetClass.getTargetMethods()) { - if (!mOverrideMethods.contains(targetMethod)) { - Set injectMethods = targetMethod.getInjectMethods(); - Method m = new Method(targetMethod.getName(), targetMethod.getDesc()); - GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cv); - for (InjectMethod injectMethod : injectMethods) { - if (!injectMethod.isAfter()) { - mg.loadThis(); - mg.loadArgs(); - mg.invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - mLog.debug("Method Add: " + injectMethod.getClassName() + "#" + injectMethod.getMethodName() + injectMethod.getMethodDesc() + " ===SuperBefore===> " + mCurrentClass + "#" + targetMethod.getName() + targetMethod.getDesc()); - } - } - if (!targetClass.isInterface()) { - mg.loadThis(); - mg.loadArgs(); - mg.invokeConstructor(Type.getObjectType(targetClass.getName()), new Method(targetMethod.getName(), targetMethod.getDesc())); - } - for (InjectMethod injectMethod : injectMethods) { - if (injectMethod.isAfter()) { - mg.loadThis(); - mg.loadArgs(); - mg.invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - mLog.debug("Method Add: " + injectMethod.getClassName() + "#" + injectMethod.getMethodName() + injectMethod.getMethodDesc() + " ===SuperAfter===> " + mCurrentClass + "#" + targetMethod.getName() + targetMethod.getDesc()); - } - } - mg.returnValue(); - mg.endMethod(); - } - } - } - super.visitEnd(); - } - - private final class InjectSuperMethodVisitor extends AdviceAdapter { - private final String mTargetMethodName; - private final String mTargetMethodDesc; - private final Set mInjectMethods; - - protected InjectSuperMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc, Set injectMethods) { - super(api, mv, access, name, desc); - mTargetMethodName = name; - mTargetMethodDesc = desc; - mInjectMethods = injectMethods; - } - - @Override - protected void onMethodEnter() { - super.onMethodEnter(); - for (InjectMethod injectMethod : mInjectMethods) { - if (!injectMethod.isAfter()) { - loadThis(); - loadArgs(); - invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - mLog.debug("Method Insert: " + injectMethod.getClassName() + "#" + injectMethod.getMethodName() + injectMethod.getMethodDesc() + " ===SuperBefore===> " + mCurrentClass + "#" + mTargetMethodName + mTargetMethodDesc); - } - } - } - - @Override - protected void onMethodExit(int opcode) { - for (InjectMethod injectMethod : mInjectMethods) { - if (injectMethod.isAfter()) { - loadThis(); - loadArgs(); - invokeStatic(Type.getObjectType(injectMethod.getClassName()), new Method(injectMethod.getMethodName(), injectMethod.getMethodDesc())); - } - mLog.debug("Method Insert: " + injectMethod.getClassName() + "#" + injectMethod.getMethodName() + injectMethod.getMethodDesc() + " ===SuperAfter===> " + mCurrentClass + "#" + mTargetMethodName + mTargetMethodDesc); - } - super.onMethodExit(opcode); - } - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/HookClassesConfig.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/HookClassesConfig.java deleted file mode 100644 index f619dd71..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/HookClassesConfig.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.hook; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * 该Class是由 inject-compiler 自动生成的,请不要随意更改! - */ -public class HookClassesConfig { - private static final Map AROUND_HOOK_CLASSES = new HashMap<>(); - - private static final Map SUPER_HOOK_CLASSES = new HashMap<>(); - - static { - putAroundHookMethod("android/webkit/WebView", "loadUrl", "(Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "webkitWebViewLoadUrl", "(Landroid/webkit/WebView;Ljava/lang/String;)V", false); - putAroundHookMethod("android/webkit/WebView", "loadUrl", "(Ljava/lang/String;Ljava/util/Map;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "webkitWebViewLoadUrl", "(Landroid/webkit/WebView;Ljava/lang/String;Ljava/util/Map;)V", false); - putAroundHookMethod("android/webkit/WebView", "loadData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "webkitWebViewLoadData", "(Landroid/webkit/WebView;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false); - putAroundHookMethod("android/webkit/WebView", "loadDataWithBaseURL", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "webkitWebViewLoadDataWithBaseURL", "(Landroid/webkit/WebView;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false); - putAroundHookMethod("android/webkit/WebView", "postUrl", "(Ljava/lang/String;[B)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "webkitWebViewPostUrl", "(Landroid/webkit/WebView;Ljava/lang/String;[B)V", false); - putAroundHookMethod("com/tencent/smtt/sdk/WebView", "loadUrl", "(Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "x5WebViewLoadUrl", "(Landroid/view/View;Ljava/lang/String;)V", false); - putAroundHookMethod("com/tencent/smtt/sdk/WebView", "loadUrl", "(Ljava/lang/String;Ljava/util/Map;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "x5WebViewLoadUrl", "(Landroid/view/View;Ljava/lang/String;Ljava/util/Map;)V", false); - putAroundHookMethod("com/tencent/smtt/sdk/WebView", "loadData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "x5WebViewLoadData", "(Landroid/view/View;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false); - putAroundHookMethod("com/tencent/smtt/sdk/WebView", "loadDataWithBaseURL", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "x5WebViewLoadDataWithBaseURL", "(Landroid/view/View;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false); - putAroundHookMethod("com/tencent/smtt/sdk/WebView", "postUrl", "(Ljava/lang/String;[B)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "x5WebViewPostUrl", "(Landroid/view/View;Ljava/lang/String;[B)V", false); - putAroundHookMethod("com/uc/webview/export/WebView", "loadUrl", "(Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "ucWebViewLoadUrl", "(Landroid/view/View;Ljava/lang/String;)V", false); - putAroundHookMethod("com/uc/webview/export/WebView", "loadUrl", "(Ljava/lang/String;Ljava/util/Map;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "ucWebViewLoadUrl", "(Landroid/view/View;Ljava/lang/String;Ljava/util/Map;)V", false); - putAroundHookMethod("com/uc/webview/export/WebView", "loadData", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "ucWebViewLoadData", "(Landroid/view/View;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false); - putAroundHookMethod("com/uc/webview/export/WebView", "loadDataWithBaseURL", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "ucWebViewLoadDataWithBaseURL", "(Landroid/view/View;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false); - putAroundHookMethod("com/uc/webview/export/WebView", "postUrl", "(Ljava/lang/String;[B)V", "com/growingio/android/sdk/autotrack/inject/WebViewInjector", "ucWebViewPostUrl", "(Landroid/view/View;Ljava/lang/String;[B)V", false); - putAroundHookMethod("android/app/AlertDialog", "show", "()V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "alertDialogShow", "(Landroid/app/AlertDialog;)V", true); - putSuperHookMethod("android/view/View$OnClickListener", "onClick", "(Landroid/view/View;)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "viewOnClick", "(Landroid/view/View$OnClickListener;Landroid/view/View;)V", false); - putSuperHookMethod("android/content/DialogInterface$OnClickListener", "onClick", "(Landroid/content/DialogInterface;I)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "dialogOnClick", "(Landroid/content/DialogInterface$OnClickListener;Landroid/content/DialogInterface;I)V", false); - putSuperHookMethod("android/widget/AdapterView$OnItemClickListener", "onItemClick", "(Landroid/widget/AdapterView;Landroid/view/View;IJ)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "adapterViewOnItemClick", "(Landroid/widget/AdapterView$OnItemClickListener;Landroid/widget/AdapterView;Landroid/view/View;IJ)V", false); - putSuperHookMethod("android/widget/AdapterView$OnItemSelectedListener", "onItemSelected", "(Landroid/widget/AdapterView;Landroid/view/View;IJ)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "adapterViewOnItemSelected", "(Landroid/widget/AdapterView$OnItemSelectedListener;Landroid/widget/AdapterView;Landroid/view/View;IJ)V", false); - putSuperHookMethod("android/widget/ExpandableListView$OnGroupClickListener", "onGroupClick", "(Landroid/widget/ExpandableListView;Landroid/view/View;IJ)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "expandableListViewOnGroupClick", "(Landroid/widget/ExpandableListView$OnGroupClickListener;Landroid/widget/ExpandableListView;Landroid/view/View;IJ)V", false); - putSuperHookMethod("android/widget/ExpandableListView$OnChildClickListener", "onChildClick", "(Landroid/widget/ExpandableListView;Landroid/view/View;IIJ)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "expandableListViewOnChildClick", "(Landroid/widget/ExpandableListView$OnChildClickListener;Landroid/widget/ExpandableListView;Landroid/view/View;IIJ)V", false); - putSuperHookMethod("android/app/ExpandableListActivity", "onChildClick", "(Landroid/widget/ExpandableListView;Landroid/view/View;IIJ)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "expandableListActivityOnChildClick", "(Landroid/app/ExpandableListActivity;Landroid/widget/ExpandableListView;Landroid/view/View;IIJ)V", false); - putSuperHookMethod("android/app/ListActivity", "onListItemClick", "(Landroid/widget/ListView;Landroid/view/View;IJ)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "listActivityOnListItemClick", "(Landroid/app/ListActivity;Landroid/widget/ListView;Landroid/view/View;IJ)V", false); - putSuperHookMethod("android/widget/CompoundButton$OnCheckedChangeListener", "onCheckedChanged", "(Landroid/widget/CompoundButton;Z)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "compoundButtonOnChecked", "(Landroid/widget/CompoundButton$OnCheckedChangeListener;Landroid/widget/CompoundButton;Z)V", false); - putSuperHookMethod("android/widget/RadioGroup$OnCheckedChangeListener", "onCheckedChanged", "(Landroid/widget/RadioGroup;I)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "radioGroupOnChecked", "(Landroid/widget/RadioGroup$OnCheckedChangeListener;Landroid/widget/RadioGroup;I)V", false); - putSuperHookMethod("android/widget/RatingBar$OnRatingBarChangeListener", "onRatingChanged", "(Landroid/widget/RatingBar;FZ)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "ratingBarOnRatingBarChange", "(Landroid/widget/RatingBar$OnRatingBarChangeListener;Landroid/widget/RatingBar;FZ)V", false); - putSuperHookMethod("android/widget/SeekBar$OnSeekBarChangeListener", "onStopTrackingTouch", "(Landroid/widget/SeekBar;)V", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "seekBarOnSeekBarChange", "(Landroid/widget/SeekBar$OnSeekBarChangeListener;Landroid/widget/SeekBar;)V", false); - putSuperHookMethod("android/widget/Toolbar$OnMenuItemClickListener", "onMenuItemClick", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "toolbarOnMenuItemClick", "(Landroid/widget/Toolbar$OnMenuItemClickListener;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/widget/ActionMenuView$OnMenuItemClickListener", "onMenuItemClick", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "actionMenuViewOnMenuItemClick", "(Landroid/widget/ActionMenuView$OnMenuItemClickListener;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/widget/PopupMenu$OnMenuItemClickListener", "onMenuItemClick", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "popupMenuOnMenuItemClick", "(Landroid/widget/PopupMenu$OnMenuItemClickListener;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/support/v4/app/Fragment", "onResume", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "v4FragmentOnResume", "(Landroid/support/v4/app/Fragment;)V", true); - putSuperHookMethod("android/support/v4/app/Fragment", "setUserVisibleHint", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "v4FragmentSetUserVisibleHint", "(Landroid/support/v4/app/Fragment;Z)V", true); - putSuperHookMethod("android/support/v4/app/Fragment", "onHiddenChanged", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "v4FragmentOnHiddenChanged", "(Landroid/support/v4/app/Fragment;Z)V", true); - putSuperHookMethod("android/support/v4/app/Fragment", "onDestroyView", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "v4FragmentOnDestroyView", "(Landroid/support/v4/app/Fragment;)V", true); - putSuperHookMethod("androidx/fragment/app/Fragment", "onResume", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "androidxFragmentOnResume", "(Landroidx/fragment/app/Fragment;)V", true); - putSuperHookMethod("androidx/fragment/app/Fragment", "setUserVisibleHint", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "androidxFragmentSetUserVisibleHint", "(Landroidx/fragment/app/Fragment;Z)V", true); - putSuperHookMethod("androidx/fragment/app/Fragment", "onHiddenChanged", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "androidxFragmentOnHiddenChanged", "(Landroidx/fragment/app/Fragment;Z)V", true); - putSuperHookMethod("androidx/fragment/app/Fragment", "onDestroyView", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "androidxFragmentOnDestroyView", "(Landroidx/fragment/app/Fragment;)V", true); - putSuperHookMethod("android/app/Activity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/accounts/AccountAuthenticatorActivity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/app/ActivityGroup", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/app/AliasActivity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/app/ExpandableListActivity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/app/LauncherActivity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/app/ListActivity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/app/NativeActivity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/app/TabActivity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/preference/PreferenceActivity", "onNewIntent", "(Landroid/content/Intent;)V", "com/growingio/android/sdk/autotrack/inject/ActivityInjector", "onActivityNewIntent", "(Landroid/app/Activity;Landroid/content/Intent;)V", false); - putSuperHookMethod("android/app/Activity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/accounts/AccountAuthenticatorActivity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/app/ActivityGroup", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/app/AliasActivity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/app/ExpandableListActivity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/app/LauncherActivity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/app/ListActivity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/app/NativeActivity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/app/TabActivity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/preference/PreferenceActivity", "onOptionsItemSelected", "(Landroid/view/MenuItem;)Z", "com/growingio/android/sdk/autotrack/click/ViewClickInjector", "menuItemOnOptionsItemSelected", "(Landroid/app/Activity;Landroid/view/MenuItem;)V", false); - putSuperHookMethod("android/app/Fragment", "onResume", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnResume", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/app/DialogFragment", "onResume", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnResume", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/app/ListFragment", "onResume", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnResume", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/preference/PreferenceFragment", "onResume", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnResume", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/webkit/WebViewFragment", "onResume", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnResume", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/app/Fragment", "setUserVisibleHint", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentSetUserVisibleHint", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/app/DialogFragment", "setUserVisibleHint", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentSetUserVisibleHint", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/app/ListFragment", "setUserVisibleHint", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentSetUserVisibleHint", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/preference/PreferenceFragment", "setUserVisibleHint", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentSetUserVisibleHint", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/webkit/WebViewFragment", "setUserVisibleHint", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentSetUserVisibleHint", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/app/Fragment", "onHiddenChanged", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnHiddenChanged", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/app/DialogFragment", "onHiddenChanged", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnHiddenChanged", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/app/ListFragment", "onHiddenChanged", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnHiddenChanged", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/preference/PreferenceFragment", "onHiddenChanged", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnHiddenChanged", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/webkit/WebViewFragment", "onHiddenChanged", "(Z)V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnHiddenChanged", "(Landroid/app/Fragment;Z)V", true); - putSuperHookMethod("android/app/Fragment", "onDestroyView", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnDestroyView", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/app/DialogFragment", "onDestroyView", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnDestroyView", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/app/ListFragment", "onDestroyView", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnDestroyView", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/preference/PreferenceFragment", "onDestroyView", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnDestroyView", "(Landroid/app/Fragment;)V", true); - putSuperHookMethod("android/webkit/WebViewFragment", "onDestroyView", "()V", "com/growingio/android/sdk/autotrack/page/FragmentInjector", "systemFragmentOnDestroyView", "(Landroid/app/Fragment;)V", true); - } - - private HookClassesConfig() { - } - - private static void putAroundHookMethod(String targetClassName, String targetMethodName, - String targetMethodDesc, String injectClassName, String injectMethodName, - String injectMethodDesc, boolean isAfter) { - putHookMethod(AROUND_HOOK_CLASSES, targetClassName, targetMethodName, targetMethodDesc, injectClassName, injectMethodName, injectMethodDesc, isAfter); - } - - private static void putSuperHookMethod(String targetClassName, String targetMethodName, - String targetMethodDesc, String injectClassName, String injectMethodName, - String injectMethodDesc, boolean isAfter) { - putHookMethod(SUPER_HOOK_CLASSES, targetClassName, targetMethodName, targetMethodDesc, injectClassName, injectMethodName, injectMethodDesc, isAfter); - } - - private static void putHookMethod(Map classMap, String targetClassName, - String targetMethodName, String targetMethodDesc, String injectClassName, - String injectMethodName, String injectMethodDesc, boolean isAfter) { - TargetClass targetClass = classMap.get(targetClassName); - if (targetClass == null) { - targetClass = new TargetClass(targetClassName); - classMap.put(targetClassName, targetClass); - } - TargetMethod targetMethod = targetClass.getTargetMethod(targetMethodName, targetMethodDesc); - if (targetMethod == null) { - targetMethod = new TargetMethod(targetMethodName, targetMethodDesc); - targetClass.addTargetMethod(targetMethod); - } - targetMethod.addInjectMethod(new InjectMethod(injectClassName, injectMethodName, injectMethodDesc, isAfter)); - } - - public static Map getAroundHookClasses() { - return Collections.unmodifiableMap(AROUND_HOOK_CLASSES); - } - - public static Map getSuperHookClasses() { - return Collections.unmodifiableMap(SUPER_HOOK_CLASSES); - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/InjectMethod.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/InjectMethod.java deleted file mode 100644 index d03a8bf9..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/InjectMethod.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.hook; - -public class InjectMethod { - private final String mClassName; - private final String mMethodName; - private final String mMethodDesc; - private final boolean mIsAfter; - - public InjectMethod(String className, String methodName, String methodDesc, boolean isAfter) { - mClassName = className; - mMethodName = methodName; - mMethodDesc = methodDesc; - mIsAfter = isAfter; - } - - public String getClassName() { - return mClassName; - } - - public String getMethodName() { - return mMethodName; - } - - public String getMethodDesc() { - return mMethodDesc; - } - - public boolean isAfter() { - return mIsAfter; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InjectMethod that = (InjectMethod) o; - - if (mIsAfter != that.mIsAfter) return false; - if (!mClassName.equals(that.mClassName)) return false; - if (!mMethodName.equals(that.mMethodName)) return false; - return mMethodDesc.equals(that.mMethodDesc); - } - - @Override - public int hashCode() { - int result = mClassName.hashCode(); - result = 31 * result + mMethodName.hashCode(); - result = 31 * result + mMethodDesc.hashCode(); - result = 31 * result + (mIsAfter ? 1 : 0); - return result; - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/TargetClass.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/TargetClass.java deleted file mode 100644 index 8786cf75..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/TargetClass.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.hook; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -public class TargetClass { - private final String mName; - private final Set mTargetMethods = new HashSet<>(); - private boolean mInterface = false; - - public TargetClass(String name) { - mName = name; - } - - public void addTargetMethod(TargetMethod method) { - mTargetMethods.add(method); - } - - public String getName() { - return mName; - } - - public Set getTargetMethods() { - return Collections.unmodifiableSet(mTargetMethods); - } - - public TargetMethod getTargetMethod(String name, String desc) { - for (TargetMethod method : mTargetMethods) { - if (name.equals(method.getName()) && desc.equals(method.getDesc())) { - return method; - } - } - return null; - } - - public void setInterface(boolean anInterface) { - mInterface = anInterface; - } - - public boolean isInterface() { - return mInterface; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TargetClass that = (TargetClass) o; - - return mName.equals(that.mName); - } - - @Override - public int hashCode() { - return mName.hashCode(); - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/TargetMethod.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/TargetMethod.java deleted file mode 100644 index 87b9e777..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/hook/TargetMethod.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.hook; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -public class TargetMethod { - private final String mName; - private final String mDesc; - private final Set mInjectMethods = new HashSet<>(); - - public TargetMethod(String name, String desc) { - mName = name; - mDesc = desc; - } - - public String getName() { - return mName; - } - - public String getDesc() { - return mDesc; - } - - public void addInjectMethod(InjectMethod method) { - mInjectMethods.add(method); - } - - public void addInjectMethods(Set methods) { - mInjectMethods.addAll(methods); - } - - public Set getInjectMethods() { - return Collections.unmodifiableSet(mInjectMethods); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TargetMethod that = (TargetMethod) o; - - if (!mName.equals(that.mName)) return false; - return mDesc.equals(that.mDesc); - } - - @Override - public int hashCode() { - int result = mName.hashCode(); - result = 31 * result + mDesc.hashCode(); - return result; - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/utils/ReflectUtil.java b/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/utils/ReflectUtil.java deleted file mode 100644 index b665d5bc..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/utils/ReflectUtil.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.utils; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -public abstract class ReflectUtil { - - public static Method getMethod(Class clazz, String methodName, Class... params) { - try { - return clazz.getMethod(methodName, params); - } catch (NoSuchMethodException e) { - return null; - } - } - - public static Field findFieldObj(Class current, String fieldName) { - while (current != Object.class) { - try { - Field field = current.getDeclaredField(fieldName); - field.setAccessible(true); - return field; - } catch (NoSuchFieldException e) { - current = current.getSuperclass(); - } - } - return null; - } - - public static T findField(Object instance, String fieldName) { - Field field = findFieldObj(instance.getClass(), fieldName); - if (field != null) { - try { - return (T) field.get(instance); - } catch (IllegalAccessException ignored) { - } - } - return null; - } -} diff --git a/growingio-autotracker-gradle-plugin/src/main/resources/META-INF/gradle-plugins/com.growingio.android.autotracker.properties b/growingio-autotracker-gradle-plugin/src/main/resources/META-INF/gradle-plugins/com.growingio.android.autotracker.properties deleted file mode 100644 index 6b53e0e1..00000000 --- a/growingio-autotracker-gradle-plugin/src/main/resources/META-INF/gradle-plugins/com.growingio.android.autotracker.properties +++ /dev/null @@ -1 +0,0 @@ -implementation-class=com.growingio.sdk.plugin.autotrack.AutotrackPlugin \ No newline at end of file diff --git a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/ByteCodeClassLoader.java b/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/ByteCodeClassLoader.java deleted file mode 100644 index 4af541eb..00000000 --- a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/ByteCodeClassLoader.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class ByteCodeClassLoader extends ClassLoader { - private static final String TAG = "ByteCodeClassLoader"; - private final ClassLoader mRealClassloader; - - public ByteCodeClassLoader(ClassLoader classLoader) { - super(getSystemClassLoader().getParent()); - mRealClassloader = classLoader; - } - - @Override - protected Class findClass(String s) throws ClassNotFoundException { - try { - return super.findClass(s); - } catch (ClassNotFoundException e) { - try { - Method findClass = ClassLoader.class.getDeclaredMethod("loadClass", String.class); - findClass.setAccessible(true); - return (Class) findClass.invoke(mRealClassloader, s); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e2) { - throw new ClassNotFoundException(s); - } - } - } - - public Class defineClass(String name, byte[] bytes) { - return defineClass(name, bytes, 0, bytes.length); - } -} diff --git a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/ClassUtils.java b/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/ClassUtils.java deleted file mode 100644 index 1be84f8e..00000000 --- a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/ClassUtils.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack; - -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; - -public class ClassUtils { - private ClassUtils() { - } - - public static InputStream classToInputStream(Class clazz) { - String className = clazz.getName(); - String classAsPath = className.replace('.', '/') + ".class"; - return clazz.getClassLoader().getResourceAsStream(classAsPath); - } - - public static byte[] classToByteArray(Class clazz) throws IOException { - return IOUtils.toByteArray(classToInputStream(clazz)); - } - - public static String getClassName(Class clazz) { - return clazz.getName().replace(".", "/"); - } -} diff --git a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectSuperClassVisitorTest.java b/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectSuperClassVisitorTest.java deleted file mode 100644 index 25a695b8..00000000 --- a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/compile/visitor/InjectSuperClassVisitorTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.compile.visitor; - -import com.google.common.truth.Truth; -import com.growingio.sdk.plugin.autotrack.ByteCodeClassLoader; -import com.growingio.sdk.plugin.autotrack.ClassUtils; -import com.growingio.sdk.plugin.autotrack.compile.AutotrackClassWriter; -import com.growingio.sdk.plugin.autotrack.compile.Context; -import com.growingio.sdk.plugin.autotrack.compile.SystemLog; -import com.growingio.sdk.plugin.autotrack.hook.HookClassesConfig; -import com.growingio.sdk.plugin.autotrack.hook.InjectMethod; -import com.growingio.sdk.plugin.autotrack.hook.TargetClass; -import com.growingio.sdk.plugin.autotrack.hook.TargetMethod; -import com.growingio.sdk.plugin.autotrack.tmp.Callback; -import com.growingio.sdk.plugin.autotrack.tmp.SubExample; -import com.growingio.sdk.plugin.autotrack.tmp.SuperExample; -import com.growingio.sdk.plugin.autotrack.tmp.inject.InjectAgent; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({HookClassesConfig.class}) -public class InjectSuperClassVisitorTest { - @Before - public void setUp() { - PowerMockito.mockStatic(HookClassesConfig.class); - } - - private void mockSuperHookClasses() { - Map targetClassMap = new HashMap<>(); - String className = ClassUtils.getClassName(SuperExample.class); - TargetClass targetClass = new TargetClass(className); - targetClassMap.put(className, targetClass); - TargetMethod targetMethod = new TargetMethod("onExecute", "()V"); - targetClass.addTargetMethod(targetMethod); - targetMethod.addInjectMethod(new InjectMethod(ClassUtils.getClassName(InjectAgent.class), "onExecute", "(L" + className + ";)V", false)); - PowerMockito.when(HookClassesConfig.getSuperHookClasses()).thenReturn(targetClassMap); - } - - @Test - public void injectSuperBefore() throws IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { - mockSuperHookClasses(); - - InputStream resourceAsStream = ClassUtils.classToInputStream(SubExample.class); - ClassReader cr = new ClassReader(resourceAsStream); - AutotrackClassWriter cw = new AutotrackClassWriter(cr, ClassWriter.COMPUTE_MAXS); - Context context = new Context(new SystemLog(), getClass().getClassLoader()); - cr.accept(new InjectSuperClassVisitor(cw.getApi(), cw, context), ClassReader.SKIP_FRAMES | ClassReader.EXPAND_FRAMES); - Class aClass = new ByteCodeClassLoader(getClass().getClassLoader()).defineClass(SubExample.class.getName(), cw.toByteArray()); - Object obj = aClass.newInstance(); - final SuperExample[] callbackResult = new SuperExample[1]; - InjectAgent.setsCallback(new Callback() { - @Override - public void onCallback(SuperExample example) { - Truth.assertThat(obj == example).isTrue(); - Truth.assertThat(example.isExecuted()).isFalse(); - callbackResult[0] = example; - } - }); - obj.getClass().getMethod("onExecute").invoke(obj); - Field isExecuted = SuperExample.class.getDeclaredField("mIsExecuted"); - isExecuted.setAccessible(true); - Truth.assertThat(callbackResult[0].isExecuted()).isTrue(); - } -} \ No newline at end of file diff --git a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/Callback.java b/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/Callback.java deleted file mode 100644 index cdb92b91..00000000 --- a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/Callback.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.tmp; - -public interface Callback { - void onCallback(SuperExample example); -} diff --git a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/SubExample.java b/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/SubExample.java deleted file mode 100644 index 8a7094e3..00000000 --- a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/SubExample.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.tmp; - -public class SubExample extends SuperExample { -// @Override -// public void onExecute() { -// super.onExecute(); -// } -} diff --git a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/SuperExample.java b/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/SuperExample.java deleted file mode 100644 index ea5bf775..00000000 --- a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/SuperExample.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.tmp; - -public class SuperExample { - private boolean mIsExecuted = false; - - public boolean isExecuted() { - return mIsExecuted; - } - - public void onExecute() { - mIsExecuted = true; - } -} diff --git a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/inject/InjectAgent.java b/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/inject/InjectAgent.java deleted file mode 100644 index e70a5063..00000000 --- a/growingio-autotracker-gradle-plugin/src/test/java/com/growingio/sdk/plugin/autotrack/tmp/inject/InjectAgent.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.tmp.inject; - -import com.growingio.sdk.plugin.autotrack.tmp.Callback; -import com.growingio.sdk.plugin.autotrack.tmp.SuperExample; - -public class InjectAgent { - private static Callback sCallback; - - private InjectAgent() { - } - - public static void setsCallback(Callback sCallback) { - InjectAgent.sCallback = sCallback; - } - - public static void onExecute(SuperExample example) { - System.out.println("InjectAgent = " + example); - if (sCallback != null) { - sCallback.onCallback(example); - } - } -} diff --git a/growingio-data/database/src/main/java/com/growingio/android/database/DatabaseDataFetcher.java b/growingio-data/database/src/main/java/com/growingio/android/database/DatabaseDataFetcher.java index 209dc15c..8f125cdd 100644 --- a/growingio-data/database/src/main/java/com/growingio/android/database/DatabaseDataFetcher.java +++ b/growingio-data/database/src/main/java/com/growingio/android/database/DatabaseDataFetcher.java @@ -24,7 +24,6 @@ import com.growingio.android.sdk.track.modelloader.DataFetcher; import static com.growingio.android.sdk.track.middleware.GEvent.SEND_POLICY_INSTANT; -import static com.growingio.android.sdk.track.middleware.GEvent.SEND_POLICY_WIFI; /** *

@@ -69,13 +68,13 @@ private EventDbResult executeDatabase(EventDatabase database) throws IllegalArgu return dbResult; } else if (database.getDbOp() == EventDatabase.DATABASE_OP_QUERY) { assertCondition(database.getLimit() > 0 - && database.getPolicy() >= SEND_POLICY_INSTANT && database.getPolicy() <= SEND_POLICY_WIFI, + && database.getPolicy() >= SEND_POLICY_INSTANT, "leak necessary param"); dataManager.queryEvents(database.getPolicy(), database.getLimit(), dbResult); return dbResult; } else if (database.getDbOp() == EventDatabase.DATABASE_OP_DELETE) { assertCondition(database.getLastId() > 0 - && database.getPolicy() >= SEND_POLICY_INSTANT && database.getPolicy() <= SEND_POLICY_WIFI + && database.getPolicy() >= SEND_POLICY_INSTANT && !TextUtils.isEmpty(database.getEventType()), "leak necessary param"); int sum = dataManager.removeEvents(database.getLastId(), database.getPolicy(), database.getEventType()); dbResult.setSum(sum); @@ -83,7 +82,7 @@ private EventDbResult executeDatabase(EventDatabase database) throws IllegalArgu return dbResult; } else if (database.getDbOp() == EventDatabase.DATABASE_OP_QUERY_DELETE) { assertCondition(database.getLimit() > 0 - && database.getPolicy() >= SEND_POLICY_INSTANT && database.getPolicy() <= SEND_POLICY_WIFI, + && database.getPolicy() >= SEND_POLICY_INSTANT, "leak necessary param"); dataManager.queryEventsAndDelete(database.getPolicy(), database.getLimit(), dbResult); return dbResult; diff --git a/growingio-data/database/src/main/java/com/growingio/android/database/EventDataManager.java b/growingio-data/database/src/main/java/com/growingio/android/database/EventDataManager.java index e628f279..0a5e594c 100644 --- a/growingio-data/database/src/main/java/com/growingio/android/database/EventDataManager.java +++ b/growingio-data/database/src/main/java/com/growingio/android/database/EventDataManager.java @@ -223,6 +223,7 @@ private Cursor queryEvents(ContentProviderClient client, int policy, int limit) + COLUMN_EVENT_TYPE + " FROM " + TABLE_EVENTS + " WHERE " + COLUMN_EVENT_TYPE + "=(" + subSelect + ") AND " + COLUMN_POLICY + "=" + policy + + " ORDER BY " + COLUMN_ID + " ASC " + " LIMIT " + limit + ";"; if (client == null) { ContentResolver contentResolver = context.getContentResolver(); diff --git a/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderDataFetcher.java b/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderDataFetcher.java index 3a94b1d0..6991b9c9 100644 --- a/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderDataFetcher.java +++ b/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderDataFetcher.java @@ -16,8 +16,8 @@ package com.growingio.android.encoder; -import com.growingio.android.sdk.track.http.EventEncoder; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventEncoder; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.modelloader.DataFetcher; import com.growingio.android.snappy.Snappy; import com.growingio.android.snappy.XORUtils; diff --git a/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderDataLoader.java b/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderDataLoader.java index 360647ef..7dd7a3d7 100644 --- a/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderDataLoader.java +++ b/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderDataLoader.java @@ -16,7 +16,7 @@ package com.growingio.android.encoder; -import com.growingio.android.sdk.track.http.EventEncoder; +import com.growingio.android.sdk.track.middleware.http.EventEncoder; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.modelloader.ModelLoaderFactory; diff --git a/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderLibraryGioModule.java b/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderLibraryGioModule.java index 68331f77..17c6d623 100644 --- a/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderLibraryGioModule.java +++ b/growingio-data/encoder/src/main/java/com/growingio/android/encoder/EncoderLibraryGioModule.java @@ -18,7 +18,7 @@ import android.content.Context; import com.growingio.android.sdk.LibraryGioModule; -import com.growingio.android.sdk.track.http.EventEncoder; +import com.growingio.android.sdk.track.middleware.http.EventEncoder; import com.growingio.android.sdk.track.modelloader.TrackerRegistry; import com.growingio.sdk.annotation.GIOLibraryModule; diff --git a/growingio-data/encoder/src/test/java/com/growingio/android/encoder/EncoderTest.java b/growingio-data/encoder/src/test/java/com/growingio/android/encoder/EncoderTest.java index a9364655..3956152e 100644 --- a/growingio-data/encoder/src/test/java/com/growingio/android/encoder/EncoderTest.java +++ b/growingio-data/encoder/src/test/java/com/growingio/android/encoder/EncoderTest.java @@ -21,8 +21,8 @@ import androidx.test.core.app.ApplicationProvider; import com.google.common.truth.Truth; -import com.growingio.android.sdk.track.http.EventEncoder; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventEncoder; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.modelloader.DataFetcher; import com.growingio.android.sdk.track.modelloader.TrackerRegistry; import com.growingio.android.snappy.Snappy; diff --git a/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridBridgeLoader.java b/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridBridgeLoader.java index 3be324a7..112ff9dd 100644 --- a/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridBridgeLoader.java +++ b/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridBridgeLoader.java @@ -21,7 +21,7 @@ import com.growingio.android.sdk.track.modelloader.DataFetcher; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.modelloader.ModelLoaderFactory; -import com.growingio.android.sdk.track.modelloader.data.HybridBridge; +import com.growingio.android.sdk.track.middleware.hybrid.HybridBridge; import com.growingio.android.sdk.track.utils.ClassExistHelper; /** diff --git a/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridDomLoader.java b/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridDomLoader.java index 3e7692d8..79a717e3 100644 --- a/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridDomLoader.java +++ b/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridDomLoader.java @@ -23,8 +23,8 @@ import com.growingio.android.sdk.track.modelloader.LoadDataFetcher; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.modelloader.ModelLoaderFactory; -import com.growingio.android.sdk.track.modelloader.data.HybridDom; -import com.growingio.android.sdk.track.modelloader.data.HybridJson; +import com.growingio.android.sdk.track.middleware.hybrid.HybridDom; +import com.growingio.android.sdk.track.middleware.hybrid.HybridJson; import com.growingio.android.sdk.track.utils.ClassExistHelper; import org.json.JSONObject; diff --git a/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridLibraryGioModule.java b/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridLibraryGioModule.java index b1664c8f..232199ba 100644 --- a/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridLibraryGioModule.java +++ b/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridLibraryGioModule.java @@ -19,9 +19,9 @@ import com.growingio.android.sdk.LibraryGioModule; import com.growingio.android.sdk.track.modelloader.TrackerRegistry; -import com.growingio.android.sdk.track.modelloader.data.HybridBridge; -import com.growingio.android.sdk.track.modelloader.data.HybridDom; -import com.growingio.android.sdk.track.modelloader.data.HybridJson; +import com.growingio.android.sdk.track.middleware.hybrid.HybridBridge; +import com.growingio.android.sdk.track.middleware.hybrid.HybridDom; +import com.growingio.android.sdk.track.middleware.hybrid.HybridJson; import com.growingio.sdk.annotation.GIOLibraryModule; /** diff --git a/growingio-hybrid/src/test/java/com/growingio/android/hybrid/HybridTest.java b/growingio-hybrid/src/test/java/com/growingio/android/hybrid/HybridTest.java index ed429621..20a25856 100644 --- a/growingio-hybrid/src/test/java/com/growingio/android/hybrid/HybridTest.java +++ b/growingio-hybrid/src/test/java/com/growingio/android/hybrid/HybridTest.java @@ -38,9 +38,9 @@ import com.growingio.android.sdk.track.modelloader.DataFetcher; import com.growingio.android.sdk.track.modelloader.LoadDataFetcher; import com.growingio.android.sdk.track.modelloader.ModelLoader; -import com.growingio.android.sdk.track.modelloader.data.HybridBridge; -import com.growingio.android.sdk.track.modelloader.data.HybridDom; -import com.growingio.android.sdk.track.modelloader.data.HybridJson; +import com.growingio.android.sdk.track.middleware.hybrid.HybridBridge; +import com.growingio.android.sdk.track.middleware.hybrid.HybridDom; +import com.growingio.android.sdk.track.middleware.hybrid.HybridJson; import com.growingio.android.sdk.track.providers.ConfigurationProvider; import com.growingio.android.sdk.track.providers.UserInfoProvider; diff --git a/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkHttpDataFetcher.java b/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkHttpDataFetcher.java index f3c60dfd..77590953 100644 --- a/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkHttpDataFetcher.java +++ b/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkHttpDataFetcher.java @@ -16,8 +16,8 @@ package com.growingio.android.okhttp3; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.middleware.http.HttpDataFetcher; diff --git a/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkHttpDataLoader.java b/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkHttpDataLoader.java index 3637e43d..d267d63b 100644 --- a/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkHttpDataLoader.java +++ b/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkHttpDataLoader.java @@ -16,8 +16,8 @@ package com.growingio.android.okhttp3; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.modelloader.ModelLoaderFactory; diff --git a/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkhttpLibraryGioModule.java b/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkhttpLibraryGioModule.java index e78e9a1c..a90889e9 100644 --- a/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkhttpLibraryGioModule.java +++ b/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/OkhttpLibraryGioModule.java @@ -19,8 +19,8 @@ import android.content.Context; import com.growingio.android.sdk.LibraryGioModule; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.modelloader.TrackerRegistry; import com.growingio.sdk.annotation.GIOLibraryModule; diff --git a/growingio-network/okhttp3/src/test/java/com/growingio/android/okhttp3/Okhttp3Test.java b/growingio-network/okhttp3/src/test/java/com/growingio/android/okhttp3/Okhttp3Test.java index 174dc414..7067bded 100644 --- a/growingio-network/okhttp3/src/test/java/com/growingio/android/okhttp3/Okhttp3Test.java +++ b/growingio-network/okhttp3/src/test/java/com/growingio/android/okhttp3/Okhttp3Test.java @@ -19,8 +19,8 @@ import android.util.Log; import com.google.common.truth.Truth; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.middleware.http.HttpDataFetcher; import com.growingio.android.sdk.track.modelloader.LoadDataFetcher; import com.growingio.android.sdk.track.modelloader.ModelLoader; diff --git a/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionDataLoader.java b/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionDataLoader.java index 0e2ccf59..28180f6b 100644 --- a/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionDataLoader.java +++ b/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionDataLoader.java @@ -16,8 +16,8 @@ package com.growingio.android.urlconnection; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.modelloader.ModelLoaderFactory; diff --git a/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionFetcher.java b/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionFetcher.java index 4051c689..301e8a41 100644 --- a/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionFetcher.java +++ b/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionFetcher.java @@ -18,8 +18,8 @@ import android.text.TextUtils; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.middleware.http.HttpDataFetcher; diff --git a/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionGioModule.java b/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionGioModule.java index 1a18445f..466795d6 100644 --- a/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionGioModule.java +++ b/growingio-network/urlconnection/src/main/java/com/growingio/android/urlconnection/UrlConnectionGioModule.java @@ -19,8 +19,8 @@ import android.content.Context; import com.growingio.android.sdk.LibraryGioModule; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.modelloader.TrackerRegistry; import com.growingio.sdk.annotation.GIOLibraryModule; diff --git a/growingio-network/urlconnection/src/test/java/com/growingio/android/uriconnection/UrlConnectionTest.java b/growingio-network/urlconnection/src/test/java/com/growingio/android/uriconnection/UrlConnectionTest.java index bdb59d8c..e8a3bc16 100644 --- a/growingio-network/urlconnection/src/test/java/com/growingio/android/uriconnection/UrlConnectionTest.java +++ b/growingio-network/urlconnection/src/test/java/com/growingio/android/uriconnection/UrlConnectionTest.java @@ -22,8 +22,8 @@ import androidx.test.core.app.ApplicationProvider; import com.google.common.truth.Truth; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.middleware.http.HttpDataFetcher; import com.growingio.android.sdk.track.modelloader.LoadDataFetcher; import com.growingio.android.sdk.track.modelloader.ModelLoader; diff --git a/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyDataFetcher.java b/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyDataFetcher.java index d7eb6d9d..f6e87415 100644 --- a/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyDataFetcher.java +++ b/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyDataFetcher.java @@ -26,8 +26,8 @@ import com.android.volley.VolleyError; import com.android.volley.toolbox.HttpHeaderParser; import com.android.volley.toolbox.RequestFuture; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.middleware.http.HttpDataFetcher; diff --git a/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyDataLoader.java b/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyDataLoader.java index 25550ee7..02cb54be 100644 --- a/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyDataLoader.java +++ b/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyDataLoader.java @@ -20,8 +20,8 @@ import com.android.volley.RequestQueue; import com.android.volley.toolbox.Volley; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.modelloader.ModelLoaderFactory; diff --git a/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyLibraryGioModule.java b/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyLibraryGioModule.java index 488f8f7c..0bd8dcf1 100644 --- a/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyLibraryGioModule.java +++ b/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyLibraryGioModule.java @@ -19,8 +19,8 @@ import android.content.Context; import com.growingio.android.sdk.LibraryGioModule; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.modelloader.TrackerRegistry; import com.growingio.sdk.annotation.GIOLibraryModule; diff --git a/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyRequestFactory.java b/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyRequestFactory.java index 1e4d1280..2a8eaa4f 100644 --- a/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyRequestFactory.java +++ b/growingio-network/volley/src/main/java/com/growingio/android/volley/VolleyRequestFactory.java @@ -18,7 +18,7 @@ import com.android.volley.Request; import com.android.volley.Response; -import com.growingio.android.sdk.track.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventResponse; import java.util.Map; diff --git a/growingio-network/volley/src/test/java/com/growingio/android/volley/VolleyTest.java b/growingio-network/volley/src/test/java/com/growingio/android/volley/VolleyTest.java index 44269b83..3d9cb5a7 100644 --- a/growingio-network/volley/src/test/java/com/growingio/android/volley/VolleyTest.java +++ b/growingio-network/volley/src/test/java/com/growingio/android/volley/VolleyTest.java @@ -22,8 +22,8 @@ import androidx.test.core.app.ApplicationProvider; import com.google.common.truth.Truth; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.middleware.http.HttpDataFetcher; import com.growingio.android.sdk.track.modelloader.DataFetcher; import com.growingio.android.sdk.track.modelloader.LoadDataFetcher; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/Tracker.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/Tracker.java index 18d0c1ee..64f79774 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/Tracker.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/Tracker.java @@ -34,7 +34,7 @@ import com.growingio.android.sdk.track.events.TrackEventGenerator; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.modelloader.ModelLoader; -import com.growingio.android.sdk.track.modelloader.data.HybridBridge; +import com.growingio.android.sdk.track.middleware.hybrid.HybridBridge; import com.growingio.android.sdk.track.providers.ActivityStateProvider; import com.growingio.android.sdk.track.providers.ConfigurationProvider; import com.growingio.android.sdk.track.providers.DeepLinkProvider; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/TrackMainThread.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/TrackMainThread.java index 47b138a0..e4c6c28b 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/TrackMainThread.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/TrackMainThread.java @@ -23,13 +23,12 @@ import android.support.annotation.NonNull; import com.growingio.android.sdk.CoreConfiguration; -import com.growingio.android.sdk.TrackerContext; import com.growingio.android.sdk.track.ipc.PersistentDataProvider; import com.growingio.android.sdk.track.events.EventBuildInterceptor; import com.growingio.android.sdk.track.events.helper.EventExcludeFilter; import com.growingio.android.sdk.track.events.base.BaseEvent; -import com.growingio.android.sdk.track.interfaces.OnTrackMainInitSDKCallback; -import com.growingio.android.sdk.track.interfaces.TrackThread; +import com.growingio.android.sdk.track.listener.OnTrackMainInitSDKCallback; +import com.growingio.android.sdk.track.listener.TrackThread; import com.growingio.android.sdk.track.listener.ListenerContainer; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.middleware.EventSender; @@ -58,7 +57,7 @@ public final class TrackMainThread extends ListenerContainer { private String mGoogleAdvertisingId; private Map mExtraSdk; - Builder() { + public Builder() { super(); } diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/base/BaseEvent.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/base/BaseEvent.java index 015c62c5..9439b111 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/base/BaseEvent.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/base/BaseEvent.java @@ -26,7 +26,7 @@ import com.growingio.android.sdk.track.ipc.EventSequenceId; import com.growingio.android.sdk.track.ipc.PersistentDataProvider; import com.growingio.android.sdk.track.events.helper.FieldIgnoreFilter; -import com.growingio.android.sdk.track.interfaces.TrackThread; +import com.growingio.android.sdk.track.listener.TrackThread; import com.growingio.android.sdk.track.middleware.GEvent; import com.growingio.android.sdk.track.providers.ActivityStateProvider; import com.growingio.android.sdk.track.providers.AppInfoProvider; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventEncoder.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventEncoder.java deleted file mode 100644 index f8adbe2f..00000000 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventEncoder.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.android.sdk.track.http; - -public class EventEncoder { - private final EventUrl eventUrl; - - public EventEncoder(EventUrl eventUrl) { - this.eventUrl = eventUrl; - } - - public EventUrl getEventUrl() { - return eventUrl; - } -} diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/interfaces/OnTrackMainInitSDKCallback.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/interfaces/OnTrackMainInitSDKCallback.java deleted file mode 100644 index 8f26bc90..00000000 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/interfaces/OnTrackMainInitSDKCallback.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.android.sdk.track.interfaces; - -public interface OnTrackMainInitSDKCallback { - @TrackThread - void onTrackMainInitSDK(); -} diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/interfaces/TrackThread.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/interfaces/TrackThread.java deleted file mode 100644 index e8468a6d..00000000 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/interfaces/TrackThread.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.android.sdk.track.interfaces; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.CONSTRUCTOR; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE; - - -/** - * 表明该方法仅在TrackThread执行 - */ -@Documented -@Retention(RetentionPolicy.SOURCE) -@Target({METHOD, CONSTRUCTOR, TYPE, PARAMETER, FIELD}) -public @interface TrackThread { -} diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/ipc/PersistentDataProvider.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/ipc/PersistentDataProvider.java index bd958559..e665c981 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/ipc/PersistentDataProvider.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/ipc/PersistentDataProvider.java @@ -26,7 +26,7 @@ import android.text.TextUtils; import com.growingio.android.sdk.TrackerContext; -import com.growingio.android.sdk.track.interfaces.TrackThread; +import com.growingio.android.sdk.track.listener.TrackThread; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.providers.ConfigurationProvider; import com.growingio.android.sdk.track.providers.SessionProvider; @@ -191,7 +191,7 @@ private void repairPid() { if (isFirstProcess) { setActivityCount(0); - setLatestPauseTime(System.currentTimeMillis()); + setLatestPauseTime(0L); setLatestNonNullUserId(getLoginUserId()); SessionProvider.get().refreshSessionId(); diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/listener/OnTrackMainInitSDKCallback.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/listener/OnTrackMainInitSDKCallback.java new file mode 100644 index 00000000..911ecfab --- /dev/null +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/listener/OnTrackMainInitSDKCallback.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.track.listener; + +public interface OnTrackMainInitSDKCallback { + @TrackThread + void onTrackMainInitSDK(); +} diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/listener/TrackThread.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/listener/TrackThread.java new file mode 100644 index 00000000..50fdb6b7 --- /dev/null +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/listener/TrackThread.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * + * 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.growingio.android.sdk.track.listener; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; + + +/** + * 表明该方法仅在TrackThread执行 + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target({METHOD, CONSTRUCTOR, TYPE, PARAMETER, FIELD}) +public @interface TrackThread { +} diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventHttpSender.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventHttpSender.java index afa173f7..a95217f4 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventHttpSender.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventHttpSender.java @@ -22,9 +22,9 @@ import com.growingio.android.sdk.CoreConfiguration; import com.growingio.android.sdk.TrackerContext; import com.growingio.android.sdk.track.events.base.BaseEvent; -import com.growingio.android.sdk.track.http.EventEncoder; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventEncoder; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.providers.ConfigurationProvider; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventSender.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventSender.java index c372966b..e19275ba 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventSender.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventSender.java @@ -62,18 +62,17 @@ public class EventSender { /** * 事件发送管理类 * - * @param context Context对象 * @param sender 网络发送的sender * @param dataUploadInterval 发送事件的时间周期,单位 s * @param cellularDataLimit 事件发送的移动网络的流量限制,单位 MB */ - public EventSender(Context context, IEventNetSender sender, long dataUploadInterval, long cellularDataLimit) { - mContext = context; + public EventSender(IEventNetSender sender, long dataUploadInterval, long cellularDataLimit) { + mContext = TrackerContext.get().getApplicationContext(); mCellularDataLimit = cellularDataLimit * 1024L * 1024L; mDataUploadInterval = dataUploadInterval * 1000L; mEventNetSender = sender; - mProcessLock = new ProcessLock(context, EventSender.class.getName()); - mSharedPreferences = context.getSharedPreferences("growing3_sender", Context.MODE_PRIVATE); + mProcessLock = new ProcessLock(mContext, EventSender.class.getName()); + mSharedPreferences = mContext.getSharedPreferences("growing3_sender", Context.MODE_PRIVATE); HandlerThread thread = new HandlerThread(EventSender.class.getName()); thread.start(); mSendHandler = new SendHandler(thread.getLooper()); @@ -103,6 +102,10 @@ public void setEventNetSender(IEventNetSender mEventNetSender) { public void cacheEvent(GEvent event) { databaseOperation(EventDatabase.insert(event)); + // 避免不触发非INSTANT事件时(如埋点SDK),cache事件不被发送 + if (mDataUploadInterval <= 0) { + mSendHandler.uploadUninstantEvents(); + } } public void sendEvent(GEvent event) { @@ -241,6 +244,7 @@ && mCellularDataLimit < todayBytes(0)) { * this api adapt for adSdk(https://github.com/growingio/growingio-sdk-android-advert) * if you want modify it,please check adsdk first */ + @Deprecated public EventDbResult getGEventsFromPolicy(int policy) { return databaseOperation(EventDatabase.queryAndDelete(policy, numOfMaxEventsPerRequest())); } diff --git a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackClassWriter.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventEncoder.java similarity index 60% rename from growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackClassWriter.java rename to growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventEncoder.java index 34279d08..6e7312ec 100644 --- a/growingio-autotracker-gradle-plugin/src/main/java/com/growingio/sdk/plugin/autotrack/compile/AutotrackClassWriter.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventEncoder.java @@ -14,24 +14,16 @@ * limitations under the License. */ -package com.growingio.sdk.plugin.autotrack.compile; +package com.growingio.android.sdk.track.middleware.http; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; +public class EventEncoder { + private final EventUrl eventUrl; - -/** - *

- * just for get asm version - * @author cpacm 2021/12/6 - */ -public class AutotrackClassWriter extends ClassWriter { - - public AutotrackClassWriter(final ClassReader classReader, final int flags) { - super(classReader, flags); + public EventEncoder(EventUrl eventUrl) { + this.eventUrl = eventUrl; } - public int getApi() { - return api; + public EventUrl getEventUrl() { + return eventUrl; } } diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventResponse.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventResponse.java similarity index 57% rename from growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventResponse.java rename to growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventResponse.java index 13887ec8..a34adc84 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventResponse.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventResponse.java @@ -1,20 +1,20 @@ /* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. * - * 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 + * 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 + * 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. + * 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.growingio.android.sdk.track.http; +package com.growingio.android.sdk.track.middleware.http; import java.io.InputStream; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventUrl.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventUrl.java similarity index 80% rename from growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventUrl.java rename to growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventUrl.java index 438dd16a..7828e8cc 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/http/EventUrl.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventUrl.java @@ -1,20 +1,20 @@ /* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. + * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. * - * 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 + * 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 + * 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. + * 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.growingio.android.sdk.track.http; +package com.growingio.android.sdk.track.middleware.http; import java.util.ArrayList; import java.util.HashMap; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridBridge.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridBridge.java similarity index 93% rename from growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridBridge.java rename to growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridBridge.java index ac60c60d..95b359e9 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridBridge.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridBridge.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.growingio.android.sdk.track.modelloader.data; +package com.growingio.android.sdk.track.middleware.hybrid; import android.view.View; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridDom.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridDom.java similarity index 95% rename from growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridDom.java rename to growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridDom.java index 47358d71..d953a0a1 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridDom.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridDom.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.growingio.android.sdk.track.modelloader.data; +package com.growingio.android.sdk.track.middleware.hybrid; import android.view.View; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridJson.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridJson.java similarity index 93% rename from growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridJson.java rename to growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridJson.java index 2049d19f..67a35664 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/modelloader/data/HybridJson.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/hybrid/HybridJson.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.growingio.android.sdk.track.modelloader.data; +package com.growingio.android.sdk.track.middleware.hybrid; import org.json.JSONObject; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/SessionProvider.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/SessionProvider.java index f1bbd939..fb820bb8 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/SessionProvider.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/SessionProvider.java @@ -21,7 +21,7 @@ import com.growingio.android.sdk.track.TrackMainThread; import com.growingio.android.sdk.track.ipc.PersistentDataProvider; import com.growingio.android.sdk.track.events.TrackEventGenerator; -import com.growingio.android.sdk.track.interfaces.TrackThread; +import com.growingio.android.sdk.track.listener.TrackThread; import com.growingio.android.sdk.track.listener.IActivityLifecycle; import com.growingio.android.sdk.track.listener.event.ActivityLifecycleEvent; import com.growingio.android.sdk.track.log.Logger; @@ -55,14 +55,6 @@ public static SessionProvider get() { return SingleInstance.INSTANCE; } - @TrackThread - void checkAndSendVisit(long resumeTime) { - if (resumeTime - PersistentDataProvider.get().getLatestPauseTime() >= mSessionInterval) { - refreshSessionId(); - generateVisit(); - } - } - /** * 刷新sessionId的场景: * 1. 第一个进程初始化时会刷新session @@ -126,12 +118,16 @@ public void onActivityLifecycle(final ActivityLifecycleEvent event) { if (activity == null) return; if (event.eventType == ActivityLifecycleEvent.EVENT_TYPE.ON_STARTED) { if (PersistentDataProvider.get().getActivityCount() == 0) { - TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { - @Override - public void run() { - checkAndSendVisit(System.currentTimeMillis()); - } - }); + long latestPauseTime = PersistentDataProvider.get().getLatestPauseTime(); + if (latestPauseTime != 0 && (System.currentTimeMillis() - latestPauseTime >= mSessionInterval)) { + TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { + @Override + public void run() { + refreshSessionId(); + generateVisit(); + } + }); + } } mActivityList.add(activity.toString()); PersistentDataProvider.get().addActivityCount(); @@ -141,10 +137,10 @@ public void run() { PersistentDataProvider.get().delActivityCount(); } if (PersistentDataProvider.get().getActivityCount() == 0) { + PersistentDataProvider.get().setLatestPauseTime(System.currentTimeMillis()); TrackMainThread.trackMain().postActionToTrackMain(new Runnable() { @Override public void run() { - PersistentDataProvider.get().setLatestPauseTime(System.currentTimeMillis()); TrackEventGenerator.generateAppClosedEvent(); } }); diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/UserInfoProvider.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/UserInfoProvider.java index 41b6d51b..9da08b84 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/UserInfoProvider.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/UserInfoProvider.java @@ -20,7 +20,7 @@ import com.growingio.android.sdk.track.ErrorLog; import com.growingio.android.sdk.track.ipc.PersistentDataProvider; -import com.growingio.android.sdk.track.interfaces.TrackThread; +import com.growingio.android.sdk.track.listener.TrackThread; import com.growingio.android.sdk.track.listener.ListenerContainer; import com.growingio.android.sdk.track.listener.OnUserIdChangedListener; import com.growingio.android.sdk.track.log.Logger; diff --git a/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/middleware/EventSenderTest.java b/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/middleware/EventSenderTest.java index d2a578c1..d20c47da 100644 --- a/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/middleware/EventSenderTest.java +++ b/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/middleware/EventSenderTest.java @@ -61,7 +61,7 @@ public void setup() { ProviderInfo providerInfo = new ProviderInfo(); providerInfo.authority = application.getPackageName() + "." + EventDataContentProvider.class.getSimpleName(); - eventSender = new EventSender(application, null, 0, 10); + eventSender = new EventSender(null, 0, 10); controller.create(providerInfo).get(); } diff --git a/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/middleware/HttpSenderTest.java b/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/middleware/HttpSenderTest.java index a0a1db06..fefde285 100644 --- a/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/middleware/HttpSenderTest.java +++ b/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/middleware/HttpSenderTest.java @@ -24,9 +24,9 @@ import com.google.common.truth.Truth; import com.growingio.android.sdk.TrackerContext; import com.growingio.android.sdk.track.events.CustomEvent; -import com.growingio.android.sdk.track.http.EventEncoder; -import com.growingio.android.sdk.track.http.EventResponse; -import com.growingio.android.sdk.track.http.EventUrl; +import com.growingio.android.sdk.track.middleware.http.EventEncoder; +import com.growingio.android.sdk.track.middleware.http.EventResponse; +import com.growingio.android.sdk.track.middleware.http.EventUrl; import org.junit.Before; import org.junit.Test; diff --git a/growingio-webservice/circler/src/main/java/com/growingio/android/circler/ThreadSafeTipView.java b/growingio-webservice/circler/src/main/java/com/growingio/android/circler/ThreadSafeTipView.java index 0bb779be..71d498eb 100644 --- a/growingio-webservice/circler/src/main/java/com/growingio/android/circler/ThreadSafeTipView.java +++ b/growingio-webservice/circler/src/main/java/com/growingio/android/circler/ThreadSafeTipView.java @@ -48,7 +48,7 @@ private void initView() { public ThreadSafeTipView(Context context) { this.context = context; - runOnUiThread(this::initView); + runOnUiThread(() -> initView()); } public void enableShow() { diff --git a/growingio-webservice/circler/src/main/java/com/growingio/android/circler/screenshot/CircleScreenshot.java b/growingio-webservice/circler/src/main/java/com/growingio/android/circler/screenshot/CircleScreenshot.java index 74c7f5f2..19bbd30a 100644 --- a/growingio-webservice/circler/src/main/java/com/growingio/android/circler/screenshot/CircleScreenshot.java +++ b/growingio-webservice/circler/src/main/java/com/growingio/android/circler/screenshot/CircleScreenshot.java @@ -30,8 +30,8 @@ import com.growingio.android.sdk.track.async.Callback; import com.growingio.android.sdk.track.modelloader.LoadDataFetcher; import com.growingio.android.sdk.track.modelloader.ModelLoader; -import com.growingio.android.sdk.track.modelloader.data.HybridDom; -import com.growingio.android.sdk.track.modelloader.data.HybridJson; +import com.growingio.android.sdk.track.middleware.hybrid.HybridDom; +import com.growingio.android.sdk.track.middleware.hybrid.HybridJson; import com.growingio.android.sdk.track.utils.ClassExistHelper; import com.growingio.android.sdk.track.utils.DeviceUtil; import com.growingio.android.sdk.track.view.DecorView; diff --git a/growingio-webservice/circler/src/main/java/com/growingio/android/circler/screenshot/ScreenshotProvider.java b/growingio-webservice/circler/src/main/java/com/growingio/android/circler/screenshot/ScreenshotProvider.java index e14c91de..db239fd0 100644 --- a/growingio-webservice/circler/src/main/java/com/growingio/android/circler/screenshot/ScreenshotProvider.java +++ b/growingio-webservice/circler/src/main/java/com/growingio/android/circler/screenshot/ScreenshotProvider.java @@ -26,8 +26,8 @@ import com.growingio.android.sdk.track.listener.ListenerContainer; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.modelloader.ModelLoader; -import com.growingio.android.sdk.track.modelloader.data.HybridDom; -import com.growingio.android.sdk.track.modelloader.data.HybridJson; +import com.growingio.android.sdk.track.middleware.hybrid.HybridDom; +import com.growingio.android.sdk.track.middleware.hybrid.HybridJson; import com.growingio.android.sdk.track.utils.DeviceUtil; import com.growingio.android.sdk.track.view.DecorView; import com.growingio.android.sdk.track.view.ScreenshotUtil; diff --git a/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/DebuggerDataLoader.java b/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/DebuggerDataLoader.java index ef61b7ba..80f33d57 100644 --- a/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/DebuggerDataLoader.java +++ b/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/DebuggerDataLoader.java @@ -65,11 +65,12 @@ private static OkHttpClient getsInternalClient() { } public Factory() { + // in order to cache app start event,like:visit,first page event + DebuggerEventWrapper.get().observeEventBuild(); } @Override public ModelLoader build() { - DebuggerEventWrapper.get().observeEventBuild(); return new DebuggerDataLoader(getsInternalClient()); } } diff --git a/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/ScreenshotProvider.java b/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/ScreenshotProvider.java index a0614789..d698d8ea 100644 --- a/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/ScreenshotProvider.java +++ b/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/ScreenshotProvider.java @@ -27,8 +27,8 @@ import com.growingio.android.sdk.track.listener.ListenerContainer; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.modelloader.ModelLoader; -import com.growingio.android.sdk.track.modelloader.data.HybridDom; -import com.growingio.android.sdk.track.modelloader.data.HybridJson; +import com.growingio.android.sdk.track.middleware.hybrid.HybridDom; +import com.growingio.android.sdk.track.middleware.hybrid.HybridJson; import com.growingio.android.sdk.track.utils.DeviceUtil; import com.growingio.android.sdk.track.view.DecorView; import com.growingio.android.sdk.track.view.ScreenshotUtil; diff --git a/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/ThreadSafeTipView.java b/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/ThreadSafeTipView.java index 3d86bfe8..e60dab59 100644 --- a/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/ThreadSafeTipView.java +++ b/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/ThreadSafeTipView.java @@ -48,7 +48,7 @@ private void initView() { public ThreadSafeTipView(Context context) { this.context = context; - runOnUiThread(this::initView); + runOnUiThread(() -> initView()); } public void enableShow() { diff --git a/inject-annotation/build.gradle b/inject-annotation/build.gradle deleted file mode 100644 index 8f7bb2c3..00000000 --- a/inject-annotation/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply plugin: 'java-library' - -java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} \ No newline at end of file diff --git a/inject-annotation/compiler/build.gradle b/inject-annotation/compiler/build.gradle deleted file mode 100644 index bdcc52b5..00000000 --- a/inject-annotation/compiler/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -import org.gradle.internal.jvm.Jvm - -plugins{ - id 'java-library' - id 'jacoco' -} - -java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} - -jacocoTestReport{ - dependsOn test // report is always generated after tests run -} - -dependencies { - testImplementation libraries.test.junit - testImplementation("com.google.testing.compile:compile-testing:0.19") { - // We don't use this and including it requires us to list it separatel which would be - // confusing. - exclude group: "com.google.auto.value", module: "auto-value" - } - - annotationProcessor libraries.google.auto_service - implementation libraries.google.auto_service_annotations - implementation libraries.squareup.javapoet - implementation libraries.android.gradle_plugin - implementation project(':inject-annotation') - - if (!Jvm.current().getJavaVersion().java9Compatible) { - compileOnly files(Jvm.current().getToolsJar()) - } -} \ No newline at end of file diff --git a/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/AnnotationUtil.java b/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/AnnotationUtil.java deleted file mode 100644 index fe7920e3..00000000 --- a/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/AnnotationUtil.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.compiler; - -import com.sun.tools.javac.code.Attribute; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; - -public final class AnnotationUtil { - private AnnotationUtil() { - } - - @Nullable - public static String getClassValue(ProcessingEnvironment processingEnv, AnnotationMirror annotationMirror, String key) { - AnnotationValue annotationValue = getAnnotationValue(annotationMirror, key); - if (annotationValue == null) { - return null; - } - - if (annotationValue instanceof Attribute.Class) { - return ((Attribute.Class) annotationValue).classType.asElement().flatName().toString(); - } - return null; - //return getConvertName(processingEnv, annotationValue.getValue().toString()); - } - - public static String getStringValue(AnnotationMirror annotationMirror, String key) { - AnnotationValue annotationValue = getAnnotationValue(annotationMirror, key); - if (annotationValue == null) { - return null; - } - return annotationValue.getValue().toString(); - } - - @Nullable - public static List getClassesValue(AnnotationMirror annotationMirror, String key) { - AnnotationValue annotationValue = getAnnotationValue(annotationMirror, key); - if (annotationValue == null) { - return null; - } - -// if (annotationValue instanceof Attribute.Array) { -// Attribute.Array arrayValue = (Attribute.Array) annotationValue; -// List valueList = new ArrayList<>(); -// for (Attribute value : arrayValue.values) { -// if (value instanceof Attribute.Class) { -// valueList.add(((Attribute.Class) value).classType.asElement().flatName().toString()); -// } else { -// throw new IllegalArgumentException(value + " is NOT CLASS"); -// } -// } -// return valueList; -// } - - Object values = annotationValue.getValue(); - - if (values instanceof List) { - List valueList = (List) values; - List result = new ArrayList<>(); - for (Object current : valueList) { - result.add(getClassFromAnnotationAttribute(current)); - } - return result; - } - return null; - - } - - private static String getClassFromAnnotationAttribute(Object attribute) { - if (attribute.getClass().isAssignableFrom(Attribute.UnresolvedClass.class)) { - throw new IllegalArgumentException( - "Failed to parse class for: " - + attribute - + ".Ensure that all" - + "class are included in your classpath."); - } - Method[] methods = attribute.getClass().getDeclaredMethods(); - if (methods.length == 0) { - throw new IllegalArgumentException( - "Failed to parse class for: " + attribute); - } - for (Method method : methods) { - if (method.getName().equals("getValue")) { - try { - return method.invoke(attribute).toString(); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalArgumentException("Failed to parse class for: " + attribute, e); - } - } - } - throw new IllegalArgumentException("Failed to parse class for: " + attribute); - } - - @Nullable - @SuppressWarnings("unchecked") - public static List getAnnotations(AnnotationMirror annotationMirror, String key) { - AnnotationValue annotationValue = getAnnotationValue(annotationMirror, key); - if (annotationValue == null) { - return null; - } - - if (annotationValue.getValue() instanceof List) { - return (List) annotationValue.getValue(); - } - - return null; - } - - public static AnnotationMirror findAnnotationMirror(Element element, Class annotationClazz) { - for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { - if (annotationClazz.getName().equals(annotationMirror.getAnnotationType().toString())) { - return annotationMirror; - } - } - return null; - } - - private static AnnotationValue getAnnotationValue(AnnotationMirror annotationMirror, String key) { - Map valueMap = annotationMirror.getElementValues(); - for (ExecutableElement executableElement : valueMap.keySet()) { - if (key.equals(executableElement.getSimpleName().toString())) { - return valueMap.get(executableElement); - } - } - return null; - } -} diff --git a/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/InjectProcessor.java b/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/InjectProcessor.java deleted file mode 100644 index 201cdb51..00000000 --- a/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/InjectProcessor.java +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.compiler; - -import com.android.annotations.VisibleForTesting; -import com.google.auto.service.AutoService; -import com.growingio.sdk.inject.annotation.After; -import com.growingio.sdk.inject.annotation.AfterSuper; -import com.growingio.sdk.inject.annotation.AfterSupers; -import com.growingio.sdk.inject.annotation.Afters; -import com.growingio.sdk.inject.annotation.Before; -import com.growingio.sdk.inject.annotation.BeforeSuper; -import com.growingio.sdk.inject.annotation.BeforeSupers; -import com.growingio.sdk.inject.annotation.Befores; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.FieldSpec; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; -import com.squareup.javapoet.TypeSpec; -import com.sun.tools.javac.code.Symbol; -import com.sun.tools.javac.code.Types; - -import org.apache.commons.io.IOUtils; -import org.objectweb.asm.Type; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.lang.annotation.Annotation; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.Messager; -import javax.annotation.processing.ProcessingEnvironment; -import javax.annotation.processing.Processor; -import javax.annotation.processing.RoundEnvironment; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.tools.Diagnostic; - -@AutoService(Processor.class) -public class InjectProcessor extends AbstractProcessor { - private static final String TAG = "InjectProcessor"; - private static final boolean DEBUG = false; - private static final String LICENSE_HEADER = "/*\n" + - " * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd.\n" + - " *\n" + - " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" + - " * you may not use this file except in compliance with the License.\n" + - " * You may obtain a copy of the License at\n" + - " *\n" + - " * http://www.apache.org/licenses/LICENSE-2.0\n" + - " *\n" + - " * Unless required by applicable law or agreed to in writing, software\n" + - " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" + - " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" + - " * See the License for the specific language governing permissions and\n" + - " * limitations under the License.\n" + - " */"; - - private final List> mAroundHookClassesArgs = new ArrayList<>(); - private final List> mSuperHookClassesArgs = new ArrayList<>(); - - private Messager mMessager; - private ProcessingEnvironment processingEnv; - private String testPath; - - public InjectProcessor(String testPath) { - this.testPath = testPath; - } - - public InjectProcessor() { - this.testPath = null; - } - - @Override - public synchronized void init(ProcessingEnvironment processingEnvironment) { - super.init(processingEnvironment); - mMessager = processingEnvironment.getMessager(); - this.processingEnv = processingEnvironment; - log("InjectProcessor init finish"); - } - - @Override - public Set getSupportedAnnotationTypes() { - Set types = new HashSet<>(); - types.add(Before.class.getCanonicalName()); - types.add(After.class.getCanonicalName()); - types.add(BeforeSuper.class.getCanonicalName()); - types.add(AfterSuper.class.getCanonicalName()); - - types.add(Befores.class.getCanonicalName()); - types.add(Afters.class.getCanonicalName()); - types.add(BeforeSupers.class.getCanonicalName()); - types.add(AfterSupers.class.getCanonicalName()); - return types; - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.RELEASE_8; - } - - @SuppressWarnings("unchecked") - @Override - public boolean process(Set set, RoundEnvironment roundEnvironment) { - Class[] allAnnotations = new Class[]{Before.class, After.class, BeforeSuper.class, AfterSuper.class, - Befores.class, Afters.class, BeforeSupers.class, AfterSupers.class}; - for (Class annotation : allAnnotations) { - analyzeAnnotation(annotation, roundEnvironment); - } - - generateJavaFile(); - return false; - } - - private void analyzeAnnotation(Class clazz, RoundEnvironment roundEnvironment) { - Set elements = roundEnvironment.getElementsAnnotatedWith(clazz); - for (Element element : elements) { - log("================[@" + clazz.getSimpleName() + "] " + element.getEnclosingElement() + "#" + element.getSimpleName() + "================"); - if (clazz == Befores.class || clazz == Afters.class || clazz == BeforeSupers.class || clazz == AfterSupers.class) { - AnnotationMirror mirror = AnnotationUtil.findAnnotationMirror(element, clazz); - if (mirror == null) { - continue; - } - List annotations = AnnotationUtil.getAnnotations(mirror, "value"); - if (annotations != null && !annotations.isEmpty()) { - for (AnnotationMirror annotation : annotations) { - stashHookClassesArgs(element, annotation); - } - } - } else { - stashHookClassesArgs(element, AnnotationUtil.findAnnotationMirror(element, clazz)); - } - } - } - - private void stashHookClassesArgs(Element element, AnnotationMirror annotationMirror) { - String originalTargetClassName = AnnotationUtil.getClassValue(processingEnv, annotationMirror, "clazz"); - String targetClassName = TypeUtil.getInternalName(originalTargetClassName); - - String targetMethodName = AnnotationUtil.getStringValue(annotationMirror, "method"); - List targetParameters = AnnotationUtil.getClassesValue(annotationMirror, "parameterTypes"); - if (targetParameters == null) { - targetParameters = new ArrayList<>(); - } - Type[] argumentTypes = new Type[targetParameters.size()]; - for (int i = 0; i < targetParameters.size(); i++) { - argumentTypes[i] = TypeUtil.getType(targetParameters.get(i)); - } - String targetReturnType = AnnotationUtil.getClassValue(processingEnv, annotationMirror, "returnType"); - if (targetReturnType == null) { - targetReturnType = void.class.getName(); - } - Type returnType = TypeUtil.getType(targetReturnType); - String targetDesc = Type.getMethodDescriptor(returnType, argumentTypes); - - String originalInjectClass = element.getEnclosingElement().toString(); - String injectClass = TypeUtil.getInternalName(originalInjectClass); - String injectMethod = element.getSimpleName().toString(); - -// if (element instanceof ExecutableElement) { -// List injectParameters = new ArrayList<>(); -// List methodParams = ((ExecutableElement) element).getParameters(); -// for (VariableElement param : methodParams) { -// String className = param.asType().toString(); -// String convertName = AnnotationUtil.getConvertName(processingEnv, className); -// injectParameters.add(convertName); -// } -// System.out.println("[change]:" + injectParameters.toString()); -// } - - if (element instanceof Symbol.MethodSymbol) { - List injectParameters = new ArrayList<>(); - Symbol.MethodSymbol methodSymbol = (Symbol.MethodSymbol) element; - List parameters = methodSymbol.getParameters(); - for (Symbol.VarSymbol parameter : parameters) { - injectParameters.add(parameter.asType().accept(new Types.DefaultTypeVisitor() { - @Override - public String visitArrayType(com.sun.tools.javac.code.Type.ArrayType t, Void unused) { - return t.elemtype.accept(this, null) + "[]"; - } - - @Override - public String visitType(com.sun.tools.javac.code.Type type, Void unused) { - return type.asElement().flatName().toString(); - } - }, null)); - } - argumentTypes = new Type[injectParameters.size()]; - for (int i = 0; i < injectParameters.size(); i++) { - argumentTypes[i] = TypeUtil.getType(injectParameters.get(i)); - } - String injectReturnType = void.class.getName(); - returnType = TypeUtil.getType(injectReturnType); - String injectDesc = Type.getMethodDescriptor(returnType, argumentTypes); - - String annotationClass = annotationMirror.getAnnotationType().toString(); - boolean isAfter = After.class.getName().equals(annotationClass) || AfterSuper.class.getName().equals(annotationClass); - - log(originalTargetClassName + "#" + targetMethodName); - if (Before.class.getName().equals(annotationClass) || After.class.getName().equals(annotationClass)) { - mAroundHookClassesArgs.add(Arrays.asList(targetClassName, targetMethodName, targetDesc, injectClass, injectMethod, injectDesc, isAfter)); - } else { - mSuperHookClassesArgs.add(Arrays.asList(targetClassName, targetMethodName, targetDesc, injectClass, injectMethod, injectDesc, isAfter)); - } - } - } - - - private void log(String msg) { - if (DEBUG) mMessager.printMessage(Diagnostic.Kind.NOTE, TAG + ": " + msg); - } - - private void generateJavaFile() { - try { - TypeSpec.Builder builder = TypeSpec.classBuilder("HookClassesConfig") - .addModifiers(Modifier.PUBLIC); - - builder.addJavadoc("该Class是由 inject-compiler 自动生成的,请不要随意更改!"); - - ClassName mapClass = ClassName.get(Map.class); - ClassName hashMapClass = ClassName.get(HashMap.class); - ClassName stringClass = ClassName.get(String.class); - ClassName collectionsClass = ClassName.get(Collections.class); - ClassName targetClassClass = ClassName.get("com.growingio.sdk.plugin.autotrack.hook", "TargetClass"); - ClassName targetMethodClass = ClassName.get("com.growingio.sdk.plugin.autotrack.hook", "TargetMethod"); - ClassName injectMethodClass = ClassName.get("com.growingio.sdk.plugin.autotrack.hook", "InjectMethod"); - TypeName mapOfTargetClass = ParameterizedTypeName.get(mapClass, stringClass, targetClassClass); - - FieldSpec aroundMethodMapField = FieldSpec.builder(mapOfTargetClass, "AROUND_HOOK_CLASSES") - .addModifiers(Modifier.PRIVATE) - .addModifiers(Modifier.STATIC) - .addModifiers(Modifier.FINAL) - .initializer("new $T<>()", hashMapClass) - .build(); - builder.addField(aroundMethodMapField); - - FieldSpec superMethodMapField = FieldSpec.builder(mapOfTargetClass, "SUPER_HOOK_CLASSES") - .addModifiers(Modifier.PRIVATE) - .addModifiers(Modifier.STATIC) - .addModifiers(Modifier.FINAL) - .initializer("new $T<>()", hashMapClass) - .build(); - builder.addField(superMethodMapField); - - CodeBlock.Builder staticBlock = CodeBlock.builder(); - for (List arg : mAroundHookClassesArgs) { - staticBlock.addStatement("putAroundHookMethod($S, $S, $S, $S, $S, $S, $L)", - arg.get(0), arg.get(1), arg.get(2), arg.get(3), arg.get(4), arg.get(5), arg.get(6)); - } - for (List arg : mSuperHookClassesArgs) { - staticBlock.addStatement("putSuperHookMethod($S, $S, $S, $S, $S, $S, $L)", - arg.get(0), arg.get(1), arg.get(2), arg.get(3), arg.get(4), arg.get(5), arg.get(6)); - } - builder.addStaticBlock(staticBlock.build()); - - MethodSpec constructor = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PRIVATE) - .build(); - builder.addMethod(constructor); - - MethodSpec putAroundHookMethod = MethodSpec.methodBuilder("putAroundHookMethod") - .addModifiers(Modifier.PRIVATE) - .addModifiers(Modifier.STATIC) - .returns(void.class) - .addParameter(String.class, "targetClassName") - .addParameter(String.class, "targetMethodName") - .addParameter(String.class, "targetMethodDesc") - .addParameter(String.class, "injectClassName") - .addParameter(String.class, "injectMethodName") - .addParameter(String.class, "injectMethodDesc") - .addParameter(boolean.class, "isAfter") - .addStatement("putHookMethod(AROUND_HOOK_CLASSES, targetClassName, targetMethodName, targetMethodDesc, injectClassName, injectMethodName, injectMethodDesc, isAfter)") - .build(); - builder.addMethod(putAroundHookMethod); - - MethodSpec putSuperHookMethod = MethodSpec.methodBuilder("putSuperHookMethod") - .addModifiers(Modifier.PRIVATE) - .addModifiers(Modifier.STATIC) - .returns(void.class) - .addParameter(String.class, "targetClassName") - .addParameter(String.class, "targetMethodName") - .addParameter(String.class, "targetMethodDesc") - .addParameter(String.class, "injectClassName") - .addParameter(String.class, "injectMethodName") - .addParameter(String.class, "injectMethodDesc") - .addParameter(boolean.class, "isAfter") - .addStatement("putHookMethod(SUPER_HOOK_CLASSES, targetClassName, targetMethodName, targetMethodDesc, injectClassName, injectMethodName, injectMethodDesc, isAfter)") - .build(); - builder.addMethod(putSuperHookMethod); - - MethodSpec putHookMethod = MethodSpec.methodBuilder("putHookMethod") - .addModifiers(Modifier.PRIVATE) - .addModifiers(Modifier.STATIC) - .returns(void.class) - .addParameter(mapOfTargetClass, "classMap") - .addParameter(String.class, "targetClassName") - .addParameter(String.class, "targetMethodName") - .addParameter(String.class, "targetMethodDesc") - .addParameter(String.class, "injectClassName") - .addParameter(String.class, "injectMethodName") - .addParameter(String.class, "injectMethodDesc") - .addParameter(boolean.class, "isAfter") - .addCode("$T targetClass = classMap.get(targetClassName);\n" + - " if (targetClass == null) {\n" + - " targetClass = new $T(targetClassName);\n" + - " classMap.put(targetClassName, targetClass);\n" + - " }\n" + - " $T targetMethod = targetClass.getTargetMethod(targetMethodName, targetMethodDesc);\n" + - " if (targetMethod == null) {\n" + - " targetMethod = new $T(targetMethodName, targetMethodDesc);\n" + - " targetClass.addTargetMethod(targetMethod);\n" + - " }\n" + - " targetMethod.addInjectMethod(new $T(injectClassName, injectMethodName, injectMethodDesc, isAfter));\n", - targetClassClass, targetClassClass, targetMethodClass, targetMethodClass, injectMethodClass) - .build(); - builder.addMethod(putHookMethod); - - MethodSpec getAroundHookClasses = MethodSpec.methodBuilder("getAroundHookClasses") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(mapOfTargetClass) - .addStatement("return $T.unmodifiableMap(AROUND_HOOK_CLASSES)", collectionsClass) - .build(); - builder.addMethod(getAroundHookClasses); - - MethodSpec getSuperHookClasses = MethodSpec.methodBuilder("getSuperHookClasses") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(mapOfTargetClass) - .addStatement("return $T.unmodifiableMap(SUPER_HOOK_CLASSES)", collectionsClass) - .build(); - builder.addMethod(getSuperHookClasses); - - JavaFile javaFile = JavaFile.builder("com.growingio.sdk.plugin.autotrack.hook", builder.build()) - .skipJavaLangImports(true) - .build(); - if (testPath != null) { - generateTestJava(javaFile); - } else { - generatePerfectJava(javaFile); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void generatePerfectJava(JavaFile javaFile) throws IOException { - String rootDir = processingEnv.getOptions().get("GRADLE_PLUGIN_DIR"); - if (rootDir == null) { - rootDir = getProjectRootPath(); - } - String classPath = rootDir + "/src/main/java/" + javaFile.packageName.replace(".", "/") + "/" + javaFile.typeSpec.name + ".java"; - File file = new File(classPath); - OutputStream out = new FileOutputStream(file); - - StringBuilder builder = new StringBuilder(LICENSE_HEADER); - builder.append(System.lineSeparator()) - .append(javaFile.toString()); - IOUtils.write(builder, out); - } - - private String getProjectRootPath() throws UnsupportedEncodingException { - File userDir = new File(System.getProperty("user.dir")); - File findPlugin = getGrowingPluginPath(userDir, 0); - if (findPlugin != null) { - return URLDecoder.decode(findPlugin.getPath(), StandardCharsets.UTF_8.name()); - } - return System.getProperty("user.dir") + "/growingio-autotracker-gradle-plugin"; - } - - private File getGrowingPluginPath(File userDir, int depth) { - if (depth >= 5 || userDir == null || !userDir.isDirectory()) return null; - File[] dirList = userDir.listFiles(); - if (dirList == null || dirList.length == 0) - return getGrowingPluginPath(userDir.getParentFile(), depth + 1); - for (File file : dirList) { - if (file.isDirectory() && file.getName().equals("growingio-autotracker-gradle-plugin")) { - return file; - } - } - return getGrowingPluginPath(userDir.getParentFile(), depth + 1); - } - - @VisibleForTesting - void generateTestJava(JavaFile javaFile) throws IOException { - String originPath = getProjectRootPath(); - if (originPath.endsWith("growingio-autotracker-gradle-plugin")) { - log("====[file origin generate]:" + originPath); - } - log("====[file test generate]:" + testPath); - File file = new File(testPath); - OutputStream out = new FileOutputStream(file); - - StringBuilder builder = new StringBuilder(LICENSE_HEADER); - builder.append(System.lineSeparator()) - .append(javaFile.toString()); - IOUtils.write(builder, out); - } - -} \ No newline at end of file diff --git a/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/TypeUtil.java b/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/TypeUtil.java deleted file mode 100644 index 443a5232..00000000 --- a/inject-annotation/compiler/src/main/java/com/growingio/sdk/inject/compiler/TypeUtil.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.compiler; - -import org.objectweb.asm.Type; - -public class TypeUtil { - private TypeUtil() { - } - - public static Type getType(final String clazz) { - return Type.getType(getDescriptor(clazz)); - } - - public static String getInternalName(final String clazz) { - if (isPrimitive(clazz)) { - return getDescriptor(clazz); - } - return getType(clazz).getInternalName(); - } - - public static String getDescriptor(final String clazz) { - StringBuilder buf = new StringBuilder(); - String d = clazz; - while (true) { - if (isPrimitive(d)) { - char car; - if (d.equals(int.class.getName())) { - car = 'I'; - } else if (d.equals(void.class.getName())) { - car = 'V'; - } else if (d.equals(boolean.class.getName())) { - car = 'Z'; - } else if (d.equals(byte.class.getName())) { - car = 'B'; - } else if (d.equals(char.class.getName())) { - car = 'C'; - } else if (d.equals(short.class.getName())) { - car = 'S'; - } else if (d.equals(double.class.getName())) { - car = 'D'; - } else if (d.equals(float.class.getName())) { - car = 'F'; - } else /* if (d == Long.TYPE) */ { - car = 'J'; - } - buf.append(car); - return buf.toString(); - } else if (isArray(d)) { - buf.append('['); - d = d.replace("[]", ""); - } else { - buf.append('L'); - int len = d.length(); - for (int i = 0; i < len; ++i) { - char car = d.charAt(i); - buf.append(car == '.' ? '/' : car); - } - buf.append(';'); - return buf.toString(); - } - } - } - - public static boolean isPrimitive(final String clazz) { - return clazz.equals(int.class.getName()) - || clazz.equals(void.class.getName()) - || clazz.equals(boolean.class.getName()) - || clazz.equals(byte.class.getName()) - || clazz.equals(char.class.getName()) - || clazz.equals(short.class.getName()) - || clazz.equals(double.class.getName()) - || clazz.equals(float.class.getName()) - || clazz.equals(long.class.getName()); - } - - public static boolean isArray(final String clazz) { - return clazz.endsWith("[]"); - } -} diff --git a/inject-annotation/compiler/src/test/java/com/growingio/sdk/inject/compiler/InjectTest.java b/inject-annotation/compiler/src/test/java/com/growingio/sdk/inject/compiler/InjectTest.java deleted file mode 100644 index 5602a4ad..00000000 --- a/inject-annotation/compiler/src/test/java/com/growingio/sdk/inject/compiler/InjectTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.compiler; - -import com.google.common.truth.Truth; -import com.google.testing.compile.Compilation; -import com.google.testing.compile.Compiler; -import com.google.testing.compile.JavaFileObjects; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import javax.tools.JavaFileObject; - -import static com.google.testing.compile.JavaFileObjectSubject.assertThat; - -@RunWith(JUnit4.class) -public class InjectTest { - private static final String MODULE_NAME = "TestInjector.java"; - - private Compilation compilation; - private String generateFile; - - @Before - public void setup() { - generateFile = JavaFileObjects.forResource(getClass().getSimpleName()).getName() + "/HookClassesConfig.java"; - compilation = Compiler.javac().withProcessors(new InjectProcessor(generateFile)).compile(forResource(MODULE_NAME)); - } - - @Test - public void generatedFileTest() { - Truth.assertThat(compilation.generatedFiles().size()).isEqualTo(1); - assertThat(forResource("HookClassesConfig.java")).hasSourceEquivalentTo(forResource("HookClassesConfigTemp.java")); - - } - - private JavaFileObject forResource(String name) { - return TestUtil.forResource(getClass().getSimpleName(), name); - } -} diff --git a/inject-annotation/compiler/src/test/java/com/growingio/sdk/inject/compiler/TestUtil.java b/inject-annotation/compiler/src/test/java/com/growingio/sdk/inject/compiler/TestUtil.java deleted file mode 100644 index ccf9c24b..00000000 --- a/inject-annotation/compiler/src/test/java/com/growingio/sdk/inject/compiler/TestUtil.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.compiler;import com.google.testing.compile.JavaFileObjects; - -import javax.tools.JavaFileObject; - -/** - * Test utilities. - */ -public final class TestUtil { - private static final String REGENERATE_TEST_RESOURCES_PROPERTY_NAME = - "com.growingio.sdk.annotation.compiler.test.regenerate.path"; - private static final String GROWINGIO_PACKAGE_NAME = "com.growingio.android.sdk"; - private static final String SUB_PACKAGE_NAME = qualified(GROWINGIO_PACKAGE_NAME, "test"); - private static final String ANNOTATION_PACKAGE_NAME = "com.growingio.sdk.annotation.compiler"; - private static final String DEFAULT_APP_DIR_NAME = "EmptyGrowingioModuleTest"; - private static final String DEFAULT_LIBRARY_DIR_NAME = "EmptyLibraryGrowingioModuleTest"; - /** - * Hardcoded file separator to workaround {@code JavaFileObjects.forResource(...)} defaulting to - * the unix one. - */ - private static final String FILE_SEPARATOR = "/"; - - private static final String LINE_SEPARATOR = "\n"; - - private TestUtil() { - // Utility class. - } - - /** - * Returns the {@code String} from a system property that is expected to contain the project - * directory for the module containing these tests or {@code null} if we're not currently - * attempting to regenerate test resources. - */ - public static String getProjectRootIfRegeneratingTestResources() { - return System.getProperty(REGENERATE_TEST_RESOURCES_PROPERTY_NAME); - } - - public static JavaFileObject emptyAppModule() { - return appResource("EmptyAppModule.java"); - } - - public static JavaFileObject emptyLibraryModule() { - return libraryResource("EmptyLibraryModule.java"); - } - - public static JavaFileObject appResource(String className) { - return forResource(DEFAULT_APP_DIR_NAME, className); - } - - public static JavaFileObject libraryResource(String className) { - return forResource(DEFAULT_LIBRARY_DIR_NAME, className); - } - - public static JavaFileObject forResource(String directoryName, String name) { - try { - return JavaFileObjects.forResource(directoryName + FILE_SEPARATOR + name); - } catch (IllegalArgumentException e) { - // IllegalArgumentException will be thrown if the resource is missing. If we're trying to - // generate test resources for a new test, we want to avoid this exception because it does not - // contain any expected output that we can write to a file. By returning an empty file, we - // avoid the exception and get the output from our comparison tests that we can then write - // out. - // If we're not regenerating test resources, we should throw the normal exception. - return JavaFileObjects.forSourceString("com.growingio.sdk.annotation.compiler", name); - } - } - - public static String annotation(String className) { - return qualified(ANNOTATION_PACKAGE_NAME, className); - } - - public static String subpackage(String className) { - return qualified(SUB_PACKAGE_NAME, className); - } - - public static String growingio(String className) { - return qualified(GROWINGIO_PACKAGE_NAME, className); - } - - public static CharSequence asUnixChars(CharSequence chars) { - return chars.toString().replace(System.lineSeparator(), LINE_SEPARATOR); - } - - private static String qualified(String packageName, String className) { - return packageName + '.' + className; - } -} diff --git a/inject-annotation/compiler/src/test/java/com/growingio/sdk/sample/TestActionProvider.java b/inject-annotation/compiler/src/test/java/com/growingio/sdk/sample/TestActionProvider.java deleted file mode 100644 index 77692670..00000000 --- a/inject-annotation/compiler/src/test/java/com/growingio/sdk/sample/TestActionProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.sample; - -import java.util.List; - -/** - *

- * - * @author cpacm 2021/6/30 - */ -public class TestActionProvider { - - public static void viewOnClick(int obj) { - System.out.println(obj); - } - - public static void alertDialogShow(Object obj) { - System.out.println(obj); - } - - public static void menuItemOnClick(TestOnClickListener listener, Object obj) { - System.out.println(obj); - } - - public static void bridgeForWebView(TestOnClickListener listener, String url) { - System.out.println(url); - } - - public static void createOrResumePage(TestOnClickListener listener) { - System.out.println(listener); - } - - public static String types(float type1, double type2, char type3, short type4, boolean type5, byte type6) { - return ""; - } - - public static void arrays(List params) { - } - - -} diff --git a/inject-annotation/compiler/src/test/resources/InjectTest/HookClassesConfigTemp.java b/inject-annotation/compiler/src/test/resources/InjectTest/HookClassesConfigTemp.java deleted file mode 100644 index a3aca104..00000000 --- a/inject-annotation/compiler/src/test/resources/InjectTest/HookClassesConfigTemp.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.plugin.autotrack.hook; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * 该Class是由 inject-compiler 自动生成的,请不要随意更改! - */ -public class HookClassesConfig { - private static final Map AROUND_HOOK_CLASSES = new HashMap<>(); - - private static final Map SUPER_HOOK_CLASSES = new HashMap<>(); - - static { - putAroundHookMethod("com/growingio/sdk/sample/TestOnClickListener", "loadUrl", "(Ljava/lang/String;)V", "com/growingio/sdk/test/TestInjector", "webkitWebViewLoadUrl", "(Lcom/growingio/sdk/sample/TestOnClickListener;Ljava/lang/String;)V", false); - putAroundHookMethod("com/growingio/sdk/sample/TestOnClickListener", "show", "()V", "com/growingio/sdk/test/TestInjector", "alertDialogShow", "(Ljava/lang/Object;)V", true); - putAroundHookMethod("com/growingio/sdk/sample/TestOnClickListener", "types", "(FDCSZB)Ljava/lang/String;", "com/growingio/sdk/test/TestInjector", "types", "(Lcom/growingio/sdk/sample/TestOnClickListener;FDCSZB)V", true); - putAroundHookMethod("com/growingio/sdk/sample/TestOnClickListener", "arrays", "(Ljava/util/List;)Ljava/lang/Object;", "com/growingio/sdk/test/TestInjector", "arrays", "(Lcom/growingio/sdk/sample/TestOnClickListener;Ljava/util/List;)V", true); - putSuperHookMethod("com/growingio/sdk/sample/TestOnClickListener", "onClick", "(I)V", "com/growingio/sdk/test/TestInjector", "viewOnClick", "(Lcom/growingio/sdk/sample/TestOnClickListener;I)V", false); - putSuperHookMethod("com/growingio/sdk/sample/TestOnClickListener", "onOptionsItemSelected", "(Ljava/lang/Object;)Z", "com/growingio/sdk/test/TestInjector", "menuItemOnOptionsItemSelected", "(Lcom/growingio/sdk/sample/TestOnClickListener;Ljava/lang/Object;)V", false); - putSuperHookMethod("com/growingio/sdk/sample/TestOnClickListener", "onOptionsItemSelected2", "(Ljava/lang/Object;)Z", "com/growingio/sdk/test/TestInjector", "menuItemOnOptionsItemSelected", "(Lcom/growingio/sdk/sample/TestOnClickListener;Ljava/lang/Object;)V", false); - putSuperHookMethod("com/growingio/sdk/sample/TestOnClickListener", "onResume", "()V", "com/growingio/sdk/test/TestInjector", "systemFragmentOnResume", "(Lcom/growingio/sdk/sample/TestOnClickListener;)V", true); - putSuperHookMethod("com/growingio/sdk/sample/TestOnClickListener", "onResume2", "()V", "com/growingio/sdk/test/TestInjector", "systemFragmentOnResume", "(Lcom/growingio/sdk/sample/TestOnClickListener;)V", true); - } - - private HookClassesConfig() { - } - - private static void putAroundHookMethod(String targetClassName, String targetMethodName, - String targetMethodDesc, String injectClassName, String injectMethodName, - String injectMethodDesc, boolean isAfter) { - putHookMethod(AROUND_HOOK_CLASSES, targetClassName, targetMethodName, targetMethodDesc, injectClassName, injectMethodName, injectMethodDesc, isAfter); - } - - private static void putSuperHookMethod(String targetClassName, String targetMethodName, - String targetMethodDesc, String injectClassName, String injectMethodName, - String injectMethodDesc, boolean isAfter) { - putHookMethod(SUPER_HOOK_CLASSES, targetClassName, targetMethodName, targetMethodDesc, injectClassName, injectMethodName, injectMethodDesc, isAfter); - } - - private static void putHookMethod(Map classMap, String targetClassName, - String targetMethodName, String targetMethodDesc, String injectClassName, - String injectMethodName, String injectMethodDesc, boolean isAfter) { - TargetClass targetClass = classMap.get(targetClassName); - if (targetClass == null) { - targetClass = new TargetClass(targetClassName); - classMap.put(targetClassName, targetClass); - } - TargetMethod targetMethod = targetClass.getTargetMethod(targetMethodName, targetMethodDesc); - if (targetMethod == null) { - targetMethod = new TargetMethod(targetMethodName, targetMethodDesc); - targetClass.addTargetMethod(targetMethod); - } - targetMethod.addInjectMethod(new InjectMethod(injectClassName, injectMethodName, injectMethodDesc, isAfter)); - } - - public static Map getAroundHookClasses() { - return Collections.unmodifiableMap(AROUND_HOOK_CLASSES); - } - - public static Map getSuperHookClasses() { - return Collections.unmodifiableMap(SUPER_HOOK_CLASSES); - } -} diff --git a/inject-annotation/compiler/src/test/resources/InjectTest/TestInjector.java b/inject-annotation/compiler/src/test/resources/InjectTest/TestInjector.java deleted file mode 100644 index a3695733..00000000 --- a/inject-annotation/compiler/src/test/resources/InjectTest/TestInjector.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.test; - -import java.util.List; -import com.growingio.sdk.inject.annotation.AfterSuper; -import com.growingio.sdk.inject.annotation.Before; -import com.growingio.sdk.sample.TestOnClickListener; -import com.growingio.sdk.sample.TestActionProvider; -import com.growingio.sdk.inject.annotation.After; -import com.growingio.sdk.inject.annotation.BeforeSuper; - -public class TestInjector { - private static final String TAG = "ViewClickInjector"; - - @BeforeSuper(clazz = TestOnClickListener.class, method = "onClick", parameterTypes = {int.class}) - public static void viewOnClick(TestOnClickListener listener, int view) { - TestActionProvider.viewOnClick(view); - } - - @Before(clazz = TestOnClickListener.class, method = "loadUrl", parameterTypes = {String.class}) - public static void webkitWebViewLoadUrl(TestOnClickListener webView, String url) { - TestActionProvider.bridgeForWebView(webView, url); - } - - @After(clazz = TestOnClickListener.class, method = "show") - public static void alertDialogShow(Object alertDialog) { - TestActionProvider.alertDialogShow(alertDialog); - } - - @BeforeSuper(clazz = TestOnClickListener.class, method = "onOptionsItemSelected", parameterTypes = {Object.class}, returnType = boolean.class) - @BeforeSuper(clazz = TestOnClickListener.class, method = "onOptionsItemSelected2", parameterTypes = {Object.class}, returnType = boolean.class) - public static void menuItemOnOptionsItemSelected(TestOnClickListener listener, Object item) { - TestActionProvider.menuItemOnClick(listener, item); - } - - @AfterSuper(clazz = TestOnClickListener.class, method = "onResume") - @AfterSuper(clazz = TestOnClickListener.class, method = "onResume2") - public static void systemFragmentOnResume(TestOnClickListener listener) { - TestActionProvider.createOrResumePage(listener); - } - - - @After(clazz = TestOnClickListener.class, method = "types", parameterTypes = {float.class, double.class, char.class, short.class, boolean.class, byte.class}, returnType = String.class) - public static void types(TestOnClickListener webView, float type1, double type2, char type3, short type4, boolean type5, byte type6) { - TestActionProvider.types(type1, type2, type3, type4, type5, type6); - } - - @After(clazz = TestOnClickListener.class, method = "arrays", parameterTypes = {List.class}, returnType = Object.class) - public static void arrays(TestOnClickListener webView, List params) { - TestActionProvider.arrays(params); - } -} - diff --git a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/After.java b/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/After.java deleted file mode 100644 index a61017bf..00000000 --- a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/After.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Repeatable(Afters.class) -public @interface After { - Class clazz(); - - String method(); - - Class[] parameterTypes() default {}; - - Class returnType() default void.class; -} diff --git a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/AfterSuper.java b/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/AfterSuper.java deleted file mode 100644 index a246c6e0..00000000 --- a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/AfterSuper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Repeatable(AfterSupers.class) -public @interface AfterSuper { - Class clazz(); - - String method(); - - Class[] parameterTypes() default {}; - - Class returnType() default void.class; -} diff --git a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/AfterSupers.java b/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/AfterSupers.java deleted file mode 100644 index f3ffd667..00000000 --- a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/AfterSupers.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface AfterSupers { - AfterSuper[] value(); -} diff --git a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Afters.java b/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Afters.java deleted file mode 100644 index a58147c4..00000000 --- a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Afters.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface Afters { - After[] value(); -} diff --git a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Before.java b/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Before.java deleted file mode 100644 index 0de381b4..00000000 --- a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Before.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Repeatable(Befores.class) -public @interface Before { - Class clazz(); - - String method(); - - Class[] parameterTypes() default {}; - - Class returnType() default void.class; -} diff --git a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/BeforeSuper.java b/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/BeforeSuper.java deleted file mode 100644 index c40472e9..00000000 --- a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/BeforeSuper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Repeatable(BeforeSupers.class) -public @interface BeforeSuper { - Class clazz(); - - String method(); - - Class[] parameterTypes() default {}; - - Class returnType() default void.class; -} diff --git a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/BeforeSupers.java b/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/BeforeSupers.java deleted file mode 100644 index f90c25f2..00000000 --- a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/BeforeSupers.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface BeforeSupers { - BeforeSuper[] value(); -} diff --git a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Befores.java b/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Befores.java deleted file mode 100644 index 0012efd9..00000000 --- a/inject-annotation/src/main/java/com/growingio/sdk/inject/annotation/Befores.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2020 Beijing Yishu Technology Co., Ltd. - * - * 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.growingio.sdk.inject.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface Befores { - Before[] value(); -} diff --git a/settings.gradle b/settings.gradle index f4af86a5..df803e3c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,9 +5,6 @@ if (!isExcludeDemos()) { } // tools -include ':growingio-autotracker-gradle-plugin' -include ':inject-annotation' -include ':inject-annotation:compiler' include ':growingio-annotation' include ':growingio-annotation:compiler' @@ -30,8 +27,12 @@ include ':growingio-tools:crash' include ':growingio-tools:snappy' include ':growingio-tools:oaid' +include ':growingio-adapter:analytics-fa' +include ':growingio-adapter:analytics-ga' + // sdks include ':gio-sdk:tracker' include ':gio-sdk:autotracker' include ':gio-sdk:tracker-cdp' include ':gio-sdk:autotracker-cdp' +