Commit ab107cf7 authored by shindli's avatar shindli
Browse files

Backed out changeset 6ff9d6783ae0 (bug 1534451) for causing build bustages in...

Backed out changeset 6ff9d6783ae0 (bug 1534451) for causing build bustages in AdvertisingUtil.java:6 CLOSED TREE
parent 905ea2ce
......@@ -177,7 +177,6 @@ android {
if (!mozconfig.substs.MOZ_ANDROID_GCM) {
exclude 'org/mozilla/gecko/gcm/**/*.java'
exclude 'org/mozilla/gecko/push/**/*.java'
exclude 'org/mozilla/gecko/advertising/**'
}
}
resources {
......@@ -245,8 +244,6 @@ dependencies {
implementation "com.google.android.gms:play-services-basement:$google_play_services_version"
implementation "com.google.android.gms:play-services-base:$google_play_services_version"
implementation "com.google.android.gms:play-services-gcm:$google_play_services_version"
implementation "com.google.android.gms:play-services-ads-identifier:$google_play_services_version"
implementation "org.mindrot:jbcrypt:0.4"
}
if (mozconfig.substs.MOZ_ANDROID_GOOGLE_PLAY_SERVICES) {
......
......@@ -138,7 +138,6 @@ import org.mozilla.gecko.tabs.TabsPanel;
import org.mozilla.gecko.telemetry.TelemetryCorePingDelegate;
import org.mozilla.gecko.telemetry.TelemetryUploadService;
import org.mozilla.gecko.telemetry.measurements.SearchCountMeasurements;
import org.mozilla.gecko.telemetry.TelemetryActivationPingDelegate;
import org.mozilla.gecko.toolbar.AutocompleteHandler;
import org.mozilla.gecko.toolbar.BrowserToolbar;
import org.mozilla.gecko.toolbar.BrowserToolbar.CommitEventSource;
......@@ -318,7 +317,6 @@ public class BrowserApp extends GeckoApp
private final DynamicToolbar mDynamicToolbar = new DynamicToolbar();
private final TelemetryCorePingDelegate mTelemetryCorePingDelegate = new TelemetryCorePingDelegate();
private final TelemetryActivationPingDelegate mTelemetryActivationPingDelegate = new TelemetryActivationPingDelegate();
private final List<BrowserAppDelegate> delegates = Collections.unmodifiableList(Arrays.asList(
new ScreenshotDelegate(),
......@@ -326,7 +324,6 @@ public class BrowserApp extends GeckoApp
new ReaderViewBookmarkPromotion(),
new PostUpdateHandler(),
mTelemetryCorePingDelegate,
mTelemetryActivationPingDelegate,
new OfflineTabStatusDelegate(),
new AdjustBrowserAppDelegate(mTelemetryCorePingDelegate)
));
......
package org.mozilla.gecko.advertising;
import android.content.Context;
import android.util.Log;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import org.mindrot.jbcrypt.BCrypt;
import org.mozilla.gecko.annotation.ReflectionTarget;
@ReflectionTarget
public class AdvertisingUtil {
private static final String LOG_TAG = AdvertisingUtil.class.getCanonicalName();
/* Use the same SALT for all BCrypt hashings. We want the SALT to be stable for all Fennec users but it should differ from the one from Fenix.
* Generated using Bcrypt.gensalt(). */
private static final String BCRYPT_SALT = "$2a$10$ZfglUfcbmTyaBbAQ7SL9OO";
/**
* Retrieves the advertising ID hashed with BCrypt. Requires Google Play Services. Note: This method must not run on
* the main thread.
*/
@ReflectionTarget
public static String getAdvertisingId(Context caller) {
try {
AdvertisingIdClient.Info info = AdvertisingIdClient.getAdvertisingIdInfo(caller);
String advertisingId = info.getId();
return advertisingId != null ? BCrypt.hashpw(advertisingId, BCRYPT_SALT) : null;
} catch (Throwable t) {
Log.e(LOG_TAG, "Error retrieving advertising ID. " + t.getMessage());
}
return null;
}
}
package org.mozilla.gecko.telemetry;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.WorkerThread;
import android.util.Log;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.BrowserApp;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoThread;
import org.mozilla.gecko.delegates.BrowserAppDelegate;
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryActivationPingBuilder;
import org.mozilla.gecko.util.StringUtils;
import org.mozilla.gecko.util.ThreadUtils;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* An activity-lifecycle delegate for uploading the activation ping.
*/
public class TelemetryActivationPingDelegate extends BrowserAppDelegate {
private static final String LOGTAG = StringUtils.safeSubstring(
"Gecko" + TelemetryActivationPingDelegate.class.getSimpleName(), 0, 23);
private TelemetryDispatcher telemetryDispatcher; // lazy
@Override
public void onCreate(BrowserApp browserApp, Bundle savedInstanceState) {
super.onCreate(browserApp, savedInstanceState);
uploadActivationPing(browserApp);
}
private void uploadActivationPing(final BrowserApp activity) {
if (!AppConstants.MOZ_ANDROID_GCM) {
return;
}
if (TelemetryActivationPingBuilder.activationPingAlreadySent(activity)) {
return;
}
ThreadUtils.postToBackgroundThread(() -> {
if (activity == null) {
return;
}
if (!TelemetryUploadService.isUploadEnabledByAppConfig(activity)) {
Log.d(LOGTAG, "Activation ping upload disabled by app config. Returning.");
return;
}
String identifier = null;
try {
final Class<?> clazz = Class.forName("org.mozilla.gecko.advertising.AdvertisingUtil");
final Method getAdvertisingId = clazz.getMethod("getAdvertisingId", Context.class);
identifier = (String) getAdvertisingId.invoke(null, activity);
} catch (Exception e) {
Log.w(LOGTAG, "Unable to get identifier: " + e);
}
final GeckoProfile profile = GeckoThread.getActiveProfile();
String clientID = null;
try {
clientID = profile.getClientId();
} catch (final IOException e) {
Log.w(LOGTAG, "Unable to get client ID: " + e);
if (identifier == null) {
//Activation ping is mandatory to be sent with either the identifier or the clientID.
Log.d(LOGTAG, "Activation ping failed to send - both identifier and clientID were unable to be retrieved.");
return;
}
}
final TelemetryActivationPingBuilder pingBuilder = new TelemetryActivationPingBuilder(activity);
if (identifier != null) {
pingBuilder.setIdentifier(identifier);
} else {
pingBuilder.setClientID(clientID);
}
getTelemetryDispatcher().queuePingForUpload(activity, pingBuilder);
});
}
@WorkerThread // via constructor
private TelemetryDispatcher getTelemetryDispatcher() {
if (telemetryDispatcher == null) {
final GeckoProfile profile = GeckoThread.getActiveProfile();
final String profilePath = profile.getDir().getAbsolutePath();
final String profileName = profile.getName();
telemetryDispatcher = new TelemetryDispatcher(profilePath, profileName);
}
return telemetryDispatcher;
}
}
......@@ -21,11 +21,11 @@ import org.mozilla.gecko.GeckoThread;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.adjust.AttributionHelperListener;
import org.mozilla.gecko.telemetry.measurements.CampaignIdMeasurements;
import org.mozilla.gecko.delegates.BrowserAppDelegateWithReference;
import org.mozilla.gecko.distribution.DistributionStoreCallback;
import org.mozilla.gecko.search.SearchEngineManager;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.telemetry.measurements.CampaignIdMeasurements;
import org.mozilla.gecko.telemetry.measurements.SearchCountMeasurements;
import org.mozilla.gecko.telemetry.measurements.SessionMeasurements;
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryCorePingBuilder;
......@@ -139,43 +139,47 @@ public class TelemetryCorePingDelegate extends BrowserAppDelegateWithReference
// the first launch of the activity doesn't trigger profile init too early.
//
// Additionally, getAndIncrementSequenceNumber must be called from a worker thread.
ThreadUtils.postToBackgroundThread(() -> {
final BrowserApp activity = getBrowserApp();
if (activity == null) {
return;
}
final GeckoProfile profile = GeckoThread.getActiveProfile();
if (!TelemetryUploadService.isUploadEnabledByProfileConfig(activity, profile)) {
Log.d(LOGTAG, "Core ping upload disabled by profile config. Returning.");
return;
}
final String clientID;
final boolean hadCanaryClientId;
try {
clientID = profile.getClientId();
hadCanaryClientId = profile.getIfHadCanaryClientId();
} catch (final IOException e) {
Log.w(LOGTAG, "Unable to get client ID properties to generate core ping: " + e);
return;
ThreadUtils.postToBackgroundThread(new Runnable() {
@WorkerThread
@Override
public void run() {
final BrowserApp activity = getBrowserApp();
if (activity == null) {
return;
}
final GeckoProfile profile = GeckoThread.getActiveProfile();
if (!TelemetryUploadService.isUploadEnabledByProfileConfig(activity, profile)) {
Log.d(LOGTAG, "Core ping upload disabled by profile config. Returning.");
return;
}
final String clientID;
final boolean hadCanaryClientId;
try {
clientID = profile.getClientId();
hadCanaryClientId = profile.getIfHadCanaryClientId();
} catch (final IOException e) {
Log.w(LOGTAG, "Unable to get client ID properties to generate core ping: " + e);
return;
}
// Each profile can have different telemetry data so we intentionally grab the shared prefs for the profile.
final SharedPreferences sharedPrefs = getSharedPreferences(activity);
final SessionMeasurements.SessionMeasurementsContainer sessionMeasurementsContainer =
sessionMeasurements.getAndResetSessionMeasurements(activity);
final TelemetryCorePingBuilder pingBuilder = new TelemetryCorePingBuilder(activity)
.setClientID(clientID)
.setHadCanaryClientId(hadCanaryClientId)
.setDefaultSearchEngine(TelemetryCorePingBuilder.getEngineIdentifier(engine))
.setProfileCreationDate(TelemetryCorePingBuilder.getProfileCreationDate(activity, profile))
.setSequenceNumber(TelemetryCorePingBuilder.getAndIncrementSequenceNumber(sharedPrefs))
.setSessionCount(sessionMeasurementsContainer.sessionCount)
.setSessionDuration(sessionMeasurementsContainer.elapsedSeconds);
maybeSetOptionalMeasurements(activity, sharedPrefs, pingBuilder);
getTelemetryDispatcher(activity).queuePingForUpload(activity, pingBuilder);
}
// Each profile can have different telemetry data so we intentionally grab the shared prefs for the profile.
final SharedPreferences sharedPrefs = getSharedPreferences(activity);
final SessionMeasurements.SessionMeasurementsContainer sessionMeasurementsContainer =
sessionMeasurements.getAndResetSessionMeasurements(activity);
final TelemetryCorePingBuilder pingBuilder = new TelemetryCorePingBuilder(activity)
.setClientID(clientID)
.setHadCanaryClientId(hadCanaryClientId)
.setDefaultSearchEngine(TelemetryCorePingBuilder.getEngineIdentifier(engine))
.setProfileCreationDate(TelemetryCorePingBuilder.getProfileCreationDate(activity, profile))
.setSequenceNumber(TelemetryCorePingBuilder.getAndIncrementSequenceNumber(sharedPrefs))
.setSessionCount(sessionMeasurementsContainer.sessionCount)
.setSessionDuration(sessionMeasurementsContainer.elapsedSeconds);
maybeSetOptionalMeasurements(activity, sharedPrefs, pingBuilder);
getTelemetryDispatcher(activity).queuePingForUpload(activity, pingBuilder);
});
}
......
......@@ -9,8 +9,6 @@ package org.mozilla.gecko.telemetry;
import android.content.Context;
import android.support.annotation.WorkerThread;
import android.util.Log;
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryActivationPingBuilder;
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryCorePingBuilder;
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryCrashPingBuilder;
import org.mozilla.gecko.telemetry.schedulers.TelemetryUploadScheduler;
......@@ -92,14 +90,6 @@ public class TelemetryDispatcher {
queuePingForUpload(context, ping, coreStore, uploadAllPingsImmediatelyScheduler);
}
/**
* Queues the given ping for upload and potentially schedules upload. This method can be called from any thread.
*/
public void queuePingForUpload(final Context context, final TelemetryActivationPingBuilder pingBuilder) {
final TelemetryOutgoingPing ping = pingBuilder.build();
queuePingForUpload(context, ping, coreStore, uploadAllPingsImmediatelyScheduler);
}
/**
* Queues the given crash ping for upload and potentially schedules upload. This method can be called from any thread.
*/
......
......@@ -19,7 +19,6 @@ import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.net.BaseResource;
import org.mozilla.gecko.sync.net.BaseResourceDelegate;
import org.mozilla.gecko.sync.net.Resource;
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryActivationPingBuilder;
import org.mozilla.gecko.telemetry.stores.TelemetryPingStore;
import org.mozilla.gecko.util.DateUtil;
import org.mozilla.gecko.util.NetworkUtils;
......@@ -126,8 +125,6 @@ public class TelemetryUploadService extends JobIntentService {
if (delegate.hadConnectionError()) {
break;
}
checkPingsPersistence(context, ping.getDocID());
}
final boolean wereAllUploadsSuccessful = !delegate.hadConnectionError();
......@@ -139,23 +136,6 @@ public class TelemetryUploadService extends JobIntentService {
return wereAllUploadsSuccessful;
}
/**
* Check if we have any pings that need to persist their succesful upload status in order to prevent further attempts.
* E.g. {@link TelemetryActivationPingBuilder}
* @param context
*/
private static void checkPingsPersistence(Context context, String successfulUploadID) {
final String activationID = TelemetryActivationPingBuilder.getActivationPingId(context);
if (activationID == null) {
return;
}
if (activationID.equals(successfulUploadID)) {
TelemetryActivationPingBuilder.setActivationPingSent(context, true);
}
}
private static void uploadPayload(final String url, final ExtendedJSONObject payload, final ResultDelegate delegate) {
final BaseResource resource;
try {
......
package org.mozilla.gecko.telemetry.pingbuilders;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.support.annotation.NonNull;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.Locales;
import org.mozilla.gecko.distribution.DistributionStoreCallback;
import org.mozilla.gecko.telemetry.TelemetryOutgoingPing;
import org.mozilla.gecko.util.DateUtil;
import org.mozilla.gecko.util.StringUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
/**
* Builds a {@link TelemetryOutgoingPing} representing a activation ping.
*
*/
public class TelemetryActivationPingBuilder extends TelemetryPingBuilder {
private static final String LOGTAG = StringUtils.safeSubstring(TelemetryActivationPingBuilder.class.getSimpleName(), 0, 23);
//Using MOZ_APP_BASENAME would be more elegant but according to the server side schema we need to be sure that we always send the "Fennec" value.
private static final String APP_NAME_VALUE = "Fennec";
private static final String PREFS_ACTIVATION_ID = "activation_ping_id";
private static final String PREFS_ACTIVATION_SENT = "activation_ping_sent";
private static final String NAME = "activation";
private static final int VERSION_VALUE = 1;
private static final String IDENTIFIER = "identifier";
private static final String CLIENT_ID = "clientId";
private static final String MANUFACTURER = "manufacturer";
private static final String MODEL = "model";
private static final String DISTRIBUTION_ID = "distribution_id";
private static final String LOCALE = "locale";
private static final String OS_ATTR = "os";
private static final String OS_VERSION = "osversion";
private static final String PING_CREATION_DATE = "created";
private static final String TIMEZONE_OFFSET = "tz";
private static final String APP_NAME = "app_name";
private static final String CHANNEL = "channel";
public TelemetryActivationPingBuilder(final Context context) {
super(VERSION_VALUE, true);
initPayloadConstants(context);
}
private void initPayloadConstants(final Context context) {
payload.put(MANUFACTURER, Build.MANUFACTURER);
payload.put(MODEL, Build.MODEL);
payload.put(LOCALE, Locales.getLanguageTag(Locale.getDefault()));
payload.put(OS_ATTR, TelemetryPingBuilder.OS_NAME);
payload.put(OS_VERSION, Integer.toString(Build.VERSION.SDK_INT)); // A String for cross-platform reasons.
final Calendar nowCalendar = Calendar.getInstance();
final DateFormat pingCreationDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
payload.put(PING_CREATION_DATE, pingCreationDateFormat.format(nowCalendar.getTime()));
payload.put(TIMEZONE_OFFSET, DateUtil.getTimezoneOffsetInMinutesForGivenDate(nowCalendar));
payload.put(APP_NAME, APP_NAME_VALUE);
payload.put(CHANNEL, AppConstants.ANDROID_PACKAGE_NAME);
SharedPreferences prefs = GeckoSharedPrefs.forApp(context);
final String distributionId = prefs.getString(DistributionStoreCallback.PREF_DISTRIBUTION_ID, null);
if (distributionId != null) {
payload.put(DISTRIBUTION_ID, distributionId);
}
prefs.edit().putString(PREFS_ACTIVATION_ID, docID).apply();
}
public static boolean activationPingAlreadySent(Context context) {
return GeckoSharedPrefs.forApp(context).getBoolean(PREFS_ACTIVATION_SENT, false);
}
public static void setActivationPingSent(Context context, boolean value) {
SharedPreferences prefs = GeckoSharedPrefs.forApp(context);
prefs.edit().putBoolean(PREFS_ACTIVATION_SENT, value).apply();
prefs.edit().remove(PREFS_ACTIVATION_ID).apply();
}
public static String getActivationPingId(Context context) {
return GeckoSharedPrefs.forApp(context).getString(PREFS_ACTIVATION_ID, null);
}
@Override
public String getDocType() {
return NAME;
}
@Override
public String[] getMandatoryFields() {
return new String[] {
MANUFACTURER,
MODEL,
LOCALE,
OS_ATTR,
OS_VERSION,
PING_CREATION_DATE,
TIMEZONE_OFFSET,
APP_NAME,
CHANNEL
};
}
public TelemetryActivationPingBuilder setIdentifier(@NonNull final String identifier) {
if (identifier == null) {
throw new IllegalArgumentException("Expected non-null identifier");
}
payload.put(IDENTIFIER, identifier);
return this;
}
public TelemetryActivationPingBuilder setClientID(@NonNull final String clientID) {
if (clientID == null) {
throw new IllegalArgumentException("Expected non-null clientID");
}
payload.put(CLIENT_ID, clientID);
return this;
}
}
......@@ -25,9 +25,6 @@ abstract class TelemetryPingBuilder {
// In the server url, the initial path directly after the "scheme://host:port/"
private static final String SERVER_INITIAL_PATH = "submit/telemetry";
// Modern pings now use a structured ingestion where we capture the schema version as one of the URI parameters.
private static final String SERVER_INITIAL_PATH_MODERN = "submit/mobile";
// By default Fennec ping's use the old telemetry version, this can be overridden
private static final int DEFAULT_TELEMETRY_VERSION = 1;
......@@ -51,12 +48,6 @@ abstract class TelemetryPingBuilder {
payload = new ExtendedJSONObject();
}
public TelemetryPingBuilder(int version, boolean modernPing) {
docID = UUID.randomUUID().toString();
serverPath = modernPing ? getModernTelemetryServerPath(getDocType(), docID, version) : getTelemetryServerPath(getDocType(), docID, version);
payload = new ExtendedJSONObject();
}
/**
* @return the name of the ping (e.g. "core")
*/
......@@ -109,22 +100,4 @@ abstract class TelemetryPingBuilder {
appBuildId +
(version == UNIFIED_TELEMETRY_VERSION ? "?v=4" : "");
}
/**
* Returns a url of the format:
* http://hostname/submit/mobile/docType/appVersion/docId/
*
* User for modern structured ingestion.
*
* @param docType The name of the ping (e.g. "main")
* @param docID A UUID that identifies the ping
* @param version The ping format version
* @return a url at which to POST the telemetry data to
*/
private static String getModernTelemetryServerPath(final String docType, final String docID, int version) {
return SERVER_INITIAL_PATH_MODERN + '/' +
docType + '/' +
version + '/' +
docID;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment