diff --git a/.github/workflows/pre_release.yml b/.github/workflows/pre_release.yml index 7faa46ee..9b4fe2a9 100644 --- a/.github/workflows/pre_release.yml +++ b/.github/workflows/pre_release.yml @@ -7,9 +7,27 @@ on: jobs: build: if: ${{ github.event.label.name == 'pre release' }} - runs-on: macos-latest + runs-on: ubuntu-latest steps: + - name: Delete unnecessary tools 🔧 + uses: jlumbroso/free-disk-space@v1.3.1 + with: + android: false # Don't remove Android tools + tool-cache: true # Remove image tool cache - rm -rf "$AGENT_TOOLSDIRECTORY" + dotnet: true # rm -rf /usr/share/dotnet + haskell: true # rm -rf /opt/ghc... + swap-storage: true # rm -f /mnt/swapfile (4GiB) + docker-images: false # Takes 16s, enable if needed in the future + large-packages: false # includes google-cloud-sdk and it's slow + + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + ls /dev/kvm + - uses: actions/checkout@v3 with: submodules: true @@ -58,10 +76,11 @@ jobs: with: api-level: 31 target: default - disable-animations: true ram-size: 4096M - cores: 4 arch: x86_64 + disable-animations: true + disk-size: 6000M + heap-size: 600M working-directory: ./demo script: ./gradlew :app:connectedAndroidTest --stacktrace diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c8873bc5..3ac1de6f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,9 +27,9 @@ protobuf = "3.22.3" powermock = "2.0.9" # !!! SDK VERSION !!! -growingio = "4.2.0" -growingioCode = "40200" -growingioPlugin = "4.1.0" +growingio = "4.3.0" +growingioCode = "40300" +growingioPlugin = "4.2.0" [plugins] android-application = { id = "com.android.application", version.ref = "pluginGradle" } diff --git a/gradle/preRelease.sh b/gradle/preRelease.sh index a0f8935a..4c6004e1 100755 --- a/gradle/preRelease.sh +++ b/gradle/preRelease.sh @@ -11,8 +11,13 @@ test_plugin_version=$(grep "^growingioPlugin =.*" gradle/libs.versions.toml | aw # echo $test_sdk_version # echo $test_plugin_version -sed -i "" "s/^growingioPlugin =.*/${test_plugin_version}/g" demo/gradle/libs.versions.toml -sed -i "" "s/^growingio =.*/${test_sdk_version}/g" demo/gradle/libs.versions.toml +# for macOS +# sed -i "" "s/^growingioPlugin =.*/${test_plugin_version}/g" demo/gradle/libs.versions.toml +# sed -i "" "s/^growingio =.*/${test_sdk_version}/g" demo/gradle/libs.versions.toml + +# for linux +sed -i "s/^growingioPlugin =.*/${test_plugin_version}/g" demo/gradle/libs.versions.toml +sed -i "s/^growingio =.*/${test_sdk_version}/g" demo/gradle/libs.versions.toml # echo 'apply from: "${rootProject.projectDir.parent}/gradle/jacoco.gradle"' >> demo/app/build.gradle diff --git a/growingio-abtest/src/main/java/com/growingio/android/abtest/ABTestDataLoader.java b/growingio-abtest/src/main/java/com/growingio/android/abtest/ABTestDataLoader.java index a87a31ba..328872d0 100644 --- a/growingio-abtest/src/main/java/com/growingio/android/abtest/ABTestDataLoader.java +++ b/growingio-abtest/src/main/java/com/growingio/android/abtest/ABTestDataLoader.java @@ -197,7 +197,6 @@ private void sendAbTestTrackEvent(ABExperiment abExperiment) { .addAttribute("$exp_layer_id", abExperiment.getLayerId()); CustomEvent.Builder customEventBuilder = new CustomEvent.Builder(); customEventBuilder.setEventName("$exp_hit"); - customEventBuilder.setCustomEventType(ConstantPool.CUSTOM_TYPE_SYSTEM); customEventBuilder.setAttributes(attributesBuilder.build()); TrackMainThread.trackMain().cacheEventToTrackMain(customEventBuilder); } diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/AutotrackConfig.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/AutotrackConfig.java index 19a1d04d..87bc6556 100644 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/AutotrackConfig.java +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/AutotrackConfig.java @@ -27,6 +27,7 @@ public class AutotrackConfig implements Configurable { private boolean enableFragmentTag = false; private final AutotrackOptions mAutotrackOptions = new AutotrackOptions(); + private boolean autotrackEnabled = true; private int pageXmlRes = 0; private final List pageRules = new ArrayList<>(); @@ -144,4 +145,13 @@ public List getPageRules() { public int getPageXmlRes() { return pageXmlRes; } + + public boolean isAutotrack() { + return autotrackEnabled; + } + + public AutotrackConfig setAutotrack(boolean enabled) { + this.autotrackEnabled = enabled; + return this; + } } diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/impression/ImpressionProvider.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/impression/ImpressionProvider.java index e8418e36..8048f4da 100644 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/impression/ImpressionProvider.java +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/impression/ImpressionProvider.java @@ -60,6 +60,7 @@ public void run() { private final ViewTreeStatusObserver viewTreeStatusObserver; private ActivityStateProvider activityStateProvider; + private AutotrackConfig autotrackConfig; public ImpressionProvider() { viewTreeStatusObserver = new ViewTreeStatusObserver(this); @@ -68,10 +69,13 @@ public ImpressionProvider() { @Override public void setup(TrackerContext context) { - AutotrackConfig configuration = context.getConfigurationProvider().getConfiguration(AutotrackConfig.class); - impressionScale = configuration == null ? 0f : configuration.getImpressionScale(); - + autotrackConfig = context.getConfigurationProvider().getConfiguration(AutotrackConfig.class); + impressionScale = autotrackConfig == null ? 0f : autotrackConfig.getImpressionScale(); activityStateProvider = context.getActivityStateProvider(); + + if (autotrackConfig == null || !autotrackConfig.isAutotrack()) { + return; + } activityStateProvider.registerActivityLifecycleListener(this); } @@ -165,6 +169,10 @@ public void trackViewImpression(View view, String impressionEventName, Map getAttributes() { } public void setAttributes(Map attributes) { - mAttributes = attributes; + if (mAttributes == null) mAttributes = new HashMap<>(); + mAttributes.clear(); + if (attributes == null) return; + mAttributes.putAll(attributes); } public abstract String getName(); @@ -188,7 +191,7 @@ public String activePath() { public Map activeAttributes() { Page activePage = lastActivePage(); if (activePage != null) return activePage.getAttributes(); - return Collections.emptyMap(); + return null; } public String getXIndex() { diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/PageConfig.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/PageConfig.java index c1f6987f..d2c09cda 100644 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/PageConfig.java +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/PageConfig.java @@ -25,12 +25,15 @@ class PageConfig { private boolean isFragmentPageEnabled = true; private boolean isDowngrade = false; - public PageConfig(List pageRuleList, boolean isActivityPageEnabled, boolean isFragmentPageEnabled, boolean enableFragmentTag, boolean isDowngrade) { + private boolean autotrack = true; + + public PageConfig(List pageRuleList, boolean isActivityPageEnabled, boolean isFragmentPageEnabled, boolean enableFragmentTag, boolean isDowngrade,boolean autotrack) { this.pageRuleList = pageRuleList; this.isActivityPageEnabled = isActivityPageEnabled; this.isFragmentPageEnabled = isFragmentPageEnabled; this.enableFragmentTag = enableFragmentTag; this.isDowngrade = isDowngrade; + this.autotrack = autotrack; } public boolean isEnableFragmentTag() { @@ -52,4 +55,8 @@ public boolean isFragmentPageEnabled() { public boolean isDowngrade() { return isDowngrade; } + + public boolean isAutotrack() { + return autotrack; + } } diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/PageProvider.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/PageProvider.java index 0a9fa11a..fec38f7e 100644 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/PageProvider.java +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/page/PageProvider.java @@ -38,7 +38,6 @@ import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -72,14 +71,16 @@ private PageProvider() { @Override public void setup(TrackerContext context) { activityStateProvider = context.getActivityStateProvider(); - activityStateProvider.registerActivityLifecycleListener(this); - loadPageConfig(context); - } - private void loadPageConfig(TrackerContext context) { ConfigurationProvider configurationProvider = context.getConfigurationProvider(); AutotrackConfig autotrackConfig = configurationProvider.getConfiguration(AutotrackConfig.class); - boolean isDowngrade = configurationProvider.isDowngrade(); + + loadPageConfig(context, autotrackConfig, configurationProvider.isDowngrade()); + + activityStateProvider.registerActivityLifecycleListener(this); + } + + private void loadPageConfig(TrackerContext context, AutotrackConfig autotrackConfig, boolean isDowngrade) { if (autotrackConfig != null) { boolean isActivityPageEnabled = autotrackConfig.getAutotrackOptions().isActivityPageEnabled(); boolean isFragmentPageEnabled = autotrackConfig.getAutotrackOptions().isFragmentPageEnabled(); @@ -88,15 +89,17 @@ private void loadPageConfig(TrackerContext context) { autotrackConfig.getPageRules().addAll(0, pageRuleList); List pageRules = Collections.unmodifiableList(autotrackConfig.getPageRules()); - pageConfig = new PageConfig(pageRules, isActivityPageEnabled, isFragmentPageEnabled, enableFragmentTag, isDowngrade); + pageConfig = new PageConfig(pageRules, isActivityPageEnabled, isFragmentPageEnabled, enableFragmentTag, isDowngrade, autotrackConfig.isAutotrack()); } else { - pageConfig = new PageConfig(null, isDowngrade, isDowngrade, false, isDowngrade); + pageConfig = new PageConfig(null, isDowngrade, isDowngrade, false, isDowngrade, true); } } @Override public void shutdown() { + ALL_PAGE_TREE.clear(); + CACHE_PAGES.clear(); activityStateProvider.unregisterActivityLifecycleListener(this); } @@ -513,8 +516,7 @@ public void setPageAttributes(SuperFragment fragment, Map att } private void setPageAttributes(Page page, Map attributes) { - if (page == null) return; - if (attributes == null) attributes = new HashMap<>(); + if (page == null || attributes == null) return; if (attributes.equals(page.getAttributes())) { Logger.w(TAG, "setPageAttributes is equals page.getAttributes"); return; diff --git a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/view/ViewUtil.java b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/view/ViewUtil.java index a500836d..70f61823 100644 --- a/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/view/ViewUtil.java +++ b/growingio-autotracker-core/src/main/java/com/growingio/android/sdk/autotrack/view/ViewUtil.java @@ -36,6 +36,7 @@ import com.google.android.material.tabs.TabLayout; import com.growingio.android.sdk.autotrack.shadow.ListMenuItemViewShadow; import com.growingio.android.sdk.track.TrackMainThread; +import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.utils.ClassExistHelper; public class ViewUtil { @@ -107,8 +108,13 @@ public static String getWidgetContent(View widget) { return compoundButtonContentValue((CompoundButton) widget); } if (ClassExistHelper.hasClass("com.google.android.material.tabs.TabLayout")) { - if (widget instanceof TabLayout.TabView) { - return tabViewContentValue((TabLayout.TabView) widget); + try { + if (widget instanceof TabLayout.TabView) { + return tabViewContentValue((TabLayout.TabView) widget); + } + } catch (IllegalAccessError e) { + // TabLayout.TabView在1.1.0版本才开始修改为public访问权限 + Logger.e("ViewUtil", "TabLayout version is low."); } } if (ClassExistHelper.hasClass("com.google.android.material.slider.Slider")) { 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 cf6e20fc..85aa9e3f 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 @@ -51,7 +51,6 @@ public EventDbResult executeData() { } } - private EventDbResult executeDatabase(EventDatabase database) throws IllegalArgumentException { EventDbResult dbResult = new EventDbResult(); if (database.getDbOp() == EventDatabase.DATABASE_OP_INSERT) { @@ -61,7 +60,8 @@ private EventDbResult executeDatabase(EventDatabase database) throws IllegalArgu dbResult.setSuccess(count == database.getEvents().size()); return dbResult; } else if (database.getDbOp() == EventDatabase.DATABASE_OP_OUTDATED) { - int sum = dataManager.removeOverdueEvents(); + int day = database.getLimit(); + int sum = dataManager.removeOverdueEvents(day); dbResult.setSum(sum); dbResult.setSuccess(sum >= 0); 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 e089adeb..35cd3e8e 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 @@ -45,7 +45,7 @@ public class EventDataManager { private static final String TAG = "EventDataManager"; - private static final long EVENT_VALID_PERIOD_MILLS = 7L * 24 * 60 * 60_000; + private static final long EVENT_VALID_PERIOD_MILLS = 24 * 60 * 60_000L; private static final double EVENT_DATA_MAX_SIZE = 2 * 1000 * 1024; // 2M private final TrackerContext context; @@ -60,7 +60,8 @@ public class EventDataManager { deprecatedEventSQLite.migrateEvents(); // when sdk start,removeOverdueEvents - removeOverdueEvents(); + int day = context.getConfigurationProvider().core().getDataValidityPeriod(); + removeOverdueEvents(day); } private EventByteArray formatData(EventFormatData data) { @@ -112,13 +113,15 @@ Uri insertEvent(GEvent gEvent) { return null; } - int removeOverdueEvents() { + int removeOverdueEvents(int day) { if (ignoreOperations) { return -1; } try { long current = System.currentTimeMillis(); - long sevenDayAgo = current - EVENT_VALID_PERIOD_MILLS; + if (day > 30) day = 30; + if (day < 3) day = 3; + long sevenDayAgo = current - day * EVENT_VALID_PERIOD_MILLS; ContentResolver contentResolver = context.getContentResolver(); Uri uri = getContentUri(); diff --git a/growingio-data/database/src/test/java/com/growingio/android/database/DbTest.java b/growingio-data/database/src/test/java/com/growingio/android/database/DbTest.java index 4cf003e8..731cc09f 100644 --- a/growingio-data/database/src/test/java/com/growingio/android/database/DbTest.java +++ b/growingio-data/database/src/test/java/com/growingio/android/database/DbTest.java @@ -142,7 +142,7 @@ public void dataModuleTest() { public void contentProviderTest() { trackerContext.getRegistry().register(EventFormatData.class, EventByteArray.class, new JsonDataLoader.Factory()); controller.create(providerInfo).get(); - sqLite.removeOverdueEvents(); + sqLite.removeOverdueEvents(7); CustomEvent customEvent = new CustomEvent.Builder() .setEventName("contentProvider") .build(); diff --git a/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridTransformerImp.java b/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridTransformerImp.java index e22d1aa2..c2d11229 100644 --- a/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridTransformerImp.java +++ b/growingio-hybrid/src/main/java/com/growingio/android/hybrid/HybridTransformerImp.java @@ -26,7 +26,6 @@ import com.growingio.android.sdk.track.events.base.BaseEvent; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.providers.EventBuilderProvider; -import com.growingio.android.sdk.track.utils.ConstantPool; import org.json.JSONException; import org.json.JSONObject; @@ -50,8 +49,6 @@ public BaseEvent.BaseBuilder transform(String hybridEvent) { return transformViewElementEventBuilder(type, eventJson); } else if (TrackEventType.CUSTOM.equals(type)) { HybridCustomEvent.Builder builder = new HybridCustomEvent.Builder(); - int customType = eventJson.optInt("customEventType", ConstantPool.CUSTOM_TYPE_SYSTEM); - builder.setCustomEventType(customType); EventBuilderProvider.parseFrom(builder, eventJson); return builder; } else if (TrackEventType.LOGIN_USER_ATTRIBUTES.equals(type)) { diff --git a/growingio-network/okhttp3/build.gradle b/growingio-network/okhttp3/build.gradle index 9c4481b1..853dfdd0 100644 --- a/growingio-network/okhttp3/build.gradle +++ b/growingio-network/okhttp3/build.gradle @@ -46,7 +46,7 @@ dependencies { implementation project(':growingio-tracker-core') implementation libs.okhttp3 - //debugImplementation libs.okhttp3.logging + //implementation libs.okhttp3.logging implementation project(":growingio-annotation") annotationProcessor project(":growingio-annotation:compiler") 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 23ff7d2e..8cefe329 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 @@ -61,7 +61,7 @@ public void loadData(DataCallback callback) { call.enqueue(this); } - private Request buildRequestWithEventUrl(){ + private Request buildRequestWithEventUrl() { Request.Builder requestBuilder = new Request.Builder().url(eventUrl.toUrl()); for (Map.Entry headerEntry : eventUrl.getHeaders().entrySet()) { String key = headerEntry.getKey(); @@ -69,14 +69,17 @@ private Request buildRequestWithEventUrl(){ } if (eventUrl.getRequestBody() != null) { requestBuilder.post(RequestBody.create(MediaType.parse(eventUrl.getMediaType()), eventUrl.getRequestBody())); + } else if (eventUrl.getRequestMethod() == EventUrl.POST) { + RequestBody requestBody = RequestBody.create(MediaType.parse(eventUrl.getMediaType()), new byte[0]); + requestBuilder.post(requestBody); + } else if (eventUrl.getRequestMethod() == EventUrl.OPTIONS) { + requestBuilder.method("OPTIONS", null); + } else if (eventUrl.getRequestMethod() == EventUrl.HEAD) { + requestBuilder.head(); } else { - if (eventUrl.getRequestMethod() == EventUrl.POST) { - RequestBody requestBody = RequestBody.create(MediaType.parse(eventUrl.getMediaType()), new byte[0]); - requestBuilder.post(requestBody); - } else { - requestBuilder.get(); - } + requestBuilder.get(); } + return requestBuilder.build(); } @@ -94,7 +97,7 @@ public EventResponse executeData() { return new EventResponse(successed, copyResponse(responseBody.byteStream()), contentLength); } else { Logger.e(TAG, "OkHttpSender failed with code:" + response.code()); - return new EventResponse(false); + return new EventResponse(response.code()); } } catch (IOException e) { Logger.e(TAG, e); @@ -149,16 +152,13 @@ public void onFailure(Call call, IOException e) { @Override public void onResponse(Call call, Response response) { try { - responseBody = response.body(); if (response.isSuccessful()) { - if (responseBody == null) { - throw new IllegalArgumentException("Must not be null or empty"); - } + responseBody = response.body(); long contentLength = responseBody.contentLength(); - EventResponse eventResponse = new EventResponse(true, responseBody.byteStream(), contentLength); + EventResponse eventResponse = new EventResponse(response.code(), responseBody.byteStream(), contentLength); callback.onDataReady(eventResponse); } else { - callback.onLoadFailed(new Exception(response.message())); + callback.onDataReady(new EventResponse(response.code())); } } finally { cleanup(); 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 97ca40a4..4ed0d449 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 @@ -80,7 +80,7 @@ private static Call.Factory getsInternalClient(OkHttpConfig config) { builder.writeTimeout(config.getWriteTimeout(), TimeUnit.MILLISECONDS); } builder.addInterceptor(new SecurityExceptionInterceptor()); - //builder.addInterceptor(new HttpLoggingInterceptor(message -> Logger.d("OKHTTP Logging", message)).setLevel(HttpLoggingInterceptor.Level.HEADERS)) + //builder.addInterceptor(new HttpLoggingInterceptor(message -> Logger.d("OKHTTP Logging", message)).setLevel(HttpLoggingInterceptor.Level.BODY)); sInternalClient = builder.build(); } } diff --git a/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/SecurityExceptionInterceptor.java b/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/SecurityExceptionInterceptor.java index 142bbec5..7ff8db2d 100644 --- a/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/SecurityExceptionInterceptor.java +++ b/growingio-network/okhttp3/src/main/java/com/growingio/android/okhttp3/SecurityExceptionInterceptor.java @@ -27,7 +27,7 @@ * 2.加强保护,将所有异常转为io异常回调失败,避免部分okhttp内部错误导致异常 * 3.捕获错误 */ -public class SecurityExceptionInterceptor implements Interceptor { +class SecurityExceptionInterceptor implements Interceptor { private static final String TAG = "SecurityExceptionInterceptor"; @Override 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 6d416915..b0268847 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 @@ -77,6 +77,12 @@ public void loadData(DataCallback callback) { headers.put("content-type", eventUrl.getMediaType()); EventResponse result = loadDataWithRedirects(new URL(eventUrl.toUrl()), 0, null, headers, eventUrl.getRequestBody()); callback.onDataReady(result); + } catch (HttpException httpException) { + if (httpException.getStatusCode() == INVALID_STATUS_CODE) { + callback.onLoadFailed(httpException); + } else { + callback.onDataReady(new EventResponse(httpException.getStatusCode())); + } } catch (IOException e) { Logger.e(TAG, "Failed to load data for url", e); callback.onLoadFailed(e); @@ -162,6 +168,10 @@ private HttpURLConnection buildAndConfigureConnection(URL url, Map headers = eventUrl.getHeaders(); headers.put("content-type", eventUrl.getMediaType()); return loadDataWithRedirects(new URL(eventUrl.toUrl()), 0, null, headers, eventUrl.getRequestBody()); + } catch (HttpException httpException) { + if (httpException.getStatusCode() == INVALID_STATUS_CODE) { + return new EventResponse(0); + } else { + return new EventResponse(httpException.getStatusCode()); + } } catch (IOException e) { Logger.d(TAG, "Failed to load data for url", e); } finally { cleanup(); Logger.v(TAG, "Finished http url fetcher fetch in " + LogTime.getElapsedMillis(startTime)); } - return new EventResponse(false); + return new EventResponse(0); } @Override diff --git a/growingio-sdk-bom/build.gradle b/growingio-sdk-bom/build.gradle index e84d92b5..657194c3 100644 --- a/growingio-sdk-bom/build.gradle +++ b/growingio-sdk-bom/build.gradle @@ -46,12 +46,12 @@ dependencies { } api "com.growingio.android:analytics-fa:4.0.0" - api "com.growingio.android:analytics-sa:4.1.0" - api "com.growingio.android:dummy-sa:4.1.0" + api "com.growingio.android:analytics-sa:4.3.0" + api "com.growingio.android:dummy-sa:4.3.0" // giokit - api 'com.growingio.giokit:giokit:2.0.0' - api 'com.growingio.giokit:giokit-no-op:2.0.0' + api 'com.growingio.giokit:giokit:2.1.2' + api 'com.growingio.giokit:giokit-no-op:2.1.2' // saas sdk //api 'com.growingio.android:vds-android-agent:autotrack-2.9.13' diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/CoreConfiguration.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/CoreConfiguration.java index fe909f78..6b2de1fb 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/CoreConfiguration.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/CoreConfiguration.java @@ -28,7 +28,7 @@ public class CoreConfiguration implements Configurable { private String mDataSourceId; private String mChannel; private boolean mDebugEnabled = false; - private int mCellularDataLimit = 10; + private int mCellularDataLimit = 20; private int mDataUploadInterval = 15; private int mSessionInterval = 30; private boolean mDataCollectionEnabled = true; @@ -42,6 +42,8 @@ public class CoreConfiguration implements Configurable { private boolean mImeiEnabled = false; private boolean mAndroidIdEnabled = false; + private int mDataValidityPeriod = 7; + public CoreConfiguration(String accountId, String urlScheme) { mProjectId = accountId; mUrlScheme = urlScheme; @@ -197,4 +199,19 @@ public CoreConfiguration setAndroidIdEnabled(boolean androidIdEnabled) { this.mAndroidIdEnabled = androidIdEnabled; return this; } + + public int getDataValidityPeriod() { + return mDataValidityPeriod; + } + + /** + * Sets the cache data validity period. From 3 days to 30 days. + *

Default: 7 days. + * + * @param dataValidityPeriod data validity period, in days. for example, 7 means that the cache data is valid for 7 days. + */ + public CoreConfiguration setDataValidityPeriod(int dataValidityPeriod) { + this.mDataValidityPeriod = dataValidityPeriod; + return this; + } } 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 77f23dde..9d219f95 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 @@ -27,6 +27,7 @@ import com.growingio.android.sdk.track.TrackMainThread; import com.growingio.android.sdk.track.events.TrackEventGenerator; +import com.growingio.android.sdk.track.events.helper.DynamicGeneralPropsGenerator; import com.growingio.android.sdk.track.log.Logger; import com.growingio.android.sdk.track.middleware.abtest.ABExperiment; import com.growingio.android.sdk.track.middleware.abtest.ABTest; @@ -154,6 +155,11 @@ public void trackCustomEvent(String eventName, Map attributes) { TrackEventGenerator.generateCustomEvent(eventName, attributes); } + public void setDynamicGeneralPropsGenerator(DynamicGeneralPropsGenerator generator) { + if (!isInited) return; + trackerContext.getEventBuilderProvider().setDynamicGeneralPropGenerator(generator); + } + public void setGeneralProps(Map variables) { if (!isInited || variables == null || variables.isEmpty()) return; TrackMainThread.trackMain().postActionToTrackMain(() -> @@ -423,6 +429,21 @@ public void registerComponent(LibraryGioModule module, Configurable config) { addComponent(module, config); } + /** + * uninstall module + */ + protected void uninstallComponent(Class modelClazz, Class dataClazz, Class configClazz, Class providerClazz) { + if (modelClazz == null) return; + if (configClazz != null) { + trackerContext.getConfigurationProvider().removeConfiguration(configClazz); + } + trackerContext.getRegistry().unregister(modelClazz, dataClazz); + if (providerClazz != null) { + TrackerLifecycleProvider provider = trackerContext.getProviderStore().remove(providerClazz); + if (provider != null) provider.shutdown(); + } + } + private void addComponent(LibraryGioModule module, Configurable config) { if (module == null) return; if (config != null) { 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 86dba6c0..543ddb64 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 @@ -86,6 +86,7 @@ public void shutdown() { this.persistentDataProvider = null; this.sessionProvider = null; this.activityStateProvider = null; + this.eventSender.shutdown(); this.eventSender = null; } @@ -173,7 +174,7 @@ private void onGenerateGEvent(BaseEvent.BaseBuilder gEvent) { @TrackThread private void saveEvent(GEvent event) { - if (event instanceof BaseEvent) { + if (event instanceof BaseEvent && coreConfiguration.isDebugEnabled()) { Logger.printJson(TAG, "save: event, type is " + event.getEventType(), EventBuilderProvider.toJson((BaseEvent) event).toString()); } if (persistentDataProvider != null && !persistentDataProvider.isSendVisitAfterRefreshSessionId()) { diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/ActivateEvent.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/ActivateEvent.java index 0d18a039..8fc71445 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/ActivateEvent.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/ActivateEvent.java @@ -139,8 +139,9 @@ public void readPropertyInTrackThread(TrackerContext context) { @Override public ActivateEvent build() { - Map map = getAttributes(); - if (map == null) map = new HashMap<>(); + Map map = new HashMap<>(); + Map oldData = getAttributes(); + if (oldData != null) map.putAll(oldData); if (!TextUtils.isEmpty(ua)) map.put("userAgent", ua); if (!TextUtils.isEmpty(classification)) map.put("deep_type", classification); if (!TextUtils.isEmpty(linkId)) map.put("deep_link_id", linkId); diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/AppClosedEvent.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/AppClosedEvent.java index 0154f8f8..b665d86f 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/AppClosedEvent.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/AppClosedEvent.java @@ -15,18 +15,18 @@ */ package com.growingio.android.sdk.track.events; -import com.growingio.android.sdk.track.events.base.BaseEvent; +import com.growingio.android.sdk.track.events.base.BaseAttributesEvent; import com.growingio.sdk.annotation.json.JsonSerializer; @JsonSerializer -public class AppClosedEvent extends BaseEvent { +public class AppClosedEvent extends BaseAttributesEvent { private static final long serialVersionUID = 1L; protected AppClosedEvent(Builder eventBuilder) { super(eventBuilder); } - public static final class Builder extends BaseBuilder { + public static final class Builder extends BaseAttributesEvent.Builder { public Builder() { super(TrackEventType.APP_CLOSED); diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/AttributesBuilder.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/AttributesBuilder.java index 20420756..3290d236 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/AttributesBuilder.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/AttributesBuilder.java @@ -20,10 +20,13 @@ import org.json.JSONArray; import org.json.JSONException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -60,6 +63,8 @@ public AttributesBuilder addAttribute(Map map) { addAttribute(key, tempValue); } else if (value instanceof JSONArray) { addAttribute(key, (JSONArray) value); + } else if (value instanceof Date) { + addAttribute(key, (Date) value); } else { addAttribute(key, String.valueOf(value)); } @@ -68,6 +73,18 @@ public AttributesBuilder addAttribute(Map map) { return this; } + public AttributesBuilder addAttribute(String key, Date date) { + if (key != null && date != null) { + attributes.put(key, formatDate(date)); + } + return this; + } + + private String formatDate(Date date) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault()); + return formatter.format(date); + } + public AttributesBuilder addAttribute(String key, String value) { if (key != null && value != null) { attributes.put(key, value); diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/CustomEvent.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/CustomEvent.java index 42e2dfae..c3ef304a 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/CustomEvent.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/CustomEvent.java @@ -16,12 +16,8 @@ package com.growingio.android.sdk.track.events; import com.growingio.android.sdk.track.events.base.BaseAttributesEvent; -import com.growingio.android.sdk.track.utils.ConstantPool; import com.growingio.sdk.annotation.json.JsonSerializer; -import java.util.HashMap; -import java.util.Map; - @JsonSerializer public class CustomEvent extends BaseAttributesEvent { private static final long serialVersionUID = 1L; @@ -39,7 +35,6 @@ public String getEventName() { public static class Builder extends BaseAttributesEvent.Builder { private String eventName; - private int customEventType = ConstantPool.CUSTOM_TYPE_SYSTEM; public Builder() { super(TrackEventType.CUSTOM); @@ -54,27 +49,6 @@ public String getEventName() { return eventName; } - public Builder setCustomEventType(int customEventType) { - this.customEventType = customEventType; - return this; - } - - public Builder setGeneralProps(Map generalProps) { - if (customEventType == ConstantPool.CUSTOM_TYPE_USER) { - if (generalProps != null && !generalProps.isEmpty()) { - Map attributes = getAttributes(); - if (attributes == null) attributes = new HashMap<>(); - for (String key : generalProps.keySet()) { - if (attributes.containsKey(key)) continue; - String value = generalProps.get(key); - attributes.put(key, value); - } - setAttributes(attributes); - } - } - return this; - } - @Override public CustomEvent build() { return new CustomEvent(this); diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/TrackEventGenerator.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/TrackEventGenerator.java index 9f9467d5..5d42a307 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/TrackEventGenerator.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/TrackEventGenerator.java @@ -16,7 +16,6 @@ package com.growingio.android.sdk.track.events; import com.growingio.android.sdk.track.TrackMainThread; -import com.growingio.android.sdk.track.utils.ConstantPool; import java.util.Map; @@ -33,7 +32,6 @@ public static void generateVisitEvent() { public static void generateCustomEvent(String name, Map attributes) { TrackMainThread.trackMain().postEventToTrackMain( new CustomEvent.Builder() - .setCustomEventType(ConstantPool.CUSTOM_TYPE_USER) .setEventName(name) .setAttributes(attributes) ); diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/VisitEvent.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/VisitEvent.java index 586e50a5..3b87d608 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/VisitEvent.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/VisitEvent.java @@ -18,14 +18,14 @@ import androidx.annotation.Nullable; import com.growingio.android.sdk.TrackerContext; -import com.growingio.android.sdk.track.events.base.BaseEvent; +import com.growingio.android.sdk.track.events.base.BaseAttributesEvent; import com.growingio.android.sdk.track.providers.DeviceInfoProvider; import com.growingio.sdk.annotation.json.JsonSerializer; import java.util.Map; @JsonSerializer -public final class VisitEvent extends BaseEvent { +public final class VisitEvent extends BaseAttributesEvent { private static final long serialVersionUID = 1L; @Nullable @@ -78,7 +78,7 @@ public Map getExtraSdk() { return extraSdk; } - public static final class Builder extends BaseBuilder { + public static final class Builder extends BaseAttributesEvent.Builder { String imei; String androidId; String oaid; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/base/BaseAttributesEvent.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/base/BaseAttributesEvent.java index 9a81d5f2..9d456916 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/base/BaseAttributesEvent.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/base/BaseAttributesEvent.java @@ -19,6 +19,7 @@ import com.growingio.sdk.annotation.json.JsonSerializer; +import java.util.HashMap; import java.util.Map; @JsonSerializer @@ -43,6 +44,20 @@ protected Builder(String eventType) { super(eventType); } + public Builder setGeneralProps(Map generalProps) { + if (generalProps != null && !generalProps.isEmpty()) { + Map newAttributes = new HashMap<>(); + if (this.attributes != null) newAttributes.putAll(this.attributes); + for (String key : generalProps.keySet()) { + if (newAttributes.containsKey(key)) continue; + String value = generalProps.get(key); + newAttributes.put(key, value); + } + setAttributes(newAttributes); + } + return this; + } + public Builder setAttributes(Map attributes) { this.attributes = attributes; return this; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/helper/DynamicGeneralPropsGenerator.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/helper/DynamicGeneralPropsGenerator.java new file mode 100644 index 00000000..013e2ed3 --- /dev/null +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/events/helper/DynamicGeneralPropsGenerator.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 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.events.helper; + +import java.util.Map; + +public interface DynamicGeneralPropsGenerator { + Map generateDynamicGeneralProps(); +} diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/log/Logger.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/log/Logger.java index 112d0cd5..543223f0 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/log/Logger.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/log/Logger.java @@ -204,16 +204,20 @@ private static String getLine(boolean isTop) { public static void printJson(String tag, String headString, String jsonStr) { String message; try { - if (jsonStr.startsWith("{")) { - JSONObject jsonObject = new JSONObject(jsonStr); - message = jsonObject.toString(2); - message = message.replace("\\/", "/"); - } else if (jsonStr.startsWith("[")) { - JSONArray jsonArray = new JSONArray(jsonStr); - message = jsonArray.toString(2); - message = message.replace("\\/", "/"); + if (jsonStr.length() > 10 * 1024) { + message = jsonStr.substring(0, 10 * 1024) + "...(json is too long, it's length is " + jsonStr.getBytes().length + ")"; } else { - message = jsonStr; + if (jsonStr.startsWith("{")) { + JSONObject jsonObject = new JSONObject(jsonStr); + message = jsonObject.toString(2); + message = message.replace("\\/", "/"); + } else if (jsonStr.startsWith("[")) { + JSONArray jsonArray = new JSONArray(jsonStr); + message = jsonArray.toString(2); + message = message.replace("\\/", "/"); + } else { + message = jsonStr; + } } } catch (JSONException e) { message = jsonStr; diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventDatabase.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventDatabase.java index 6b20c707..ecd563d1 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventDatabase.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/EventDatabase.java @@ -39,7 +39,6 @@ public class EventDatabase { private long lastId; private String eventType; - public int getDbOp() { return dbOp; } @@ -83,6 +82,14 @@ public static EventDatabase inserts(List events) { public static EventDatabase outDated() { EventDatabase ed = new EventDatabase(); ed.dbOp = DATABASE_OP_OUTDATED; + ed.limit = 7; + return ed; + } + + public static EventDatabase outDated(int day) { + EventDatabase ed = new EventDatabase(); + ed.dbOp = DATABASE_OP_OUTDATED; + ed.limit = day; return ed; } 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 15297456..556779a5 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 @@ -18,6 +18,7 @@ import android.text.TextUtils; import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.track.listener.TrackThread; 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; @@ -32,26 +33,58 @@ public class EventHttpSender implements IEventNetSender { private final String mProjectId; private final String mServerHost; private final TrackerRegistry trackerRegistry; + private final boolean defaultPreflight; + + private boolean requestPreflightChecked = false; public EventHttpSender(TrackerContext context) { ConfigurationProvider configurationProvider = context.getConfigurationProvider(); this.trackerRegistry = context.getRegistry(); mProjectId = configurationProvider.core().getProjectId(); mServerHost = configurationProvider.core().getDataCollectionServerHost(); + defaultPreflight = false; + } + + private boolean isPreflightChecked() { + if (defaultPreflight) return requestPreflightChecked; + else return true; } private ModelLoader getNetworkModelLoader() { return trackerRegistry.getModelLoader(EventUrl.class, EventResponse.class); } + private EventResponse requestPreflight(long time) { + EventUrl eventUrl = new EventUrl(mServerHost, time) + .setRequestMethod(EventUrl.OPTIONS) + .addPath("v3") + .addPath("projects") + .addPath(mProjectId) + .addPath("collect") + .addHeader("Access-Control-Request-Method", "POST") + .addHeader("Origin", mServerHost) + .addParam("stm", String.valueOf(time)); + ModelLoader.LoadData loadData = getNetworkModelLoader().buildLoadData(eventUrl); + if (!loadData.fetcher.getDataClass().isAssignableFrom(EventResponse.class)) { + Logger.e(TAG, new IllegalArgumentException("illegal data class for http response.")); + return new EventResponse(0); + } + EventResponse response = loadData.fetcher.executeData(); + if (response.isSucceeded()) { + requestPreflightChecked = true; + } + return response; + } + + @TrackThread @Override public SendResponse send(byte[] events, String mediaType) { if (events == null || events.length == 0) { - return new SendResponse(false, 0); + return new SendResponse(0, 0); } if (getNetworkModelLoader() == null) { Logger.e(TAG, "please register http request component first"); - return new SendResponse(false, 0); + return new SendResponse(0, 0); } long time = System.currentTimeMillis(); EventUrl eventUrl = new EventUrl(mServerHost, time) @@ -71,16 +104,19 @@ public SendResponse send(byte[] events, String mediaType) { byte[] data = eventUrl.getRequestBody(); Logger.d(TAG, "send event to url: " + eventUrl.toString()); - ModelLoader.LoadData loadData = getNetworkModelLoader().buildLoadData(eventUrl); if (!loadData.fetcher.getDataClass().isAssignableFrom(EventResponse.class)) { Logger.e(TAG, new IllegalArgumentException("illegal data class for http response.")); - return new SendResponse(false, 0); + return new SendResponse(0, 0); } EventResponse response = loadData.fetcher.executeData(); - - boolean successful = response != null && response.isSucceeded(); + int responseCode = response != null ? response.getResponseCode() : 0; + if (responseCode >= 200 && responseCode < 300) { + requestPreflightChecked = true; + } else if (responseCode == 403) { + requestPreflightChecked = false; + } long totalUsed = data == null ? 0L : data.length; - return new SendResponse(successful, totalUsed); + return new SendResponse(responseCode, totalUsed); } } 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 61d56cec..adf50717 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 @@ -19,6 +19,7 @@ import android.app.ActivityManager; import android.content.Context; import android.content.SharedPreferences; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -45,19 +46,12 @@ public class EventSender { private static final String TAG = "EventSender"; - private static final int EVENTS_BULK_SIZE = 100; - private final Context mContext; private IEventNetSender mEventNetSender; private final SharedPreferences mSharedPreferences; private final SendHandler mSendHandler; private final ProcessLock mProcessLock; - - private final long mDataUploadInterval; private final long mCellularDataLimit; - - private int mCacheEventNum = 0; - private final TrackerRegistry mRegistry; /** @@ -72,13 +66,22 @@ public EventSender(Context context, TrackerRegistry registry, IEventNetSender se mContext = context.getApplicationContext(); mRegistry = registry; mCellularDataLimit = cellularDataLimit * 1024L * 1024L; - mDataUploadInterval = dataUploadInterval * 1000L; mEventNetSender = sender; 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()); + mSendHandler = new SendHandler(thread.getLooper(), dataUploadInterval * 1000L); + } + + public void shutdown() { + mProcessLock.release(); + mSendHandler.removeCallbacksAndMessages(null); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + mSendHandler.getLooper().quitSafely(); + } else { + mSendHandler.getLooper().quit(); + } } private ModelLoader getDatabaseModelLoader() { @@ -100,28 +103,16 @@ void setEventNetSender(IEventNetSender mEventNetSender) { } public void cacheEvent(GEvent event) { - databaseOperation(EventDatabase.insert(event)); // 避免不触发非INSTANT事件时(如埋点SDK),cache事件不被发送 - if (mDataUploadInterval <= 0) { - mSendHandler.uploadUninstantEvents(); - } + databaseOperation(EventDatabase.insert(event)); } public void sendEvent(GEvent event) { databaseOperation(EventDatabase.insert(event)); if (event.getSendPolicy() == SEND_POLICY_INSTANT) { - mSendHandler.uploadInstantEvents(); + mSendHandler.uploadInstantEvent(); } else { - if (mDataUploadInterval > 0) { - mCacheEventNum++; - if (mCacheEventNum >= EVENTS_BULK_SIZE) { - Logger.w(TAG, "cacheEventNum >= EVENTS_BULK_SIZE, toggle one send action"); - mSendHandler.uploadUninstantEvents(); - mCacheEventNum = 0; - } - } else { - mSendHandler.uploadUninstantEvents(); - } + mSendHandler.uploadUninstantEvent(); } } @@ -211,8 +202,12 @@ void sendEvents(boolean onlyInstant) { uploadEvents = new int[]{SEND_POLICY_INSTANT, GEvent.SEND_POLICY_MOBILE_DATA}; } + boolean succeeded = true; for (int policy : uploadEvents) { - boolean succeeded; + if (!succeeded) { + Logger.e(TAG, "upload events break with http failed."); + break; + } do { if (policy != SEND_POLICY_INSTANT && networkState.isMobileData() @@ -227,12 +222,28 @@ && mCellularDataLimit < todayBytes(0)) { } else { SendResponse sendResponse = mEventNetSender.send(dbResult.getData(), dbResult.getMediaType()); succeeded = sendResponse.isSucceeded(); + int responseCode = sendResponse.getResponseCode(); if (succeeded) { String eventType = dbResult.getEventType(); databaseOperation(EventDatabase.delete(dbResult.getLastId(), policy, eventType)); if (networkState.isMobileData()) { todayBytes(sendResponse.getUsedBytes()); } + mSendHandler.resetBackoff(); + } else if (responseCode == 413) { + String eventType = dbResult.getEventType(); + databaseOperation(EventDatabase.delete(dbResult.getLastId(), policy, eventType)); + if (networkState.isMobileData()) { + todayBytes(sendResponse.getUsedBytes()); + } + Logger.e(TAG, "action: sendEvents, delete events with responseCode: " + responseCode); + break; + } else if (responseCode >= 400) { + // Logger.e(TAG, "action: sendEvents, backoff with some reasons,eg: Unavailable For Legal Reasons"); + // 5xx Service Unavailable + mSendHandler.backoff(); + Logger.e(TAG, "action: sendEvents, service unavailable with responseCode: " + responseCode); + break; } } @@ -253,21 +264,68 @@ private final class SendHandler extends Handler { private static final int MSG_SEND_INSTANT_EVENTS = 1; private static final int MSG_SEND_UNINSTANT_EVENTS = 2; - private SendHandler(@NonNull Looper looper) { + private static final long EVENTS_UPLOAD_INTERVAL_MAX = 5 * 60 * 1000; // 5 minutes + private static final int EVENTS_BULK_SIZE = 100; + + private final long mDataUploadInterval; + private long backoffUploadInterval; + private int cacheEventNum = 0; + + private SendHandler(@NonNull Looper looper, long dataUploadInterval) { super(looper); - if (mDataUploadInterval > 0) { - sendEmptyMessageDelayed(MSG_SEND_UNINSTANT_EVENTS, mDataUploadInterval); + this.mDataUploadInterval = dataUploadInterval; + backoffUploadInterval = mDataUploadInterval; + if (backoffUploadInterval > 0) { + sendEmptyMessageDelayed(MSG_SEND_UNINSTANT_EVENTS, backoffUploadInterval); + } + } + + void backoff() { + if (backoffUploadInterval > 0) { + backoffUploadInterval = Math.min(backoffUploadInterval * 2, EVENTS_UPLOAD_INTERVAL_MAX); + } else { + backoffUploadInterval = 15000L; + } + removeCallbacksAndMessages(null); + sendEmptyMessageDelayed(MSG_SEND_UNINSTANT_EVENTS, backoffUploadInterval); + } + + void resetBackoff() { + if (isNotBackoffState()) return; + backoffUploadInterval = mDataUploadInterval; + removeCallbacksAndMessages(null); + if (backoffUploadInterval > 0) { + sendEmptyMessageDelayed(MSG_SEND_UNINSTANT_EVENTS, backoffUploadInterval); } } - private void uploadInstantEvents() { - removeMessages(MSG_SEND_INSTANT_EVENTS); - sendEmptyMessage(MSG_SEND_INSTANT_EVENTS); + boolean isNotBackoffState() { + return backoffUploadInterval == mDataUploadInterval; + } + + private void uploadInstantEvent() { + if (isNotBackoffState()) { + removeMessages(MSG_SEND_INSTANT_EVENTS); + sendEmptyMessage(MSG_SEND_INSTANT_EVENTS); + } } - private void uploadUninstantEvents() { - removeMessages(MSG_SEND_UNINSTANT_EVENTS); - sendEmptyMessage(MSG_SEND_UNINSTANT_EVENTS); + private void uploadUninstantEvent() { + if (backoffUploadInterval > 0) { + cacheEventNum++; + // If it is a non-real-time event, + // it will be sent immediately when the number of cached events reaches a certain amount, + // provided that it is not in a backoff state. + if (cacheEventNum >= EVENTS_BULK_SIZE && isNotBackoffState()) { + Logger.w(TAG, "cacheEventNum >= EVENTS_BULK_SIZE, merge events and send."); + cacheEventNum = 0; + removeMessages(MSG_SEND_UNINSTANT_EVENTS); + sendEmptyMessage(MSG_SEND_UNINSTANT_EVENTS); + } + } else { + removeMessages(MSG_SEND_UNINSTANT_EVENTS); + sendEmptyMessage(MSG_SEND_UNINSTANT_EVENTS); + } } @Override @@ -279,8 +337,8 @@ public void handleMessage(@NonNull Message msg) { case MSG_SEND_UNINSTANT_EVENTS: removeMessages(MSG_SEND_UNINSTANT_EVENTS); sendEvents(false); - if (mDataUploadInterval > 0) { - sendEmptyMessageDelayed(MSG_SEND_UNINSTANT_EVENTS, mDataUploadInterval); + if (backoffUploadInterval > 0) { + sendEmptyMessageDelayed(MSG_SEND_UNINSTANT_EVENTS, backoffUploadInterval); } break; default: diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/IEventNetSender.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/IEventNetSender.java index 29e3aa4b..0d86f8ce 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/IEventNetSender.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/IEventNetSender.java @@ -15,6 +15,9 @@ */ package com.growingio.android.sdk.track.middleware; +import com.growingio.android.sdk.track.listener.TrackThread; + public interface IEventNetSender { + @TrackThread SendResponse send(byte[] events, String mediaType); } diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/SendResponse.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/SendResponse.java index 2b9bfd36..e1df8452 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/SendResponse.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/SendResponse.java @@ -16,19 +16,23 @@ package com.growingio.android.sdk.track.middleware; public class SendResponse { - private final boolean mSucceeded; - private final long mUsedBytes; + private final int responseCode; + private final long usedBytes; - public SendResponse(boolean succeeded, long usedBytes) { - mSucceeded = succeeded; - mUsedBytes = usedBytes; + public SendResponse(int responseCode, long usedBytes) { + this.responseCode = responseCode; + this.usedBytes = usedBytes; } public boolean isSucceeded() { - return mSucceeded; + return responseCode >= 200 && responseCode < 300; } public long getUsedBytes() { - return mUsedBytes; + return usedBytes; + } + + public int getResponseCode() { + return responseCode; } } diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventResponse.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventResponse.java index dcde66b6..98a57402 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventResponse.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventResponse.java @@ -19,11 +19,20 @@ public class EventResponse { private final boolean succeeded; - private final InputStream stream; //it's useless + private final InputStream stream; private final long usedBytes; //it's useless + private final int responseCode; + + public EventResponse(int code) { + this.responseCode = code; + this.succeeded = responseCode >= 200 && responseCode < 300; + usedBytes = 0L; + stream = null; + } public EventResponse(boolean succeeded) { this.succeeded = succeeded; + this.responseCode = 0; usedBytes = 0L; stream = null; } @@ -32,11 +41,13 @@ public EventResponse(boolean succeeded, InputStream stream, long usedBytes) { this.succeeded = succeeded; this.usedBytes = usedBytes; this.stream = stream; + this.responseCode = 204; } - public EventResponse(boolean succeeded, InputStream stream) { - this.succeeded = succeeded; - usedBytes = 0L; + public EventResponse(int responseCode, InputStream stream, long usedBytes) { + this.responseCode = responseCode; + this.succeeded = responseCode >= 200 && responseCode < 300; + this.usedBytes = usedBytes; this.stream = stream; } @@ -51,4 +62,8 @@ public long getUsedBytes() { public InputStream getStream() { return stream; } + + public int getResponseCode() { + return responseCode; + } } diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventUrl.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventUrl.java index 9c8abcf1..43debf2f 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventUrl.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/middleware/http/EventUrl.java @@ -23,6 +23,9 @@ public class EventUrl { public static int GET = 0; public static int POST = 1; + + public static int HEAD = 4; + public static int OPTIONS = 6; private final String mHost; private final Map mHeaders = new HashMap<>(); private final List mPaths = new ArrayList<>(); @@ -32,7 +35,6 @@ public class EventUrl { private String mMediaType = "application/json"; //or "application/x-www-form-urlencoded" for data private int mCallTimeout = -1; - private int mRequestMethod = GET; public EventUrl(String host, long time) { diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/ConfigurationProvider.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/ConfigurationProvider.java index ff64c0c1..214266ce 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/ConfigurationProvider.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/ConfigurationProvider.java @@ -83,6 +83,12 @@ public void addConfiguration(Configurable config) { } } + public void removeConfiguration(Class configClazz) { + if (configClazz != null) { + sModuleConfigs.remove(configClazz); + } + } + public String printAllConfigurationInfo() { StringBuilder info = new StringBuilder(); if (!mCoreConfiguration.isDebugEnabled()) { diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/DeepLinkProvider.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/DeepLinkProvider.java index 4317d6ac..58a722ff 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/DeepLinkProvider.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/DeepLinkProvider.java @@ -190,7 +190,7 @@ public void onDataReady(WebService data) { @Override public void onLoadFailed(Exception e) { - Logger.e(TAG, e.getMessage()); + Logger.e(TAG, "Are you implement autotrack sdk or set autotrack is true in configuration?"); } }); } diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/EventBuilderProvider.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/EventBuilderProvider.java index 577bd2d2..6d6265a5 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/EventBuilderProvider.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/providers/EventBuilderProvider.java @@ -24,10 +24,11 @@ import com.growingio.android.sdk.track.events.EventFilterInterceptor; import com.growingio.android.sdk.track.events.PageEvent; import com.growingio.android.sdk.track.events.PageLevelCustomEvent; -import com.growingio.android.sdk.track.events.TrackEventType; import com.growingio.android.sdk.track.events.ViewElementEvent; +import com.growingio.android.sdk.track.events.base.BaseAttributesEvent; import com.growingio.android.sdk.track.events.base.BaseEvent; import com.growingio.android.sdk.track.events.helper.DefaultEventFilterInterceptor; +import com.growingio.android.sdk.track.events.helper.DynamicGeneralPropsGenerator; import com.growingio.android.sdk.track.events.helper.JsonSerializableFactory; import com.growingio.android.sdk.track.listener.TrackThread; import com.growingio.android.sdk.track.log.Logger; @@ -51,6 +52,7 @@ public class EventBuilderProvider implements TrackerLifecycleProvider { private final List mEventBuildInterceptors = new ArrayList<>(); private EventFilterInterceptor defaultFilterInterceptor; + private DynamicGeneralPropsGenerator dynamicGeneralPropsGenerator; private static final JsonSerializableFactory serializableFactory = new JsonSerializableFactory(); @@ -71,6 +73,8 @@ public void setup(TrackerContext context) { @Override public void shutdown() { mEventBuildInterceptors.clear(); + generalProps.clear(); + dynamicGeneralPropsGenerator = null; } public static JSONObject toJson(BaseEvent event) { @@ -114,7 +118,8 @@ public BaseEvent onGenerateGEvent(BaseEvent.BaseBuilder gEvent) { if (!filterEvent(gEvent)) return null; - addGeneralPropsToEvent(gEvent); + addDynamicPropsToAllEvent(gEvent); + addGeneralPropsToAllEvent(gEvent); gEvent.readPropertyInTrackThread(context); if (!configurationProvider.isDowngrade()) { gEvent.readNewPropertyInTrackThread(context); @@ -126,12 +131,23 @@ public BaseEvent onGenerateGEvent(BaseEvent.BaseBuilder gEvent) { return event; } - private void addGeneralPropsToEvent(BaseEvent.BaseBuilder gEvent) { - if (gEvent.getEventType().equals(TrackEventType.CUSTOM)) { - if (gEvent instanceof CustomEvent.Builder) { - CustomEvent.Builder customEventBuilder = (CustomEvent.Builder) gEvent; - customEventBuilder.setGeneralProps(generalProps.build()); + private void addDynamicPropsToAllEvent(BaseEvent.BaseBuilder gEvent) { + if (dynamicGeneralPropsGenerator == null) return; + try { + if (gEvent instanceof BaseAttributesEvent.Builder) { + BaseAttributesEvent.Builder attrEventBuilder = (BaseAttributesEvent.Builder) gEvent; + Map dynamicProps = dynamicGeneralPropsGenerator.generateDynamicGeneralProps(); + attrEventBuilder.setGeneralProps(dynamicProps); } + } catch (Exception e) { + Logger.e(TAG, "dynamicGeneralPropGenerator generateDynamicGeneralProps error", e); + } + } + + private void addGeneralPropsToAllEvent(BaseEvent.BaseBuilder gEvent) { + if (gEvent instanceof BaseAttributesEvent.Builder) { + BaseAttributesEvent.Builder attrEventBuilder = (BaseAttributesEvent.Builder) gEvent; + attrEventBuilder.setGeneralProps(generalProps.build()); } } @@ -256,4 +272,8 @@ String getEventPath(BaseEvent.BaseBuilder eventBuilder) { } return null; } + + public void setDynamicGeneralPropGenerator(DynamicGeneralPropsGenerator dynamicGeneralPropsGenerator) { + this.dynamicGeneralPropsGenerator = dynamicGeneralPropsGenerator; + } } diff --git a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/utils/ConstantPool.java b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/utils/ConstantPool.java index ef563c16..798b3fde 100644 --- a/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/utils/ConstantPool.java +++ b/growingio-tracker-core/src/main/java/com/growingio/android/sdk/track/utils/ConstantPool.java @@ -22,8 +22,5 @@ private ConstantPool() { public static final String UNKNOWN = "UNKNOWN"; public static final String ANDROID = "Android"; - public static final int CUSTOM_TYPE_SYSTEM = 0; - public static final int CUSTOM_TYPE_USER = 1; - public static final String PREF_FILE_NAME = "growing_profile"; } diff --git a/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/events/EventsTest.java b/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/events/EventsTest.java index 41dea838..90591392 100644 --- a/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/events/EventsTest.java +++ b/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/events/EventsTest.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -120,13 +121,15 @@ public void eventLoginUserBuilder() { .addAttribute("key9", list) .addAttribute("", Arrays.asList("", "", "")) .addAttribute("key10", Arrays.asList(null, "1")) + .addAttribute("key11", new Date(1713774942168L)) .build(); - Truth.assertThat(map.size()).isEqualTo(6); + Truth.assertThat(map.size()).isEqualTo(7); Truth.assertThat(map.containsKey("key5")).isFalse(); Truth.assertThat("1||2||3||4").isEqualTo(map.get("key2")); Truth.assertThat("1111||2222").isEqualTo(map.get("key9")); Truth.assertThat("||||").isEqualTo(map.get("")); Truth.assertThat("||1").isEqualTo(map.get("key10")); + Truth.assertThat(map.get("key11").startsWith("2024-04-2")).isTrue(); } @Test 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 32dc2b13..c21e7aac 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 @@ -79,7 +79,7 @@ public void eventSendTest() { } catch (InvalidProtocolBufferException e) { e.printStackTrace(); } - return new SendResponse(true, 1000L); + return new SendResponse(204, 1000L); }); eventSender.sendEvent(new CustomEvent.Builder() .setEventName("cpacm") @@ -114,7 +114,7 @@ public void eventCacheTestPb() throws InvalidProtocolBufferException { } catch (InvalidProtocolBufferException e) { e.printStackTrace(); } - return new SendResponse(true, 1000L); + return new SendResponse(204, 1000L); }); eventSender.cacheEvent(ce); eventSender.cacheEvent(ce); @@ -151,7 +151,7 @@ public void eventCacheTestJson() throws JSONException { e.printStackTrace(); } - return new SendResponse(true, 1000L); + return new SendResponse(204, 1000L); }); eventSender.cacheEvent(ce); eventSender.cacheEvent(ce); diff --git a/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/providers/EventBuilderProviderFilterTest.java b/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/providers/EventBuilderProviderFilterTest.java index 4c517d73..aaa93adf 100644 --- a/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/providers/EventBuilderProviderFilterTest.java +++ b/growingio-tracker-core/src/test/java/com/growingio/android/sdk/track/providers/EventBuilderProviderFilterTest.java @@ -31,7 +31,6 @@ import com.growingio.android.sdk.track.events.base.BaseField; import com.growingio.android.sdk.track.events.helper.DefaultEventFilterInterceptor; import com.growingio.android.sdk.track.middleware.GEvent; -import com.growingio.android.sdk.track.utils.ConstantPool; import org.junit.Before; import org.junit.Test; @@ -176,7 +175,7 @@ public void eventDidBuild(GEvent event) { } } }); - eventBuilderProvider.onGenerateGEvent(new CustomEvent.Builder().setCustomEventType(ConstantPool.CUSTOM_TYPE_USER).setEventName("cpacm")); + eventBuilderProvider.onGenerateGEvent(new CustomEvent.Builder().setEventName("cpacm")); } } diff --git a/growingio-webservice/circler/build.gradle b/growingio-webservice/circler/build.gradle index 113cb5ed..f16197c0 100644 --- a/growingio-webservice/circler/build.gradle +++ b/growingio-webservice/circler/build.gradle @@ -39,6 +39,7 @@ android { } dependencies { + testImplementation libs.google.material testImplementation libs.bundles.test testImplementation libs.okhttp3.mockwebserver testImplementation libs.androidx.test.core diff --git a/growingio-webservice/circler/src/main/java/com/growingio/android/circler/CirclerDataLoader.java b/growingio-webservice/circler/src/main/java/com/growingio/android/circler/CirclerDataLoader.java index 8dedbef5..7f041274 100644 --- a/growingio-webservice/circler/src/main/java/com/growingio/android/circler/CirclerDataLoader.java +++ b/growingio-webservice/circler/src/main/java/com/growingio/android/circler/CirclerDataLoader.java @@ -16,6 +16,7 @@ package com.growingio.android.circler; import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.autotrack.AutotrackConfig; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.modelloader.ModelLoaderFactory; import com.growingio.android.sdk.track.middleware.webservice.Circler; @@ -72,6 +73,11 @@ public Factory(TrackerContext context) { @Override public ModelLoader build() { + // circler is enabled when autotrack is enabled + AutotrackConfig config = context.getConfigurationProvider().getConfiguration(AutotrackConfig.class); + if (config == null || !config.isAutotrack()) { + return null; + } return new CirclerDataLoader(getsInternalClient(), context); } } diff --git a/growingio-webservice/circler/src/test/java/com/growingio/android/circler/CirclerTest.java b/growingio-webservice/circler/src/test/java/com/growingio/android/circler/CirclerTest.java index 1942f125..ea866b0d 100644 --- a/growingio-webservice/circler/src/test/java/com/growingio/android/circler/CirclerTest.java +++ b/growingio-webservice/circler/src/test/java/com/growingio/android/circler/CirclerTest.java @@ -23,12 +23,16 @@ import com.google.common.truth.Truth; import com.google.common.util.concurrent.Uninterruptibles; import com.growingio.android.circler.shadow.ShadowThreadUtils; +import com.growingio.android.sdk.Configurable; +import com.growingio.android.sdk.CoreConfiguration; import com.growingio.android.sdk.Tracker; import com.growingio.android.sdk.TrackerContext; +import com.growingio.android.sdk.autotrack.AutotrackConfig; import com.growingio.android.sdk.track.modelloader.DataFetcher; import com.growingio.android.sdk.track.modelloader.ModelLoader; import com.growingio.android.sdk.track.middleware.webservice.Circler; import com.growingio.android.sdk.track.middleware.webservice.WebService; +import com.growingio.android.sdk.track.providers.TrackerLifecycleProviderFactory; import org.json.JSONException; import org.json.JSONObject; @@ -39,6 +43,7 @@ import org.robolectric.annotation.Config; import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; @@ -78,6 +83,10 @@ private void sendMessage(WebSocket webSocket, String message) { @Before public void setup() { + Map, Configurable> sModuleConfigs = new HashMap<>(); + sModuleConfigs.put(AutotrackConfig.class, new AutotrackConfig()); + TrackerLifecycleProviderFactory.create().createConfigurationProviderWithConfig(new CoreConfiguration("growing.project", "growing.test"), sModuleConfigs); + Tracker tracker = new Tracker(application); CirclerLibraryGioModule dModule = new CirclerLibraryGioModule(); tracker.registerComponent(dModule); diff --git a/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/DebuggerService.java b/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/DebuggerService.java index e4911439..9a38ff77 100644 --- a/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/DebuggerService.java +++ b/growingio-webservice/debugger/src/main/java/com/growingio/android/debugger/DebuggerService.java @@ -185,7 +185,7 @@ public void onFailed() { } socketState.set(SOCKET_STATE_CLOSED); - Logger.e(TAG, "Start CirclerService Failed"); + Logger.e(TAG, "Start DebuggerService Failed"); screenshotProvider.setTipViewMessage(R.string.growing_debugger_connected_to_web_failed); screenshotProvider.showQuitDialog(this::cleanup); }