Files
tubestation/mobile/android/base/tiles/TilesRecorder.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;
}
}