/*
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2014 Digi International Inc., All Rights Reserved.
*/
package com.digi.android.wva.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragment;
import com.digi.android.wva.BuildConfig;
import com.digi.android.wva.R;
import com.digi.android.wva.WvaApplication;
import com.digi.android.wva.adapters.FaultCodesAdapter;
import com.digi.wva.WVA;
import com.digi.wva.async.FaultCodeCommon;
import com.digi.wva.async.WvaCallback;
import com.digi.wva.exc.WvaHttpException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class FaultCodeBrowsingFragment extends SherlockFragment implements FaultCodesAdapter.OnCanBusRefreshListener {
private ExpandableListView listView;
private FaultCodesAdapter adapter;
private WVA device;
private static final String TAG = "WVA Demo FCBFragment";
public static interface FaultCodeEcuSelectedListener {
public void onSelect(FaultCodeCommon.Bus bus, String ecu);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Hold onto this instance of the fragment
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fault_code_browse_fragment, null);
listView = (ExpandableListView) v.findViewById(R.id.expandableList);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (adapter == null) {
// The fragment is being created for the first time, so we need to instantiate an
// adapter as well.
Activity holdingActivity = getActivity();
adapter = new FaultCodesAdapter(holdingActivity, this, (WvaApplication)holdingActivity.getApplication());
// Add each bus known to the library into the adapter.
for (FaultCodeCommon.Bus canbus : FaultCodeCommon.Bus.values()) {
adapter.putGroup(canbus.toString().toUpperCase(), new ArrayList<String>());
}
}
this.device = ((WvaApplication) getActivity().getApplication()).getDevice();
listView.setAdapter(adapter);
// Call back into the activity when the user picks an ECU to look at
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView expandableListView, View view, int groupPosition, int childPosition, long id) {
if (BuildConfig.DEBUG) {
if (!(getActivity() instanceof FaultCodeEcuSelectedListener))
throw new AssertionError("FaultCodeBrowsingFragment - activity doesn't implement FaultCodeEcuSelectedListener");
}
((FaultCodeEcuSelectedListener)getActivity()).onSelect(adapter.getBusFromGroupPosition(groupPosition), (String)view.getTag());
return true;
}
});
// Load the ECU name list when the group is expanded for the first time (or there were no
// ECUs the last time we checked)
listView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView expandableListView, View view, int groupPosition, long id) {
// isGroupExpanded will return the state of the group BEFORE taking this click into account.
boolean isClosing = listView.isGroupExpanded(groupPosition);
if (isClosing) {
return false;
}
if (adapter.getActualChildrenCount(groupPosition) == 0) {
// No ECUs currently. Let's automatically refresh that list.
onRefresh((FaultCodeCommon.Bus) view.getTag(), view);
}
return false;
}
});
}
@Override
public void onRefresh(final FaultCodeCommon.Bus bus, final View headerView) {
final String busName = bus.toString().toUpperCase();
if (adapter.refreshingBuses.contains(bus)) {
Log.d(TAG, "Already refreshing " + busName);
return;
}
// Keep track that we're refreshing this bus's ECU list, so that the adapter can represent it
// correctly on screen rotation, etc.
adapter.refreshingBuses.add(bus);
// Hide the button, show the progress indicator
adapter.setRefreshState(headerView, true);
device.fetchFaultCodeEcuNames(bus, new WvaCallback<Set<String>>() {
@Override
public void onResponse(Throwable error, Set<String> names) {
if (error != null) {
String err;
if (error instanceof WvaHttpException.WvaHttpNotFound) {
Log.w(TAG, "404 error in fetchFaultCodeEcuNames");
err = "404 error fetching ECUs. Ensure your device is running firmware with support for fault codes.";
} else {
error.printStackTrace();
err = String.format("Error fetching %s ECUs: %s", busName, error.getMessage());
}
Toast.makeText(getActivity(), err, Toast.LENGTH_SHORT).show();
} else {
List<String> nameList = new ArrayList<String>(names);
Collections.sort(nameList);
adapter.putGroup(busName, nameList);
Log.i(TAG, String.format("Found %d ECUs on %s", names.size(), busName));
}
adapter.setRefreshState(headerView, false);
adapter.notifyDataSetChanged();
adapter.refreshingBuses.remove(bus);
}
});
}
}