From 4f923003a7a0a168e799e3bb50a28674eba5b17e Mon Sep 17 00:00:00 2001 From: Schoumi Date: Tue, 1 Nov 2016 17:30:20 +0100 Subject: [PATCH] App V1 Add Parts Feedback during flash and erros Better handle of the plug/unplug usb device Icon Launcher Better User Experience --- app/build.gradle | 16 +- app/src/main/AndroidManifest.xml | 17 +- .../lpcprog/activity/DeviceActivity.java | 218 ----------- .../mobdev/lpcprog/activity/MainActivity.java | 245 +++++++++--- .../lpcprog/adapters/BinariesAdapter.java | 36 +- .../lpcprog/adapters/DeviceAdapter.java | 12 +- .../mobdev/lpcprog/adapters/PartsAdapter.java | 116 ++++++ .../lpcprog/adapters/ServerAdapter.java | 21 +- .../mobdev/lpcprog/dialog/ServerDialog.java | 10 +- .../lpcprog/fragment/AddPartFragment.java | 273 +++++++++++++ .../lpcprog/fragment/DeviceFragment.java | 360 ++++++++++++++++++ .../lpcprog/fragment/PartsFragment.java | 81 ++++ .../ServersFragment.java} | 73 ++-- .../lpcprog/fragment/USBListFragment.java | 125 ++++++ .../fr/mobdev/lpcprog/fragment/Watcher.java | 80 ++++ .../lpcprog/listener/FlashListener.java | 8 +- .../lpcprog/listener/NetworkListener.java | 1 - .../lpcprog/managers/DatabaseManager.java | 153 +++++++- .../mobdev/lpcprog/managers/IspManager.java | 47 ++- .../lpcprog/managers/NetworkManager.java | 15 +- .../lpcprog/managers/UsbCommManager.java | 2 +- .../lpcprog/objects/{Parts.java => Part.java} | 2 +- app/src/main/res/drawable-hdpi/edit.png | Bin 0 -> 805 bytes .../main/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 1109 bytes app/src/main/res/drawable-mdpi/edit.png | Bin 0 -> 648 bytes .../main/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 909 bytes app/src/main/res/drawable-xhdpi/edit.png | Bin 0 -> 940 bytes .../main/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 990 bytes app/src/main/res/drawable-xxhdpi/edit.png | Bin 0 -> 1675 bytes .../main/res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 1439 bytes .../main/res/drawable-xxxhdpi/ic_launcher.png | Bin 0 -> 1270 bytes app/src/main/res/drawable/border_red.xml | 6 + app/src/main/res/drawable/side_nav_bar.xml | 9 + app/src/main/res/layout/add_part.xml | 253 ++++++++++++ app/src/main/res/layout/app_bar_main.xml | 30 ++ app/src/main/res/layout/binary_item.xml | 3 +- app/src/main/res/layout/content_main.xml | 15 + app/src/main/res/layout/device.xml | 124 +++--- app/src/main/res/layout/main.xml | 25 ++ app/src/main/res/layout/main_activity.xml | 33 -- app/src/main/res/layout/nav_header_main.xml | 21 + app/src/main/res/layout/part_item.xml | 33 ++ app/src/main/res/layout/parts.xml | 11 + app/src/main/res/layout/server_item.xml | 2 +- app/src/main/res/layout/server_section.xml | 5 +- app/src/main/res/layout/servers.xml | 50 +-- app/src/main/res/layout/usb_list.xml | 22 ++ app/src/main/res/menu/main_drawer.xml | 16 + app/src/main/res/menu/menu_main.xml | 9 +- app/src/main/res/menu/menu_servers.xml | 8 - app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3418 -> 0 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2206 -> 0 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4842 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 7718 -> 0 bytes app/src/main/res/values-v21/styles.xml | 1 + app/src/main/res/values/dimens.xml | 4 + app/src/main/res/values/drawables.xml | 8 + app/src/main/res/values/strings.xml | 48 ++- app/src/main/res/values/styles.xml | 23 +- app/src/main/res/xml/device_filter.xml | 4 + build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 62 files changed, 2092 insertions(+), 588 deletions(-) delete mode 100644 app/src/main/java/fr/mobdev/lpcprog/activity/DeviceActivity.java create mode 100644 app/src/main/java/fr/mobdev/lpcprog/adapters/PartsAdapter.java create mode 100644 app/src/main/java/fr/mobdev/lpcprog/fragment/AddPartFragment.java create mode 100644 app/src/main/java/fr/mobdev/lpcprog/fragment/DeviceFragment.java create mode 100644 app/src/main/java/fr/mobdev/lpcprog/fragment/PartsFragment.java rename app/src/main/java/fr/mobdev/lpcprog/{activity/ServersActivity.java => fragment/ServersFragment.java} (63%) create mode 100644 app/src/main/java/fr/mobdev/lpcprog/fragment/USBListFragment.java create mode 100644 app/src/main/java/fr/mobdev/lpcprog/fragment/Watcher.java rename app/src/main/java/fr/mobdev/lpcprog/objects/{Parts.java => Part.java} (98%) create mode 100644 app/src/main/res/drawable-hdpi/edit.png create mode 100644 app/src/main/res/drawable-hdpi/ic_launcher.png create mode 100644 app/src/main/res/drawable-mdpi/edit.png create mode 100644 app/src/main/res/drawable-mdpi/ic_launcher.png create mode 100644 app/src/main/res/drawable-xhdpi/edit.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/drawable-xxhdpi/edit.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/drawable/border_red.xml create mode 100644 app/src/main/res/drawable/side_nav_bar.xml create mode 100644 app/src/main/res/layout/add_part.xml create mode 100644 app/src/main/res/layout/app_bar_main.xml create mode 100644 app/src/main/res/layout/content_main.xml create mode 100644 app/src/main/res/layout/main.xml delete mode 100644 app/src/main/res/layout/main_activity.xml create mode 100644 app/src/main/res/layout/nav_header_main.xml create mode 100644 app/src/main/res/layout/part_item.xml create mode 100644 app/src/main/res/layout/parts.xml create mode 100644 app/src/main/res/layout/usb_list.xml create mode 100644 app/src/main/res/menu/main_drawer.xml delete mode 100644 app/src/main/res/menu/menu_servers.xml delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/values-v21/styles.xml create mode 100644 app/src/main/res/values/drawables.xml create mode 100644 app/src/main/res/xml/device_filter.xml diff --git a/app/build.gradle b/app/build.gradle index 4cd354c..1225d4b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,13 +1,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 23 - buildToolsVersion "23.0.2" + compileSdkVersion 24 + buildToolsVersion "24.0.3" defaultConfig { applicationId "fr.mobdev.lpcprog" - minSdkVersion 12 - targetSdkVersion 23 + minSdkVersion 14 + targetSdkVersion 24 versionCode 1 versionName "1.0" } @@ -19,13 +19,13 @@ android { } } -repositories{ +repositories { maven { url "https://jitpack.io" } } dependencies { - compile 'com.android.support:appcompat-v7:23.1.1' - compile 'com.android.support:design:23.1.1' - //compile 'com.github.felHR85:UsbSerial:4.1.1' compile files('src/main/libs/d2xx.jar') + compile 'com.android.support:appcompat-v7:24.2.1' + compile 'com.android.support:design:24.2.1' + compile 'com.android.support:support-v4:24.2.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6de4084..81424fd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,17 +5,20 @@ - - + + + @@ -23,14 +26,6 @@ - - \ No newline at end of file diff --git a/app/src/main/java/fr/mobdev/lpcprog/activity/DeviceActivity.java b/app/src/main/java/fr/mobdev/lpcprog/activity/DeviceActivity.java deleted file mode 100644 index ef4671f..0000000 --- a/app/src/main/java/fr/mobdev/lpcprog/activity/DeviceActivity.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2016 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.activity; - -import android.annotation.SuppressLint; -import android.support.design.widget.Snackbar; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.Toolbar; -import android.view.View; -import android.widget.ProgressBar; -import android.widget.TextView; - -import java.util.ArrayList; -import java.util.List; - -import fr.mobdev.lpcprog.adapters.BinariesAdapter; -import fr.mobdev.lpcprog.listener.NetworkListener; -import fr.mobdev.lpcprog.managers.DatabaseManager; -import fr.mobdev.lpcprog.managers.IspManager; -import fr.mobdev.lpcprog.R; -import fr.mobdev.lpcprog.managers.NetworkManager; -import fr.mobdev.lpcprog.objects.Server; -import fr.mobdev.lpcprog.objects.USBDevice; -import fr.mobdev.lpcprog.managers.UsbCommManager; - -public class DeviceActivity extends AppCompatActivity { - - private UsbCommManager comm; - private USBDevice dev; - private List servers; - private long part_id; - - @Override - @SuppressLint("SetTextI18n") - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.device); - Toolbar toolbar = (Toolbar) findViewById(R.id.device_toolbar); - setSupportActionBar(toolbar); - servers = new ArrayList<>(); - comm = UsbCommManager.getInstance(this); - part_id = 0; - List devices = comm.getDevices(); - int pid = getIntent().getIntExtra("PID",-1); - int vid = getIntent().getIntExtra("VID",-1); - for(USBDevice device : devices){ - if(device.PID == pid && device.VID == vid){ - dev = device; - System.out.println("device found"); - break; - } - } - if(dev != null) { - TextView name = (TextView) findViewById(R.id.name); - name.setText(getApplicationContext().getString(R.string.dev_name)+ dev.description); - TextView vendor = (TextView) findViewById(R.id.vendor_id); - vendor.setText(String.format("Vendor Id: %04x", dev.VID)); - TextView product = (TextView) findViewById(R.id.id); - product.setText(String.format("Product id: %04x", dev.PID)); - } - doUsb(); - ProgressBar bar = (ProgressBar) findViewById(R.id.progress_browse); - bar.setVisibility(View.GONE); - - RecyclerView list = (RecyclerView) findViewById(R.id.bin_list); - list.setLayoutManager(new LinearLayoutManager(this)); - updateRepositories(); - } - - private void doUsb(){ - System.out.println("doUsb"); - new Thread(new Runnable() { - @Override - public void run() { - boolean conn = comm.openConnection(dev); - IspManager manager = IspManager.getInstance(DeviceActivity.this); - String uidStr = "No UID Found or error"; - String bootStr = "No Boot Version Found or error"; - String partidStr = "No Part ID Found or error"; - if(conn && manager.setupDevice(dev, 115200)) { - if(!manager.synchronizeIfPossible(10000)) { - System.out.println("Sync failed :("); - return; - } - String[] version = manager.readBootVersion(); - String partid = manager.readPartId(); - String[] uids = manager.readUid(); - if (uids != null) { - uidStr = String.format("UID: %08x - %08x - %08x - %08x",Long.parseLong(uids[0]), - Long.parseLong(uids[1]), - Long.parseLong(uids[2]), - Long.parseLong(uids[3])); - } - if (version != null) { - bootStr = "Boot Version: " + version[0] + "." + version[1]; - } - if(partid != null){ - partidStr = String.format("Part Id %08x",Long.parseLong(partid)); - part_id = Long.parseLong(partid); - IspManager.getInstance(DeviceActivity.this).setPartId(part_id); - } - } - updateIDS(uidStr,partidStr,bootStr); - - } - }).start(); - } - - private void updateIDS(final String uid, final String partid, final String boot) { - runOnUiThread(new Runnable() { - @Override - public void run() { - TextView view = (TextView) findViewById(R.id.uids); - view.setText(uid); - - view = (TextView) findViewById(R.id.part_id); - view.setText(partid); - - view = (TextView) findViewById(R.id.boot_version); - view.setText(boot); - } - }); - } - - private void updateRepositories(){ - System.out.println("Update Repo"); - NetworkListener listener = new NetworkListener() { - @Override - public void startBinaries() { - runOnUiThread(new Runnable() { - @Override - public void run() { - ProgressBar bar = (ProgressBar) findViewById(R.id.progress_browse); - bar.setVisibility(View.VISIBLE); - RecyclerView list = (RecyclerView) findViewById(R.id.bin_list); - list.setVisibility(View.GONE); - - } - }); - } - - @Override - public void startServer(Server server) { - } - - @Override - public void endServer(Server server) { - if(!server.binaries.isEmpty()) - servers.add(server); - } - - @Override - public void endBinaries() { - runOnUiThread(new Runnable() { - @Override - public void run() { - ProgressBar bar = (ProgressBar) findViewById(R.id.progress_browse); - bar.setVisibility(View.GONE); - RecyclerView list = (RecyclerView) findViewById(R.id.bin_list); - list.setVisibility(View.VISIBLE); - BinariesAdapter adapter = new BinariesAdapter(servers, DeviceActivity.this); - list.setAdapter(adapter); - } - }); - } - - @Override - public void onError(final String error) { - runOnUiThread(new Runnable() { - @Override - public void run() { - ProgressBar bar = (ProgressBar) findViewById(R.id.progress_browse); - bar.setVisibility(View.GONE); - final Snackbar msg = Snackbar.make(findViewById(R.id.bin_list), error,Snackbar.LENGTH_INDEFINITE); - msg.setAction(R.string.retry_browse, new View.OnClickListener() { - @Override - public void onClick(View v) { - msg.dismiss(); - updateRepositories(); - } - }); - msg.show(); - List> localServers = DatabaseManager.getInstance(DeviceActivity.this).getServers(); - servers.addAll(localServers.get(0)); - servers.addAll(localServers.get(1)); - servers.addAll(localServers.get(2)); - RecyclerView list = (RecyclerView) findViewById(R.id.bin_list); - list.setVisibility(View.VISIBLE); - BinariesAdapter adapter = new BinariesAdapter(servers,DeviceActivity.this); - list.setAdapter(adapter); - - } - }); - } - }; - NetworkManager.getInstance(listener,this).browseBinaries(); - - } -} diff --git a/app/src/main/java/fr/mobdev/lpcprog/activity/MainActivity.java b/app/src/main/java/fr/mobdev/lpcprog/activity/MainActivity.java index e141173..39e50cf 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/activity/MainActivity.java +++ b/app/src/main/java/fr/mobdev/lpcprog/activity/MainActivity.java @@ -18,103 +18,232 @@ package fr.mobdev.lpcprog.activity; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.design.widget.NavigationView; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; -import android.view.GestureDetector; import android.view.Menu; import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import java.util.List; - -import fr.mobdev.lpcprog.adapters.DeviceAdapter; import fr.mobdev.lpcprog.R; +import fr.mobdev.lpcprog.dialog.ServerDialog; +import fr.mobdev.lpcprog.fragment.AddPartFragment; +import fr.mobdev.lpcprog.fragment.DeviceFragment; +import fr.mobdev.lpcprog.fragment.PartsFragment; +import fr.mobdev.lpcprog.fragment.ServersFragment; +import fr.mobdev.lpcprog.fragment.USBListFragment; +import fr.mobdev.lpcprog.listener.ServerListener; import fr.mobdev.lpcprog.objects.USBDevice; -import fr.mobdev.lpcprog.managers.UsbCommManager; - -public class MainActivity extends AppCompatActivity { - - private UsbCommManager comm; - private List devices; - private int value = 0; +public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, + USBListFragment.USBInteractionListener, + AddPartFragment.OnAddInteractionListener +{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.main_activity); - Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar); + setContentView(R.layout.main); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); - comm = UsbCommManager.getInstance(this); - final GestureDetector gestureDetector = new GestureDetector(MainActivity.this, new GestureDetector.SimpleOnGestureListener(){ + DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + drawer.addDrawerListener(toggle); + toggle.syncState(); + + final FragmentManager manager = getSupportFragmentManager(); + FragmentTransaction transaction = manager.beginTransaction(); + Fragment frag = USBListFragment.newInstance(); + transaction.replace(R.id.fragment_container, frag); + transaction.commit(); + + IntentFilter filter = new IntentFilter("android.hardware.usb.action.USB_DEVICE_ATTACHED"); + filter.addAction("android.hardware.usb.action.USB_DEVICE_DETACHED"); + filter.addAction("com.ftdi.j2xx"); + registerReceiver(new BroadcastReceiver() { @Override - public boolean onSingleTapUp(MotionEvent e){ - return true; - } - }); - - RecyclerView view = (RecyclerView) findViewById(R.id.device_list); - view.setLayoutManager(new LinearLayoutManager(this)); - 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); - System.out.println("touch "+ ++value); - onItemClick(pos); - return true; + public void onReceive(Context context, Intent intent) { + Fragment fragment = manager.findFragmentById(R.id.fragment_container); + if(fragment instanceof USBListFragment) { + ((USBListFragment)fragment).updateDevice(null); } - return false; + else if(fragment instanceof DeviceFragment){ + manager.popBackStack(); + } + } - }); - updateList(); + },filter); + + NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(this); + } + + @Override + public void onBackPressed() { + DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + super.onBackPressed(); + updateMenu(null); + } + } + + private void updateMenu(Fragment frag) { + Toolbar bar = (Toolbar) findViewById(R.id.toolbar); + Menu menu = bar.getMenu(); + MenuItem add = menu.findItem(R.id.action_add_new); + MenuItem refresh = menu.findItem(R.id.action_refresh); + if(frag == null) { + FragmentManager manager = getSupportFragmentManager(); + frag = manager.findFragmentById(R.id.fragment_container); + } + if(frag instanceof USBListFragment || frag instanceof DeviceFragment) { + add.setVisible(false); + refresh.setVisible(true); + } else if(frag instanceof PartsFragment || frag instanceof ServersFragment) { + add.setVisible(true); + refresh.setVisible(false); + } else { + add.setVisible(false); + refresh.setVisible(false); + } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); + updateMenu(null); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); + FragmentManager manager = getSupportFragmentManager(); + final Fragment frag = manager.findFragmentById(R.id.fragment_container); if (id == R.id.action_refresh) { - updateList(); - return true; - } - else if(id == R.id.action_server){ - Intent newIntent = new Intent(this,ServersActivity.class); - startActivity(newIntent); - } + if(frag instanceof USBListFragment) { + ((USBListFragment) frag).updateDevice(null); + } else if (frag instanceof DeviceFragment) { + ((DeviceFragment) frag).updateRepositories(null); + } + } else if (id == R.id.action_add_new) { + if(frag instanceof ServersFragment) { + + ServerDialog serverDialog = new ServerDialog(); + serverDialog.setServerListener(new ServerListener() { + @Override + public void updateServerList() { + ((ServersFragment) frag).updateServers(null); + } + }); + serverDialog.show(getSupportFragmentManager(),"Server Dialog"); + } else if(frag instanceof PartsFragment) { + FragmentTransaction transaction = manager.beginTransaction(); + Fragment fragment = AddPartFragment.newInstance(-1); + transaction.replace(R.id.fragment_container, fragment); + transaction.addToBackStack(null); + transaction.commit(); + updateMenu(fragment); + } + + } return super.onOptionsItemSelected(item); } - private void updateList(){ - devices = comm.getDevices(); - DeviceAdapter adapter = new DeviceAdapter(devices); - RecyclerView view = (RecyclerView) findViewById(R.id.device_list); - view.setAdapter(adapter); + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + int id = item.getItemId(); + Fragment frag = null; + final FragmentManager manager = getSupportFragmentManager(); + final FragmentTransaction transaction = manager.beginTransaction(); + final Fragment old = manager.findFragmentById(R.id.fragment_container); + if(id == R.id.nav_devices) { + if(!(old instanceof USBListFragment)) { + frag = USBListFragment.newInstance(); + transaction.replace(R.id.fragment_container, frag); + transaction.addToBackStack(null); + transaction.commit(); + } + } else if (id == R.id.nav_servers) { + if(!(old instanceof ServersFragment)) { + frag = ServersFragment.newInstance(); + transaction.replace(R.id.fragment_container, frag); + transaction.addToBackStack(null); + transaction.commit(); + } + } else if (id == R.id.nav_parts) { + if(!(old instanceof PartsFragment)) { + frag = PartsFragment.newInstance(); + final PartsFragment fragmentParts = (PartsFragment) frag; + fragmentParts.setOnEditPressListener(new PartsFragment.OnEditPressListener() { + + @Override + public void onEditPress(Long part_id) { + Fragment fragment = AddPartFragment.newInstance(part_id); + transaction.replace(R.id.fragment_container, fragment); + transaction.addToBackStack(null); + transaction.commit(); + fragmentParts.updateList(); + updateMenu(fragment); + + } + + @Override + public void onDeletePress() { + fragmentParts.updateList(); + } + }); + transaction.replace(R.id.fragment_container, frag); + transaction.addToBackStack(null); + transaction.commit(); + } + } + DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + drawer.closeDrawer(GravityCompat.START); + updateMenu(frag); + return true; + } + + @Override + public void onUSBDeviceClick(USBDevice device) { + FragmentManager manager = getSupportFragmentManager(); + FragmentTransaction transaction = manager.beginTransaction(); + Fragment frag = DeviceFragment.newInstance(device.PID,device.VID); + transaction.replace(R.id.fragment_container, frag); + transaction.addToBackStack(null); + transaction.commit(); + } + @Override + public void onCancel() { + onBackPressed(); + } - private void onItemClick(final int pos){ - if(devices.size()>pos){ - Intent intent = new Intent(this,DeviceActivity.class); - intent.putExtra("PID",devices.get(pos).PID); - intent.putExtra("VID",devices.get(pos).VID); - startActivity(intent); + @Override + public void onSubmit() { + onBackPressed(); + FragmentManager manager = getSupportFragmentManager(); + Fragment frag = manager.findFragmentById(R.id.fragment_container); + if(frag instanceof PartsFragment) { + ((PartsFragment)frag).updateList(); + updateMenu(frag); } } } diff --git a/app/src/main/java/fr/mobdev/lpcprog/adapters/BinariesAdapter.java b/app/src/main/java/fr/mobdev/lpcprog/adapters/BinariesAdapter.java index afd15a3..6745452 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/adapters/BinariesAdapter.java +++ b/app/src/main/java/fr/mobdev/lpcprog/adapters/BinariesAdapter.java @@ -18,6 +18,7 @@ package fr.mobdev.lpcprog.adapters; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.DialogInterface; import android.support.design.widget.Snackbar; @@ -51,10 +52,12 @@ public class BinariesAdapter extends RecyclerView.Adapter servers; private int count; private Activity activity; + private FlashListener listener; - public BinariesAdapter(List servers, Activity activity) { + public BinariesAdapter(List servers, Activity activity, FlashListener listener) { this.servers = servers; this.activity = activity; + this.listener = listener; countElements(); } @@ -85,7 +88,7 @@ public class BinariesAdapter extends RecyclerView.Adapter { class DeviceHolder extends RecyclerView.ViewHolder { - public DeviceHolder(View itemView) { + DeviceHolder(View itemView) { super(itemView); } - public void setupDevice(USBDevice device){ + @SuppressLint("SetTextI18n") + void setupDevice(USBDevice device){ TextView name = (TextView) itemView.findViewById(R.id.device_name); - name.setText("Name: " + device.description); + name.setText(itemView.getContext().getString(R.string.dev_name) + device.description); TextView vendor = (TextView) itemView.findViewById(R.id.device_vendor_id); - vendor.setText(String.format("Vendor Id: %04x",device.VID)); + vendor.setText(itemView.getContext().getString(R.string.vendor_id)+String.format("%04x",device.VID)); TextView product = (TextView) itemView.findViewById(R.id.device_id); - product.setText(String.format("Product id: %04x", device.PID)); + product.setText(itemView.getContext().getString(R.string.product_id)+String.format("%04x", device.PID)); } diff --git a/app/src/main/java/fr/mobdev/lpcprog/adapters/PartsAdapter.java b/app/src/main/java/fr/mobdev/lpcprog/adapters/PartsAdapter.java new file mode 100644 index 0000000..ad62732 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/adapters/PartsAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2016 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.adapters; + +import android.content.DialogInterface; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.List; + +import fr.mobdev.lpcprog.R; +import fr.mobdev.lpcprog.fragment.PartsFragment; +import fr.mobdev.lpcprog.managers.DatabaseManager; +import fr.mobdev.lpcprog.objects.Part; + +public class PartsAdapter extends RecyclerView.Adapter{ + + private List parts; + private PartsFragment.OnEditPressListener listener; + + public PartsAdapter(List devices, PartsFragment.OnEditPressListener listener){ + this.parts = devices; + this.listener = listener; + } + + @Override + public PartHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.part_item,parent,false); + return new PartHolder(view,listener); + } + + @Override + public void onBindViewHolder(PartHolder holder, int position) { + holder.setupPart(parts.get(position)); + } + + @Override + public int getItemCount() { + return parts.size(); + } +} + +class PartHolder extends RecyclerView.ViewHolder { + + private PartsFragment.OnEditPressListener listener; + + PartHolder(View itemView, PartsFragment.OnEditPressListener listener) { + super(itemView); + this.listener = listener; + } + + void setupPart(final Part part){ + TextView name = (TextView) itemView.findViewById(R.id.part_name); + name.setText(part.part_name); + ImageView deleteView = (ImageView) itemView.findViewById(R.id.part_delete); + deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + AlertDialog.Builder builder = new AlertDialog.Builder(itemView.getContext()); + builder.setMessage(itemView.getContext().getString(R.string.delete_part_message)+" "+part.part_name) + .setCancelable(false) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + //delete server from database and update the view + DatabaseManager.getInstance(itemView.getContext()).deletePart(part.id); + listener.onDeletePress(); + } + }) + .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + final AlertDialog alert = builder.create(); + alert.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogInterface) { + alert.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(0xFF000000); + alert.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(0xFF000000); + } + }); + alert.show(); + } + }); + + ImageView editView = (ImageView) itemView.findViewById(R.id.part_edit); + editView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + listener.onEditPress(part.part_id); + } + }); + } +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/adapters/ServerAdapter.java b/app/src/main/java/fr/mobdev/lpcprog/adapters/ServerAdapter.java index 4f0f9d9..76a2d95 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/adapters/ServerAdapter.java +++ b/app/src/main/java/fr/mobdev/lpcprog/adapters/ServerAdapter.java @@ -90,6 +90,7 @@ public class ServerAdapter extends RecyclerView.Adapter } } count = size; + System.out.println("get count"+count); } private int getRealPosition(int fakePosition) { @@ -123,6 +124,7 @@ public class ServerAdapter extends RecyclerView.Adapter @Override public int getItemCount() { + System.out.println("get count"+count); return count; } @@ -141,13 +143,13 @@ public class ServerAdapter extends RecyclerView.Adapter } class ServerHolder extends RecyclerView.ViewHolder{ - ServerListener serverListener; - public ServerHolder(View itemView, ServerListener serverListener) { + private ServerListener serverListener; + ServerHolder(View itemView, ServerListener serverListener) { super(itemView); this.serverListener = serverListener; } - public void setupServer(final Server server){ + void setupServer(final Server server){ TextView view = (TextView) itemView.findViewById(R.id.server_name); view.setText(server.url.toString()); ImageView deleteView = (ImageView) itemView.findViewById(R.id.server_delete); @@ -170,7 +172,14 @@ class ServerHolder extends RecyclerView.ViewHolder{ dialog.cancel(); } }); - AlertDialog alert = builder.create(); + final AlertDialog alert = builder.create(); + alert.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogInterface) { + alert.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(0xFF000000); + alert.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(0xFF000000); + } + }); alert.show(); } }); @@ -179,11 +188,11 @@ class ServerHolder extends RecyclerView.ViewHolder{ class SectionHolder extends RecyclerView.ViewHolder { - public SectionHolder(View itemView) { + SectionHolder(View itemView) { super(itemView); } - public void setupSection(String sectionName) { + void setupSection(String sectionName) { TextView view = (TextView)itemView.findViewById(R.id.section_name); view.setText(sectionName); } diff --git a/app/src/main/java/fr/mobdev/lpcprog/dialog/ServerDialog.java b/app/src/main/java/fr/mobdev/lpcprog/dialog/ServerDialog.java index ee39594..6a267e7 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/dialog/ServerDialog.java +++ b/app/src/main/java/fr/mobdev/lpcprog/dialog/ServerDialog.java @@ -79,7 +79,15 @@ public class ServerDialog extends DialogFragment { dismiss(); } }); + final AlertDialog alert = builder.create(); + alert.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogInterface) { + alert.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(0xFF000000); + alert.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(0xFF000000); + } + }); - return builder.create(); + return alert; } } diff --git a/app/src/main/java/fr/mobdev/lpcprog/fragment/AddPartFragment.java b/app/src/main/java/fr/mobdev/lpcprog/fragment/AddPartFragment.java new file mode 100644 index 0000000..475900e --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/fragment/AddPartFragment.java @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2016 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.content.Context; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Spinner; + +import java.util.ArrayList; +import java.util.List; + +import fr.mobdev.lpcprog.R; +import fr.mobdev.lpcprog.managers.DatabaseManager; +import fr.mobdev.lpcprog.objects.Part; + +public class AddPartFragment extends Fragment { + + private Part part; + + private OnAddInteractionListener listener; + private List watchers; + + public AddPartFragment() { + // Required empty public constructor + } + + public static AddPartFragment newInstance(long part_id) { + AddPartFragment fragment = new AddPartFragment(); + Bundle args = new Bundle(); + args.putLong("part_id", part_id); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + long part_id = getArguments().getLong("part_id"); + if(part_id != -1) + part = DatabaseManager.getInstance(getActivity()).getPart(part_id); + else + part = null; + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + watchers = new ArrayList<>(); + final View v = inflater.inflate(R.layout.add_part, container, false); + EditText t = (EditText) v.findViewById(R.id.edit_part_id); + watchers.add(new HexaWatcher(t,this)); + t.setText(part != null ? "0x"+String.format("%08x",part.part_id).toUpperCase() : "0x"); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + t = (EditText) v.findViewById(R.id.edit_flash_base_addr); + watchers.add(new HexaWatcher(t,this)); + t.setText(part != null ? "0x"+String.format("%08x",part.flash_base_addr).toUpperCase() : "0x"); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + t = (EditText) v.findViewById(R.id.edit_flash_size); + watchers.add(new HexaWatcher(t,this)); + t.setText(part != null ? "0x"+String.format("%04x",part.flash_size).toUpperCase() : "0x"); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + t = (EditText) v.findViewById(R.id.edit_reset_vector_offset); + watchers.add(new HexaWatcher(t,this)); + t.setText(part != null ? "0x"+String.format("%02x",part.reset_vector_offset).toUpperCase() : "0x"); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + t = (EditText) v.findViewById(R.id.edit_ram_base_addr); + watchers.add(new HexaWatcher(t,this)); + t.setText(part != null ? "0x"+String.format("%08x",part.ram_base_addr).toUpperCase() : "0x"); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + t = (EditText) v.findViewById(R.id.edit_ram_size); + watchers.add(new HexaWatcher(t,this)); + t.setText(part != null ? "0x"+String.format("%04x",part.ram_size).toUpperCase() : "0x"); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + t = (EditText) v.findViewById(R.id.edit_ram_buf_offset); + watchers.add(new HexaWatcher(t,this)); + t.setText(part != null ? "0x"+String.format("%03x",part.ram_buffer_offset).toUpperCase() : "0x"); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + t = (EditText) v.findViewById(R.id.edit_ram_buf_size); + watchers.add(new HexaWatcher(t,this)); + t.setText(part != null ? "0x"+String.format("%03x",part.ram_buffer_size).toUpperCase() : "0x"); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + + t = (EditText) v.findViewById(R.id.edit_part_name); + watchers.add(new EmptyWatcher(t,this)); + t.setText(part != null ? part.part_name : ""); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + t = (EditText) v.findViewById(R.id.edit_flash_nb_sector); + watchers.add(new EmptyWatcher(t,this)); + t.setText(part != null ? String.valueOf(part.flash_nb_sectors) : ""); + t.addTextChangedListener(watchers.get(watchers.size()-1)); + + Spinner s = (Spinner) v.findViewById(R.id.spinner_uuencode); + if(part != null) + s.setSelection(part.uuencode ? 0 : 1); + + Button b = (Button) v.findViewById(R.id.submit); + b.setTextColor(0xFF000000); + b.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(part == null) { + part = new Part(); + part.id = -1; + } + EditText t = (EditText) v.findViewById(R.id.edit_part_id); + part.part_id = Long.parseLong(t.getText().toString().replace("0x",""),16); + t = (EditText) v.findViewById(R.id.edit_flash_base_addr); + part.flash_base_addr = Integer.parseInt(t.getText().toString().replace("0x",""),16); + t = (EditText) v.findViewById(R.id.edit_flash_size); + part.flash_size = Integer.parseInt(t.getText().toString().replace("0x",""),16); + t = (EditText) v.findViewById(R.id.edit_reset_vector_offset); + part.reset_vector_offset = Integer.parseInt(t.getText().toString().replace("0x",""),16); + t = (EditText) v.findViewById(R.id.edit_ram_base_addr); + part.ram_base_addr = Integer.parseInt(t.getText().toString().replace("0x",""),16); + t = (EditText) v.findViewById(R.id.edit_ram_size); + part.ram_size = Integer.parseInt(t.getText().toString().replace("0x",""),16); + t = (EditText) v.findViewById(R.id.edit_ram_buf_offset); + part.ram_buffer_offset = Integer.parseInt(t.getText().toString().replace("0x",""),16); + t = (EditText) v.findViewById(R.id.edit_ram_buf_size); + part.ram_buffer_size = Integer.parseInt(t.getText().toString().replace("0x",""),16); + + t = (EditText) v.findViewById(R.id.edit_part_name); + part.part_name = t.getText().toString(); + t = (EditText) v.findViewById(R.id.edit_flash_nb_sector); + part.flash_nb_sectors = Integer.parseInt(t.getText().toString()); + Spinner s = (Spinner) v.findViewById(R.id.spinner_uuencode); + part.uuencode = s.getSelectedItemPosition() == 0; + if(part.id == -1) + DatabaseManager.getInstance(getActivity()).addPart(part); + else + DatabaseManager.getInstance(getActivity()).updatePart(part); + + //cleanup(); + listener.onSubmit(); + } + }); + b = (Button) v.findViewById(R.id.cancel); + b.setTextColor(0xFF000000); + b.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + cleanup(); + listener.onCancel(); + } + }); + modifyBt(v); + return v; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + listener = (OnAddInteractionListener) context; + } + + @Override + public void onDetach() { + super.onDetach(); + listener = null; + } + + public interface OnAddInteractionListener { + void onCancel(); + void onSubmit(); + } + public void modifyBt (View v){ + if (v == null) + v = getView(); + boolean isValid = true; + assert v != null; + EditText t = (EditText) v.findViewById(R.id.edit_part_id); + String hexa = t.getText().toString(); + if(!hexa.matches("0x[0-9A-F]*")) + isValid = false; + t = (EditText) v.findViewById(R.id.edit_flash_base_addr); + hexa = t.getText().toString(); + if(!hexa.matches("0x[0-9A-F]*")) + isValid = false; + t = (EditText) v.findViewById(R.id.edit_flash_size); + hexa = t.getText().toString(); + if(!hexa.matches("0x[0-9A-F]*")) + isValid = false; + t = (EditText) v.findViewById(R.id.edit_reset_vector_offset); + hexa = t.getText().toString(); + if(!hexa.matches("0x[0-9A-F]*")) + isValid = false; + t = (EditText) v.findViewById(R.id.edit_ram_base_addr); + hexa = t.getText().toString(); + if(!hexa.matches("0x[0-9A-F]*")) + isValid = false; + t = (EditText) v.findViewById(R.id.edit_ram_size); + hexa = t.getText().toString(); + if(!hexa.matches("0x[0-9A-F]*")) + isValid = false; + t = (EditText) v.findViewById(R.id.edit_ram_buf_offset); + hexa = t.getText().toString(); + if(!hexa.matches("0x[0-9A-F]*")) + isValid = false; + t = (EditText) v.findViewById(R.id.edit_ram_buf_size); + hexa = t.getText().toString(); + if(!hexa.matches("0x[0-9A-F]*")) + isValid = false; + + t = (EditText) v.findViewById(R.id.edit_flash_nb_sector); + if(t.getText().toString().isEmpty()) + isValid = false; + t = (EditText) v.findViewById(R.id.edit_part_name); + if(t.getText().toString().isEmpty()) + isValid = false; + Button b = (Button) v.findViewById(R.id.submit); + if(isValid) { + b.setTextColor(0xFF000000); + b.setEnabled(true); + } + else { + b.setTextColor(0xFFA0A0A0); + b.setEnabled(false); + } + + } + + public void cleanup() { + View v = getView(); + assert v != null; + EditText t = (EditText) v.findViewById(R.id.edit_part_id); + t.removeTextChangedListener(watchers.get(0)); + t = (EditText) v.findViewById(R.id.edit_flash_base_addr); + t.removeTextChangedListener(watchers.get(1)); + t = (EditText) v.findViewById(R.id.edit_flash_size); + t.removeTextChangedListener(watchers.get(2)); + t = (EditText) v.findViewById(R.id.edit_reset_vector_offset); + t.removeTextChangedListener(watchers.get(3)); + t = (EditText) v.findViewById(R.id.edit_ram_base_addr); + t.removeTextChangedListener(watchers.get(4)); + t = (EditText) v.findViewById(R.id.edit_ram_size); + t.removeTextChangedListener(watchers.get(5)); + t = (EditText) v.findViewById(R.id.edit_ram_buf_offset); + t.removeTextChangedListener(watchers.get(6)); + t = (EditText) v.findViewById(R.id.edit_ram_buf_size); + t.removeTextChangedListener(watchers.get(7)); + t = (EditText) v.findViewById(R.id.edit_part_name); + t.removeTextChangedListener(watchers.get(8)); + t = (EditText) v.findViewById(R.id.edit_flash_nb_sector); + t.removeTextChangedListener(watchers.get(9)); + + watchers.clear(); + } +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/fragment/DeviceFragment.java b/app/src/main/java/fr/mobdev/lpcprog/fragment/DeviceFragment.java new file mode 100644 index 0000000..d8ed021 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/fragment/DeviceFragment.java @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2016 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.annotation.SuppressLint; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.support.design.widget.Snackbar; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v7.app.AlertDialog; +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.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import fr.mobdev.lpcprog.adapters.BinariesAdapter; +import fr.mobdev.lpcprog.listener.FlashListener; +import fr.mobdev.lpcprog.listener.NetworkListener; +import fr.mobdev.lpcprog.managers.DatabaseManager; +import fr.mobdev.lpcprog.managers.IspManager; +import fr.mobdev.lpcprog.R; +import fr.mobdev.lpcprog.managers.NetworkManager; +import fr.mobdev.lpcprog.objects.Server; +import fr.mobdev.lpcprog.objects.USBDevice; +import fr.mobdev.lpcprog.managers.UsbCommManager; + +public class DeviceFragment extends Fragment { + + private UsbCommManager comm; + private USBDevice dev; + private List servers; + private long part_id; + private FlashListener flashListener; + + public DeviceFragment() { + + } + + public static DeviceFragment newInstance(int PID, int VID) { + DeviceFragment frag = new DeviceFragment(); + Bundle args = new Bundle(); + args.putInt("PID",PID); + args.putInt("VID",VID); + frag.setArguments(args); + return frag; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @SuppressLint("SetTextI18n") + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + super.onCreateView(inflater,container,savedInstanceState); + final View v = inflater.inflate(R.layout.device,container,false); + servers = new ArrayList<>(); + comm = UsbCommManager.getInstance(getActivity()); + part_id = 0; + List devices = comm.getDevices(); + int pid = getArguments().getInt("PID",-1); + int vid = getArguments().getInt("VID",-1); + for(USBDevice device : devices){ + if(device.PID == pid && device.VID == vid){ + dev = device; + System.out.println("device found"); + break; + } + } + if(dev != null) { + TextView name = (TextView) v.findViewById(R.id.name); + name.setText(getString(R.string.dev_name)+ dev.description); + TextView vendor = (TextView) v.findViewById(R.id.vendor_id); + vendor.setText(getString(R.string.vendor_id)+String.format("%04x", dev.VID)); + TextView product = (TextView) v.findViewById(R.id.id); + product.setText(getString(R.string.product_id)+String.format("%04x", dev.PID)); + } + doUsb(); + ProgressBar bar = (ProgressBar) v.findViewById(R.id.progress_browse); + bar.setVisibility(View.GONE); + + RecyclerView list = (RecyclerView) v.findViewById(R.id.bin_list); + list.setLayoutManager(new LinearLayoutManager(getContext())); + final ProgressDialog dialog = new ProgressDialog(getActivity()); + dialog.setCancelable(false); + dialog.setTitle(R.string.flash_progress); + dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + dialog.setMessage("toto"); + + flashListener = new FlashListener() { + + @Override + public void onStartFlash() { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + dialog.show(); + + } + }); + } + + @Override + public void onSuccess() { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + dialog.dismiss(); + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.flash_succeed); + builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialogInterface, int i) { + + } + }); + final AlertDialog alert = builder.create(); + alert.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogInterface) { + alert.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(0xFF000000); + } + }); + alert.show(); + } + }); + } + + @Override + public void onProgress(final int step, final int endStep, final int progress, final int step_res_id) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + dialog.setMax(100); + dialog.setProgress(progress); + dialog.setMessage(getString(R.string.step)+" "+String.valueOf(step)+"/"+String.valueOf(endStep)+" "+getString(step_res_id)); + dialog.show(); + } + }); + } + + @Override + public void onError(final String error, final ImageView view) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + dialog.dismiss(); + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setMessage(error); + builder.setPositiveButton(R.string.retry_browse, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + view.performClick(); + } + }); + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + + } + }); + final AlertDialog alert = builder.create(); + alert.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogInterface) { + alert.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(0xFF000000); + alert.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(0xFF000000); + } + }); + alert.show(); + } + }); + } + }; + updateRepositories(v); + return v; + } + + private void doUsb(){ + System.out.println("doUsb"); + new Thread(new Runnable() { + @Override + public void run() { + boolean conn = comm.openConnection(dev); + IspManager manager = IspManager.getInstance(getActivity()); + String uidStr = "No UID Found or error"; + String bootStr = "No Boot Version Found or error"; + String partidStr = "No Part ID Found or error"; + if(conn && manager.setupDevice(dev, 115200)) { + if(!manager.synchronizeIfPossible(10000)) { + updateIDS(uidStr,partidStr,bootStr); + getActivity().runOnUiThread(new Thread(new Runnable() { + @Override + public void run() { + View v = getView(); + if(v == null) + return; + final Snackbar msg = Snackbar.make(v.findViewById(R.id.bin_list), getString(R.string.can_read_uid),Snackbar.LENGTH_INDEFINITE); + msg.setAction(R.string.retry_browse, new View.OnClickListener() { + @Override + public void onClick(View v) { + msg.dismiss(); + doUsb(); + } + }); + msg.show(); + } + })); + return; + } + String[] version = manager.readBootVersion(); + String partid = manager.readPartId(); + String[] uids = manager.readUid(); + if (uids != null) { + uidStr = String.format("UID: %08x - %08x - %08x - %08x",Long.parseLong(uids[0]), + Long.parseLong(uids[1]), + Long.parseLong(uids[2]), + Long.parseLong(uids[3])); + } + if (version != null) { + bootStr = "Boot Version: " + version[0] + "." + version[1]; + } + if(partid != null){ + partidStr = String.format("Part Id %08x",Long.parseLong(partid)); + part_id = Long.parseLong(partid); + IspManager.getInstance(getActivity()).setPartId(part_id); + } + } + updateIDS(uidStr,partidStr,bootStr); + + } + }).start(); + } + @SuppressLint("N") + private void updateIDS(final String uid, final String partid, final String boot) { + final View v = getView(); + assert v != null; + if(getActivity() != null) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + TextView view = (TextView) v.findViewById(R.id.uids); + view.setText(uid); + + view = (TextView) v.findViewById(R.id.part_id); + view.setText(partid); + + view = (TextView) v.findViewById(R.id.boot_version); + view.setText(boot); + } + }); + } + } + + public void updateRepositories(View view){ + System.out.println("Update Repo"); + 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() { + ProgressBar bar = (ProgressBar) v.findViewById(R.id.progress_browse); + bar.setVisibility(View.VISIBLE); + RecyclerView list = (RecyclerView) v.findViewById(R.id.bin_list); + list.setVisibility(View.GONE); + + } + }); + } + + @Override + public void startServer(Server server) { + } + + @Override + public void endServer(Server server) { + System.out.println(server.url.toString()+"empty "+server.binaries.isEmpty()+" "+server.binaries.size()); + if(!server.binaries.isEmpty()) + servers.add(server); + } + + @Override + public void endBinaries() { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + ProgressBar bar = (ProgressBar) v.findViewById(R.id.progress_browse); + bar.setVisibility(View.GONE); + RecyclerView list = (RecyclerView) v.findViewById(R.id.bin_list); + list.setVisibility(View.VISIBLE); + BinariesAdapter adapter = new BinariesAdapter(servers, getActivity(),flashListener); + list.setAdapter(adapter); + } + }); + } + + @Override + public void onError(final String error) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + ProgressBar bar = (ProgressBar) v.findViewById(R.id.progress_browse); + bar.setVisibility(View.GONE); + final Snackbar msg = Snackbar.make(v.findViewById(R.id.bin_list), error,Snackbar.LENGTH_INDEFINITE); + msg.setAction(R.string.retry_browse, new View.OnClickListener() { + @Override + public void onClick(View v) { + msg.dismiss(); + updateRepositories(null); + } + }); + msg.show(); + List> localServers = DatabaseManager.getInstance(getActivity()).getServers(); + servers.addAll(localServers.get(0)); + servers.addAll(localServers.get(1)); + servers.addAll(localServers.get(2)); + RecyclerView list = (RecyclerView) v.findViewById(R.id.bin_list); + list.setVisibility(View.VISIBLE); + BinariesAdapter adapter = new BinariesAdapter(servers,getActivity(),flashListener); + list.setAdapter(adapter); + + } + }); + } + }; + NetworkManager.getInstance(listener,getActivity()).browseBinaries(); + } +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/fragment/PartsFragment.java b/app/src/main/java/fr/mobdev/lpcprog/fragment/PartsFragment.java new file mode 100644 index 0000000..f9ec848 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/fragment/PartsFragment.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 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.os.Bundle; +import android.support.v4.app.Fragment; +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 java.util.List; + +import fr.mobdev.lpcprog.R; +import fr.mobdev.lpcprog.adapters.PartsAdapter; +import fr.mobdev.lpcprog.managers.DatabaseManager; +import fr.mobdev.lpcprog.objects.Part; + +public class PartsFragment extends Fragment { + + private OnEditPressListener onEditListener; + + public PartsFragment() { + } + + public static PartsFragment newInstance() { + return new PartsFragment(); + } + + public void setOnEditPressListener(OnEditPressListener listener){ + onEditListener = listener; + } + + @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.parts, container, false); + RecyclerView list = (RecyclerView) v.findViewById(R.id.parts_list); + list.setLayoutManager(new LinearLayoutManager(getActivity())); + List parts = DatabaseManager.getInstance(getActivity()).getParts(); + PartsAdapter adapter = new PartsAdapter(parts,onEditListener); + list.setAdapter(adapter); + return v; + } + + public void updateList() { + View v = getView(); + if(v == null) + return; + RecyclerView list = (RecyclerView) v.findViewById(R.id.parts_list); + List parts = DatabaseManager.getInstance(getActivity()).getParts(); + PartsAdapter adapter = new PartsAdapter(parts,onEditListener); + list.setAdapter(adapter); + } + + public interface OnEditPressListener{ + void onEditPress(Long part_id); + void onDeletePress(); + } +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/activity/ServersActivity.java b/app/src/main/java/fr/mobdev/lpcprog/fragment/ServersFragment.java similarity index 63% rename from app/src/main/java/fr/mobdev/lpcprog/activity/ServersActivity.java rename to app/src/main/java/fr/mobdev/lpcprog/fragment/ServersFragment.java index acc6e33..bbac282 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/activity/ServersActivity.java +++ b/app/src/main/java/fr/mobdev/lpcprog/fragment/ServersFragment.java @@ -16,43 +16,48 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package fr.mobdev.lpcprog.activity; +package fr.mobdev.lpcprog.fragment; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.Toolbar; -import android.view.Menu; -import android.view.MenuItem; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; import fr.mobdev.lpcprog.R; import fr.mobdev.lpcprog.adapters.ServerAdapter; -import fr.mobdev.lpcprog.dialog.ServerDialog; import fr.mobdev.lpcprog.listener.ServerListener; import fr.mobdev.lpcprog.managers.DatabaseManager; import fr.mobdev.lpcprog.objects.Server; /* - * Activity that allow user to manage the server where he want to upload his images. Server must be lutim instance to work with the app + * Activity that allow user to manage the server where he want to upload his images. Server must contains a Binaries file to work with the app */ -public class ServersActivity extends AppCompatActivity { +public class ServersFragment extends Fragment { - private List> dbServers; private ServerListener serverListener; + public ServersFragment() { + + } + + public static Fragment newInstance() { + return new ServersFragment(); + } + @Override - protected void onCreate(Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.servers); - - Toolbar toolbar = (Toolbar) findViewById(R.id.servers_toolbar); - setSupportActionBar(toolbar); + } + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View v = inflater.inflate(R.layout.servers,container,false); /* ***** Change status of the repos: active to inactive or reverse ***** ListView serverList = (ListView) findViewById(R.id.servers_list); @@ -68,47 +73,29 @@ public class ServersActivity extends AppCompatActivity { serverListener = new ServerListener() { @Override public void updateServerList() { - updateServers(); + updateServers(null); } }; - updateServers(); + updateServers(v); + return v; } - private void updateServers() + public void updateServers(View v) { // build the view with server list in database - dbServers = DatabaseManager.getInstance(getApplicationContext()).getServers(); + List> dbServers = DatabaseManager.getInstance(getActivity()).getServers(); List namesList = new ArrayList<>(); namesList.add(getString(R.string.active_section)); namesList.add(getString(R.string.inactive_section)); namesList.add(getString(R.string.failed_section)); ServerAdapter adapter = new ServerAdapter(dbServers,namesList,serverListener); - - RecyclerView serverList = (RecyclerView) findViewById(R.id.servers_list); - serverList.setLayoutManager(new LinearLayoutManager(this)); - serverList.setAdapter(adapter); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_servers, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - - if (id == R.id.action_add_server) { - - ServerDialog serverDialog = new ServerDialog(); - serverDialog.setServerListener(serverListener); - serverDialog.show(getSupportFragmentManager(),"Server Dialog"); - return true; + if (v == null) + v = getView(); + if(v!=null) { + RecyclerView serverList = (RecyclerView) v.findViewById(R.id.servers_list); + serverList.setLayoutManager(new LinearLayoutManager(getContext())); + serverList.setAdapter(adapter); } - - return super.onOptionsItemSelected(item); } - } diff --git a/app/src/main/java/fr/mobdev/lpcprog/fragment/USBListFragment.java b/app/src/main/java/fr/mobdev/lpcprog/fragment/USBListFragment.java new file mode 100644 index 0000000..f9c9621 --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/fragment/USBListFragment.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 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.content.Context; +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.GestureDetector; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; + +import java.util.List; + +import fr.mobdev.lpcprog.adapters.DeviceAdapter; +import fr.mobdev.lpcprog.R; +import fr.mobdev.lpcprog.objects.USBDevice; +import fr.mobdev.lpcprog.managers.UsbCommManager; + +public class USBListFragment extends Fragment { + + private List devices; + private int value = 0; + private USBInteractionListener listener; + private UsbCommManager comm; + + public USBListFragment() { + + } + + public static USBListFragment newInstance() { + return new USBListFragment(); + } + + + @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.usb_list,container,false); + comm = UsbCommManager.getInstance(getActivity()); + + final GestureDetector gestureDetector = new GestureDetector(getActivity(), new GestureDetector.SimpleOnGestureListener(){ + @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); + System.out.println("touch "+ ++value); + onItemClick(pos); + return true; + } + return false; + } + }); + updateDevice(v); + return v; + } + + public void updateDevice(View v) { + devices = comm.getDevices(); + if(v == null) + v = getView(); + assert v != null; + DeviceAdapter adapter = new DeviceAdapter(devices); + RecyclerView view = (RecyclerView) v.findViewById(R.id.device_list); + view.setAdapter(adapter); + } + + @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 interface USBInteractionListener { + void onUSBDeviceClick(USBDevice device); + } +} diff --git a/app/src/main/java/fr/mobdev/lpcprog/fragment/Watcher.java b/app/src/main/java/fr/mobdev/lpcprog/fragment/Watcher.java new file mode 100644 index 0000000..15dbb4d --- /dev/null +++ b/app/src/main/java/fr/mobdev/lpcprog/fragment/Watcher.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 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.graphics.PorterDuff; +import android.text.Editable; +import android.text.TextWatcher; +import android.widget.EditText; + +class HexaWatcher implements TextWatcher { + + private EditText v; + private AddPartFragment fragment; + HexaWatcher(EditText view,AddPartFragment fragment) { + v = view; + this.fragment = fragment; + } + + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + String hexa = editable.toString(); + if(!hexa.matches("0x[0-9A-F]+")) + v.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.SRC); + else + v.getBackground().clearColorFilter(); + fragment.modifyBt(null); + } +} + +class EmptyWatcher implements TextWatcher { + + private EditText v; + private AddPartFragment fragment; + EmptyWatcher(EditText view,AddPartFragment fragment) { + v = view; + this.fragment = fragment; + } + + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + String data = editable.toString(); + fragment.modifyBt(null); + } +} \ No newline at end of file diff --git a/app/src/main/java/fr/mobdev/lpcprog/listener/FlashListener.java b/app/src/main/java/fr/mobdev/lpcprog/listener/FlashListener.java index de6933d..4cdfce8 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/listener/FlashListener.java +++ b/app/src/main/java/fr/mobdev/lpcprog/listener/FlashListener.java @@ -18,9 +18,13 @@ package fr.mobdev.lpcprog.listener; +import android.widget.ImageView; + import java.util.EventListener; public interface FlashListener extends EventListener{ - - void onError(String string); + void onStartFlash(); + void onSuccess(); + void onProgress(int step, int endStep, int progress, int step_res_id); + void onError(String string, ImageView imageView); } diff --git a/app/src/main/java/fr/mobdev/lpcprog/listener/NetworkListener.java b/app/src/main/java/fr/mobdev/lpcprog/listener/NetworkListener.java index 669e7df..d1a1581 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/listener/NetworkListener.java +++ b/app/src/main/java/fr/mobdev/lpcprog/listener/NetworkListener.java @@ -20,7 +20,6 @@ package fr.mobdev.lpcprog.listener; import java.util.EventListener; -import fr.mobdev.lpcprog.objects.Binary; import fr.mobdev.lpcprog.objects.Server; public interface NetworkListener extends EventListener{ diff --git a/app/src/main/java/fr/mobdev/lpcprog/managers/DatabaseManager.java b/app/src/main/java/fr/mobdev/lpcprog/managers/DatabaseManager.java index e9019c4..71998a4 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/managers/DatabaseManager.java +++ b/app/src/main/java/fr/mobdev/lpcprog/managers/DatabaseManager.java @@ -29,7 +29,7 @@ import java.util.ArrayList; import java.util.List; import fr.mobdev.lpcprog.objects.Binary; -import fr.mobdev.lpcprog.objects.Parts; +import fr.mobdev.lpcprog.objects.Part; import fr.mobdev.lpcprog.objects.Server; public class DatabaseManager extends SQLiteOpenHelper { @@ -61,6 +61,49 @@ public class DatabaseManager extends SQLiteOpenHelper { values.put("attempted",0); db.insert("servers",null,values); + values.clear(); + values.put("part_id",0x00008100); + values.put("part_name","LPC810M021FN8"); + values.put("fl_base_addr",0x0); + values.put("fl_size",0x1000); + values.put("fl_nb_sect",4); + values.put("reset_vector_offset",0x04); + values.put("ram_base_addr",0x10000000); + values.put("ram_size",0x0400); + values.put("ram_buf_off",0x300); + values.put("ram_buf_size",0x100); + values.put("UU_encode",false); + db.insert("definitions",null,values); + + + values.clear(); + values.put("part_id",0x00008122); + values.put("part_name","LPC812M101JHD20"); + values.put("fl_base_addr",0x0); + values.put("fl_size",0x4000); + values.put("fl_nb_sect",16); + values.put("reset_vector_offset",0x04); + values.put("ram_base_addr",0x10000000); + values.put("ram_size",0x1000); + values.put("ram_buf_off",0x800); + values.put("ram_buf_size",0x400); + values.put("UU_encode",false); + db.insert("definitions",null,values); + + values.clear(); + values.put("part_id",0x2540102B); + values.put("part_name","LPC1114FHN33/302"); + values.put("fl_base_addr",0x0); + values.put("fl_size",0x8000); + values.put("fl_nb_sect",8); + values.put("reset_vector_offset",0x04); + values.put("ram_base_addr",0x10000000); + values.put("ram_size",0x2000); + values.put("ram_buf_off",0x800); + values.put("ram_buf_size",0x400); + values.put("UU_encode",true); + db.insert("definitions",null,values); + values.clear(); values.put("part_id",0x3640C02B); values.put("part_name","LPC1224FBD48/101"); @@ -74,6 +117,21 @@ public class DatabaseManager extends SQLiteOpenHelper { values.put("ram_buf_size",0x400); values.put("UU_encode",true); db.insert("definitions",null,values); + + values.clear(); + values.put("part_id",0x26011922); + values.put("part_name","LPC1764FBD100"); + values.put("fl_base_addr",0x0); + values.put("fl_size",0x10000); + values.put("fl_nb_sect",16); + values.put("reset_vector_offset",0x04); + values.put("ram_base_addr",0x10000000); + values.put("ram_size",0x4000); + values.put("ram_buf_off",0x800); + values.put("ram_buf_size",0x800); + values.put("UU_encode",true); + db.insert("definitions",null,values); + } @Override @@ -96,7 +154,6 @@ public class DatabaseManager extends SQLiteOpenHelper { String whereArgs[] = new String[1]; whereArgs[0] = String.valueOf(id); getWritableDatabase().update("servers",values,where,whereArgs); - } public void deleteServer(long id) @@ -166,7 +223,7 @@ public class DatabaseManager extends SQLiteOpenHelper { return binaries; } - public void serverFail(Server server) { + void serverFail(Server server) { server.attempted++; if(server.attempted == 5){ server.attempted = 0; @@ -181,7 +238,7 @@ public class DatabaseManager extends SQLiteOpenHelper { getWritableDatabase().update("servers",values,whereClause,whereArgs); } - public void addBinary(Server server, Binary binary) { + void addBinary(Server server, Binary binary) { System.out.println("add binary"); ContentValues values = new ContentValues(); values.put("server_id",server.id); @@ -201,30 +258,88 @@ public class DatabaseManager extends SQLiteOpenHelper { getWritableDatabase().delete("binaries",whereClause,whereArgs); } - public Parts getParts(long part_id) { - Parts parts = null; + public Part getPart(long part_id) { + Part part = null; String whereClause = "part_id = ?"; String[] whereArgs = new String[1]; whereArgs[0] = String.valueOf(part_id); System.out.println("part_id "+part_id); Cursor cursor = getReadableDatabase().query("definitions", null, whereClause, whereArgs, null, null, null); if (cursor.moveToNext()) { - parts = new Parts(); + part = new Part(); int col = 0; - parts.id = cursor.getLong(col++); - parts.part_id = cursor.getInt(col++); - parts.part_name = cursor.getString(col++); - parts.flash_base_addr = cursor.getInt(col++); - parts.flash_size = cursor.getInt(col++); - parts.flash_nb_sectors = cursor.getInt(col++); - parts.reset_vector_offset = cursor.getInt(col++); - parts.ram_base_addr = cursor.getInt(col++); - parts.ram_size = cursor.getInt(col++); - parts.ram_buffer_offset = cursor.getInt(col++); - parts.ram_buffer_size = cursor.getInt(col++); - parts.uuencode = cursor.getInt(col) == 1; + part.id = cursor.getLong(col++); + part.part_id = cursor.getInt(col++); + part.part_name = cursor.getString(col++); + part.flash_base_addr = cursor.getInt(col++); + part.flash_size = cursor.getInt(col++); + part.flash_nb_sectors = cursor.getInt(col++); + part.reset_vector_offset = cursor.getInt(col++); + part.ram_base_addr = cursor.getInt(col++); + part.ram_size = cursor.getInt(col++); + part.ram_buffer_offset = cursor.getInt(col++); + part.ram_buffer_size = cursor.getInt(col++); + part.uuencode = cursor.getInt(col) == 1; } + cursor.close(); + return part; + } + + public List getParts() { + List parts = new ArrayList<>(); + String[] columns = new String[1]; + columns[0] = "part_id"; + Cursor cursor = getReadableDatabase().query("definitions",columns,null,null,null,null,null); + while (cursor.moveToNext()) { + long id = cursor.getLong(0); + Part part = getPart(id); + parts.add(part); + } + cursor.close(); return parts; } + + public void deletePart(long id) { + String whereClause = "id = ?"; + String whereArgs[] = new String[1]; + whereArgs[0] = String.valueOf(id); + getWritableDatabase().delete("definitions",whereClause,whereArgs); + } + + public void addPart(Part part) { + ContentValues values = new ContentValues(); + values.put("part_id",part.part_id); + values.put("part_name",part.part_name); + values.put("fl_base_addr",part.flash_base_addr); + values.put("fl_size",part.flash_size); + values.put("fl_nb_sect",part.flash_nb_sectors); + values.put("reset_vector_offset",part.reset_vector_offset); + values.put("ram_base_addr",part.ram_base_addr); + values.put("ram_size",part.ram_size); + values.put("ram_buf_off",part.ram_buffer_offset); + values.put("ram_buf_size",part.ram_buffer_size); + values.put("UU_encode",part.uuencode); + getWritableDatabase().insert("definitions",null,values); + + } + + public void updatePart(Part part) { + String whereClause = "id = ?"; + String whereArgs[] = new String[1]; + whereArgs[0] = String.valueOf(part.id); + ContentValues values = new ContentValues(); + values.put("part_id",part.part_id); + values.put("part_name",part.part_name); + values.put("fl_base_addr",part.flash_base_addr); + values.put("fl_size",part.flash_size); + values.put("fl_nb_sect",part.flash_nb_sectors); + values.put("reset_vector_offset",part.reset_vector_offset); + values.put("ram_base_addr",part.ram_base_addr); + values.put("ram_size",part.ram_size); + values.put("ram_buf_off",part.ram_buffer_offset); + values.put("ram_buf_size",part.ram_buffer_size); + values.put("UU_encode",part.uuencode); + getWritableDatabase().update("definitions",values,whereClause,whereArgs); + } } diff --git a/app/src/main/java/fr/mobdev/lpcprog/managers/IspManager.java b/app/src/main/java/fr/mobdev/lpcprog/managers/IspManager.java index 9dea052..65ef901 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/managers/IspManager.java +++ b/app/src/main/java/fr/mobdev/lpcprog/managers/IspManager.java @@ -19,6 +19,7 @@ package fr.mobdev.lpcprog.managers; import android.content.Context; +import android.widget.ImageView; import com.ftdi.j2xx.D2xxManager; import com.ftdi.j2xx.FT_Device; @@ -31,7 +32,7 @@ import java.util.Locale; import fr.mobdev.lpcprog.R; import fr.mobdev.lpcprog.listener.FlashListener; import fr.mobdev.lpcprog.objects.Binary; -import fr.mobdev.lpcprog.objects.Parts; +import fr.mobdev.lpcprog.objects.Part; import fr.mobdev.lpcprog.objects.Server; import fr.mobdev.lpcprog.objects.USBDevice; @@ -212,82 +213,92 @@ public class IspManager { return version; } - public int flashBinary(Server server, Binary binary, FlashListener listener) { - Parts parts = DatabaseManager.getInstance(context).getParts(part_id); + public int flashBinary(Server server, Binary binary, FlashListener listener, ImageView flashView) { + Part parts = DatabaseManager.getInstance(context).getPart(part_id); + listener.onStartFlash(); if(parts == null) { - listener.onError(context.getString(R.string.parts_missing)); + listener.onError(context.getString(R.string.parts_missing),flashView); 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); //Sanity Checks if (ram_addr > parts.ram_base_addr + parts.ram_size) { - listener.onError(context.getString(R.string.buffer_out_ram)); + listener.onError(context.getString(R.string.buffer_out_ram),flashView); 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)); + listener.onError(context.getString(R.string.block_size_null),flashView); return -3; } - int ret = eraseFlash(parts); + listener.onProgress(2,5,0,R.string.erase_flash); + int ret = eraseFlash(parts,listener); if (ret != 0) { - listener.onError(context.getString(R.string.cant_erase_flash)); + listener.onError(context.getString(R.string.cant_erase_flash),flashView); return -4; } + listener.onProgress(3,5,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) { System.out.println("Size " + size); - listener.onError(context.getString(R.string.copy_file)); + listener.onError(context.getString(R.string.copy_file),flashView); return -5; } + listener.onProgress(3,5,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); if(!verifyChecksum(data,cksum)) { - listener.onError(context.getString(R.string.checksum_failed)); + listener.onError(context.getString(R.string.checksum_failed),flashView); return -6; } + listener.onProgress(1,2,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)); + listener.onError(context.getString(R.string.flash_outside_end),flashView); } + listener.onProgress(4,5,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); 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); + listener.onError(context.getString(R.string.prepare_write_error)+" "+i,flashView); 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); + listener.onError(context.getString(R.string.write_ram_error)+" "+i,flashView); 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); + listener.onError(context.getString(R.string.copy_to_flash_error)+" "+i,flashView); return ret; } } + listener.onProgress(5,5,100,R.string.end_flash); + listener.onSuccess(); return ret; } @@ -530,13 +541,14 @@ public class IspManager { return Integer.parseInt(str); } - private int eraseFlash(Parts parts) { + private int eraseFlash(Part parts,FlashListener listener) { int ret = unlock(); if (ret != 0) { System.out.println("unlock fail"); return -1; } for (int i = 0; i < parts.flash_nb_sectors; i++) { + listener.onProgress(2,5,i*100/parts.flash_nb_sectors,R.string.erase_flash); //blank-check ret = send_cmd_sectors('I', i, i); if (ret == 0) { @@ -563,6 +575,7 @@ public class IspManager { return ret; } } + listener.onProgress(2,5,100,R.string.erase_flash); return 0; } @@ -712,8 +725,8 @@ public class IspManager { int sizeToRead = serialPort.getQueueStatus(); if (sizeRead + sizeToRead > size) sizeToRead = size - sizeRead; - byte[] buf = new byte[sizeToRead]; if (sizeToRead > 0) { + byte[] buf = new byte[sizeToRead]; int sizeReceived = serialPort.read(buf, sizeToRead, 50); if (sizeReceived < 0) return sizeReceived; diff --git a/app/src/main/java/fr/mobdev/lpcprog/managers/NetworkManager.java b/app/src/main/java/fr/mobdev/lpcprog/managers/NetworkManager.java index b17fa73..afe8c9b 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/managers/NetworkManager.java +++ b/app/src/main/java/fr/mobdev/lpcprog/managers/NetworkManager.java @@ -125,11 +125,12 @@ public class NetworkManager { String line = reader.readLine(); System.out.println("Browse binaries"); while(line != null){ - Binary b = parseLine(line); - System.out.println("Found a binary "+b.name); - if(b != null && !server.contains(b)) { - server.addBinary(b); - DatabaseManager.getInstance(context).addBinary(server,b); + if(!line.startsWith("#")) { + Binary b = parseLine(line); + if (b != null && !server.contains(b)) { + server.addBinary(b); + DatabaseManager.getInstance(context).addBinary(server, b); + } } line = reader.readLine(); } @@ -218,7 +219,7 @@ public class NetworkManager { cancelList.remove(binary); } - public boolean checkFileSha1(Server server, Binary binary){ + private boolean checkFileSha1(Server server, Binary binary){ String sha1 = ""; try { File f = new File(context.getApplicationInfo().dataDir+"/"+server.id+"/"+binary.path+binary.filename); @@ -240,7 +241,7 @@ public class NetworkManager { return sha1.compareToIgnoreCase(binary.sha1) == 0; } - public boolean cleanupFile(Server server, Binary binary){ + private boolean cleanupFile(Server server, Binary binary){ File f = new File(context.getApplicationInfo().dataDir+"/"+server.id+"/"+binary.path+binary.filename); return f.delete(); } diff --git a/app/src/main/java/fr/mobdev/lpcprog/managers/UsbCommManager.java b/app/src/main/java/fr/mobdev/lpcprog/managers/UsbCommManager.java index f2a724f..7c60c80 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/managers/UsbCommManager.java +++ b/app/src/main/java/fr/mobdev/lpcprog/managers/UsbCommManager.java @@ -33,7 +33,7 @@ public class UsbCommManager { private D2xxManager manager = null; private Context context; - List openedDevices; + private List openedDevices; private UsbCommManager(Context context){ diff --git a/app/src/main/java/fr/mobdev/lpcprog/objects/Parts.java b/app/src/main/java/fr/mobdev/lpcprog/objects/Part.java similarity index 98% rename from app/src/main/java/fr/mobdev/lpcprog/objects/Parts.java rename to app/src/main/java/fr/mobdev/lpcprog/objects/Part.java index d6cec55..8f23aaa 100644 --- a/app/src/main/java/fr/mobdev/lpcprog/objects/Parts.java +++ b/app/src/main/java/fr/mobdev/lpcprog/objects/Part.java @@ -18,7 +18,7 @@ package fr.mobdev.lpcprog.objects; -public class Parts { +public class Part { public long id; public long part_id; public String part_name; diff --git a/app/src/main/res/drawable-hdpi/edit.png b/app/src/main/res/drawable-hdpi/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..b728f6d615261a89a6fb940d94b651b425f85324 GIT binary patch literal 805 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhawSkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|U1(2s1Lwnj--eWH0gbb!C6R!OdwVvhW*oDo~Szr;B4q#=W<<_WIop5IOL% z{t?3>S0@i21x1x5exbWRG8k-dIm5%~IN@gC;&rJh4_G6tJ}}7MsAMuzJG9+nf`FjP z#2yyU;PL}gEIzu=`E@UQVfCJh4K;Ok`@a8racY6{acgepq;)3o5eaj+c(3;V{q&;p z)D4?W$6K;^BxZzcocnls)}+~s=Uh1(==JHDhVsv1k%>iDYAn4xB2P6cbgDG-Fmz9u zRj z*E~-?YMHz$=g3_xsT`JqCQmPme=4am`ICbD)K~iWnjZH(H7WRf;pC+GFa8$f4KtTo&RPscmyM5KkvZ$h#eU7{8(VAPAFJD9W%1uvf1Epi%cC{E zT_O|I&es~nT@$fvleyGf#doIAy|M9xildCd#*IJ3CaUx>Ti=jf@?oRO1mgqyCNC+U zKJ-O0n zFrS}z$#>GBMo+)mXOm`!Og`Lrvtile(paO2#L#QRdP`(kYX@0 zFf`LOu+TL$3^6pcGBvg`Hq|yTvNAAeSho_5UNXEUlv(9G=JBl2) zpY59~9UU#4)4S!0R%1}qhy5Q^L|ysg_EcyrHLNPfv{H*6H8BargF^zd!5LA)xrrIHT*c{-gtL z%BT6=ulaXrBy94#I`P$#4#p32-#!rA;4zaaRZQh3kF_M8u`ZFy%D|r!0G@ywQzAF3VL;^8Gj|7x2Jg(yg3{ zhncjrxc+Rfm7gqk%Cl|5#S@c7_iuffEF-(&M#}YxuX--`^QLHcRr#3R$i3<`S!d#b zX)30MT|1@)P0x~J&oBv3o^82riUXE(fEzxnkXD-{u;Eb+L0|AJ5z=U&-M z>vaG7bNGH}O8jVfm^n-KdW7;x+eb=8f1gR-|HEP0sHta~xkF0+#wV`aa|PW?BqaCb z%)SsSmtMK`tGu zx+vA>{wEgc^jf{YRC?O}{%VfPcSuO#0ozg5bn z-54S(nA8_Hn`@fYMTV zwHU|VM|+(lmvHGXv{`Sdd#Gw&(Bdl_pNU_;)mFc5)>GL|zU)6oOZ5yCdiI>(wEO)1 zL-E(PaeA$h`CEGZ=)wsB9xGyhyf>O`GfRXuSFlQY`-!`kjuo4J`j;5@H0xkmhsuJ$ z)XSFn@}*l1ykw+%l_bwA)vg!2QZU;jbJHF{+a*@ZB2}H+LYJw&Oy0EQDH00)|WTsW()-YA0%LJ%_ N!PC{xWt~$(697#C#Yq4F literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/edit.png b/app/src/main/res/drawable-mdpi/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..2c4ef64a74dde1d6a7912b42b4f5b043859bf8b2 GIT binary patch literal 648 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}tmUKs7M+SzC{oH>NS%G|oWRD45dJguM!v-tY$DUh!@P+6=(yLU`q0KcVYP7-hXC4kjGiz z5n0T@z%2~Ij105pNB{-dOFVsD*&lFlbDD`P{KlNhz`$7T>Eaj?aro`EyEb%k^aPp-aoC->454&$?&vfo219vhov6dt+K;nHuD zDEjYl#{C!}(`%uX-(5OGOY2G&`MtXRu=+{6`m2-;r613=l*Rdl_Xg3Z&8wew1}VAU*nU&(_h@hYEvpBCdU0La$@Gcy=AGayh@f; zg+;-gnQDRdP`(kYX@0Ff`LOu+TL$ z3^6pcGBvg`Hq|yTvNAAeSGKr{q*+2sN?FnGH9xvXNS%G|oWRD45dJguM!v-tY$DUh!@P+6=(yLU`q0KcVYP7-hXC4kjGiz z5n0T@z%2~Ij105pNB{-dOFVsD*&lGpa4Pb>lXN-{)YRbV;usQf`0e$B*&*&S>>tk0 z&RMnGVb?a%mI==MY}vL^SDL2_t(N=p=&1L>Xuc?$ul^sVBEZ%JP_K&SAI_{_5{Cn2snf2$n@BiG(|Ix$WyT-jfz&ZGh z&_(^p(YMa9`0dI&mC@BV+w5&c7n{$H#6u1@8Mex?9Cjt{`8;?ufVe$N#*$Spd$A-5^! z@SJ5C8#C@XK7SikeyMWef_4}0I^Sx8CpoH}zs~H^=Xhp%UFd_>-@4$;3L}2o7dd~X zoO3L=vO(k5_OHjP%w3fExSQHmZZ%sg`B`|;$5SlqQD%ELCSCrn5qP;}rOL&ZUdgQ6 zZTy5vH)fXT{=FSr7<+Ke>1^rk67R1rvzHQb)vw-r;`&juW~OOTk%?1%&u`6%(v8)( zel}%6+OeHetJa4=a$OF!JgCq$Nn2VB+= zuiVaB*?PXImhI}*Ztr)R7p))m9zD0r|E0{9i(g_qB)3M$luhf~`P50oCO>_F*{QDk z=RTE{ew6ODQ2D&wx^q$X$LPLYw~Mx44YpC6F716$GVtB>vu_=jy^#yQw_CBvckv$? zotax71iqHDd~fwE_)CALFnCgG)PbTQH$NpatrE9}sTy4- PKn)C@u6{1-oD!M_8nN;Ety z7cb^~%#_ijVX;JE@+2uOt`~w64n2@(2#R_U6nG)XeUXnND{qrfl#11ygkmqhCoLWu zdz@raH9EwO-%I|MuwOEBpGowRihFl2zByvJqww*u-q|w64pIhYa;0fI-KL6eTWa|7 z_;bEok*;{1qPSU;%WR~+1ROjst>-cMQjh(yaE-XzlLd}#f1z0+SmQmfN&fJ51;x(% zil*fU%`FZ-UMF_{M$2KHj8DD3Gal`n%V{S%TewE*Oz>9IhwslBKjA!{(nfR2W?;Oo}c~U0#Dtymfuf5Jw9*qQrIrg{PDYV?-z#I zV)n64{cLrWHFude=Q*9M*}HrF`~(ww%YzklHBF*_Ua(~Uc*q&{@wl+x<^#67e>~=N zKmA8!uf)HKrq-I)q!TqWy_aX~OX_VqTl2b1E^*(#_Ljc)Kd_*9ru`>p?X6ky@lcxG z0iO47o>W&i*@{PsN?#jzPhfS&+pB`F8|2B9j?DF$N0@D;d#~J+o&H=wTAN^6@ z!`1pywc~SQSHIwnCoIfA3TDoqcv{)+Acx(Z6p77;77Oz{JiNHYR?X(1#J=O3kHpp) z9h9(>dA{~oca}+F+w`Y(^VRFleR6%h!eCYa_d1>#+Fwllt!tlIXq=rpM{V~k#xBu3 z&ti4?zegXO|M}tPS+-ca%`V+$vX_~(eA@q9^^ zo0oOspx8nC4iWyht_$7yo5cC$zN%DcRDFz&5ODpV+@T<{u&FBGgTN8*g{?A6Y(ri+ z-fC_MdF8rc#gdyj*Svjz43Lfjc2CNmWLToTgp-(7e?^ogu950CL3xL^K4)+k#!jMd6|C!ccq zm$IrXI`lFm_~gRV+a=`9InEocw<%VOTW)B)=UEEZ{O1=QsqJo?Kd+IYzj%(<)!^G3 zRmCnWS?KdPQoOSf20j8B&P5|JJxc}%vJao<|+T4ffSo|NmC#RGVp<|gXw zohrb%O^|V$=BBydW`x|@*j-)tcFS?)bsCX2$)4d3f^W7QKI$PR|0pi(m!$$Qh+?c| zHy!0v?OwL8LFvXzz3%pDfw_#X8!lh?`@OBwcRm0e}3;*I=WE;2P-g@SE?hUn~ERF&!imLSt za$6pJTOHIR0!;6!C9V-ADTyViR>?)FK#IZ0z|c(B&_LJ7BE-iiX_$l+3hB+#058beRA(FnGH9xvXlU1#U)!#=$4bDrn-KJR(Y@57UKEcB@P zCc8}l0GJ2i1Bf8rTQ8H1V815sZ3SUtykCeP0Q^vFwn{Prxg!Nn3;}=(y8s~j3IMEt zQuglvz(N4PbSwbi_yDl=e1$apAoyTNCL9d_{^Av@+CXM{9v{U705j|LG61euYy(9| zdQeCpWX#0O)N4!S;sz=J7;%CE{ElZ1=`|t26@jphw{QIOwq0$hs_ah)fkqzs$l5w2 zF=R^<{NW#I3r^<>^WNTqEa(*Fkh50x*G@IIKrDB`)tB?$R_%iC?QVWpM!eHPAVmA^ zF)QZT1THQN#(yv9QoT`{ce1BSUtQ!nMfvWjE+c;WPpd0q$vB4a=SmAvrLSV*vTaOb zx0pV`fWKr*1ylCk)UQ|rVSD7WQ!bG~@7MT~=oT4=IKF^rOZFFWV#ZA{4>)8JI`{`J zb_c0YSmkwMr*7{;N0nCuiWY8PZzHZPR9lE^Q3LMcB1LdD$(GeoO|@kmWj%47R63I}+hZ4m9MCq; zTwpwwlv5gHL;Z}a5DDFpWzDj%d7nt&s>2c>FQHfEz8x8 z7K%SP`9=6tpKD^0ie2XdtJb2k-Epj&g?`Ny!xe2w_4}CjnVVlc5zlB z@^;Pa#7Srgb~w40cS;p$oXfv^tYC1H{dZ}l{JW||WOSvi*l7CY z76o|0?t7SKrgDUjYZ^hFsI%mS=poEG+0b^~&AK%*__cFK5+FB=Ri;iyPK)I~Hf#@* zyV8oS#r&s1Dzb$$GWy(c6`N1!joKOe{8^K{L6iJtlx)x+XXu7ZO31~Q$&;Nlo^n{I zo!$C$0k&c_4$kf&<9t%>enS4)T8{Pv_oc4y>k6Z3Jnxk&W>Uzu%>8*-GDzhx3o)0= zKk#ZZXyvcM>~Mw(aQuKH&3@snfcgBCZmh^R8?xMmO&ODA3D@A^5LHYyoEZu;5bskP zcr5iV{~0E#+YrY+k$H*USbI5cc6@&Utbw4{orKQ&XB_e=X&N(UA>|tA`K`Bu@Vl8M zBAl8H!IvBs4jH^(jsJSmST+P_{ivGzrDo}V2EoA-^>C?8Ar)FwEGK$vo5z|LzyowKzz3{MzGbfdee=JFRaO zm78%uic0sY7gqH2i|%A~`S?ud3P>1d+?7y*0~$4QxRvs|C#EDfo+)vT>H;+Gta;U3 z;x644w)76+79ml!o2W{7|)HG+*1Z~ zt~Qisn1tiJn~^WJgX;TXD>UP5*83Of6#gW%pdsN+O+7Z< z@@(2Sj2di@p|YWsBdvTMF{Oci$iR*@^JCSI!kZ4V*R$R!J@90D94VcOqoh$m06Y*# zFE_+~Hze{n5{W~ja4573!UKmuT)9~YM)!XVDXDSiXj%Vb@cdwi$oEbG4M0#}Xn@E+ GHs@~@fd%dW literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..6351f3d4d6acb1c6dcd3bb216eaea5453c2d4178 GIT binary patch literal 1439 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q1xWh(YZ(J6mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1OBOz`!jG!i)^F=12eq*-JcqUD+RS$#5$2y_0l0543QSr;B4q#jUq<&u7b|%CyhF zdDcv2YouX75!cc^W@ney+yTW@~fV0cU-xd%j? zahd3H_ZO4?*P8Iz_iyOwSf1x9-IRB7N~j#m?LB9h=DsWH<-NA6^my0yo5}lsXMXnY z-(WMn(!)CZlj8K|=(WXjb++H_d3`0hG*N5Sf)=;)cDFd*ZRG5ox6Q=s`&+9EFQWTg zbXP6lJkZ1$>h%#CAxpF^hcjbKR8PHhMZgWuC8i+H{rg`wh-*l@rtSEPOLI%4tWeRm$k&-pR42 zLr1*WUQxz$Df9Fezx&(ORF`+POtELSY++nc)DioDZL{br{_faypI!%QhYN-zPn#L| zz3#xYzD2K2VsRKuh%4-HXUi1fMxiZdjruxj;=06s$d392N#edRi&xi5el3fcn*Bp4W zQGTLn-lyO%+xR^%wC@o}+e(D+UWfi7f>6K^mx*+wQ?b;ICa^L^& zOKzxX?l~hrB|M~QQzwV!t3PM6Tfb)+znd0rtND0AZJzwvMgEt-feLdwJe*eqB+pxV z$R&05efPUxoDC13HsNZz+H?Eh{bPJ88Lh8b%T0y0?J#mn%sJIvBkXZ&|Iz+Xma8-L z_PjNg{VDk6v0CD+;MTvw>XP%D5fQjxU6SlKu6d6-|#L-LTmX`9-M?!+2jku3|>Jh(HzC-T%j zCa(*+_fGrn`!=Pe_T5I4SI797RWq9Nn_nM${;{=1>^}Q3$JtLq{f}9!IA-;p{aWZA zeKSiLLxWEiu(XTC6AQdH-0J*k)|8yG{Zvl2q55C@Ggtn!&-}7~f6Ce|;-cz*`=@`g zx^r5Vtv>e%&-35^bYE{-^i@fzblt|oVc$0&-a2XTBcbobsoQs)U+QpD^;+gruYad! z8}1e~PBc6Ha^KTUWhTGxoe|24oNM{4=yc@6wI7oYhZ`d2C#aho&rB@g+Opfb_tNbB zl5gjIKfAp-FxqW)^PO8d?-pAaHeXE@E9z{Ml3v4VZG7IVf5DWi2bL%o$GrLd_2t@6 zmPdQxC4*1je};<}7$?kn9C#O4V5ye4MwFx^mZVxG7o`Fz1|tJQGhIUiT_cMSLqjWL sBP&BoZ381K1A`}}Mja>`a`RI%(<*Umn5xlb0@T3Z>FVdQ&MBb@0F19{$p8QV literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..5a56f5cadb8a5d57742912b8ab9372be58507d53 GIT binary patch literal 1270 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE1xWt5x}*n4v7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R3&|Mvbf`++>p z0*}aI1_o|n5N2eUHAey{$X?><>&pIsONLXC@13O6c?JgNm!2+;Ar-gY-gV5DNo8pN z_&;s2#x#~|ZUSGH$vZq^7YOWMTD3}H#a}k14s-rE7k;@tVqXFR_Gs+vm_BJ6mutFN`0ec*pLsXWetw-hxjZd>eoESmN@HIY&q*-Uoz<|eR<}Rh z=3`&kX6w{D8q2kg-97Jj&?;T>Hlxu2gZO7t-^f;$TF!s^SyS2mY_#ZOy=To$ThAG7 zV?KQ*YqCo7nx`+ju7@w{lL_sU7F}C9ZKG_&qOdjfk_>4KGZ+)t8n7|k;`;1P9Q`xp zukw1n;>uSidUHa1b_Z>_7I`e|Uq|?EjtfvD|dYTQ||8C(p>%Y z&&jj7bABI|N~v7Pyk+0{4>}xpY(bKW`1$s5pxv3t!u5&O88hB*a?C&XN0a}9%ekjF zZ@vHV^9W1CtWD1){Lk3@itnyv-m9Je?Cq@niV62W*KIp3mfD~;@AT@e@%yJ9_Y!~V zC~m-Z|HNlWTrOJd@3&bgp?9FRp9m zd3m<)IKv!JSWJ~?mU}W=bGp*Hi_*sZr&f2FwR|7;rGs-OUTt)?dFjVdrdrum9m{K>kOkdn^C`T3Zt+bs$y% zi|(5jePd3C2kW`oXv9w0ymwK&!6Y6BhC7`^2DK znSbieg<57CoB7i&u^3rLwa<~=YXNfW8ujB1`-^|ykdNJSwOQT$yV`-?J#997W?!Go zQ2$i?m#%{i+ksQ{%>T}$&0Dosq;T@R8I>V&3D)n^0)ES~e>rw$al0kkmxoIh%1^j? z(dx;Y7e^CuCne-azP(-L_|3)UD}$?Z{qIYk+1K&kV(!;#({HLjjyWs)%XfwA9sk!e z_gENiO`f6c`k8lDU#+Hoc+c*6>-`_iS;j3H{%7}vmpA&gj{kM=JNJ=5(vm1wEK}d_ zcV}OWUd@@n%NxII9nY129qiQiAn!y^QC8An_MP!l7QDQ1wd*(^-zWEN8~q*Od2Z5{ z1OFJEgpOKtZ8@t2EC*CeTq8 + + + + diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml new file mode 100644 index 0000000..f43ae16 --- /dev/null +++ b/app/src/main/res/drawable/side_nav_bar.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/add_part.xml b/app/src/main/res/layout/add_part.xml new file mode 100644 index 0000000..e2b757a --- /dev/null +++ b/app/src/main/res/layout/add_part.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +