<commit_before>package no.nordicsemi.activities;

import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.radiusnetworks.ibeacon.IBeacon;

import org.droidparts.activity.Activity;
import org.droidparts.annotation.bus.ReceiveEvents;
import org.droidparts.annotation.inject.InjectDependency;
import org.droidparts.annotation.inject.InjectView;
import org.droidparts.concurrent.task.AsyncTaskResultListener;
import org.droidparts.concurrent.task.SimpleAsyncTask;
import org.droidparts.util.L;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import no.nordicsemi.R;
import no.nordicsemi.actuators.Actuator;
import no.nordicsemi.adapters.RuleAdapter;
import no.nordicsemi.bluetooth.gatt.CharacteristicChangeListener;
import no.nordicsemi.bluetooth.gatt.GattManager;
import no.nordicsemi.bluetooth.gatt.operations.GattSetNotificationOperation;
import no.nordicsemi.db.ActionManager;
import no.nordicsemi.db.PuckManager;
import no.nordicsemi.db.RuleManager;
import no.nordicsemi.models.Action;
import no.nordicsemi.models.Puck;
import no.nordicsemi.models.Rule;
import no.nordicsemi.services.GattServices;
import no.nordicsemi.triggers.Trigger;


public class MainActivity extends Activity {

    @InjectView(id = R.id.lvRules)
    ListView mLvRules;

    @InjectView(id = R.id.tvClosestPuck)
    TextView mClosestPuck;

    @InjectDependency
    private ActionManager mActionManager;

    @InjectDependency
    private RuleManager mRuleManager;

    @InjectDependency
    private PuckManager mPuckManager;

    @InjectDependency
    private GattManager mGattManager;

    private RuleAdapter mRuleAdapter;

    @Override
    public void onPreInject() {
        super.onPreInject();
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mRuleAdapter = new RuleAdapter(this, mRuleManager.select());
        mLvRules.setAdapter(mRuleAdapter);

        bindBluetoothListeners();
    }

    public void bindBluetoothListeners() {
        final List<Rule> rules = mRuleManager.getRulesForTriggers(
                Trigger.TRIGGER_ROTATE_CUBE_UP,
                Trigger.TRIGGER_ROTATE_CUBE_DOWN,
                Trigger.TRIGGER_ROTATE_CUBE_LEFT,
                Trigger.TRIGGER_ROTATE_CUBE_RIGHT,
                Trigger.TRIGGER_ROTATE_CUBE_FRONT,
                Trigger.TRIGGER_ROTATE_CUBE_BACK);

        // Multiple rules may point to the same puck,
        // no need to bind up duplicate listeners.
        final Set<Puck> puckSet = new HashSet<>();
        for (Rule rule : rules) {
            puckSet.add(rule.getPuck());
        }

        new SimpleAsyncTask<Void>(this, null) {
            @Override
            protected Void onExecute() throws Exception {
                for (Puck puck : puckSet) {
                    bindBluetoothListener(puck);
                    // Android BLE stack might have issues connecting to
                    // multiple Gatt services right after another.
                    // See: http://stackoverflow.com/questions/21237093/android-4-3-how-to-connect-to-multiple-bluetooth-low-energy-devices
                    Thread.sleep(1000);
                }
                return null;
            }
        }.execute();
    }

    public void bindBluetoothListener(final Puck puck) {
        L.e("Binding GATT callback to %s (%s)", puck.getName(), puck.getAddress());
        BluetoothAdapter bluetoothAdapter = ((BluetoothManager) getSystemService
                (Context.BLUETOOTH_SERVICE)).getAdapter();
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(puck.getAddress());

        mGattManager.queue(new GattSetNotificationOperation(
            device,
            GattServices.CUBE_SERVICE_UUID,
            GattServices.CUBE_CHARACTERISTIC_DIRECTION_UUID,
            GattServices.CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID,
            new CharacteristicChangeListener() {
                @Override
                public void onCharacteristicChanged(BluetoothGattCharacteristic characteristic) {
                    int orientation = characteristic.getValue()[0];
                    final int UP = 0;
                    final int DOWN = 1;
                    final int LEFT = 2;
                    final int RIGHT = 3;
                    final int FRONT = 4;
                    final int BACK = 5;
                    switch(orientation) {
                        case UP: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_UP); break;
                        case DOWN: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_DOWN); break;
                        case LEFT: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_LEFT); break;
                        case RIGHT: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_RIGHT); break;
                        case FRONT: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_FRONT); break;
                        case BACK: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_BACK); break;
                    }
                }
            }
        ));
    }

    @ReceiveEvents(name = Trigger.TRIGGER_UPDATE_CLOSEST_PUCK_TV)
    public void updateTV(String _, Object toDisplay) {
        mClosestPuck.setText(String.valueOf(toDisplay));
    }

    @ReceiveEvents(name = Trigger.TRIGGER_ADD_ACTUATOR_FOR_EXISTING_RULE)
    public void addActuatorForExistingRule(String _, Object rule) {
        selectActuatorDialog((Rule) rule);
    }

    @ReceiveEvents(name = Trigger.TRIGGER_REMOVE_RULE)
    public void removeRule(String _, final Object rule) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle(R.string.rule_remove)<commit_msg>Add notification sound on cube puck triggers<commit_after>package no.nordicsemi.activities;

import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.DialogInterface;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.radiusnetworks.ibeacon.IBeacon;

import org.droidparts.Injector;
import org.droidparts.activity.Activity;
import org.droidparts.annotation.bus.ReceiveEvents;
import org.droidparts.annotation.inject.InjectDependency;
import org.droidparts.annotation.inject.InjectView;
import org.droidparts.concurrent.task.AsyncTaskResultListener;
import org.droidparts.concurrent.task.SimpleAsyncTask;
import org.droidparts.util.L;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import no.nordicsemi.R;
import no.nordicsemi.actuators.Actuator;
import no.nordicsemi.adapters.RuleAdapter;
import no.nordicsemi.bluetooth.gatt.CharacteristicChangeListener;
import no.nordicsemi.bluetooth.gatt.GattManager;
import no.nordicsemi.bluetooth.gatt.operations.GattSetNotificationOperation;
import no.nordicsemi.db.ActionManager;
import no.nordicsemi.db.PuckManager;
import no.nordicsemi.db.RuleManager;
import no.nordicsemi.models.Action;
import no.nordicsemi.models.Puck;
import no.nordicsemi.models.Rule;
import no.nordicsemi.services.GattServices;
import no.nordicsemi.triggers.Trigger;


public class MainActivity extends Activity {

    @InjectView(id = R.id.lvRules)
    ListView mLvRules;

    @InjectView(id = R.id.tvClosestPuck)
    TextView mClosestPuck;

    @InjectDependency
    private ActionManager mActionManager;

    @InjectDependency
    private RuleManager mRuleManager;

    @InjectDependency
    private PuckManager mPuckManager;

    @InjectDependency
    private GattManager mGattManager;

    private RuleAdapter mRuleAdapter;

    @Override
    public void onPreInject() {
        super.onPreInject();
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mRuleAdapter = new RuleAdapter(this, mRuleManager.select());
        mLvRules.setAdapter(mRuleAdapter);

        bindBluetoothListeners();
    }

    public void bindBluetoothListeners() {
        final List<Rule> rules = mRuleManager.getRulesForTriggers(
                Trigger.TRIGGER_ROTATE_CUBE_UP,
                Trigger.TRIGGER_ROTATE_CUBE_DOWN,
                Trigger.TRIGGER_ROTATE_CUBE_LEFT,
                Trigger.TRIGGER_ROTATE_CUBE_RIGHT,
                Trigger.TRIGGER_ROTATE_CUBE_FRONT,
                Trigger.TRIGGER_ROTATE_CUBE_BACK);

        // Multiple rules may point to the same puck,
        // no need to bind up duplicate listeners.
        final Set<Puck> puckSet = new HashSet<>();
        for (Rule rule : rules) {
            puckSet.add(rule.getPuck());
        }

        new SimpleAsyncTask<Void>(this, null) {
            @Override
            protected Void onExecute() throws Exception {
                for (Puck puck : puckSet) {
                    bindBluetoothListener(puck);
                    // Android BLE stack might have issues connecting to
                    // multiple Gatt services right after another.
                    // See: http://stackoverflow.com/questions/21237093/android-4-3-how-to-connect-to-multiple-bluetooth-low-energy-devices
                    Thread.sleep(1000);
                }
                return null;
            }
        }.execute();
    }

    public void bindBluetoothListener(final Puck puck) {
        L.e("Binding GATT callback to %s (%s)", puck.getName(), puck.getAddress());
        BluetoothAdapter bluetoothAdapter = ((BluetoothManager) getSystemService
                (Context.BLUETOOTH_SERVICE)).getAdapter();
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(puck.getAddress());

        mGattManager.queue(new GattSetNotificationOperation(
            device,
            GattServices.CUBE_SERVICE_UUID,
            GattServices.CUBE_CHARACTERISTIC_DIRECTION_UUID,
            GattServices.CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID,
            new CharacteristicChangeListener() {
                @Override
                public void onCharacteristicChanged(BluetoothGattCharacteristic characteristic) {
                    playDefaultNotificationSound();
                    int orientation = characteristic.getValue()[0];
                    final int UP = 0;
                    final int DOWN = 1;
                    final int LEFT = 2;
                    final int RIGHT = 3;
                    final int FRONT = 4;
                    final int BACK = 5;
                    switch(orientation) {
                        case UP: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_UP); break;
                        case DOWN: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_DOWN); break;
                        case LEFT: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_LEFT); break;
                        case RIGHT: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_RIGHT); break;
                        case FRONT: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_FRONT); break;
                        case BACK: Trigger.trigger(puck, Trigger.TRIGGER_ROTATE_CUBE_BACK); break;
                    }
                }

                private void playDefaultNotificationSound() {
                    Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                    RingtoneManager.getRingtone(Injector.getApplicationContext(), notification).play();
                }
            }
        ));
    }

    @ReceiveEvents(name = Trigger.TRIGGER_UPDATE_CLOSEST_PUCK_TV)
    public void updateTV(String _, Object toDisplay) {
        mClosestPuck.setText(String.valueOf(toDisplay));
    }

    @ReceiveEvents(name = Trigger.TRIGGER_ADD_ACTUATOR_FOR_EXISTING_RULE)
    public void addActuatorForExistingRule(String _, Object rule) {
        selectActuatorDialog((Rule) rule);
    }

    @ReceiveEvents(name = Trigger.TRIGGER_REMOVE_RULE)
    public void removeRule(String _, final Object rule) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle(R.string.rule_remove)
{'fraction_non_alphanumeric': 0.08109318996415771, 'fraction_numerical': 0.0031362007168458782, 'mean_word_length': 2.801589554357082, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, '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': '2769270', 'n_tokens_mistral': 4048, 'n_tokens_neox': 3821, 'n_words': 698}