Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Countly/countly-sdk-android
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 24.7.1
Choose a base ref
...
head repository: Countly/countly-sdk-android
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 24.7.2
Choose a head ref
  • 12 commits
  • 8 files changed
  • 3 contributors

Commits on Jul 25, 2024

  1. feat: countly timer

    arifBurakDemiray committed Jul 25, 2024
    Copy the full SHA
    0a879f3 View commit details
  2. feat: countly timer tests

    arifBurakDemiray committed Jul 25, 2024
    Copy the full SHA
    11a8a53 View commit details
  3. feat: secondo

    arifBurakDemiray committed Jul 25, 2024
    Copy the full SHA
    98bebf7 View commit details

Commits on Jul 26, 2024

  1. Update CountlyTimer.java

    arifBurakDemiray authored Jul 26, 2024
    Copy the full SHA
    d6db35a View commit details

Commits on Aug 14, 2024

  1. Merge pull request #366 from Countly/countly_timer

    Countly timer
    turtledreams authored Aug 14, 2024
    Copy the full SHA
    4955c24 View commit details
  2. fix: upload plugin

    arifBurakDemiray committed Aug 14, 2024
    Copy the full SHA
    69e0166 View commit details
  3. fix: upload plugin changelog

    arifBurakDemiray committed Aug 14, 2024
    Copy the full SHA
    5c0ced0 View commit details
  4. feat: update version

    arifBurakDemiray committed Aug 14, 2024
    Copy the full SHA
    2587cd3 View commit details
  5. Update CHANGELOG.md

    turtledreams authored Aug 14, 2024
    Copy the full SHA
    9ada3aa View commit details
  6. Copy the full SHA
    c71a1a9 View commit details
  7. merge: changelog

    arifBurakDemiray committed Aug 14, 2024
    Copy the full SHA
    0d8ba27 View commit details
  8. Merge pull request #377 from Countly/fix_plugin

    fix: upload plugin
    turtledreams authored Aug 14, 2024
    Copy the full SHA
    9669272 View commit details
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 24.7.2
* Mitigated an issue in the upload plugin that prevented the upload of a symbol file

## 24.7.1
* ! Minor breaking change ! Unsupported types for user properties will now be omitted, they won't be converted to strings.

2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ org.gradle.configureondemand=true
android.useAndroidX=true
android.enableJetifier=true
# RELEASE FIELD SECTION
VERSION_NAME=24.7.1
VERSION_NAME=24.7.2
GROUP=ly.count.android
POM_URL=https://github.com/Countly/countly-sdk-android
POM_SCM_URL=https://github.com/Countly/countly-sdk-android
104 changes: 104 additions & 0 deletions sdk/src/androidTest/java/ly/count/android/sdk/CountlyTimerTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package ly.count.android.sdk;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.concurrent.ExecutorService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;

@RunWith(AndroidJUnit4.class)
public class CountlyTimerTests {

private CountlyTimer countlyTimer;
private ModuleLog mockLog;

@Before
public void setUp() {
countlyTimer = new CountlyTimer();
mockLog = Mockito.mock(ModuleLog.class);
CountlyTimer.TIMER_DELAY_MS = 0;
}

@After
public void tearDown() {
countlyTimer.stopTimer(mockLog);
Assert.assertNull(countlyTimer.timerService);
}

@Test
public void validateInitialValues() {
Assert.assertNull(countlyTimer.timerService);
Assert.assertEquals(0, CountlyTimer.TIMER_DELAY_MS);
}

@Test
public void startTimer_validDelay() {
Runnable mockRunnable = Mockito.mock(Runnable.class);

countlyTimer.startTimer(1, mockRunnable, mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] startTimer, Starting timer timerDelay: [1000 ms]");
}

@Test
public void startTimer_invalidDelay() {
Runnable mockRunnable = Mockito.mock(Runnable.class);

countlyTimer.startTimer(-1, mockRunnable, mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] startTimer, Starting timer timerDelay: [1000 ms]");
}

@Test
public void startTimer() {
Runnable mockRunnable = Mockito.mock(Runnable.class);

countlyTimer.startTimer(99, mockRunnable, mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] startTimer, Starting timer timerDelay: [99000 ms]");
}

@Test
public void startTimer_withTimerDelayMS() {
CountlyTimer.TIMER_DELAY_MS = 500;
Runnable mockRunnable = Mockito.mock(Runnable.class);

countlyTimer.startTimer(1, mockRunnable, mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] startTimer, Starting timer timerDelay: [500 ms]");
}

/**
* Test that the timer is stopped when a new timer is started
* This is to prevent multiple timers from running at the same time
* And it is not reusing the previous timer
*/
@Test
public void startTimer_reuseTimer() {
countlyTimer.stopTimer(mockLog);

Assert.assertNull(countlyTimer.timerService);

Runnable mockRunnable = Mockito.mock(Runnable.class);
countlyTimer.startTimer(1, mockRunnable, mockLog);

Assert.assertNotNull(countlyTimer.timerService);
ExecutorService timerService = countlyTimer.timerService;

countlyTimer.startTimer(2, mockRunnable, mockLog);
Assert.assertNotEquals(timerService, countlyTimer.timerService);
}

@Test
public void stopTimer() {
countlyTimer.startTimer(1, Mockito.mock(Runnable.class), mockLog);
countlyTimer.stopTimer(mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] stopTimer, Stopping timer");
}

@Test
public void stopTimer_nullTimer() {
countlyTimer.stopTimer(mockLog);
Mockito.verify(mockLog, Mockito.never()).i("[CountlyTimer] stopTimer, Stopping timer");
Mockito.verify(mockLog).d("[CountlyTimer] stopTimer, Timer already stopped");
}
}
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ public class TestUtils {
public final static String commonAppKey = "appkey";
public final static String commonDeviceId = "1234";
public final static String SDK_NAME = "java-native-android";
public final static String SDK_VERSION = "24.7.1";
public final static String SDK_VERSION = "24.7.2";
public static final int MAX_THREAD_COUNT_PER_STACK_TRACE = 50;

public static class Activity2 extends Activity {
2 changes: 1 addition & 1 deletion sdk/src/main/java/ly/count/android/sdk/Countly.java
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ of this software and associated documentation files (the "Software"), to deal
*/
public class Countly {

private final String DEFAULT_COUNTLY_SDK_VERSION_STRING = "24.7.1";
private final String DEFAULT_COUNTLY_SDK_VERSION_STRING = "24.7.2";

/**
* Used as request meta data on every request
54 changes: 54 additions & 0 deletions sdk/src/main/java/ly/count/android/sdk/CountlyTimer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package ly.count.android.sdk;

import androidx.annotation.NonNull;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

class CountlyTimer {

ScheduledExecutorService timerService;
protected static int TIMER_DELAY_MS = 0; // for testing purposes

protected void stopTimer(@NonNull ModuleLog L) {
if (timerService != null) {
L.i("[CountlyTimer] stopTimer, Stopping timer");
try {
timerService.shutdown();
if (!timerService.awaitTermination(1, TimeUnit.SECONDS)) {
timerService.shutdownNow();
if (!timerService.awaitTermination(1, TimeUnit.SECONDS)) {
L.e("[CountlyTimer] stopTimer, Global timer must be locked");
}
}
} catch (Exception e) {
L.e("[CountlyTimer] stopTimer, Error while stopping global timer " + e);
}
timerService = null;
} else {
L.d("[CountlyTimer] stopTimer, Timer already stopped");
}
}

protected void startTimer(long timerDelay, @NonNull Runnable runnable, @NonNull ModuleLog L) {
long timerDelayInternal = timerDelay * 1000;

if (timerDelayInternal < UtilsTime.ONE_SECOND_IN_MS) {
timerDelayInternal = UtilsTime.ONE_SECOND_IN_MS;
}

if (TIMER_DELAY_MS > 0) {
timerDelayInternal = TIMER_DELAY_MS;
}

L.i("[CountlyTimer] startTimer, Starting timer timerDelay: [" + timerDelayInternal + " ms]");

if (timerService != null) {
L.d("[CountlyTimer] startTimer, timer was running, stopping it");
stopTimer(L);
}

timerService = Executors.newSingleThreadScheduledExecutor();
timerService.scheduleWithFixedDelay(runnable, 0, timerDelayInternal, TimeUnit.MILLISECONDS);
}
}
1 change: 1 addition & 0 deletions sdk/src/main/java/ly/count/android/sdk/UtilsTime.java
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
import java.util.List;

public class UtilsTime {
protected static int ONE_SECOND_IN_MS = 1000;

public static class Instant {
public final long timestampMs;
Original file line number Diff line number Diff line change
@@ -36,7 +36,10 @@ class UploadSymbolsPlugin implements Plugin<Project> {
throw new StopExecutionException("Please specify your server in countly block.")
}
String buildVersion = project.android.defaultConfig.versionName
String url = "${ext.server}/i/crash_symbols/upload_symbol"
String url = ext.server;
String path = "i/crash_symbols/upload_symbol";
// Ensure there is exactly one "/" between the base URL and the path
url = url.endsWith("/") ? url + path : url + "/" + path;
def filePath = "$project.buildDir/$ext.mappingFile"
logger.debug("uploadJavaSymbols, Version name:[ {} ], Upload symbol url:[ {} ], Mapping file path:[ {} ]", buildVersion, url, filePath)
File file = new File(filePath)
@@ -55,17 +58,27 @@ class UploadSymbolsPlugin implements Plugin<Project> {
.build()
request = new Request.Builder().url(url).post(formBody).build()
}
logger.debug("uploadJavaSymbols, Generated request: {}", request.body().toString())
doLast {
if (request == null) {
logger.error("Request not constructed")
throw new StopActionException("Something happened while constructing the request. Please try again.")
}

if (request.body() != null) {
logger.debug("uploadJavaSymbols, Generated request: {}", request.body().toString())
} else {
logger.error("uploadJavaSymbols, Request body is null which should not be the case")
}

client = new OkHttpClient()
Response response = client.newCall(request).execute()

if (response.code() != 200) {
logger.error("An error occurred while uploading the mapping file: {}", response.body().string())
if (response.body() != null) {
logger.error("An error occurred while uploading the mapping file: {}", response.body().string())
} else {
logger.error("An error occurred while uploading the mapping file, response body null")
}
} else {
logger.debug("File upload successful")
}