package andraus.bluetoothhidemu.settings; import andraus.bluetoothhidemu.BluetoothHidEmuActivity; import andraus.bluetoothhidemu.R; import andraus.bluetoothhidemu.spoof.Spoof; import andraus.bluetoothhidemu.spoof.Spoof.SpoofMode; import andraus.bluetoothhidemu.util.DoLog; import andraus.bluetoothhidemu.view.BluetoothDeviceArrayAdapter; import andraus.bluetoothhidemu.view.BluetoothDeviceView; import android.app.Activity; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.preference.Preference; import android.preference.PreferenceCategory; import android.widget.Spinner; /** * */ public class BluetoothDeviceStateReceiver extends BroadcastReceiver { private static final String TAG = BluetoothHidEmuActivity.TAG; private PreferenceCategory mBluetoothDevicePrefCategory = null; private Spinner mDeviceSpinner = null; /** * * @param bluetoothDevicePrefCategory */ public BluetoothDeviceStateReceiver(PreferenceCategory bluetoothDevicePrefCategory) { super(); mBluetoothDevicePrefCategory = bluetoothDevicePrefCategory; } /** * * @param bluetoothDeviceArrayAdapter */ public BluetoothDeviceStateReceiver(Spinner deviceSpinner) { super(); mDeviceSpinner = deviceSpinner; } /** * */ @Override public void onReceive(Context context, Intent intent) { DoLog.d(TAG, "context: " + context); if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { final BluetoothDevice device = (BluetoothDevice) intent.getExtras().get(BluetoothDevice.EXTRA_DEVICE); final int state = intent.getExtras().getInt(BluetoothDevice.EXTRA_BOND_STATE); final int prevState = intent.getExtras().getInt(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE); DoLog.d("BluetoothHidEmu", String.format("device receiver: device = %s | state = %s | prevState = %s", device, state, prevState)); switch (state) { case BluetoothDevice.BOND_BONDED: SpoofMode emulationMode = Settings.getPrefEmulationMode(context); if (BluetoothDeviceView.isBluetoothDevicePs3(device) && emulationMode != SpoofMode.HID_PS3KEYPAD) { emulationMode = SpoofMode.INVALID; /* * There are two instances of BluetoothDeviceStateReceiver: one is created * for the Settings activity, the other for the main activity. We need to * verify which one is on foreground before showing this dialog. * */ if ( ((Activity) context).hasWindowFocus() ) { Settings.showPs3InvalidModeDialog(context); } } addDeviceToPreference(context, device, emulationMode); addDeviceToArrayAdapter(device, emulationMode); Settings.storeDeviceEmulationMode(context, device, emulationMode); break; case BluetoothDevice.BOND_NONE: removeDeviceFromPreference(device); removeDeviceFromArrayAdapter(device); break; } } } /** * * @param device */ private void removeDeviceFromPreference(BluetoothDevice device) { if (mBluetoothDevicePrefCategory == null) { return; } for (int i = 0; i < mBluetoothDevicePrefCategory.getPreferenceCount(); i++) { Preference pref = (Preference) mBluetoothDevicePrefCategory.getPreference(i); /* * Summary has format of <address>/n<Emulation:lorem...> * Need to compare only with address. */ String summary = pref.getSummary().toString(); String[] token = summary.split("\n"); if (token[0].equals(device.getAddress())) { mBluetoothDevicePrefCategory.removePreference(pref); break; } } } /** * * @param device */ private void removeDeviceFromArrayAdapter(BluetoothDevice device) { if (mDeviceSpinner == null) { return; } BluetoothDeviceArrayAdapter bluetoothDeviceArrayAdapter = (BluetoothDeviceArrayAdapter) mDeviceSpinner.getAdapter(); for (int i = 0; i < bluetoothDeviceArrayAdapter.getCount(); i++) { BluetoothDeviceView deviceView = bluetoothDeviceArrayAdapter.getItem(i); if (deviceView.getAddress().equals(device.getAddress())) { bluetoothDeviceArrayAdapter.remove(deviceView); DoLog.d(TAG, "removed: " + deviceView); break; } } mDeviceSpinner.setSelection(bluetoothDeviceArrayAdapter.getNullPosition()); } /** * * @param context * @param device */ private void addDeviceToPreference(Context context, BluetoothDevice device, SpoofMode spoofMode) { if (mBluetoothDevicePrefCategory == null) { return; } String emulationSummary = (spoofMode == SpoofMode.INVALID) ? context.getResources().getString(R.string.msg_pref_summary_device_emulation_mode_invalid) : Settings.getEmulationModeSummary(context, Spoof.intValue(spoofMode)); boolean exists = false; for (int i = 0; i < mBluetoothDevicePrefCategory.getPreferenceCount(); i++) { Preference pref = (Preference) mBluetoothDevicePrefCategory.getPreference(i); /* * Summary has format of <address>/n<Emulation:lorem...> * Need to compare only with address. */ String summary = pref.getSummary().toString(); String[] token = summary.split("\n"); if (token[0].equals(device.getAddress())) { pref.setTitle(device.getName()); pref.setSummary(device.getAddress() + "\n" + String.format(context.getResources().getString(R.string.msg_pref_summary_device_emulation_mode), emulationSummary)); exists = true; break; } } if (!exists) { Preference devicePref = new Preference(context); devicePref.setTitle(device.getName().equals("") ? device.getAddress() : device.getName()); devicePref.setSummary(device.getAddress() + "\n" + String.format(context.getResources().getString(R.string.msg_pref_summary_device_emulation_mode), emulationSummary)); mBluetoothDevicePrefCategory.addPreference(devicePref); } } /** * * @param device */ private void addDeviceToArrayAdapter(BluetoothDevice device, SpoofMode spoofMode) { if (mDeviceSpinner == null) { return; } BluetoothDeviceArrayAdapter bluetoothDeviceArrayAdapter = (BluetoothDeviceArrayAdapter) mDeviceSpinner.getAdapter(); boolean exists = false; for (int i = 0; i < bluetoothDeviceArrayAdapter.getCount(); i++) { BluetoothDeviceView deviceView = bluetoothDeviceArrayAdapter.getItem(i); if (device.getAddress().equals(deviceView.getAddress())) { deviceView.setBluetoothDevice(device); exists = true; break; } } if (!exists) { BluetoothDeviceView deviceView = new BluetoothDeviceView(device, spoofMode); bluetoothDeviceArrayAdapter.add(deviceView); mDeviceSpinner.setSelection(bluetoothDeviceArrayAdapter.getNullPosition()); } } }