Bug 1329157 - Safely collect caller app information. r=frank,sebastian data-r?bsmedberg

MozReview-Commit-ID: 7oXYArRyWKY

--HG--
extra : rebase_source : 61697025808692eab1a2f78fda8d552e525ffe8c
This commit is contained in:
nechen 2017-03-14 12:06:08 +08:00
Родитель 468cc2b92a
Коммит e470b697ec
4 изменённых файлов: 107 добавлений и 0 удалений

Просмотреть файл

@ -15,6 +15,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Browser;
import android.support.annotation.ColorInt; import android.support.annotation.ColorInt;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.StyleRes; import android.support.annotation.StyleRes;
@ -35,6 +36,7 @@ import android.view.ViewGroup.LayoutParams;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoApp; import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.R; import org.mozilla.gecko.R;
import org.mozilla.gecko.SnackbarBuilder; import org.mozilla.gecko.SnackbarBuilder;
@ -46,7 +48,9 @@ import org.mozilla.gecko.menu.GeckoMenu;
import org.mozilla.gecko.menu.GeckoMenuInflater; import org.mozilla.gecko.menu.GeckoMenuInflater;
import org.mozilla.gecko.util.Clipboard; import org.mozilla.gecko.util.Clipboard;
import org.mozilla.gecko.util.ColorUtil; import org.mozilla.gecko.util.ColorUtil;
import org.mozilla.gecko.util.IntentUtils;
import org.mozilla.gecko.widget.GeckoPopupMenu; import org.mozilla.gecko.widget.GeckoPopupMenu;
import org.mozilla.gecko.util.GeckoBundle;
import java.util.List; import java.util.List;
@ -78,6 +82,8 @@ public class CustomTabsActivity extends GeckoApp implements Tabs.OnTabsChangedLi
} else { } else {
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "customtab"); Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "customtab");
toolbarColor = getIntent().getIntExtra(EXTRA_TOOLBAR_COLOR, DEFAULT_ACTION_BAR_COLOR); toolbarColor = getIntent().getIntExtra(EXTRA_TOOLBAR_COLOR, DEFAULT_ACTION_BAR_COLOR);
final String host = getReferrerHost();
recordCustomTabUsage(host);
} }
// Translucent color does not make sense for toolbar color. Ensure it is 0xFF. // Translucent color does not make sense for toolbar color. Ensure it is 0xFF.
@ -100,6 +106,17 @@ public class CustomTabsActivity extends GeckoApp implements Tabs.OnTabsChangedLi
Tabs.registerOnTabsChangedListener(this); Tabs.registerOnTabsChangedListener(this);
} }
private void recordCustomTabUsage(final String host) {
final GeckoBundle data = new GeckoBundle(1);
if (host != null) {
data.putString("client", host);
} else {
data.putString("client", "unknown");
}
// Pass a message to Gecko to send Telemetry data
EventDispatcher.getInstance().dispatch("Telemetry:CustomTabsPing", data);
}
private void setThemeFromToolbarColor() { private void setThemeFromToolbarColor() {
@StyleRes @StyleRes
int styleRes = (ColorUtil.getReadableTextColor(toolbarColor) == Color.BLACK) int styleRes = (ColorUtil.getReadableTextColor(toolbarColor) == Color.BLACK)
@ -440,6 +457,7 @@ public class CustomTabsActivity extends GeckoApp implements Tabs.OnTabsChangedLi
performPendingIntent(pendingIntent); performPendingIntent(pendingIntent);
} }
/** /**
* Callback for Share menu item. * Callback for Share menu item.
*/ */
@ -474,4 +492,21 @@ public class CustomTabsActivity extends GeckoApp implements Tabs.OnTabsChangedLi
return true; return true;
} }
} }
private String getReferrerHost() {
final Intent intent = this.getIntent();
String applicationId = IntentUtils.getStringExtraSafe(intent, Browser.EXTRA_APPLICATION_ID);
if (applicationId != null) {
return applicationId;
}
Uri referrer = intent.getParcelableExtra("android.intent.extra.REFERRER");
if (referrer != null) {
return referrer.getHost();
}
String referrerName = intent.getStringExtra("android.intent.extra.REFERRER_NAME");
if (referrerName != null) {
return Uri.parse(referrerName).getHost();
}
return null;
}
} }

Просмотреть файл

@ -16,6 +16,7 @@ Cu.import("resource://gre/modules/DelayedInit.jsm");
Cu.import("resource://gre/modules/Messaging.jsm"); Cu.import("resource://gre/modules/Messaging.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/TelemetryController.jsm");
if (AppConstants.ACCESSIBILITY) { if (AppConstants.ACCESSIBILITY) {
XPCOMUtils.defineLazyModuleGetter(this, "AccessFu", XPCOMUtils.defineLazyModuleGetter(this, "AccessFu",
@ -413,6 +414,7 @@ var BrowserApp = {
"Session:Navigate", "Session:Navigate",
"Session:Reload", "Session:Reload",
"Session:Stop", "Session:Stop",
"Telemetry:CustomTabsPing",
]); ]);
// Provide compatibility for add-ons like QuitNow that send "Browser:Quit" // Provide compatibility for add-ons like QuitNow that send "Browser:Quit"
@ -1763,6 +1765,11 @@ var BrowserApp = {
break; break;
} }
case "Telemetry:CustomTabsPing": {
TelemetryController.submitExternalPing("anonymous", { client: data.client }, { addClientId: false });
break;
}
case "Session:GetHistory": { case "Session:GetHistory": {
callback.onSuccess(this.getHistory(data)); callback.onSuccess(this.getHistory(data));
break; break;

Просмотреть файл

@ -0,0 +1,64 @@
"anonymous" ping
============
This ping is only for product survey purpose and will not track/associate client ID. It's used
to evaluate custom tab usage and see which app is using our custom tab.
Submission interval & triggers
Since this ping is used to measure the feature usage, it should be sent each time the client app uses our custom tab.
Dataset:
Only opt-in users will send out this ping.
Since all other pings will collect client ID. We need this custom ping to not do that.
Size and volume:
The size of submitted payload is small. And this custom ping should be deprecated after it's released for 6 months.
Privacy:
We won't collect customer information so there'll be no PI leak.
Data contents:
The content of this ping will let us know which app is using our custom tab.
Just like other feature usage measurement, we only need it for opt-in users (which consider as heavy users).
Structure:
.. code-block:: js
{
"payload": {
"client": <string> // The package name of the caller app.
}
type: <string>, // "anonymous", "activation", "deletion", "saved-session", ...
id: <UUID>, // a UUID that identifies this ping
creationDate: <ISO date>, // the date the ping was generated
version: <number>, // the version of the ping format, currently 4
application: {
architecture: <string>, // build architecture, e.g. x86
buildId: <string>, // "20141126041045"
name: <string>, // "Firefox"
version: <string>, // "35.0"
displayVersion: <string>, // "35.0b3"
vendor: <string>, // "Mozilla"
platformVersion: <string>, // "35.0"
xpcomAbi: <string>, // e.g. "x86-msvc"
channel: <string>, // "beta"
},
}
Field details
-------------
client
~~~~~~
It could be ``com.example.app``, which is the identifier of the app.
Version history
---------------
* v1: initial version - Will be shipped in `Fennec 55 <https://bugzilla.mozilla.org/show_bug.cgi?id=1329157>`_.
Notes
~~~~~
There's no option in this custom ping since we don't collect clientId nor environment data.

Просмотреть файл

@ -12,6 +12,7 @@ Data documentation
main-ping main-ping
deletion-ping deletion-ping
crash-ping crash-ping
anonymous-ping
*-ping *-ping
The `mozilla-pipeline-schemas repository <https://github.com/mozilla-services/mozilla-pipeline-schemas/>`_ contains schemas for some of the pings. The `mozilla-pipeline-schemas repository <https://github.com/mozilla-services/mozilla-pipeline-schemas/>`_ contains schemas for some of the pings.