summaryrefslogtreecommitdiffstats
path: root/mobile/android/docs/mma.rst
blob: 6d484f63896f3a1c93acf3b20947b8ba1738400b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
.. -*- Mode: rst; fill-column: 100; -*-

======================================
 MMA Mobile Marketing Automation
======================================

We want to engage with users more. MMA is the project for this purpose. When a user performs a certain
UI action, he/she will see a prompt and have a chance to  interact with it. For example, if a user uses
Firefox 10 times a week, but Firefox is not his default browser, we'll prompt the user the next time
when he launchers our app, and guide him to set us as default browser.

Mozilla is using a third party framework called "Leanplum" in order to achieve above goal for
Android 56 release. Leanplum is a San Francisco company, founded in 2012. We put their SDK in
our codebase and sync upstream when there's a major update. Please find it in ``mobile/android/thirdparty/com/leanplum``.
The SDK is documented at https://www.leanplum.com/docs/android/

There are three major component in Leanplum SDK.
1. Events : Triggers when users perform certain actions. An event will normally trigger a prompt message.
2. Deep Links : Actions that users can perform to interact with the prompt message.
3. Messages :  Campaigns that we want to engage with users. Messages is a combination of an Event and a Deep Link.

Data collection
~~~~~~~~~~~~~~~

Who will have Leanplum enabled?
======================================================

* We use Switchboard https://wiki.mozilla.org/Firefox/Kinto to filter users to have Leanplum enabled. Currently, for users in the USA
  and whose locale is set to English, 10% of that users will have Leanplum enabled.
* If the user has "Health Report" setting enabled.
* If above two are true, when the app starts, and switchboard configure arrived, Firefox for Android will send the
  triggers and message interaction history to Leanplum server when available.


Where does data sent to the Leanplum backend go?
======================================================

The Leanplum SDK is hard-coded to send data to the endpoint https://www.leanplum.com.  The endpoint is
defined by ``com.leanplum.internal.Constants.API_HOST_NAME`` at
https://searchfox.org/mozilla-central/rev/c49a70b53f67dd5550eec8a08793805f2aca8d42/mobile/android/thirdparty/com/leanplum/internal/Constants.java#32.

The user is identified by Leanplum using a random UUID generated by Firefox for Android when Leanplum is initialized for the first time.
This unique identifier is only used by Leanplum and can't be tracked back to any Firefox users.


What data is collected and sent to the Leanplum backend?
==========================================================

The Leanplum SDK collects and sends two messages to the Leanplum backend.  The messages have the
following parameters::

  // Sent every time when an event is triggered
  "action" -> "track"                   // track: an event is tracked.
  "event" -> "Launch"                   // Used when an event is triggered. e.g. E_Saved_Bookmark.
  "info" -> ""                          // Used when an event is triggered. Basic context associated with the event.
  "value" -> 0.0                        // Used when an event is triggered. Value of that event.
  "messageId" -> 5111602214338560       // Used when an event is triggered. The ID of the message.

  // Sent when the app starts
  "action" -> "start"                   // start: Leanplum SDK starts. heartbeat
  "userAttributes" -> "{                // A set of key-value pairs used to describe the user.
    "Focus Installed" -> true           // If Focus for Android is installed.
    "Klar Installed" -> true            // If Klar for Android is installed.
    "Pocket Installed" -> true          // If Pocket for Android is installed.
    "Signed In Sync" -> true            // If the user has signed in to Mozilla account.
    "Default Browser" -> true           // If the user has set Firefox for Android as default browser.
    "Pocket in Top Sites" -> true       // If Pocket recommendations for Top Sites home panel are enabled (by default or through user action)
  }
  "appId" -> "app_6Ao...."              // Leanplum App ID.
  "clientKey" -> "dev_srwDUNZR...."     // Leanplum client access key.
  "systemName" -> "Android OS"          // Fixed String in SDK.
  "locale" -> "zh_TW"                   // System Locale.
  "timezone" -> "Asia/Taipei"           // System Timezone.
  "versionName" -> "55.0a1"             // Firefox for Android version.
  "systemVersion" -> "7.1.2"            // System version.
  "deviceModel" -> "Google Pixel"       // System device model.
  "timezoneOffsetSeconds" -> "28800"    // User timezone offset with PST.
  "deviceName" -> "Google Pixel"        // System device name.
  "region" -> "(detect)"                // Not used. We strip play-SERVICES-location so this is will be the default stub value in Leanplum SDK.
  "city" -> "(detect)"                  // Same as above.
  "country" -> "(detect)"               // Same as above.
  "location" -> "(detect)"              // Same as above.
  "newsfeedMessages" -> " size = 0"     // Not used. New Leanplum Inbox message(Leanplum feature) count.
  "includeDefaults" -> "false"          // Not used. Always false.

  // Other life cycle actions
  "action" -> "heartbeat"               // heartbeat: every 15 minutes when app is in the foreground
                                        // pauseSession: when app goes to background
                                        // resumeSession: when app goes to foreground

  // Sent for every action
  "userId" -> "b13b3c239d01aa7c"        // Set by Firefox for Android, we use random uuid so users are anonymous to Leanplum.
  "deviceId" -> "b13b3c239d01aa7c"      // Same as above.
  "sdkVersion" -> "2.2.2-SNAPSHOT"      // Leanplum SDK version.
  "devMode" -> "true"                   // If the SDK is in developer mode. For official builds, it's false.
  "time" -> "1.497595093902E9"          // System time in second.
  "token" -> "nksZ5pa0R5iegC7wj...."    // Token come from Leanplum backend.


  "gcmRegistrationId" -> "APA91...."    // Send GCM token to Leanplum backend. This happens separately when Leanplum SDK gets initialized.

Notes on what data is collected
-------------------------------

User Identifier:
Since Device ID is a random UUID, Leanplum can't map the device to any know Client ID in Firefox for Android nor Advertising ID.

Events:
Most of the Leanplum events can be mapped to a single combination of Telemetry event (Event+Method+Extra).
Some events are not collected in Mozilla Telemetry. This will be addressed separately in each campaign review.
There are three elements that are used for each event. They are: event name, value(default: 0.0), and info(default: "").
Default value for event value is 0.0. Default value for event info is empty string.

List of current Events related data that is sent:

* When a page could be reader mode and is visible to the user

.. code-block:: json

    {
      "event": "E_Reader_Available"
    }

* Download videos or any other media

.. code-block:: json

    {
      "event" : "E_Download_Media_Saved_Image"
    }

* Save password and login from door hanger

.. code-block:: json

    {
      "event" : "E_Saved_Login_And_Password"
    }

* Save a bookmark from Firefox for Android menu

.. code-block:: json

    {
      "event" : "E_Saved_Bookmark"
    }

* Load the bookmark from home panel

.. code-block:: json

    {
      "event" : "E_Opened_Bookmark"
    }

* Interact with search url area

.. code-block:: json

    {
      "event" : "E_Interact_With_Search_URL_Area"
    }

* Interact with search widget

.. code-block:: json

    {
      "event" : "E_Interact_With_Search_Widget"
    }

* When a screenshot is taken

.. code-block:: json

    {
      "event" : "E_Screenshot"
    }

* Open a new tab

.. code-block:: json

    {
      "event" : "E_Opened_New_Tab"
    }

* App start but Firefox for Android is not set as default browser

.. code-block:: json

    {
      "event" : "E_Launch_But_Not_Default_Browser"
    }

* General app start event

.. code-block:: json

    {
      "event" : "E_Launch_Browser"
    }

* The user just dismissed on-boarding

.. code-block:: json

    {
      "event" : "E_Dismiss_Onboarding"
    }

* Sign in Firefox Account

.. code-block:: json

    {
      "event" : "E_User_Signed_In_To_FxA"
    }

* Firefox Sync finished event

.. code-block:: json

    {
      "event" : "E_User_Finished_Sync"
    }

* The user just resumed the app from background

.. code-block:: json

    {
      "event" : "E_Resumed_From_Background"
    }

* User set Firefox for Android as default browser and resumed the app

.. code-block:: json

    {
      "event" : "E_Changed_Default_To_Fennec"
    }

* User installed the Focus app

.. code-block:: json

    {
      "event" : "E_Just_Installed_Focus"
    }

* User installed the Klar app

.. code-block:: json

    {
      "event" : "E_Just_Installed_Klar"
    }

* User accessed the promo webpage for the Awesomescreen's Firefox promo banner.

.. code-block:: json

    {
      "event" : "E_Opened_Firefox_Promo"
    }

* User dismissed the Awesomescreen's Firefox promo banner.

.. code-block:: json

    {
      "event" : "E_Dismissed_Firefox_Promo"
    }

Deep Links:
Deep links are actions that can point Firefox for Android to open certain pages or load features such as `show bookmark list` or
`open a SUMO page`. When users see a prompt Leanplum message, they can click the button(s) on it. These buttons can
trigger the following deep links:

* Link to open pages specifically in Firefox for Android (firefox://open?url=)
* Link to Set Default Browser settings (firefox://default_browser)
* Link to specific Add-on page (http://link_to_the_add_on_page)
* Link to sync signup/sign in (firefox://sign_up)
* Link to default search engine settings (firefox://preferences_search)
* Link to “Save as PDF” feature (firefox://save_as_pdf)
* Take user directly to a Sign up for a newsletter (http://link_to_newsletter_page)
* Link to bookmark list (firefox://bookmark_list)
* Link to history list (firefox://history_list)
* Link to main preferences (firefox://preferences)
* Link to privacy preferences (firefox://preferences_privacy)
* Link to notifications preferences (firefox://preferences_notifications)
* Link to accessibility preferences (firefox://preferences_accessibility)
* Link to general setting (firefox://preferences_general)
* Link to home page setting (firefox://preferences_home)

Messages :
Messages are prompts to the user from Leanplum. Messages can be in-app prompts or push notifications. The interaction of that prompt will be kept and sent to Leanplum backend (such
as "Accept" and "Show"). A messages is a combination of an Event and a Deep Link. The combinations are downloaded from Leanplum
when Leanplum SDK is initialized. When the criteria is met (set in Leanplum backend, could be when an event happens a certain number of times,
and/or targeting certain user attribute ), a prompt message will show up. And there may be buttons for users to click. Those clicks
may trigger deep links.

We use another Mozilla's Google Cloud Messaging(GCM) sender ID to send push notifications.
These push notifications will look like the notifications that Sync sends out.
Sender ID let GCM knows Mozilla is sending push notifications via Leanplum.
GCM will generate a token at client side. We'll send this GCM token to Leanplum so Leanplum knows whom to send push notifications.
This token is only useful to Mozilla's sender ID so it's anonymized to other parties.
Push Notifications can be triggered by Events, or be sent by Mozilla marketing team manually.

The list of current messages for Android can be found here: https://wiki.mozilla.org/Leanplum_Contextual_Hints#Android

Technical notes
~~~~~~~~~~~~~~~

Build flags controlling the Leanplum SDK integration
======================================================

To test this locally, add lines like:

export MOZ_ANDROID_MMA=1
ac_add_options --with-leanplum-sdk-keyfile=/path/to/leanplum-sdk-developer.token

MOZ_ANDROID_MMA depends on MOZ_ANDROID_GOOGLE_PLAY_SERVICES and MOZ_ANDROID_GCM.
Since Leanplum requires Google Play Services library, those flags are a proxy for it, and enable respectively.

We want to enable MOZ_ANDROID_MMA in Nightly, but only for
MOZILLA_OFFICIAL builds.  Since MOZILLA_OFFICIAL is still defined in
old-configure.in, we can't integrate it in
mobile/android/moz.configure, and therefore we enable using the
automation mozconfigs.

Technical notes on the Leanplum SDK integration
================================================

Just like Adjust, MmaDelegate uses mmaInterface to inject the MmaLeanplumImp and MmaStubImp.
Constants used by Leanplum is in MmaConstants. Services in AndroidManifest are in
``mobile/android/base/MmaAndroidManifest_services.xml.in`` which is also injected by build flag
MOZ_ANDROID_MMA.

Notes and links
=================

* Leanplum web page: http://leanplum.com/
* Leanplum SDK github repo: https://github.com/Leanplum/Leanplum-Android-SDK