Commit 011b586c authored by Schoumi's avatar Schoumi

Enhance flow for flashing

Add Browse repository capacity
Fixes #10 #4
parent 12b8fc36
......@@ -28,6 +28,7 @@ import android.widget.TextView;
import java.util.List;
import fr.mobdev.lpcprog.R;
import fr.mobdev.lpcprog.fragment.BrowseDeviceFragment;
import fr.mobdev.lpcprog.objects.USBDevice;
/*
......@@ -35,15 +36,25 @@ import fr.mobdev.lpcprog.objects.USBDevice;
*/
public class DeviceAdapter extends RecyclerView.Adapter<DeviceHolder> {
BrowseDeviceFragment.BrowseDeviceListener listener;
private List<USBDevice> devices;
public DeviceAdapter(List<USBDevice> devices){
public DeviceAdapter(List<USBDevice> devices, BrowseDeviceFragment.BrowseDeviceListener listener){
this.devices = devices;
this.listener = listener;
}
@Override
public DeviceHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.device_item,parent,false);
return new DeviceHolder(view);
final DeviceHolder holder = new DeviceHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onDeviceClick(holder.usbDevice);
}
});
return holder;
}
@Override
......@@ -59,6 +70,7 @@ public class DeviceAdapter extends RecyclerView.Adapter<DeviceHolder> {
class DeviceHolder extends RecyclerView.ViewHolder {
USBDevice usbDevice;
DeviceHolder(View itemView) {
super(itemView);
......@@ -66,11 +78,12 @@ class DeviceHolder extends RecyclerView.ViewHolder {
@SuppressLint("SetTextI18n")
void setupDevice(USBDevice device){
TextView name = (TextView) itemView.findViewById(R.id.device_name);
usbDevice = device;
TextView name = itemView.findViewById(R.id.device_name);
name.setText(itemView.getContext().getString(R.string.dev_name) + device.description);
TextView vendor = (TextView) itemView.findViewById(R.id.device_vendor_id);
TextView vendor = itemView.findViewById(R.id.device_vendor_id);
vendor.setText(itemView.getContext().getString(R.string.vendor_id)+String.format("%04x",device.VID));
TextView product = (TextView) itemView.findViewById(R.id.device_id);
TextView product = itemView.findViewById(R.id.device_id);
product.setText(itemView.getContext().getString(R.string.product_id)+String.format("%04x", device.PID));
}
......
......@@ -18,9 +18,9 @@
package fr.mobdev.lpcprog.fragment;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
......
......@@ -18,14 +18,12 @@
package fr.mobdev.lpcprog.fragment;
import android.content.Context;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
......@@ -39,18 +37,20 @@ import fr.mobdev.lpcprog.managers.UsbCommManager;
/*
Fragment use to display USB device plugged through OTG port
*/
public class USBListFragment extends Fragment {
public class BrowseDeviceFragment extends Fragment {
private List<USBDevice> devices;
private USBInteractionListener listener;
private BrowseDeviceListener listener;
private UsbCommManager comm;
public USBListFragment() {
public BrowseDeviceFragment() {
}
public static USBListFragment newInstance() {
return new USBListFragment();
public static BrowseDeviceFragment newInstance(BrowseDeviceListener browseDeviceListener) {
BrowseDeviceFragment fragment = new BrowseDeviceFragment();
fragment.setBrowseDeviceListener(browseDeviceListener);
return fragment;
}
......@@ -61,30 +61,16 @@ public class USBListFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.usb_list,container,false);
final View v = inflater.inflate(R.layout.usb_list,container,false);
RecyclerView list = v.findViewById(R.id.device_list);
list.setLayoutManager(new LinearLayoutManager(getActivity()));
comm = UsbCommManager.getInstance(getActivity());
final GestureDetector gestureDetector = new GestureDetector(getActivity(), new GestureDetector.SimpleOnGestureListener(){
SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.swipe_refresh);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public boolean onSingleTapUp(MotionEvent e){
return true;
}
});
RecyclerView view = (RecyclerView) v.findViewById(R.id.device_list);
view.setLayoutManager(new LinearLayoutManager(getContext()));
view.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e){
View v = view.findChildViewUnder(e.getX(), e.getY());
if(v != null && gestureDetector.onTouchEvent(e)){
int pos = view.getChildAdapterPosition(v);
onItemClick(pos);
return true;
}
return false;
public void onRefresh() {
updateDevice(v);
}
});
updateDevice(v);
......@@ -96,31 +82,18 @@ public class USBListFragment extends Fragment {
if(v == null)
v = getView();
assert v != null;
DeviceAdapter adapter = new DeviceAdapter(devices);
RecyclerView view = (RecyclerView) v.findViewById(R.id.device_list);
DeviceAdapter adapter = new DeviceAdapter(devices,listener);
RecyclerView view = v.findViewById(R.id.device_list);
view.setAdapter(adapter);
SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.swipe_refresh);
swipeRefresh.setRefreshing(false);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (USBInteractionListener) context;
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
private void onItemClick(int pos){
if(devices.size()>pos){
listener.onUSBDeviceClick(devices.get(pos));
}
public void setBrowseDeviceListener(BrowseDeviceListener browseDeviceListener) {
listener = browseDeviceListener;
}
public interface USBInteractionListener {
void onUSBDeviceClick(USBDevice device);
public interface BrowseDeviceListener {
void onDeviceClick(USBDevice device);
}
}
package fr.mobdev.lpcprog.fragment;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import java.util.ArrayList;
import java.util.List;
import fr.mobdev.lpcprog.R;
import fr.mobdev.lpcprog.adapters.BinariesAdapter;
import fr.mobdev.lpcprog.listener.NetworkListener;
import fr.mobdev.lpcprog.managers.DatabaseManager;
import fr.mobdev.lpcprog.managers.NetworkManager;
import fr.mobdev.lpcprog.objects.Binary;
import fr.mobdev.lpcprog.objects.Server;
public class BrowseRepositoryFragment extends Fragment {
private BrowseRepositoryListener browseListener;
private List<Server> servers;
public static BrowseRepositoryFragment newInstance(BrowseRepositoryListener browseRepositoryListener) {
BrowseRepositoryFragment fragment = new BrowseRepositoryFragment();
fragment.setBrowseRepositoryListener(browseRepositoryListener);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
servers = new ArrayList<>();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.repository,container,false);
RecyclerView list = v.findViewById(R.id.bin_list);
list.setLayoutManager(new LinearLayoutManager(getActivity()));
SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.swipe_refresh);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
updateRepositories(v);
}
});
return v;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
updateRepositories(view);
}
public void setBrowseRepositoryListener(BrowseRepositoryListener browseRepositoryListener) {
browseListener = browseRepositoryListener;
}
public void updateRepositories(View view){
if(view == null)
view = getView();
final View v = view;
assert v != null;
servers.clear();
final NetworkListener listener = new NetworkListener() {
@Override
public void startBinaries() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.swipe_refresh);
swipeRefresh.setRefreshing(true);
}
});
}
@Override
public void startServer(Server server) {
}
@Override
public void endServer(Server server) {
if(!server.binaries.isEmpty())
servers.add(server);
}
@Override
public void endBinaries() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
RecyclerView list = v.findViewById(R.id.bin_list);
BinariesAdapter adapter = new BinariesAdapter(servers,browseListener);
list.setAdapter(adapter);
SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.swipe_refresh);
swipeRefresh.setRefreshing(false);
}
});
}
@Override
public void onError(final String error) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
final Snackbar msg = Snackbar.make(v.findViewById(R.id.swipe_refresh), error,Snackbar.LENGTH_LONG);
msg.show();
List<List<Server>> localServers = DatabaseManager.getInstance(getActivity()).getServers(getActivity());
servers.addAll(localServers.get(0));
servers.addAll(localServers.get(1));
servers.addAll(localServers.get(2));
RecyclerView list = v.findViewById(R.id.bin_list);
BinariesAdapter adapter = new BinariesAdapter(servers,browseListener);
list.setAdapter(adapter);
SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.swipe_refresh);
swipeRefresh.setRefreshing(false);
}
});
}
};
NetworkManager.getInstance(listener).browseBinaries(getActivity());
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if(servers != null)
updateRepositories(null);
}
public interface BrowseRepositoryListener {
void onBinaryClick(Server server, Binary binary);
}
}
/*
* Copyright (C) 2017 Anthony Chomienne, anthony@mob-dev.fr
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.mobdev.lpcprog.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import fr.mobdev.lpcprog.R;
/*
Main Fragment that Handle navigation threw device or repository in the Flashing Flow
*/
public class HomeFragment extends Fragment{
private HomeListener homeListener;
public static HomeFragment newInstance(HomeListener listener) {
HomeFragment fragment = new HomeFragment();
fragment.setHomeListener(listener);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.home, container, false);
Button bt = v.findViewById(R.id.browse_repo);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
homeListener.onBrowseRepositoryClick();
}
});
bt = v.findViewById(R.id.browse_device);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
homeListener.onBrowseDeviceClick();
}
});
return v;
}
public void setHomeListener(HomeListener homeListener) {
this.homeListener = homeListener;
}
public interface HomeListener {
void onBrowseRepositoryClick();
void onBrowseDeviceClick();
}
}
......@@ -18,8 +18,8 @@
package fr.mobdev.lpcprog.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
......
......@@ -18,8 +18,8 @@
package fr.mobdev.lpcprog.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
......
......@@ -28,7 +28,6 @@ import fr.mobdev.lpcprog.objects.Server;
*/
public interface DownloadListener extends EventListener {
void downloadCanceled(Server server, Binary binary);
void downloadSuccessful(Server server, Binary binary);
void downloadError(Server server, Binary binary, String string);
void progress(Server server, Binary binary, int progress);
......
......@@ -29,5 +29,5 @@ public interface FlashListener extends EventListener{
void onStartFlash();
void onSuccess();
void onProgress(int step, int endStep, int progress, int step_res_id);
void onError(String string, ImageView imageView);
void onError(String string);
}
......@@ -205,90 +205,90 @@ public class IspManager {
return version;
}
public int flashBinary(Server server, Binary binary, FlashListener listener, ImageView flashView) {
public int flashBinary(Server server, Binary binary, FlashListener listener) {
Part parts = DatabaseManager.getInstance(context).getPart(part_id);
listener.onStartFlash();
if(parts == null) {
listener.onError(context.getString(R.string.parts_missing),flashView);
listener.onError(context.getString(R.string.parts_missing));
return -1;
}
int sector_size = parts.flash_size / parts.flash_nb_sectors;
long ram_addr = parts.ram_base_addr + parts.ram_buffer_offset;
boolean uuencode = parts.uuencode;
byte data[];
listener.onProgress(1,5,100,R.string.sanity_check);
listener.onProgress(1,6,100,R.string.sanity_check);
//Sanity Checks
if (ram_addr > parts.ram_base_addr + parts.ram_size) {
listener.onError(context.getString(R.string.buffer_out_ram),flashView);
listener.onError(context.getString(R.string.buffer_out_ram));
return -2;
}
long write_size = calcWriteSize(sector_size, parts.ram_buffer_size);
if (write_size == 0) {
listener.onError(context.getString(R.string.block_size_null),flashView);
listener.onError(context.getString(R.string.block_size_null));
return -3;
}
listener.onProgress(2,5,0,R.string.erase_flash);
listener.onProgress(2,6,0,R.string.erase_flash);
int ret = eraseFlash(parts,listener);
if (ret != 0) {
listener.onError(context.getString(R.string.cant_erase_flash),flashView);
listener.onError(context.getString(R.string.cant_erase_flash));
return -4;
}
listener.onProgress(3,5,0,R.string.read_file);
listener.onProgress(3,6,0,R.string.read_file);
data = new byte[parts.flash_size];
//copy file buffer to data array
File file = new File(context.getApplicationInfo().dataDir + "/" + server.id + "/" + binary.path + binary.filename);
int size = copy_buffer(file, data, parts.flash_size);
if (size <= 0) {
listener.onError(context.getString(R.string.copy_file),flashView);
listener.onError(context.getString(R.string.copy_file));
return -5;
}
listener.onProgress(3,5,100,R.string.read_file);
listener.onProgress(3,6,100,R.string.read_file);
fill_data_with_0(data, size, parts.flash_size);
int cksum = calc_binary_checksum(data);
setChecksum(data, 28, cksum);
listener.onProgress(1,2,0,R.string.verify_checksum);
listener.onProgress(4,6,0,R.string.verify_checksum);
if(!verifyChecksum(data,cksum)) {
listener.onError(context.getString(R.string.checksum_failed),flashView);
listener.onError(context.getString(R.string.checksum_failed));
return -6;
}
listener.onProgress(1,2,100,R.string.verify_checksum);
listener.onProgress(4,6,100,R.string.verify_checksum);
long blocks = (size / write_size) + ((size % write_size == 0) ? 0 : 1);
if (blocks * write_size > parts.flash_size) {
listener.onError(context.getString(R.string.flash_outside_end),flashView);
listener.onError(context.getString(R.string.flash_outside_end));
}
listener.onProgress(4,5,0,R.string.write_to_flash);
listener.onProgress(5,6,0,R.string.write_to_flash);
for(int i = 0; i < blocks; i++){
listener.onProgress(4,5,(int)(i*100/blocks),R.string.write_to_flash);
listener.onProgress(5,6,(int)(i*100/blocks),R.string.write_to_flash);
int current_sector = (int)(i*write_size)/sector_size;
int flash_addr = (int)(parts.flash_base_addr + (i*write_size));
//prepare-for-write
ret = send_cmd_sectors('P',current_sector,current_sector);
if(ret != 0){
listener.onError(context.getString(R.string.prepare_write_error)+" "+i,flashView);
listener.onError(context.getString(R.string.prepare_write_error)+" "+i);
return ret;
}
ret = send_buf_to_ram(data,(int)(i*write_size),(int)ram_addr,(int)write_size, uuencode);
if(ret != 0) {
listener.onError(context.getString(R.string.write_ram_error)+" "+i,flashView);
listener.onError(context.getString(R.string.write_ram_error)+" "+i);
return ret;
}
//write-to-ram
ret = send_cmd_address('C', flash_addr, (int)ram_addr, (int) write_size);
if(ret != 0){
listener.onError(context.getString(R.string.copy_to_flash_error)+" "+i,flashView);
listener.onError(context.getString(R.string.copy_to_flash_error)+" "+i);
return ret;
}
}
listener.onProgress(5,5,100,R.string.end_flash);
listener.onProgress(6,6,100,R.string.end_flash);
listener.onSuccess();
return ret;
......@@ -502,7 +502,7 @@ public class IspManager {
String str = new String(data,0,2);
str = str.replace("\r", "");
str = str.replace("\n", "");
if (!str.matches("[0-9 -+]*"))
if (!str.matches("[0-9 -+]*")||str.isEmpty())
return -1;
return Integer.parseInt(str);
}
......
......@@ -48,20 +48,15 @@ public class NetworkManager {
private NetworkListener listener;
private static NetworkManager instance;
private Context context;
private boolean downloadInProgress;
private List<Binary> cancelList;
private NetworkManager(NetworkListener listener, Context context)
private NetworkManager(NetworkListener listener)
{
this.listener = listener;
this.context = context;
cancelList = new ArrayList<>();
}
public static NetworkManager getInstance(NetworkListener listener, Context context){
public static NetworkManager getInstance(NetworkListener listener){
if (instance == null)
instance = new NetworkManager(listener,context);
instance = new NetworkManager(listener);
if(listener != null && listener != instance.getListener())
instance.setListener(listener);
return instance;
......@@ -77,12 +72,12 @@ public class NetworkManager {
this.listener = listener;
}
public void browseBinaries(){
public void browseBinaries(final Context context){
if(isConnectedToInternet(context)) {
new Thread(new Runnable() {
@Override
public void run() {
getBinariesList();
getBinariesList(context);
}
}).start();
}
......@@ -90,20 +85,20 @@ public class NetworkManager {
listener.onError(context.getString(R.string.network_error));
}
public void retrieveBinary(final Server server, final Binary binary, final DownloadListener downloadListener){
public void retrieveBinary(final Context context, final Server server, final Binary binary, final DownloadListener downloadListener){
if(isConnectedToInternet(context)){
new Thread(new Runnable() {
@Override
public void run() {
getBinary(server, binary,downloadListener);
getBinary(context,server, binary,downloadListener);
}
}).start();
}
else
this.listener.onError(context.getString(R.string.network_error));
downloadListener.downloadError(server,binary,context.getString(R.string.network_error));
}
private void getBinariesList(){
private void getBinariesList(Context context){
List<List<Server>> servers = DatabaseManager.getInstance(context).getServers(context);
List<Server> serversAvailable = new ArrayList<>();
for(Server server : servers.get(0)){
......@@ -170,10 +165,9 @@ public class NetworkManager {
return b;
}
private void getBinary(Server server, Binary binary, DownloadListener downloadListener){
private void getBinary(Context context, Server server, Binary binary, DownloadListener downloadListener){
try {
URL url = new URL(server.url.toString() + binary.path + binary.filename);
downloadInProgress = true;
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
InputStream stream = connection.getInputStream();
......@@ -189,15 +183,6 @@ public class NetworkManager {
long totalSizeReaded = 0;
int sizeReaded ;
while((sizeReaded = stream.read(data)) != -1){
if(cancelList.contains(binary)) {
downloadInProgress = false;
downloadListener.downloadCanceled(server,binary);
stream.close();