From f1d1e10932812af2d1aa9c01cd8f2429c7891a4d Mon Sep 17 00:00:00 2001 From: Devin Smythe Date: Mon, 13 Apr 2020 08:36:11 -0700 Subject: [PATCH] [CUSTENG-2544] Transaction too large exception when getting schedule id (#725) * Attempting to catch TransactionTooLarge exception and ensure multiple threads don't call get schedule id * Initial attempt at getting test for the exception * Removed unused imports * updated dispatcher test * Fix test Co-authored-by: Devin Smythe Co-authored-by: Ryan Lepinski --- .../com/urbanairship/job/JobDispatcher.java | 15 ++++---- .../urbanairship/job/JobDispatcherTest.java | 36 ++++++++++++++++++- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/urbanairship-core/src/main/java/com/urbanairship/job/JobDispatcher.java b/urbanairship-core/src/main/java/com/urbanairship/job/JobDispatcher.java index a48a64da6..8e4e40428 100644 --- a/urbanairship-core/src/main/java/com/urbanairship/job/JobDispatcher.java +++ b/urbanairship-core/src/main/java/com/urbanairship/job/JobDispatcher.java @@ -10,16 +10,17 @@ import android.net.NetworkInfo; import android.os.Build; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.RestrictTo; -import androidx.annotation.VisibleForTesting; import com.urbanairship.Logger; import com.urbanairship.UAirship; import com.urbanairship.app.ActivityMonitor; import com.urbanairship.app.GlobalActivityMonitor; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RestrictTo; +import androidx.annotation.VisibleForTesting; + /** * Dispatches jobs. When a job is dispatched with a delay or specifies that it requires network activity, * it will be scheduled using either the AlarmManager or GcmNetworkManager. When a job is finally performed, @@ -205,13 +206,13 @@ private boolean useFallbackScheduler() { * @param jobId The job ID. * @return A scheduler ID. */ - private int getScheduleId(int jobId) { + private synchronized int getScheduleId(int jobId) { if (jobIdStart == null) { ApplicationInfo ai = null; try { ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); - } catch (PackageManager.NameNotFoundException e) { - Logger.error("Failed get application info."); + } catch (Exception e) { + Logger.error(e, "Failed to get application info."); } if (ai != null && ai.metaData != null) { diff --git a/urbanairship-core/src/test/java/com/urbanairship/job/JobDispatcherTest.java b/urbanairship-core/src/test/java/com/urbanairship/job/JobDispatcherTest.java index 602e62d3b..affaf5bfe 100644 --- a/urbanairship-core/src/test/java/com/urbanairship/job/JobDispatcherTest.java +++ b/urbanairship-core/src/test/java/com/urbanairship/job/JobDispatcherTest.java @@ -4,8 +4,9 @@ import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.os.Bundle; -import androidx.annotation.NonNull; +import android.os.TransactionTooLargeException; import com.urbanairship.BaseTestCase; import com.urbanairship.TestActivityMonitor; @@ -15,12 +16,18 @@ import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import org.robolectric.RuntimeEnvironment; +import androidx.annotation.NonNull; + import static junit.framework.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; public class JobDispatcherTest extends BaseTestCase { @@ -126,4 +133,31 @@ public void testCancelFallback() throws SchedulerException { verify(mockFallbackScheduler).cancel(context, 3000007); } + @Test + public void testCatchesTransactionTooLargeException() throws PackageManager.NameNotFoundException, SchedulerException { + Context context = mock(Context.class); + when(context.getApplicationContext()).thenReturn(context); + when(context.getPackageName()).thenReturn("package"); + + PackageManager pm = Mockito.mock(PackageManager.class); + + when(context.getPackageManager()).thenReturn(pm); + when(pm.getApplicationInfo(anyString(), anyInt())).thenThrow(new RuntimeException(new TransactionTooLargeException())); + + JobDispatcher dispatcher = new JobDispatcher(context, new JobDispatcher.SchedulerFactory() { + @NonNull + @Override + public Scheduler createScheduler(Context context) { + return mockScheduler; + } + + @NonNull + @Override + public Scheduler createFallbackScheduler(Context context) { + return mockFallbackScheduler; + } + }, activityMonitor); + + dispatcher.dispatch(jobInfo); + } } \ No newline at end of file