/*
UVCDeviceListFragment.java
Copyright (c) 2015 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.deviceplugin.uvc.fragment;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import org.deviceconnect.android.deviceplugin.uvc.R;
import org.deviceconnect.android.deviceplugin.uvc.core.UVCDevice;
import org.deviceconnect.android.deviceplugin.uvc.UVCDeviceApplication;
import org.deviceconnect.android.deviceplugin.uvc.core.UVCDeviceManager;
import org.deviceconnect.android.deviceplugin.uvc.fragment.dialog.ErrorDialogFragment;
import org.deviceconnect.android.deviceplugin.uvc.fragment.dialog.ProgressDialogFragment;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Logger;
import static org.deviceconnect.android.deviceplugin.uvc.core.UVCDeviceManager.ConnectionListener;
import static org.deviceconnect.android.deviceplugin.uvc.core.UVCDeviceManager.DiscoveryListener;
public class UVCDeviceListFragment extends Fragment {
/**
* Adapter.
*/
private DeviceAdapter mDeviceAdapter;
/**
* Error Dialog.
*/
private ErrorDialogFragment mErrorDialogFragment;
/**
* Progress Dialog.
*/
private ProgressDialogFragment mProgressDialogFragment;
/**
* UVC device list view.
*/
private ListView mListView;
/**
* Footer view.
*/
private View mFooterView;
/**
* Logger.
*/
private final Logger mLogger = Logger.getLogger("uvc.dplugin");
/**
* Executor.
*/
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
mDeviceAdapter = new DeviceAdapter(getActivity(), createDeviceContainers());
mFooterView = inflater.inflate(R.layout.item_uvc_error, null);
View rootView = inflater.inflate(R.layout.fragment_uvc_device_list, null);
mListView = (ListView) rootView.findViewById(R.id.device_list_view);
mListView.setAdapter(mDeviceAdapter);
mListView.setItemsCanFocus(true);
return rootView;
}
@Override
public void onResume() {
super.onResume();
addFooterView();
getManager().startScan();
getManager().addConnectionListener(mConnectionListener);
getManager().addDiscoveryListener(mDiscoverListener);
}
@Override
public void onPause() {
super.onPause();
getManager().removeConnectionListener(mConnectionListener);
getManager().removeDiscoveryListener(mDiscoverListener);
getManager().stopScan();
dismissProgressDialog();
dismissErrorDialog();
}
/**
* Added the view at ListView.
*/
private void addFooterView() {
final Activity activity = getActivity();
if (activity == null) {
return;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
UVCDeviceManager mgr = getManager();
if (mgr == null) {
return;
}
LayoutInflater inflater = activity.getLayoutInflater();
if (mFooterView != null) {
mListView.removeFooterView(mFooterView);
}
if (mgr.getDeviceList().size() == 0) {
mFooterView = inflater.inflate(R.layout.item_uvc_error, null);
mListView.addFooterView(mFooterView);
}
}
});
}
/**
* Connect to the UVC device that have heart rate service.
*
* @param device UVC device that have heart rate service.
*/
private void connectDevice(final DeviceContainer device) {
showProgressDialog(device.getName());
mExecutor.execute(new Runnable() {
@Override
public void run() {
getManager().connectDevice(device.getId());
}
});
}
/**
* Disconnect to the UVC device that have heart rate service.
*
* @param device UVC device that have heart rate service.
*/
private void disconnectDevice(final DeviceContainer device) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
getManager().disconnectDevice(device.getId());
}
});
}
/**
* Display the dialog of connecting a ble device.
*
* @param name device name
*/
private void showProgressDialog(final String name) {
dismissProgressDialog();
Resources res = getActivity().getResources();
String title = res.getString(R.string.uvc_settings_connecting_title);
String message = res.getString(R.string.uvc_settings_connecting_message, name);
mProgressDialogFragment = ProgressDialogFragment.newInstance(title, message);
mProgressDialogFragment.show(getFragmentManager(), "dialog");
}
/**
* Dismiss the dialog of connecting a ble device.
*/
private void dismissProgressDialog() {
if (mProgressDialogFragment != null) {
mProgressDialogFragment.dismiss();
mProgressDialogFragment = null;
}
}
/**
* Display the error dialog of not connect device.
*
* @param name device name
*/
private void showErrorDialogNotConnect(final String name) {
Resources res = getActivity().getResources();
String message;
if (name == null) {
message = res.getString(R.string.uvc_settings_dialog_error_message,
getString(R.string.uvc_settings_default_name));
} else {
message = res.getString(R.string.uvc_settings_dialog_error_message, name);
}
showErrorDialog(message);
}
/**
* Display the error dialog.
*
* @param message error message
*/
public void showErrorDialog(final String message) {
dismissErrorDialog();
Resources res = getActivity().getResources();
String title = res.getString(R.string.uvc_settings_dialog_error_title);
mErrorDialogFragment = ErrorDialogFragment.newInstance(title, message);
mErrorDialogFragment.show(getFragmentManager(), "error_dialog");
mErrorDialogFragment.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
mErrorDialogFragment = null;
}
});
}
/**
* Dismiss the error dialog.
*/
private void dismissErrorDialog() {
if (mErrorDialogFragment != null) {
mErrorDialogFragment.dismiss();
mErrorDialogFragment = null;
}
}
/**
* Gets a instance of UVCDeviceManager.
*
* @return UVCDeviceManager
*/
private UVCDeviceManager getManager() {
Activity activity = getActivity();
if (activity == null) {
return null;
}
UVCDeviceApplication application =
(UVCDeviceApplication) activity.getApplication();
return application.getDeviceManager();
}
private ConnectionListener mConnectionListener = new ConnectionListener() {
@Override
public void onConnect(final UVCDevice device) {
if (getActivity() == null) {
return;
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
DeviceContainer container = findDeviceContainerById(device.getId());
if (container != null) {
container.setRegisterFlag(true);
mDeviceAdapter.notifyDataSetChanged();
}
dismissProgressDialog();
}
});
}
@Override
public void onConnectionFailed(final UVCDevice device) {
if (getActivity() == null) {
return;
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
dismissProgressDialog();
showErrorDialogNotConnect(device.getName());
}
});
}
@Override
public void onDisconnect(final UVCDevice device) {
if (getActivity() == null) {
return;
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
DeviceContainer container = findDeviceContainerById(device.getId());
if (container != null) {
container.setRegisterFlag(false);
mDeviceAdapter.notifyDataSetChanged();
}
dismissProgressDialog();
}
});
}
};
private final DiscoveryListener mDiscoverListener = new DiscoveryListener() {
@Override
public void onDiscovery(final List<UVCDevice> devices) {
mLogger.info("Discovered devices: " + devices.size());
if (mDeviceAdapter == null) {
return;
}
if (getActivity() == null) {
return;
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mDeviceAdapter.clear();
mDeviceAdapter.addAll(createDeviceContainers());
mDeviceAdapter.notifyDataSetChanged();
addFooterView();
}
});
}
};
/**
* Create a list of device.
*
* @return list of device
*/
private List<DeviceContainer> createDeviceContainers() {
List<DeviceContainer> containers = new ArrayList<>();
List<UVCDevice> devices = getManager().getDeviceList();
for (UVCDevice device : devices) {
containers.add(createContainer(device, device.isInitialized()));
}
return containers;
}
/**
* Look for a DeviceContainer with the given id.
*
* @param id id of device
* @return The DeviceContainer that has the given id or null
*/
private DeviceContainer findDeviceContainerById(final String id) {
int size = mDeviceAdapter.getCount();
for (int i = 0; i < size; i++) {
DeviceContainer container = mDeviceAdapter.getItem(i);
if (container.getId().equalsIgnoreCase(id)) {
return container;
}
}
return null;
}
/**
* Create a DeviceContainer from UVCDevice.
*
* @param device Instance of UVCDevice
* @param register Registration flag
* @return Instance of DeviceContainer
*/
private DeviceContainer createContainer(final UVCDevice device, final boolean register) {
DeviceContainer container = new DeviceContainer();
container.setName(device.getName());
container.setId(device.getId());
container.setRegisterFlag(register);
return container;
}
private class DeviceContainer {
private String mName;
private String mId;
private boolean mRegisterFlag;
public String getName() {
return mName;
}
public void setName(final String name) {
if (name == null) {
mName = getActivity().getResources().getString(
R.string.uvc_settings_default_name);
} else {
mName = name;
}
}
public String getId() {
return mId;
}
public void setId(final String id) {
mId = id;
}
public boolean isRegisterFlag() {
return mRegisterFlag;
}
public void setRegisterFlag(boolean registerFlag) {
mRegisterFlag = registerFlag;
}
}
private class DeviceAdapter extends ArrayAdapter<DeviceContainer> {
private LayoutInflater mInflater;
public DeviceAdapter(final Context context, final List<DeviceContainer> objects) {
super(context, 0, objects);
mInflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_uvc_device, null);
}
final DeviceContainer device = getItem(position);
String name = device.getName();
TextView nameView = (TextView) convertView.findViewById(R.id.device_name);
nameView.setText(name);
Button btn = (Button) convertView.findViewById(R.id.btn_connect_device);
if (device.isRegisterFlag()) {
btn.setBackgroundResource(R.drawable.button_red);
btn.setText(R.string.uvc_settings_disconnect);
} else {
btn.setBackgroundResource(R.drawable.button_blue);
btn.setText(R.string.uvc_settings_connect);
}
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
if (device.isRegisterFlag()) {
disconnectDevice(device);
} else {
connectDevice(device);
}
}
});
return convertView;
}
}
}