package com.arksine.easycam; import android.app.Activity; import android.content.Context; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.util.Log; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; /** * TODO: Create a fragment to Add and Edit entries in the devices.json file. * PrefenceFragment isn't robust enough to easily handle all of the functionality * required. In the meantime, the devices.json file can be edited directly * if we need to change settings or create a new device profile. This will probably * require that I implement a custom "ListPreference" for the "select device" preference. */ public class SettingsActivity extends Activity { private static String TAG = "SettingsActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFragmentManager().beginTransaction() .add(android.R.id.content, new SettingsFragment()) .commit(); } public static class SettingsFragment extends PreferenceFragment { private class DeviceEntry { public String deviceDescription; public String deviceName; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); PreferenceScreen root = this.getPreferenceScreen(); ListPreference selectDevice = (ListPreference) root.findPreference("pref_key_select_device"); ListPreference selectStandard = (ListPreference) root.findPreference("pref_key_select_standard"); ListPreference selectDeint = (ListPreference) root.findPreference("pref_key_deinterlace_method"); EditTextPreference selectDevLoc = (EditTextPreference) root.findPreference("pref_select_dev_loc"); ArrayList<DeviceEntry> validStreamingDeviceList = enumerateUsbDevices(); populateDeviceListPreference(validStreamingDeviceList, selectDevice); // Set the summaries for preferences that assign them dynamically selectDevice.setSummary(selectDevice.getEntry()); selectStandard.setSummary(selectStandard.getEntry()); selectDeint.setSummary(selectDeint.getEntry()); selectDevLoc.setSummary(selectDevLoc.getText()); /** * Below are listeners for each of our device settings that update the summary based on the * currently selected value. */ selectDevice.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { ListPreference list = (ListPreference)preference; CharSequence[] entries = list.getEntries(); int index = list.findIndexOfValue((String)newValue); preference.setSummary(entries[index]); return true; } }); selectStandard.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { ListPreference list = (ListPreference)preference; CharSequence[] entries = list.getEntries(); int index = list.findIndexOfValue((String)newValue); preference.setSummary(entries[index]); return true; } }); selectDeint.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { ListPreference list = (ListPreference)preference; CharSequence[] entries = list.getEntries(); int index = list.findIndexOfValue((String)newValue); preference.setSummary(entries[index]); return true; } }); selectDevLoc.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { preference.setSummary((String)newValue); return true; } }); } private void populateDeviceListPreference(ArrayList<DeviceEntry> validStreamingDeviceList, ListPreference selectDevice) { CharSequence[] entries; CharSequence[] entryValues; if (validStreamingDeviceList.isEmpty()) { Log.i(TAG, "No V4L2 compatible streaming devices found on system"); entries = new CharSequence[1]; entryValues = new CharSequence[1]; entries[0] = "No devices found"; entryValues[0] = "NO_DEVICE"; selectDevice.setSummary(entries[0]); } else { entries = new CharSequence[validStreamingDeviceList.size()]; entryValues = new CharSequence[validStreamingDeviceList.size()]; for (int i = 0; i < validStreamingDeviceList.size(); i++) { entries[i] = validStreamingDeviceList.get(i).deviceDescription; entryValues[i] = validStreamingDeviceList.get(i).deviceName; } } selectDevice.setEntries(entries); selectDevice.setEntryValues(entryValues); } private ArrayList<DeviceEntry> enumerateUsbDevices() { ArrayList<DeviceEntry> validStreamingDeviceList = new ArrayList<>(5); synchronized (JsonManager.lock) { //Make sure the JsonManger has been initialized if (!JsonManager.isInitialized()) JsonManager.initialize(); // Enumerate a list of currently connected Usb devices so we can pick out which // ones are supported easycap devices UsbManager mUsbManager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE); HashMap<String, UsbDevice> usbDeviceList = mUsbManager.getDeviceList(); Iterator<UsbDevice> deviceIterator = usbDeviceList.values().iterator(); // Make sure the device list is empty before enumeration validStreamingDeviceList.clear(); while(deviceIterator.hasNext()) { UsbDevice uDevice = deviceIterator.next(); DeviceInfo devInfo = JsonManager.getDevice(uDevice.getVendorId(), uDevice.getProductId(), DeviceInfo.DeviceStandard.NTSC); // If a supported device is listed in json list, request permission // to access it if (devInfo != null) { Log.i(TAG, "Supported usb device found: " + uDevice.toString()); Log.i(TAG, "Device ID: " + uDevice.getDeviceId()); Log.i(TAG, "Device Name: " + uDevice.getDeviceName()); Log.i(TAG, "Vendor: ID " + uDevice.getVendorId()); Log.i(TAG, "Product ID: " + uDevice.getProductId()); DeviceEntry devEntry = new DeviceEntry(); devEntry.deviceDescription = devInfo.getDescription() + " @ " + uDevice.getDeviceName(); devEntry.deviceName = uDevice.getDeviceName() + ":" + devInfo.getVendorID() + ":" + devInfo.getProductID(); validStreamingDeviceList.add(devEntry); } } } return validStreamingDeviceList; } } }