Skip to content

Commit

Permalink
fix: 解决在Visit事件前发送事件导致sessionId不正常
Browse files Browse the repository at this point in the history
  • Loading branch information
LitterSun committed Dec 15, 2020
1 parent 6fa83e0 commit f5393f1
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import android.view.WindowManager;

import androidx.lifecycle.Lifecycle;
import androidx.test.core.app.ActivityScenario;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;

Expand All @@ -34,6 +34,7 @@
import com.google.common.truth.Truth;
import com.growingio.android.sdk.track.BuildConfig;
import com.growingio.android.sdk.track.GrowingTracker;
import com.growingio.android.sdk.track.data.PersistentDataProvider;
import com.growingio.android.sdk.track.providers.ConfigurationProvider;
import com.growingio.autotest.EventsTest;
import com.growingio.autotest.TestTrackConfiguration;
Expand All @@ -46,7 +47,6 @@
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -67,9 +67,6 @@ public class SessionEventsTest extends EventsTest {
private String mLoginUserId;
private long mVisitTimestamp;

@Rule
public ActivityScenarioRule<MainActivity> scenarioRule = new ActivityScenarioRule<>(MainActivity.class);

@BeforeAppOnCreate
public static void beforeAppOnCreate() {
DataHelper.deleteAllData();
Expand Down Expand Up @@ -149,10 +146,11 @@ protected void onReceivedAppClosedEvents(JSONArray jsonArray) throws JSONExcepti
}
}
});
ActivityScenario<MainActivity> scenario = ActivityScenario.launch(MainActivity.class);
Awaiter.untilTrue(receivedVisit);

//To State STOP
scenarioRule.getScenario().moveToState(Lifecycle.State.CREATED);
scenario.moveToState(Lifecycle.State.CREATED);
Awaiter.untilTrue(receivedAppClosed);

receivedAppClosed.set(false);
Expand All @@ -171,9 +169,9 @@ protected void onReceivedAppClosedEvents(JSONArray jsonArray) throws JSONExcepti
}
});
//To State RESUMED
scenarioRule.getScenario().moveToState(Lifecycle.State.RESUMED);
scenario.moveToState(Lifecycle.State.RESUMED);
//To State STOP
scenarioRule.getScenario().moveToState(Lifecycle.State.CREATED);
scenario.moveToState(Lifecycle.State.CREATED);
Awaiter.untilTrue(receivedAppClosed);

receivedVisit.set(false);
Expand Down Expand Up @@ -205,10 +203,10 @@ protected void onReceivedAppClosedEvents(JSONArray jsonArray) throws JSONExcepti
Uninterruptibles.sleepUninterruptibly(delayTime * 1000 + 1, TimeUnit.MILLISECONDS);

//To State RESUMED
scenarioRule.getScenario().moveToState(Lifecycle.State.RESUMED);
scenario.moveToState(Lifecycle.State.RESUMED);
Awaiter.untilTrue(receivedVisit);
//To State DESTROYED
scenarioRule.getScenario().moveToState(Lifecycle.State.DESTROYED);
scenario.moveToState(Lifecycle.State.DESTROYED);
Awaiter.untilTrue(receivedAppClosed);
}

Expand Down Expand Up @@ -239,6 +237,7 @@ protected void onReceivedVisitEvents(JSONArray jsonArray) throws JSONException {
}
}
});
ActivityScenario<MainActivity> scenario = ActivityScenario.launch(MainActivity.class);
Awaiter.untilTrue(receivedVisit);

resendVisitEventLoginUserIdFirstFromNull2NotNull();
Expand All @@ -248,6 +247,7 @@ protected void onReceivedVisitEvents(JSONArray jsonArray) throws JSONException {
resendVisitEventLoginUserIdFromNull2New();
resendVisitEventLoginUserIdFromNotNull2Same();
resendVisitEventLoginUserIdFromNotNull2New();
scenario.close();
}

private void resendVisitEventLoginUserIdFromNull2New() {
Expand Down Expand Up @@ -360,13 +360,15 @@ protected void onReceivedVisitEvents(JSONArray jsonArray) throws JSONException {
receivedVisit.set(true);
}
});
ActivityScenario<MainActivity> scenario = ActivityScenario.launch(MainActivity.class);
Awaiter.untilTrue(receivedVisit);

resendVisitEventLocationFromNull2NotNull();
resendVisitEventLocationFromNotNull2NotNull();

GrowingTracker.get().cleanLocation();
resendVisitEventLocationFromNull2NotNull();
scenario.close();
}

private void resendVisitEventLocationFromNull2NotNull() {
Expand Down Expand Up @@ -397,4 +399,60 @@ protected void onReceivedVisitEvents(JSONArray jsonArray) throws JSONException {
Uninterruptibles.sleepUninterruptibly(1, SECONDS);
}

/**
* 如果在visit事件前触发埋点事件,需要强制补发visit事件后再发送custom事件,
* 且后续Activity生命周期不在触发visit事件
*/
@Test
public void forceReissueVisitEventTest() {
final AtomicBoolean receivedVisit = new AtomicBoolean(false);
final AtomicBoolean receivedCustom = new AtomicBoolean(false);
String oldSessionId = PersistentDataProvider.get().getSessionId();
getEventsApiServer().setOnReceivedEventListener(new MockEventsApiServer.OnReceivedEventListener() {
@Override
protected void onReceivedVisitEvents(JSONArray jsonArray) throws JSONException {
checkVisitEvent(jsonArray);
JSONObject visit = jsonArray.getJSONObject(0);
mSessionId = visit.getString("sessionId");
Truth.assertThat(mSessionId).isNotEmpty();
Truth.assertThat(oldSessionId).isNotEqualTo(mSessionId);
receivedVisit.set(true);
}

@Override
protected void onReceivedCustomEvents(JSONArray jsonArray) throws JSONException {
JSONObject jsonObject = jsonArray.getJSONObject(0);
if ("beforeVisitEvent".equals(jsonObject.getString("eventName"))
&& mSessionId.equals(jsonObject.getString("sessionId"))) {
receivedCustom.set(true);
}
}
});

GrowingTracker.get().trackCustomEvent("beforeVisitEvent");
Awaiter.untilTrue(receivedVisit);
Awaiter.untilTrue(receivedCustom);

receivedCustom.set(false);
getEventsApiServer().setOnReceivedEventListener(new MockEventsApiServer.OnReceivedEventListener() {
@Override
protected void onReceivedVisitEvents(JSONArray jsonArray) throws JSONException {
Truth.assertWithMessage("Received Visit Event").fail();
}

@Override
protected void onReceivedCustomEvents(JSONArray jsonArray) throws JSONException {
JSONObject jsonObject = jsonArray.getJSONObject(0);
if ("beforeVisitEvent".equals(jsonObject.getString("eventName"))
&& mSessionId.equals(jsonObject.getString("sessionId"))) {
receivedCustom.set(true);
}
}
});

ActivityScenario<MainActivity> scenario = ActivityScenario.launch(MainActivity.class);
GrowingTracker.get().trackCustomEvent("beforeVisitEvent");
scenario.close();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -286,20 +286,23 @@ public long getAndIncrement(String key, long startValue) {
@Override
public long getAndAdd(String key, long delta, long startValue) {
synchronized (this) {
Logger.d(TAG, "getAndAdd: key = " + key + ", delta = " + delta + ", startValue = " + startValue);
awaitLoadedLocked();
final long[] result = new long[1];
SharedEntry entry = mSharedEntries.get(key);
if (entry != null) {
lockedRun(new Runnable() {
@Override
public void run() {
result[0] = (long) entry.getValue(mMappedByteBuffer);
entry.putLong(mMappedByteBuffer, result[0] + delta);
result[0] = (long) entry.getValue(mMappedByteBuffer) + delta;
entry.putLong(mMappedByteBuffer, result[0]);
}
}, entry.getPosition(), SharedEntry.MAX_SIZE);
Logger.d(TAG, "getAndAdd: result = " + result[0]);
return result[0];
} else {
putValue(key, SharedEntry.VALUE_TYPE_LONG, startValue);
Logger.d(TAG, "getAndAdd: return startValue");
return startValue;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

package com.growingio.android.sdk.track.providers;

import android.content.Context;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.growingio.android.sdk.track.ContextProvider;
import com.growingio.android.sdk.track.TrackMainThread;
import com.growingio.android.sdk.track.data.PersistentDataProvider;
import com.growingio.android.sdk.track.events.TrackEventGenerator;
Expand All @@ -28,6 +30,7 @@
import com.growingio.android.sdk.track.listener.OnUserIdChangedListener;
import com.growingio.android.sdk.track.listener.event.ActivityLifecycleEvent;
import com.growingio.android.sdk.track.log.Logger;
import com.growingio.android.sdk.track.utils.SystemUtil;

import java.util.UUID;

Expand All @@ -44,12 +47,14 @@ public class SessionProvider implements IActivityLifecycle, OnUserIdChangedListe
private long mLatestPauseTime = 0;
private long mLatestVisitTime = 0;
private volatile String mSessionId;
private final Context mContext;

private static class SingleInstance {
private static final SessionProvider INSTANCE = new SessionProvider();
}

private SessionProvider() {
mContext = ContextProvider.getApplicationContext();
mSessionInterval = ConfigurationProvider.get().getTrackConfiguration().getSessionInterval() * 1000;
ActivityStateProvider.get().registerActivityLifecycleListener(this);
}
Expand All @@ -58,8 +63,12 @@ public static SessionProvider get() {
return SingleInstance.INSTANCE;
}

@TrackThread
void checkAndSendVisit(long resumeTime) {
if (mAlreadySendVisit && mLatestPauseTime == 0) {
Logger.w(TAG, "Visit event already send by force reissue");
return;
}

if (resumeTime - mLatestPauseTime >= mSessionInterval) {
String sessionId = refreshSessionId();
generateVisit(sessionId, resumeTime);
Expand Down Expand Up @@ -101,7 +110,7 @@ public boolean createdSession() {
}

public void forceReissueVisit() {
if (mAlreadySendVisit || ActivityStateProvider.get().getForegroundActivity() == null) {
if (mAlreadySendVisit || !SystemUtil.isMainProcess(mContext)) {
return;
}
String sessionId = refreshSessionId();
Expand Down Expand Up @@ -156,7 +165,6 @@ public void onTrackMainInitSDK() {
UserInfoProvider.get().registerUserIdChangedListener(this);
}


@Override
public void onUserIdChanged(@Nullable String newUserId) {
Logger.d(TAG, "onUserIdChanged: newUserId = " + newUserId + ", mLatestNonNullUserId = " + mLatestNonNullUserId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@
import android.app.ActivityManager;
import android.content.Context;
import android.os.Process;
import android.text.TextUtils;

import com.growingio.android.sdk.track.log.Logger;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.List;

public class SystemUtil {
private static final String TAG = "SystemUtil";

private SystemUtil() {
}

Expand All @@ -41,4 +49,22 @@ public static void killAppProcess(Context context) {
Process.killProcess(Process.myPid());
System.exit(0);
}

public static String getProcessName() {
try {
File file = new File("/proc/" + android.os.Process.myPid() + "/" + "cmdline");
BufferedReader mBufferedReader = new BufferedReader(new FileReader(file));
String processName = mBufferedReader.readLine().trim();
mBufferedReader.close();
return processName;
} catch (Exception e) {
Logger.e(TAG, e);
return null;
}
}

public static boolean isMainProcess(Context context) {
String processName = getProcessName();
return !TextUtils.isEmpty(processName) && processName.equals(context.getPackageName());
}
}

0 comments on commit f5393f1

Please sign in to comment.