109 lines
3.8 KiB
Java
109 lines
3.8 KiB
Java
/* 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.tiles;
|
|
|
|
import java.util.List;
|
|
|
|
import org.json.JSONArray;
|
|
import org.json.JSONObject;
|
|
import org.json.JSONException;
|
|
|
|
import org.mozilla.gecko.GeckoAppShell;
|
|
import org.mozilla.gecko.GeckoEvent;
|
|
import org.mozilla.gecko.Tab;
|
|
|
|
import android.util.Log;
|
|
|
|
public class TilesRecorder {
|
|
public static final String ACTION_CLICK = "click";
|
|
|
|
private static final String LOG_TAG = "GeckoTilesRecorder";
|
|
private static final String EVENT_TILES_CLICK = "Tiles:Click";
|
|
|
|
private TilesRecorder() {
|
|
// Empty private constructor to prevent construction
|
|
}
|
|
|
|
public static void recordAction(Tab tab, String action, int index, List<Tile> tiles, String locale) {
|
|
final Tile clickedTile = tiles.get(index);
|
|
|
|
if (tab == null || clickedTile == null) {
|
|
throw new IllegalArgumentException("Tab and tile cannot be null");
|
|
}
|
|
|
|
if (clickedTile.id == -1) {
|
|
// User clicked a non-distribution tile, so we don't need to report it.
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final JSONArray tilesJSON = new JSONArray();
|
|
int clickedTileIndex = -1;
|
|
int currentTileIndex = 0;
|
|
|
|
for (int i = 0; i < tiles.size(); i++) {
|
|
final Tile tile = tiles.get(i);
|
|
if (tile == null) {
|
|
// Tiles may be null if there are pinned tiles with blank tiles in between.
|
|
continue;
|
|
}
|
|
|
|
// jsonForTile will return {} if the tile isn't tracked or pinned. That's fine
|
|
// as we still want to record that a tile exists (i.e., is not empty).
|
|
tilesJSON.put(jsonForTile(tile, currentTileIndex, i));
|
|
|
|
// The click index is relative to the tiles array we're building. That index is
|
|
// incremented whenever we hit a non-null tile. When we find the tile that was
|
|
// clicked, the index will match its position in the new array.
|
|
if (clickedTile == tile) {
|
|
clickedTileIndex = currentTileIndex;
|
|
}
|
|
|
|
currentTileIndex++;
|
|
}
|
|
|
|
if (clickedTileIndex == -1) {
|
|
throw new IllegalStateException("Clicked tile index not set");
|
|
}
|
|
|
|
final JSONObject payload = new JSONObject();
|
|
payload.put(action, clickedTileIndex);
|
|
payload.put("tiles", tilesJSON);
|
|
payload.put("locale", locale);
|
|
|
|
final JSONObject data = new JSONObject();
|
|
data.put("tabId", tab.getId());
|
|
data.put("payload", payload.toString());
|
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(EVENT_TILES_CLICK, data.toString()));
|
|
} catch (JSONException e) {
|
|
Log.e(LOG_TAG, "JSON error", e);
|
|
}
|
|
}
|
|
|
|
private static JSONObject jsonForTile(Tile tile, int tileIndex, int viewIndex) throws JSONException {
|
|
final JSONObject tileJSON = new JSONObject();
|
|
|
|
// Set the ID only if it is a distribution tile with a tracking ID.
|
|
if (tile.id != -1) {
|
|
tileJSON.put("id", tile.id);
|
|
}
|
|
|
|
// Set pinned to true only if the tile is pinned.
|
|
if (tile.pinned) {
|
|
tileJSON.put("pin", true);
|
|
}
|
|
|
|
// If the tile's index in the new array does not match its index in the view grid, record
|
|
// its position in the view grid. This can happen if there are pinned tiles with blank tiles
|
|
// in between.
|
|
if (tileIndex != viewIndex) {
|
|
tileJSON.put("pos", viewIndex);
|
|
}
|
|
|
|
return tileJSON;
|
|
}
|
|
}
|