Skip to content

Commit 312558b

Browse files
committed
Fixed Chrome tab NPE and proguard build error
1 parent e5bb3e9 commit 312558b

File tree

8 files changed

+89
-42
lines changed

8 files changed

+89
-42
lines changed

OneSignalSDK/app/build.gradle

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ android {
99
manifestPlaceholders = [onesignal_app_id: "b2f7f966-d8cc-11e4-bed1-df8f05be55ba",
1010
// Project number pulled from dashboard, local value is ignored.
1111
onesignal_google_project_number: "REMOTE"]
12-
minSdkVersion 15
12+
minSdkVersion 9
1313
targetSdkVersion 24
1414
versionCode 1
1515
versionName "1.0"
@@ -18,19 +18,21 @@ android {
1818
debug {
1919
// Test with proguard enabled to make sure our consumer rules are correct in the SDK.
2020
// minify does not work with GMS 7.0.0 with the current settings. Use 8.4.0 to test.
21-
minifyEnabled false
22-
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21+
minifyEnabled true
22+
proguardFiles 'proguard-rules.pro'
23+
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
2324
}
2425
}
2526
}
2627

2728
dependencies {
2829
compile fileTree(dir: 'libs', include: ['*.jar'])
29-
compile 'com.android.support:appcompat-v7:24.2.1'
30+
// compile 'com.android.support:appcompat-v7:25.3.0'
3031

3132
// Use for SDK Development
3233
compile(project(':onesignal')) {
3334
exclude group: 'com.android.support', module: 'support-v4'
35+
exclude group: 'com.android.support', module: 'customtabs'
3436
exclude group: 'com.google.android.gms', module: 'play-services-gcm'
3537
exclude group: 'com.google.android.gms', module: 'play-services-analytics'
3638
exclude group: 'com.google.android.gms', module: 'play-services-location'
@@ -43,13 +45,28 @@ dependencies {
4345
// compile 'com.onesignal:OneSignal:3.+@aar'
4446

4547
// Test with 7.0.0 to make sure there are no breaking changes in Google's libraries.
46-
// This insure that the SDK will work if an app developer is using an older version of GMS.
47-
compile "com.google.android.gms:play-services-gcm:7.0.0"
48+
// This insures that the SDK will work if an app developer is using an older version of GMS.
49+
compile "com.google.android.gms:play-services-gcm:10.0.1"
4850

4951
// play-services-analytics is required for AdvertisingIdClient when using GMS 8.1.0 or lower.
50-
// 8.3.0 it is included in 'basement' which is required by 'base'.
51-
//compile "com.google.android.gms:play-services-analytics:7.0.0"
52-
compile "com.google.android.gms:play-services-location:7.0.0"
52+
// In 8.3.0 it is included in 'basement' which is required by 'base'.
53+
// compile 'com.google.android.gms:play-services-analytics:7.0.0'
5354

54-
compile 'com.google.android.gms:play-services-analytics:7.0.0'
55+
compile "com.google.android.gms:play-services-location:10.0.1"
56+
57+
58+
// NOTES: Android Support Library v4 breakout. VERSION - 24.2.0
59+
// com.android.support-v4 24.2.0 breaks out the library to 5 or so pieces.
60+
// However com.google.android.gms:play-services-gcm:10.2.1 still depends on 24.0.0
61+
// exclude group: 'com.android.support', module:'support-v4' can be used and your own defined one can be used instead if you choose.
62+
// com.android.support:support-core-utils 24.2.0+ contains WakefulBroadcastReceiver
63+
// compile 'com.android.support:support-core-utils:24.2.1'
64+
65+
// For Chrome tabs
66+
compile 'com.android.support:customtabs:24.0.0'
67+
68+
69+
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
70+
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
71+
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
5572
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@
5757
import android.net.Uri;
5858
import android.os.Build;
5959
import android.os.Bundle;
60-
import android.os.Handler;
61-
import android.os.Looper;
6260
import android.os.SystemClock;
6361
import android.support.annotation.NonNull;
6462
import android.util.Base64;

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalChromeTab.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,15 @@ static void setup(Context context, String appId, String userId, String adId) {
5858
if (userId == null || adId == null || appId.equals("OptedOut"))
5959
return;
6060

61-
String params = "?app_id=" + appId + "&user_id=" + userId + "&ad_id=" + adId + "&cbs_id=" + new Random().nextInt(Integer.MAX_VALUE);
62-
6361
try {
64-
CustomTabsServiceConnection connection = new OneSignalCustomTabsServiceConnection(context, params);
65-
opened = CustomTabsClient.bindCustomTabsService(context, "com.android.chrome", connection);
66-
} catch (NoClassDefFoundError e) {
67-
// May not be included in app.
62+
Class.forName("android.support.customtabs.CustomTabsServiceConnection");
63+
} catch (ClassNotFoundException e) {
64+
return;
6865
}
66+
67+
String params = "?app_id=" + appId + "&user_id=" + userId + "&ad_id=" + adId + "&cbs_id=" + new Random().nextInt(Integer.MAX_VALUE);
68+
CustomTabsServiceConnection connection = new OneSignalCustomTabsServiceConnection(context, params);
69+
opened = CustomTabsClient.bindCustomTabsService(context, "com.android.chrome", connection);
6970
}
7071

7172
private static class OneSignalCustomTabsServiceConnection extends CustomTabsServiceConnection {
@@ -82,22 +83,25 @@ private static class OneSignalCustomTabsServiceConnection extends CustomTabsServ
8283
public void onCustomTabsServiceConnected(ComponentName componentName, CustomTabsClient customTabsClient) {
8384
if (customTabsClient == null)
8485
return;
85-
86+
8687
customTabsClient.warmup(0);
87-
88+
8889
CustomTabsSession session = customTabsClient.newSession(new CustomTabsCallback() {
8990
public void onNavigationEvent(int navigationEvent, Bundle extras) {
9091
super.onNavigationEvent(navigationEvent, extras);
9192
}
92-
93+
9394
public void extraCallback(String callbackName, Bundle args) {
9495
super.extraCallback(callbackName, args);
9596
}
9697
});
97-
98+
99+
if (session == null)
100+
return;
101+
98102
Uri uri = Uri.parse("https://onesignal.com/android_frame.html" + mParams);
99103
session.mayLaunchUrl(uri, null, null);
100-
104+
101105
// Shows tab as it's own Activity
102106
/*
103107
CustomTabsIntent.Builder mBuilder = new CustomTabsIntent.Builder(session);

OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowCustomTabsClient.java

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,53 @@
3939
import org.robolectric.annotation.Implements;
4040

4141
import java.lang.reflect.Constructor;
42+
import java.util.Set;
4243

4344
@Implements(CustomTabsClient.class)
4445
public class ShadowCustomTabsClient {
4546

4647
public static boolean bindCustomTabsServiceCalled;
48+
public static boolean nullNewSession;
49+
50+
public static void resetStatics() {
51+
bindCustomTabsServiceCalled = false;
52+
nullNewSession = false;
53+
}
4754

4855
public boolean warmup(long flags) {
4956
return true;
5057
}
5158

52-
public static boolean bindCustomTabsService(Context context, String packageName, CustomTabsServiceConnection connection) {
53-
try {
54-
Constructor<CustomTabsClient> constructor = CustomTabsClient.class.getDeclaredConstructor(ICustomTabsService.class, ComponentName.class);
55-
constructor.setAccessible(true);
56-
CustomTabsClient inst = constructor.newInstance(null, null);
57-
58-
bindCustomTabsServiceCalled = true;
59-
connection.onCustomTabsServiceConnected(null, inst);
60-
} catch(Throwable t) {
61-
}
59+
public static boolean bindCustomTabsService(Context context, String packageName, final CustomTabsServiceConnection connection) {
60+
new Thread(new Runnable() {
61+
@Override
62+
public void run() {
63+
try {
64+
Constructor<CustomTabsClient> constructor = CustomTabsClient.class.getDeclaredConstructor(ICustomTabsService.class, ComponentName.class);
65+
constructor.setAccessible(true);
66+
CustomTabsClient inst = constructor.newInstance(null, null);
67+
68+
bindCustomTabsServiceCalled = true;
69+
connection.onCustomTabsServiceConnected(null, inst);
70+
}
71+
catch (Throwable t) {
72+
// Catch any errors and make it interrupt all other threads to force the unit test to fail.
73+
t.printStackTrace();
74+
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
75+
for (Thread thread : threadSet) {
76+
if (thread.getId() != Thread.currentThread().getId())
77+
thread.interrupt();
78+
}
79+
}
80+
}
81+
}, "OS_SHADOW_BIND_CUSTOM_TABS").start();
6282
return true;
6383
}
6484

6585
public CustomTabsSession newSession(final CustomTabsCallback callback) {
86+
if (nullNewSession)
87+
return null;
88+
6689
try {
6790
Constructor<CustomTabsSession> constructor = CustomTabsSession.class.getDeclaredConstructor(ICustomTabsService.class,
6891
ICustomTabsCallback.class,

OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowCustomTabsSession.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929

3030
import android.net.Uri;
3131
import android.os.Bundle;
32-
import android.support.customtabs.CustomTabsClient;
3332
import android.support.customtabs.CustomTabsSession;
3433

3534
import org.robolectric.annotation.Implements;

OneSignalSDK/unittest/src/test/java/com/onesignal/StaticResetHelper.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,9 @@ public boolean onOtherField(Field field) throws Exception {
3737
return false;
3838
}
3939
}));
40-
41-
classes.add(new StaticResetHelper().new ClassState(OneSignalDbHelper.class, new OtherFieldHandler() {
42-
@Override
43-
public boolean onOtherField(Field field) {
44-
return false;
45-
}
46-
}));
40+
41+
classes.add(new StaticResetHelper().new ClassState(OneSignalChromeTab.class, null));
42+
classes.add(new StaticResetHelper().new ClassState(OneSignalDbHelper.class, null));
4743
}
4844

4945
private interface OtherFieldHandler {
@@ -91,7 +87,7 @@ private void restSetStaticFields() throws Exception {
9187
field.getName();
9288
field.setAccessible(true);
9389

94-
if (!otherFieldHandler.onOtherField(field))
90+
if (otherFieldHandler == null || !otherFieldHandler.onOtherField(field))
9591
field.set(null, tryClone(value));
9692
}
9793
}

OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,13 @@ public void shouldOpenChromeTab() throws Exception {
16091609
Assert.assertTrue(ShadowCustomTabsSession.lastURL.toString().contains("https://onesignal.com/android_frame.html?app_id=b2f7f966-d8cc-11e4-bed1-df8f05be55ba&user_id=a2f7f967-e8cc-11e4-bed1-118f05be4511&ad_id=11111111-2222-3333-4444-555555555555&cbs_id="));
16101610
}
16111611

1612+
@Test
1613+
public void shouldHandleChromeNullNewSession() throws Exception {
1614+
ShadowCustomTabsClient.nullNewSession = true;
1615+
OneSignalInit();
1616+
threadAndTaskWait();
1617+
}
1618+
16121619
private OSPermissionStateChanges lastPermissionStateChanges;
16131620
private boolean currentPermission;
16141621
// Firing right away to match iOS behavior for wrapper SDKs.

OneSignalSDK/unittest/src/test/java/com/test/onesignal/TestHelpers.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.test.onesignal;
22

33
import com.onesignal.OneSignalPackagePrivateHelper;
4+
import com.onesignal.ShadowCustomTabsClient;
45
import com.onesignal.ShadowNotificationManagerCompat;
56
import com.onesignal.ShadowOSUtils;
67
import com.onesignal.ShadowOneSignalRestClient;
@@ -28,6 +29,8 @@ static void betweenTestsCleanup() {
2829
ShadowNotificationManagerCompat.enabled = true;
2930

3031
ShadowOSUtils.subscribableStatus = 1;
32+
33+
ShadowCustomTabsClient.resetStatics();
3134

3235
// DB seems to be cleaned up on it's own.
3336
/*

0 commit comments

Comments
 (0)