/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.distribution; import org.mozilla.gecko.AdjustConstants; import org.mozilla.gecko.annotation.RobocopTarget; import org.mozilla.gecko.AppConstants; import org.mozilla.gecko.GeckoAppShell; import org.json.JSONException; import org.json.JSONObject; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; import android.util.Log; public class ReferrerReceiver extends BroadcastReceiver { private static final String LOGTAG = "GeckoReferrerReceiver"; private static final String ACTION_INSTALL_REFERRER = "com.android.vending.INSTALL_REFERRER"; // Sent when we're done. @RobocopTarget public static final String ACTION_REFERRER_RECEIVED = "org.mozilla.fennec.REFERRER_RECEIVED"; /** * If the install intent has this source, it is a Mozilla specific or over * the air distribution referral. We'll track the campaign ID using * Mozilla's metrics systems. * * If the install intent has a source different than this one, it is a * referral from an advertising network. We may track these campaigns using * third-party tracking and metrics systems. */ private static final String MOZILLA_UTM_SOURCE = "mozilla"; /** * If the install intent has this campaign, we'll load the specified distribution. */ private static final String DISTRIBUTION_UTM_CAMPAIGN = "distribution"; @Override public void onReceive(Context context, Intent intent) { Log.v(LOGTAG, "Received intent " + intent); if (!ACTION_INSTALL_REFERRER.equals(intent.getAction())) { // This should never happen. return; } // Track the referrer object for distribution handling. ReferrerDescriptor referrer = new ReferrerDescriptor(intent.getStringExtra("referrer")); if (!TextUtils.equals(referrer.source, MOZILLA_UTM_SOURCE)) { // Allow the Adjust handler to process the intent. try { AdjustConstants.getAdjustHelper().onReceive(context, intent); } catch (Exception e) { Log.e(LOGTAG, "Got exception in Adjust's onReceive; ignoring referrer intent.", e); } return; } if (TextUtils.equals(referrer.campaign, DISTRIBUTION_UTM_CAMPAIGN)) { Distribution.onReceivedReferrer(context, referrer); // We want Adjust information for OTA distributions as well try { AdjustConstants.getAdjustHelper().onReceive(context, intent); } catch (Exception e) { Log.e(LOGTAG, "Got exception in Adjust's onReceive for distribution.", e); } } else { Log.d(LOGTAG, "Not downloading distribution: non-matching campaign."); // If this is a Mozilla campaign, pass the campaign along to Gecko. // It'll pretend to be a "playstore" distribution for BLP purposes. propagateMozillaCampaign(referrer); } // Broadcast a secondary, local intent to allow test code to respond. final Intent receivedIntent = new Intent(ACTION_REFERRER_RECEIVED); LocalBroadcastManager.getInstance(context).sendBroadcast(receivedIntent); } private void propagateMozillaCampaign(ReferrerDescriptor referrer) { if (referrer.campaign == null) { return; } try { final JSONObject data = new JSONObject(); data.put("id", "playstore"); data.put("version", referrer.campaign); String payload = data.toString(); // Try to make sure the prefs are written as a group. GeckoAppShell.notifyObservers("Campaign:Set", payload); } catch (JSONException e) { Log.e(LOGTAG, "Error propagating campaign identifier.", e); } } }