From 1d56439458b0dc8a46cfe0442ed4b8cb572256ed Mon Sep 17 00:00:00 2001 From: Quintin Willison Date: Tue, 20 Oct 2020 13:48:52 +0100 Subject: [PATCH 1/3] Add toString() implementation. --- .../main/java/io/ably/lib/types/RegistrationToken.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/android/src/main/java/io/ably/lib/types/RegistrationToken.java b/android/src/main/java/io/ably/lib/types/RegistrationToken.java index 69646d9e1..8b684e67f 100644 --- a/android/src/main/java/io/ably/lib/types/RegistrationToken.java +++ b/android/src/main/java/io/ably/lib/types/RegistrationToken.java @@ -33,4 +33,12 @@ public String toName() { return name().toLowerCase(); } } + + @Override + public String toString() { + return "RegistrationToken{" + + "type=" + type + + ", token='" + token + '\'' + + '}'; + } } From d354d19c67ec86ffaf4e8918fe09422bc4da9832 Mon Sep 17 00:00:00 2001 From: Quintin Willison Date: Tue, 20 Oct 2020 13:50:00 +0100 Subject: [PATCH 2/3] Add state-related log output relating to push, local device and activation / application context. --- .../java/io/ably/lib/platform/Platform.java | 8 ++++++ .../io/ably/lib/push/ActivationContext.java | 24 ++++++++++++++++++ .../java/io/ably/lib/push/LocalDevice.java | 13 ++++++++-- .../src/main/java/io/ably/lib/push/Push.java | 25 +++++++++++++++---- .../main/java/io/ably/lib/rest/AblyRest.java | 2 ++ 5 files changed, 65 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/io/ably/lib/platform/Platform.java b/android/src/main/java/io/ably/lib/platform/Platform.java index 839a77d84..8f3446999 100644 --- a/android/src/main/java/io/ably/lib/platform/Platform.java +++ b/android/src/main/java/io/ably/lib/platform/Platform.java @@ -10,6 +10,7 @@ import io.ably.lib.transport.NetworkConnectivity.DelegatedNetworkConnectivity; import io.ably.lib.types.AblyException; import io.ably.lib.types.ErrorInfo; +import io.ably.lib.util.Log; import java.util.WeakHashMap; @@ -25,12 +26,17 @@ public Context getApplicationContext() { * Set the Android Context for this instance */ public void setAndroidContext(Context context) throws AblyException { + Log.v(TAG, "setAndroidContext: context=" + context); context = context.getApplicationContext(); if(applicationContext != null) { + Log.v(TAG, "setAndroidContext(): applicationContext has already been set"); if(context == applicationContext) { + Log.v(TAG, "setAndroidContext(): existing applicationContext is compatible with that being set"); return; } throw AblyException.fromErrorInfo(new ErrorInfo("Incompatible application context set", 40000, 400)); + } else { + Log.v(TAG, "setAndroidContext(): there was no existing applicationContext"); } applicationContext = context; AndroidNetworkConnectivity.getNetworkConnectivity(context).addListener(this.networkConnectivity); @@ -50,4 +56,6 @@ public NetworkConnectivity getNetworkConnectivity() { private Context applicationContext; private final DelegatedNetworkConnectivity networkConnectivity = new DelegatedNetworkConnectivity(); + + private static final String TAG = Platform.class.getName(); } diff --git a/android/src/main/java/io/ably/lib/push/ActivationContext.java b/android/src/main/java/io/ably/lib/push/ActivationContext.java index 9156806fc..c89e2f287 100644 --- a/android/src/main/java/io/ably/lib/push/ActivationContext.java +++ b/android/src/main/java/io/ably/lib/push/ActivationContext.java @@ -30,18 +30,25 @@ Context getContext() { public synchronized LocalDevice getLocalDevice() { if(localDevice == null) { + Log.v(TAG, "getLocalDevice(): creating new instance and returning that"); localDevice = new LocalDevice(this); + } else { + Log.v(TAG, "getLocalDevice(): returning existing instance"); } return localDevice; } public synchronized void setActivationStateMachine(ActivationStateMachine activationStateMachine) { + Log.v(TAG, "setActivationStateMachine(): activationStateMachine=" + activationStateMachine); this.activationStateMachine = activationStateMachine; } public synchronized ActivationStateMachine getActivationStateMachine() { if(activationStateMachine == null) { + Log.v(TAG, "getActivationStateMachine(): creating new instance and returning that"); activationStateMachine = new ActivationStateMachine(this); + } else { + Log.v(TAG, "getActivationStateMachine(): returning existing instance"); } return activationStateMachine; } @@ -55,6 +62,8 @@ AblyRest getAbly() throws AblyException { if(ably != null) { Log.v(TAG, "getAbly(): returning existing Ably instance"); return ably; + } else { + Log.v(TAG, "getAbly(): creating new Ably instance"); } String deviceIdentityToken = getLocalDevice().deviceIdentityToken; @@ -67,22 +76,27 @@ AblyRest getAbly() throws AblyException { } public boolean setClientId(String clientId, boolean propagateGotPushDeviceDetails) { + Log.v(TAG, "setClientId(): clientId=" + clientId + ", propagateGotPushDeviceDetails=" + propagateGotPushDeviceDetails); boolean updated = !clientId.equals(this.clientId); if(updated) { this.clientId = clientId; if(localDevice != null) { + Log.v(TAG, "setClientId(): local device exists"); /* Spec: RSH8d */ localDevice.setClientId(clientId); if(localDevice.isRegistered() && activationStateMachine != null && propagateGotPushDeviceDetails) { /* Spec: RSH8e */ activationStateMachine.handleEvent(new ActivationStateMachine.GotPushDeviceDetails()); } + } else { + Log.v(TAG, "setClientId(): local device doest not exist"); } } return updated; } public void onNewRegistrationToken(RegistrationToken.Type type, String token) { + Log.v(TAG, "onNewRegistrationToken(): type=" + type + ", token=" + token); LocalDevice localDevice = getLocalDevice(); RegistrationToken previous = localDevice.getRegistrationToken(); if (previous != null) { @@ -100,6 +114,8 @@ public void onNewRegistrationToken(RegistrationToken.Type type, String token) { } public void reset() { + Log.v(TAG, "reset()"); + ably = null; getActivationStateMachine().reset(); @@ -120,19 +136,26 @@ public static ActivationContext getActivationContext(Context applicationContext, if(activationContext == null) { Log.v(TAG, "getActivationContext(): creating new ActivationContext for this application"); activationContexts.put(applicationContext, (activationContext = new ActivationContext(applicationContext))); + } else { + Log.v(TAG, "getActivationContext(): returning existing ActivationContext for this application"); } if(ably != null) { + Log.v(TAG, "Setting Ably instance on the activation context"); activationContext.setAbly(ably); + } else { + Log.v(TAG, "Not setting Ably instance on the activation context"); } } return activationContext; } protected void getRegistrationToken(final Callback callback) { + Log.v(TAG, "getRegistrationToken(): callback=" + callback); FirebaseInstanceId.getInstance().getInstanceId() .addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(Task task) { + Log.v(TAG, "getRegistrationToken(): firebase called onComplete(): task=" + task); if(task.isSuccessful()) { /* Get new Instance ID token */ String token = task.getResult().getToken(); @@ -145,6 +168,7 @@ public void onComplete(Task task) { } public static void setActivationContext(Context applicationContext, ActivationContext activationContext) { + Log.v(TAG, "setActivationContext(): applicationContext=" + applicationContext + ", activationContext=" + activationContext); activationContexts.put(applicationContext, activationContext); } diff --git a/android/src/main/java/io/ably/lib/push/LocalDevice.java b/android/src/main/java/io/ably/lib/push/LocalDevice.java index 5c2b5b2fc..8f82fa334 100644 --- a/android/src/main/java/io/ably/lib/push/LocalDevice.java +++ b/android/src/main/java/io/ably/lib/push/LocalDevice.java @@ -54,6 +54,8 @@ private void loadPersisted() { if(id != null) { Log.v(TAG, "loadPersisted(): existing deviceId found; id: " + id); deviceSecret = prefs.getString(SharedPrefKeys.DEVICE_SECRET, null); + } else { + Log.v(TAG, "loadPersisted(): existing deviceId not found."); } this.clientId = prefs.getString(SharedPrefKeys.CLIENT_ID, null); this.deviceIdentityToken = prefs.getString(SharedPrefKeys.DEVICE_TOKEN, null); @@ -65,8 +67,8 @@ private void loadPersisted() { if(type != null) { RegistrationToken token = null; String tokenString = prefs.getString(SharedPrefKeys.TOKEN, null); + Log.d(TAG, "loadPersisted(): token string = " + tokenString); if(tokenString != null) { - Log.d(TAG, "loadPersisted(): token string = " + tokenString); token = new RegistrationToken(type, tokenString); setRegistrationToken(token); } @@ -76,8 +78,10 @@ private void loadPersisted() { RegistrationToken getRegistrationToken() { JsonObject recipient = push.recipient; if(recipient == null) { + Log.v(TAG, "getRegistrationToken(): returning null because push.recipient is null"); return null; } + Log.v(TAG, "getRegistrationToken(): returning a new registration token because push.recipient is set"); return new RegistrationToken( RegistrationToken.Type.fromName(recipient.get("transportType").getAsString()), recipient.get("registrationToken").getAsString() @@ -85,17 +89,19 @@ RegistrationToken getRegistrationToken() { } private void setRegistrationToken(RegistrationToken token) { + Log.v(TAG, "setRegistrationToken(): token=" + token); push.recipient = new JsonObject(); push.recipient.addProperty("transportType", token.type.toName()); push.recipient.addProperty("registrationToken", token.token); } private void clearRegistrationToken() { + Log.v(TAG, "clearRegistrationToken()"); push.recipient = null; } void setAndPersistRegistrationToken(RegistrationToken token) { - Log.v(TAG, "setAndPersistRegistrationToken(): token: " + token.token); + Log.v(TAG, "setAndPersistRegistrationToken(): token=" + token); setRegistrationToken(token); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activationContext.getContext()); prefs.edit() @@ -105,12 +111,14 @@ void setAndPersistRegistrationToken(RegistrationToken token) { } void setClientId(String clientId) { + Log.v(TAG, "setClientId(): clientId=" + clientId); this.clientId = clientId; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activationContext.getContext()); prefs.edit().putString(SharedPrefKeys.CLIENT_ID, clientId).apply(); } public void setDeviceIdentityToken(String token) { + Log.v(TAG, "setDeviceIdentityToken(): token=" + token); this.deviceIdentityToken = token; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activationContext.getContext()); prefs.edit().putString(SharedPrefKeys.DEVICE_TOKEN, token).apply(); @@ -178,6 +186,7 @@ private static class SharedPrefKeys { } private static String generateSecret() { + Log.v(TAG, "generateSecret()"); byte[] entropy = new byte[64]; (new SecureRandom()).nextBytes(entropy); MessageDigest digest = null; diff --git a/android/src/main/java/io/ably/lib/push/Push.java b/android/src/main/java/io/ably/lib/push/Push.java index 5e00160a0..6552a3696 100644 --- a/android/src/main/java/io/ably/lib/push/Push.java +++ b/android/src/main/java/io/ably/lib/push/Push.java @@ -11,6 +11,8 @@ import io.ably.lib.types.Param; import io.ably.lib.util.Log; +import java.util.Arrays; + public class Push extends PushBase { public Push(AblyBase rest) { @@ -22,7 +24,7 @@ public void activate() throws AblyException { } public void activate(boolean useCustomRegistrar) throws AblyException { - Log.v(TAG, "activate(): useCustomRegistrar " + useCustomRegistrar); + Log.v(TAG, "activate(): useCustomRegistrar=" + useCustomRegistrar); Context context = getApplicationContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); getStateMachine().handleEvent(ActivationStateMachine.CalledActivate.useCustomRegistrar(useCustomRegistrar, prefs)); @@ -33,7 +35,7 @@ public void deactivate() throws AblyException { } public void deactivate(boolean useCustomRegistrar) throws AblyException { - Log.v(TAG, "deactivate(): useCustomRegistrar " + useCustomRegistrar); + Log.v(TAG, "deactivate(): useCustomRegistrar=" + useCustomRegistrar); Context context = getApplicationContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); getStateMachine().handleEvent(ActivationStateMachine.CalledDeactivate.useCustomRegistrar(useCustomRegistrar, prefs)); @@ -46,7 +48,10 @@ synchronized ActivationStateMachine getStateMachine() throws AblyException { public void tryRequestRegistrationToken() { try { if (getLocalDevice().isRegistered()) { + Log.v(TAG, "Local device is registered."); getStateMachine().getRegistrationToken(); + } else { + Log.v(TAG, "Local device is not registered."); } } catch (AblyException e) { Log.e(TAG, "couldn't validate existing push recipient device details", e); @@ -66,8 +71,11 @@ Context getApplicationContext() throws AblyException { public ActivationContext getActivationContext() throws AblyException { if (activationContext == null) { + Log.v(TAG, "getActivationContext(): creating a new context and returning that"); Context applicationContext = getApplicationContext(); activationContext = ActivationContext.getActivationContext(applicationContext, (AblyRest)rest); + } else { + Log.v(TAG, "getActivationContext(): returning existing content"); } return activationContext; } @@ -81,11 +89,16 @@ Param[] pushRequestHeaders(boolean forLocalDevice) { Param[] headers = super.pushRequestHeaders(forLocalDevice); if(forLocalDevice) { try { - Param[] deviceIdentityHeaders = getLocalDevice().deviceIdentityHeaders(); + final Param[] deviceIdentityHeaders = getLocalDevice().deviceIdentityHeaders(); if(deviceIdentityHeaders != null) { + Log.v(TAG, "pushRequestHeaders(): deviceIdentityHeaders=" + Arrays.toString(deviceIdentityHeaders)); headers = HttpUtils.mergeHeaders(headers, deviceIdentityHeaders); + } else { + Log.w(TAG, "pushRequestHeaders(): Local device returned null device identity headers!"); } - } catch (AblyException e) {} + } catch (AblyException e) { + Log.w(TAG, "pushRequestHeaders(): Failed to get device identity headers. forLocalDevice=" + forLocalDevice, e); + } } return headers; } @@ -94,7 +107,9 @@ Param[] pushRequestHeaders(String deviceId) { boolean forLocalDevice = false; try { forLocalDevice = deviceId != null && deviceId.equals(getLocalDevice().id); - } catch (AblyException e) {} + } catch (AblyException e) { + Log.w(TAG, "pushRequestHeaders(): deviceId=" + deviceId, e); + } return pushRequestHeaders(forLocalDevice); } diff --git a/android/src/main/java/io/ably/lib/rest/AblyRest.java b/android/src/main/java/io/ably/lib/rest/AblyRest.java index 5f36c160b..a53af4954 100644 --- a/android/src/main/java/io/ably/lib/rest/AblyRest.java +++ b/android/src/main/java/io/ably/lib/rest/AblyRest.java @@ -41,6 +41,7 @@ public LocalDevice device() throws AblyException { * Set the Android Context for this instance */ public void setAndroidContext(Context context) throws AblyException { + Log.v(TAG, "setAndroidContext(): context=" + context); this.platform.setAndroidContext(context); this.push.tryRequestRegistrationToken(); } @@ -49,6 +50,7 @@ public void setAndroidContext(Context context) throws AblyException { * clientId set by late initialisation */ protected void onClientIdSet(String clientId) { + Log.v(TAG, "onClientIdSet(): clientId=" + clientId); /* we only need to propagate any update to clientId if this is a late init */ if(push != null && platform.hasApplicationContext()) { try { From ae09d05cfcdc6787cc0a840c63532dd2fa198a51 Mon Sep 17 00:00:00 2001 From: Quintin Willison Date: Tue, 20 Oct 2020 13:50:54 +0100 Subject: [PATCH 3/3] Add entry point logs for push-related API calls. --- .../main/java/io/ably/lib/push/PushBase.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/src/main/java/io/ably/lib/push/PushBase.java b/lib/src/main/java/io/ably/lib/push/PushBase.java index 15aa737ef..c735df2c5 100644 --- a/lib/src/main/java/io/ably/lib/push/PushBase.java +++ b/lib/src/main/java/io/ably/lib/push/PushBase.java @@ -15,9 +15,11 @@ import io.ably.lib.types.Callback; import io.ably.lib.types.PaginatedResult; import io.ably.lib.types.Param; +import io.ably.lib.util.Log; import io.ably.lib.util.Serialisation; import io.ably.lib.util.StringUtils; +import java.util.Arrays; import java.util.Map; @@ -28,6 +30,8 @@ public PushBase(AblyBase rest) { } public static class Admin { + private static final String TAG = Admin.class.getName(); + public final DeviceRegistrations deviceRegistrations; public final ChannelSubscriptions channelSubscriptions; @@ -46,6 +50,7 @@ public void publishAsync(Param[] recipient, JsonObject payload, final Completion } private Http.Request publishImpl(final Param[] recipient, final JsonObject payload) { + Log.v(TAG, "publishImpl(): recipient=" + Arrays.toString(recipient) + ", payload=" + payload); return rest.http.request(new Http.Execute() { @Override public void execute(HttpScheduler http, Callback callback) throws AblyException { @@ -81,6 +86,8 @@ public void execute(HttpScheduler http, Callback callback) throws AblyExce } public static class DeviceRegistrations { + private static final String TAG = DeviceRegistrations.class.getName(); + public DeviceDetails save(DeviceDetails device) throws AblyException { return saveImpl(device).sync(); } @@ -90,6 +97,7 @@ public void saveAsync(DeviceDetails device, final Callback callba } protected Http.Request saveImpl(final DeviceDetails device) { + Log.v(TAG, "saveImpl(): device=" + device); final HttpCore.RequestBody body = HttpUtils.requestBodyFromGson(device.toJsonObject(), rest.options.useBinaryProtocol); return rest.http.request(new Http.Execute() { @Override @@ -112,6 +120,7 @@ public void getAsync(String deviceId, final Callback callback) { } protected Http.Request getImpl(final String deviceId) { + Log.v(TAG, "getImpl(): deviceId=" + deviceId); return rest.http.request(new Http.Execute() { @Override public void execute(HttpScheduler http, Callback callback) throws AblyException { @@ -133,6 +142,7 @@ public void listAsync(Param[] params, Callback listImpl(Param[] params) { + Log.v(TAG, "listImpl(): params=" + Arrays.toString(params)); return new BasePaginatedQuery(rest.http, "/push/deviceRegistrations", HttpUtils.defaultAcceptHeaders(rest.options.useBinaryProtocol), params, DeviceDetails.httpBodyHandler).get(); } @@ -153,6 +163,7 @@ public void removeAsync(String deviceId, CompletionListener listener) { } protected Http.Request removeImpl(final String deviceId) { + Log.v(TAG, "removeImpl(): deviceId=" + deviceId); return rest.http.request(new Http.Execute() { @Override public void execute(HttpScheduler http, Callback callback) throws AblyException { @@ -174,6 +185,7 @@ public void removeWhereAsync(Param[] params, CompletionListener listener) { } protected Http.Request removeWhereImpl(Param[] params) { + Log.v(TAG, "removeWhereImpl(): params=" + Arrays.toString(params)); if (rest.options.pushFullWait) { params = Param.push(params, "fullWait", "true"); } @@ -194,6 +206,8 @@ public void execute(HttpScheduler http, Callback callback) throws AblyExce } public static class ChannelSubscriptions { + private static final String TAG = ChannelSubscriptions.class.getName(); + public ChannelSubscription save(ChannelSubscription subscription) throws AblyException { return saveImpl(subscription).sync(); } @@ -203,6 +217,7 @@ public void saveAsync(ChannelSubscription subscription, final Callback saveImpl(final ChannelSubscription subscription) { + Log.v(TAG, "saveImpl(): subscription=" + subscription); final HttpCore.RequestBody body = HttpUtils.requestBodyFromGson(subscription.toJsonObject(), rest.options.useBinaryProtocol); return rest.http.request(new Http.Execute() { @Override @@ -225,6 +240,7 @@ public void listAsync(Param[] params, Callback listImpl(Param[] params) { + Log.v(TAG, "listImpl(): params=" + Arrays.toString(params)); String deviceId = HttpUtils.getParam(params, "deviceId"); return new BasePaginatedQuery(rest.http, "/push/channelSubscriptions", rest.push.pushRequestHeaders(deviceId), params, ChannelSubscription.httpBodyHandler).get(); } @@ -238,6 +254,7 @@ public void removeAsync(ChannelSubscription subscription, CompletionListener lis } protected Http.Request removeImpl(ChannelSubscription subscription) { + Log.v(TAG, "removeImpl(): subscription=" + subscription); Param[] params = new Param[] { new Param("channel", subscription.channel) }; if (subscription.deviceId != null) { params = Param.push(params, "deviceId", subscription.deviceId); @@ -260,6 +277,7 @@ public void removeWhereAsync(Param[] params, CompletionListener listener) { } protected Http.Request removeWhereImpl(Param[] params) { + Log.v(TAG, "removeWhereImpl(): params=" + Arrays.toString(params)); String deviceId = HttpUtils.getParam(params, "deviceId"); if (rest.options.pushFullWait) { params = Param.push(params, "fullWait", "true"); @@ -283,6 +301,7 @@ public void listChannelsAsync(Param[] params, Callback listChannelsImpl(Param[] params) { + Log.v(TAG, "listChannelsImpl(): params=" + Arrays.toString(params)); String deviceId = HttpUtils.getParam(params, "deviceId"); return new BasePaginatedQuery(rest.http, "/push/channels", rest.push.pushRequestHeaders(deviceId), params, StringUtils.httpBodyHandler).get(); }