package sh.nym.irisglass; import android.app.Service; import android.content.Intent; import android.content.SharedPreferences; import android.os.HandlerThread; import android.os.IBinder; import android.preference.PreferenceManager; import android.util.Log; import org.json.JSONException; import java.util.List; public final class BleLinkService extends Service implements BleCentralClient.Callback { private static final String PREF_KEY_LAST_WINNER_ID = "winner_last_id"; private HandlerThread bleThread; private BleCentralClient client; @Override public void onCreate() { super.onCreate(); bleThread = new HandlerThread("ble-link"); bleThread.start(); client = new BleCentralClient(getApplicationContext(), this, bleThread.getLooper()); } @Override public int onStartCommand(Intent intent, int flags, int startId) { String action = intent != null ? intent.getAction() : null; if (Constants.ACTION_RESCAN.equals(action)) { client.rescan(); } else { client.start(); } return START_STICKY; } @Override public void onDestroy() { try { if (client != null) client.stop(); } catch (Throwable ignored) { } if (bleThread != null) { bleThread.quit(); bleThread = null; } super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onStatus(String status, String lastErrorOrNull, boolean shouldRender) { Log.i(Constants.TAG_BLE, "Status: " + status + (lastErrorOrNull != null ? (" (" + lastErrorOrNull + ")") : "")); Intent i = new Intent(Constants.ACTION_BLE_STATUS); i.putExtra(Constants.EXTRA_BLE_STATUS, status); i.putExtra(Constants.EXTRA_BLE_ERROR, lastErrorOrNull); sendBroadcast(i); } @Override public void onConnected() { Intent i = new Intent(Constants.ACTION_BLE_STATUS); i.putExtra(Constants.EXTRA_BLE_STATUS, "Connected"); sendBroadcast(i); } @Override public void onPing() { } @Override public void onFeedJson(String json) { if (json == null) return; try { FeedEnvelope env = FeedParser.parseEnvelope(json); HudState.get().setFeed(env.items, env.meta, true); maybeNudgeWinnerChanged(env); } catch (JSONException e) { Log.w(Constants.TAG_FEED, "Parse error: " + e); Intent i = new Intent(Constants.ACTION_BLE_STATUS); i.putExtra(Constants.EXTRA_BLE_STATUS, "Connected"); i.putExtra(Constants.EXTRA_BLE_ERROR, "Feed parse error: " + e.getMessage()); sendBroadcast(i); } } private void maybeNudgeWinnerChanged(FeedEnvelope env) { if (env == null) return; String winnerId = env.meta != null ? env.meta.winnerId : null; if (winnerId == null || winnerId.length() == 0) { List active = env.activeItems(); if (!active.isEmpty()) { FeedItem first = active.get(0); if (first != null) winnerId = first.id; } } if (winnerId == null || winnerId.length() == 0) return; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); String lastWinnerId = prefs.getString(PREF_KEY_LAST_WINNER_ID, null); if (lastWinnerId == null) { prefs.edit().putString(PREF_KEY_LAST_WINNER_ID, winnerId).apply(); Log.i(Constants.TAG_HUD, "Winner nudge: seeded last winner id=" + winnerId); return; } if (winnerId.equals(lastWinnerId)) return; prefs.edit().putString(PREF_KEY_LAST_WINNER_ID, winnerId).apply(); Log.i(Constants.TAG_HUD, "Winner nudge: winner changed " + lastWinnerId + " -> " + winnerId); Intent i = new Intent(getApplicationContext(), HudService.class); i.setAction(Constants.ACTION_WINNER_CHANGED); i.putExtra(Constants.EXTRA_WINNER_ID, winnerId); startService(i); } }