<commit_before>package org.apps8os.trafficsense.pebble;


import java.util.HashMap;
import java.util.UUID;

import org.apps8os.trafficsense.android.Constants;
import org.apps8os.trafficsense.core.Waypoint;

import com.getpebble.android.kit.PebbleKit;
import com.getpebble.android.kit.util.PebbleDictionary;
import com.google.gson.Gson;

import android.content.Context;
import android.content.Intent;

/**
 * Handles all communication between Android side and Pebble.
 * 
 * The application should first instantiate this class, invoke {@link #startAppOnPebble()}
 * before any Pebble interaction, and {@link #stop()} after finished.
 * 
 * Instantiated/started by TrafficsenseContainer.
 * Mostly invoked from PebbleUiController
 */
public class PebbleCommunication {
	/**
	 * See appinfo.json of Pebble application.
	 */
	private static final UUID APP_UUID = UUID.fromString(Constants.PEBBLE_APP_UUID);
	private static final int KEY_COMMAND = 0;
	private static final int COMMAND_GET_STOP = 0;
	private static final int COMMAND_UPDATELIST = 1;
	private static final int KEY_STOP_NUM = 1;
	private static final int KEY_STOP_NAME = 2;
	private static final int KEY_STOP_CODE = 3;
	private static final int KEY_STOP_TIME = 4;
	
	private static final int COMMAND_INIT_SEGMENT = 2;
	private static final int KEY_LINE_NUMBER = 1;
	private static final int KEY_FIRST_STOP_NAME = 2; // Don't confuse with KEY_STOP_NAME and -_CODE1
	private static final int KEY_FIRST_STOP_CODE = 3;
	private static final int KEY_START_TIME_HOUR = 4;
	private static final int KEY_START_TIME_MIN = 5;
	private static final int KEY_START_TIME_SEC = 6;
	
	private static final int COMMAND_SHOW_3STOP_WINDOW = 3;
	//private static final int MAX_DICT_SIZE = 124;
	public static final int NUM_STOPS = 3;
	
	/**
	 * Commands that can be sent from pebble to android
	 */
	// Command for getting required data, stop names etc. e.g. when the user starts
	// the pebble app in the middle of the journey
	private static final int PEBBLE_COMMAND_GET = 0;
	
	
	/**
	 * The Context in which we works.
	 */
	private Context mContext;
	/**
	 * Handle Pebble (Bluetooth) communication in another Thread. 
	 */
	private Thread mMessageManagerThread;
	/**
	 * Pebble MessageHandler.
	 */
	private final MessageManager messageManager;
	/**
	 * Handle Pebble messaging ACKs.
	 */
	private PebbleKit.PebbleAckReceiver ackReceiver;
	/**
	 * Handle Pebble messaging NACKs.
	 */
	private PebbleKit.PebbleNackReceiver nackReceiver;

	/**
	 * Constructor.
	 * 
	 * @param applicationContext the Context in which we works.
	 */
	public PebbleCommunication(Context applicationContext) {
		mContext = applicationContext;
		messageManager = new MessageManager(mContext, APP_UUID);
		// The thread is started in startAppOnPebble()
		mMessageManagerThread = new Thread(messageManager);
	}


	/**
	 * Start the MessageManager thread and the smart watch app on Pebble.
	 * Must be called before any other operations.
	 */
	public void startAppOnPebble() {
		mMessageManagerThread.start();
		registerReceivers();
		PebbleKit.startAppOnPebble(mContext, APP_UUID);
	}
	
	/**
	 * Swithches the screen shown in pebble to the 3 stop list
	 */
	public void switchTo3stopScreen() {
		PebbleDictionary dictionary = new PebbleDictionary();
		dictionary.addUint8(KEY_COMMAND, (byte) COMMAND_SHOW_3STOP_WINDOW);
		/**
		 * En-queue this message to MessageHandler.
		 */
		if (messageManager.offer(dictionary) == false) {
			System.out.println("DBG PebbleCommunicaitonswitchTo3stopScreen error: " +
					"could not offer dictionary");
		} else {
			System.out.println("DBG PebbleCommunication switchTo3stopScreen() success");
		}
	}

	/**
	 * Send a text notification to Pebble.
	 * 
	 * @param title the title of the notification.
	 * @param message the content of the notification.
	 */
	public void sendMessage(String title, String message) {
		Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION");
		Gson gson = new Gson();
		HashMap<String, String> payload = new HashMap<String, String>();
		payload.put("title", title);
		payload.put("body", message);
		String notificationPayload = gson.toJson(payload);
		i.putExtra("messageType", "PEBBLE_ALERT");
		i.putExtra("sender", "TrafficSense");
		i.putExtra("notificationData", notificationPayload);
		System.out.println("DBG sendMessage " + notificationPayload);
		mContext.sendBroadcast(i);
	}

	/**
	 * Send a Waypoint to Pebble.
	 * This is usually invoked in a loop to initialize the Pebble UI at start.
	 * 
	 * @param waypoint the Waypoint.
	 * @param listIndex the sequence number of this Waypoint in the journey. 
	 */
	public void sendWaypoint(Waypoint waypoint, int listIndex) {
		// If waypoint = null, send empty waypoints to scroll the list
		String code;<commit_msg>fixed pebble alarm bug<commit_after>package org.apps8os.trafficsense.pebble;


import java.util.HashMap;
import java.util.UUID;

import org.apps8os.trafficsense.android.Constants;
import org.apps8os.trafficsense.core.Waypoint;

import com.getpebble.android.kit.PebbleKit;
import com.getpebble.android.kit.util.PebbleDictionary;
import com.google.gson.Gson;

import android.content.Context;
import android.content.Intent;

/**
 * Handles all communication between Android side and Pebble.
 * 
 * The application should first instantiate this class, invoke {@link #startAppOnPebble()}
 * before any Pebble interaction, and {@link #stop()} after finished.
 * 
 * Instantiated/started by TrafficsenseContainer.
 * Mostly invoked from PebbleUiController
 */
public class PebbleCommunication {
	/**
	 * See appinfo.json of Pebble application.
	 */
	private static final UUID APP_UUID = UUID.fromString(Constants.PEBBLE_APP_UUID);
	private static final int KEY_COMMAND = 0;
	private static final int COMMAND_GET_STOP = 0;
	private static final int COMMAND_UPDATELIST = 1;
	private static final int KEY_STOP_NUM = 1;
	private static final int KEY_STOP_NAME = 2;
	private static final int KEY_STOP_CODE = 3;
	private static final int KEY_STOP_TIME = 4;
	
	private static final int COMMAND_INIT_SEGMENT = 2;
	private static final int KEY_LINE_NUMBER = 1;
	private static final int KEY_FIRST_STOP_NAME = 2; // Don't confuse with KEY_STOP_NAME and -_CODE1
	private static final int KEY_FIRST_STOP_CODE = 3;
	private static final int KEY_START_TIME_HOUR = 4;
	private static final int KEY_START_TIME_MIN = 5;
	private static final int KEY_START_TIME_SEC = 6;
	
	private static final int COMMAND_SHOW_3STOP_WINDOW = 3;
	//private static final int MAX_DICT_SIZE = 124;
	public static final int NUM_STOPS = 3;
	
	/**
	 * Commands that can be sent from pebble to android
	 */
	// Command for getting required data, stop names etc. e.g. when the user starts
	// the pebble app in the middle of the journey
	private static final int PEBBLE_COMMAND_GET = 0;
	
	
	/**
	 * The Context in which we works.
	 */
	private Context mContext;
	/**
	 * Handle Pebble (Bluetooth) communication in another Thread. 
	 */
	private Thread mMessageManagerThread;
	/**
	 * Pebble MessageHandler.
	 */
	private final MessageManager messageManager;
	/**
	 * Handle Pebble messaging ACKs.
	 */
	private PebbleKit.PebbleAckReceiver ackReceiver;
	/**
	 * Handle Pebble messaging NACKs.
	 */
	private PebbleKit.PebbleNackReceiver nackReceiver;

	/**
	 * Constructor.
	 * 
	 * @param applicationContext the Context in which we works.
	 */
	public PebbleCommunication(Context applicationContext) {
		mContext = applicationContext;
		messageManager = new MessageManager(mContext, APP_UUID);
		// The thread is started in startAppOnPebble()
		mMessageManagerThread = new Thread(messageManager);
	}


	/**
	 * Start the MessageManager thread and the smart watch app on Pebble.
	 * Must be called before any other operations.
	 */
	public void startAppOnPebble() {
		mMessageManagerThread.start();
		registerReceivers();
		PebbleKit.startAppOnPebble(mContext, APP_UUID);
	}
	
	/**
	 * Swithches the screen shown in pebble to the 3 stop list
	 */
	public void switchTo3stopScreen() {
		PebbleDictionary dictionary = new PebbleDictionary();
		dictionary.addUint8(KEY_COMMAND, (byte) COMMAND_SHOW_3STOP_WINDOW);
		/**
		 * En-queue this message to MessageHandler.
		 */
		if (messageManager.offer(dictionary) == false) {
			System.out.println("DBG PebbleCommunicaitonswitchTo3stopScreen error: " +
					"could not offer dictionary");
		} else {
			System.out.println("DBG PebbleCommunication switchTo3stopScreen() success");
		}
	}

	/**
	 * Send a text notification to Pebble.
	 * 
	 * @param title the title of the notification.
	 * @param message the content of the notification.
	 */
	public void sendMessage(String title, String message) {
		Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION");
		Gson gson = new Gson();
		HashMap<String, String> payload = new HashMap<String, String>();
		payload.put("title", title);
		payload.put("body", message);
		String notificationPayload = "[" + gson.toJson(payload) + "]";
		i.putExtra("messageType", "PEBBLE_ALERT");
		i.putExtra("sender", "TrafficSense");
		i.putExtra("notificationData", notificationPayload);
		System.out.println("DBG sendMessage " + notificationPayload);
		mContext.sendBroadcast(i);
	}

	/**
	 * Send a Waypoint to Pebble.
	 * This is usually invoked in a loop to initialize the Pebble UI at start.
	 * 
	 * @param waypoint the Waypoint.
	 * @param listIndex the sequence number of this Waypoint in the journey. 
	 */
	public void sendWaypoint(Waypoint waypoint, int listIndex) {
		// If waypoint = null, send empty waypoints to scroll the list
		String code;
{'fraction_non_alphanumeric': 0.09017679673606026, 'fraction_numerical': 0.006486034103985772, 'mean_word_length': 4.241228070175438, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3960019', 'n_tokens_mistral': 3185, 'n_tokens_neox': 2911, 'n_words': 910}