-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Conversation
d57b421
to
d9a24e1
Compare
To satisfy semver, I need to refactor telemetry module into an abstract class and add static methods |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work so far!
apply plugin: 'com.android.library' | ||
|
||
android { | ||
compileSdkVersion 28 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use dependencies.gradle
references here?
if (context == null) { | ||
throw new IllegalStateException("MapboxConfigurationWrapper isn't initialised correctly."); | ||
} | ||
return instance.getBaseContext(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: this can return the context
variable.
} | ||
|
||
public static String getAccessToken() { | ||
if (accessToken == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check and the exception that is thrown removes the possibility of passing a null
access token.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are two places in code where this is referenced:
- Telemetry.java -> no issue there
- Mapbox.java -> indeed an issue
added try/catch and return null in those cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to fixup Mapbox.java for unit tests, will look for a solution without the try catch
@@ -97,7 +98,7 @@ private void showTelemetryDialog() { | |||
builder.setPositiveButton(R.string.mapbox_attributionTelemetryPositive, new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
Telemetry.enableOnUserRequest(); | |||
Mapbox.getTelemetry().enableOnUserRequest(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will throw an NPE if the access token is null
.
@@ -111,7 +112,7 @@ public void onClick(DialogInterface dialog, int which) { | |||
builder.setNegativeButton(R.string.mapbox_attributionTelemetryNegative, new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
Telemetry.disableOnUserRequest(); | |||
Mapbox.getTelemetry().disableOnUserRequest(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will throw an NPE if the access token is null
.
@@ -4,7 +4,7 @@ | |||
|
|||
private static final String OPENSTREETMAP = "OpenStreetMap"; | |||
private static final String OPENSTREETMAP_ABBR = "OSM"; | |||
static final String TELEMETRY = "Telemetry Settings"; | |||
static final String TELEMETRY = "TelemetryBase Settings"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is an unnecessary result of the class name change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactor issue, nice catch
@@ -17,7 +17,7 @@ | |||
* Creates a Mapbox configuration exception thrown by MapboxMap when the SDK hasn't been properly initialised. | |||
*/ | |||
public MapboxConfigurationException() { | |||
super("\nUsing MapView requires calling Mapbox.getInstance(Context context, String accessToken) before " | |||
super("\nUsing MapView requires calling Mapbox.initialize(Context context, String accessToken) before " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should still point to Mapbox.getInstance
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactor issue, nice catch
@@ -4,7 +4,7 @@ | |||
import android.os.StrictMode; | |||
import android.text.TextUtils; | |||
import com.mapbox.mapboxsdk.Mapbox; | |||
import com.mapbox.mapboxsdk.maps.Telemetry; | |||
import com.mapbox.mapboxsdk.telemetry.Telemetry; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in #12468 (comment), this and all other Telemetry.java
changes are semver major.
When it comes to logging, I feel like tagging all our logs with a unified tag, like |
|
||
static void log(int type, String errorMessage) { | ||
if (logEnabled) { | ||
Timber.log(type, errorMessage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rely on the Logger
here instead of Timber
? A user might want to use our http module with a different LoggerDefinition
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, timber also removed from build.gradle
5e8cec2
to
9606d09
Compare
A compromise between granularity and consistency could be to have all tags start with the same Mapbox-specific prefix (say |
Yes, this is already in place with https://github.com/mapbox/mapbox-gl-native/pull/12468/files#diff-8f41632c292f442353443b7ff4520ca1R16 @zugaldia @LukasPaczos, before re-reviewing, I will be working on removing the different modules. This is not a hard requirement. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small request to move all new implementations into the same package. Otherwise this is looking great, lots of moving pieces well taken care of.
@@ -0,0 +1,196 @@ | |||
package com.mapbox.mapboxsdk.http; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we move this file to a modules
folder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible yes, but to completely exclude okhttp, the user would also have to exclude com.mapbox.mapboxsdk.http.HttpRequestUtil
which we can't move due to semver. I'm suggesting postponing changing package names until next major release.
@@ -1,75 +1,157 @@ | |||
package com.mapbox.mapboxsdk.maps; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as before, if this is the implementation, could we move this file to a modules
folder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not possible due to semver
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point - could we move everything we can (new classes) and leave the rest for 7.x?
@@ -39,14 +41,15 @@ public void onCreate() { | |||
private boolean initializeLeakCanary() { | |||
if (LeakCanary.isInAnalyzerProcess(this)) { | |||
// This process is dedicated to LeakCanary for heap analysis. | |||
// You should not init your app in this process. | |||
// You should not init your app in this process.male |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bad copypasta?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great catch
Looks good to me! I'm leaving the final word to @zugaldia. |
e13c993
to
4a182a7
Compare
@LukasPaczos @zugaldia another iteration on this PR, would love another round of 👀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changeset is massive which makes it a bit hard to review. Perhaps it could be broken up into smaller pieces.
Also any chance using git mv
of git cp
will preserve some of the blame?
*/ | ||
@Deprecated | ||
public static void setOkHttpClient(OkHttpClient client) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method will require okhttp to build
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is one of the files that would need to be excluded, due to semver we can't change this
* @param etag http header, identifier for a specific version of a resource | ||
* @param modified http header, used to determine if a resource hasn't been modified since | ||
*/ | ||
public abstract void executeRequest(HttpRequestResponder httpRequest, long nativePtr, String resourceUrl, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Favor composition over inheritance" is one of the rules from Effective Java
https://stackoverflow.com/questions/2399544/difference-between-inheritance-and-composition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
composition is provided in the module file here. The HttpRequest class is the contract between the SDK and the alternate implementation. How would you enforce the availability of predefined methods, the sdk needs a predefined hook, either an interface or an abstract class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An interface is generally preferable since it doesn't lock the API user into single inheritance. I think an interface should work here unless I'm missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead with an interface for HttpRequest, other functionality besides executeRequest and cancel was extracted in separate classes. Looks a lot cleaner now, thank you for the clarification.
|
||
@Override | ||
public void v(String tag, String msg) { | ||
Log.v(String.format(TAG_TEMPLATE, tag), msg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will perform string regex even if logging is off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wasn't aware of this, having this TAG_TEMPLATE formatting was only a nice to have, will remove it.
httpRequest.handleFailure(type, errorMessage); | ||
} | ||
|
||
private void logFailure(int type, String errorMessage, String requestUrl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this method specific to OKHttp?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move it up to the base class, though will apply composition to it so it will be found in a separate helper class.
platform/android/src/logger.cpp
Outdated
if(severity == EventSeverity::Debug){ | ||
auto method = _class.GetStaticMethod<Signature>(env, "d"); | ||
_class.Call(env, method, tag, message); | ||
}else if(severity == EventSeverity::Info){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} else
^
802e0bf
to
d0fbde0
Compare
e2c0fd8
to
b540403
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the concerns from #12468 (comment) but couldn't we add the Mbx-
prefix to every TAG
that is currently being created in all of the classes instead?
With the current setup and the TelemetryDefinition
being returned in the public API, TelemetryImpl#onAppUserTurnstileEvent
and TelemetryImpl#onGestureInteraction
are not package-restricted and can be possibly used to pollute our telemetry data.
@@ -4,7 +4,7 @@ | |||
|
|||
private static final String OPENSTREETMAP = "OpenStreetMap"; | |||
private static final String OPENSTREETMAP_ABBR = "OSM"; | |||
static final String TELEMETRY = "Telemetry Settings"; | |||
static final String TELEMETRY = "TelemetryImpl Settings"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor artifact?
* Create a new concrete implementation of HttpRequest. | ||
* | ||
* @return a new instance of an HttpRequest | ||
*/ |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
* Get the concrete implementation of TelemetryDefinition | ||
* | ||
* @return a single instance of Telemetry | ||
*/ |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
HttpRequest createHttpRequest(); | ||
|
||
@Nullable | ||
TelemetryDefinition obtianTelemetry(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TYPO: obtainTelemetry
*/ | ||
public class ModuleProviderImpl implements ModuleProvider { | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about moving this javadoc to the interface definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: since the javadoc in the interface is identical, we can remove this one.
Field field = interval.getClass().getDeclaredField("interval"); | ||
field.setAccessible(true); | ||
Integer intervalValue = (Integer) field.get(interval); | ||
return getInstance().setSessionIdRotationInterval(intervalValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should get the TelemetryImpl
reference using the Mapbox#getTelemetry
and check for nullability to avoid crashing.
*/ | ||
@Deprecated | ||
public static void enableOnUserRequest() { | ||
getInstance().setUserTelemetryRequestState(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should get the TelemetryImpl
reference using the Mapbox#getTelemetry
and check for nullability to avoid crashing.
*/ | ||
@Deprecated | ||
public static void disableOnUserRequest() { | ||
getInstance().setUserTelemetryRequestState(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should get the TelemetryImpl
reference using the Mapbox#getTelemetry
and check for nullability to avoid crashing.
@@ -70,7 +73,10 @@ private void initializeMapbox() { | |||
String accessToken = TokenUtils.getMapboxAccessToken(getApplicationContext()); | |||
validateAccessToken(accessToken); | |||
Mapbox.getInstance(getApplicationContext(), accessToken); | |||
Telemetry.updateDebugLoggingEnabled(true); | |||
TelemetryDefinition telemetry = Mapbox.getTelemetry(); | |||
if (telemetry != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about removing the null-check here, or crashing the app with a clearer exception, to catch start-up telemetry regressions during internal testing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added:
if (telemetry == null) {
throw new IllegalStateException("Telemetry was unavailable during test application start.");
}
} | ||
} | ||
|
||
public static void initialize() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might not be impactful but breaks the semver. How about leaving an empty impl instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great catch!
5fe8f97
to
123d2b4
Compare
*/ | ||
public class ModuleProviderImpl implements ModuleProvider { | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: since the javadoc in the interface is identical, we can remove this one.
return new HttpRequestImpl(); | ||
} | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: since the javadoc in the interface is identical, we can remove this one.
4d4d8bd
to
1a4697a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📦
Follow up from #12449 and #12391.
This PR makes the following components configurable: