diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index 6cd94204b..3c36d00e2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -127,12 +127,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.PendingIntentUtils; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.util.WidgetPreferenceStorage; -//import nodomain.freeyourgadget.internethelper.IFtpService; -//import nodomain.freeyourgadget.internethelper.IFtpServiceCallback; -//import nodomain.freeyourgadget.internethelper.IHttpService; -//import nodomain.freeyourgadget.internethelper.IHttpServiceCallback; -//import nodomain.freeyourgadget.internethelper.IWifiService; -//import nodomain.freeyourgadget.internethelper.IWifiServiceCallback; +import nodomain.freeyourgadget.internethelper.aidl.wifi.IWifiService; +import nodomain.freeyourgadget.internethelper.aidl.wifi.IWifiCallback; public class DebugActivity extends AbstractGBActivity { private static final Logger LOG = LoggerFactory.getLogger(DebugActivity.class); @@ -922,18 +918,17 @@ public class DebugActivity extends AbstractGBActivity { return; } + doWiFi(); + //GBApplication.deviceService().onTestNewFunction(); } - /* - IFtpService iFtpService; - IHttpService ihttpService; IWifiService iWifiService; String client; int i = 0; private void doWiFi() { - final IWifiServiceCallback.Stub cb = new IWifiServiceCallback.Stub() { + final IWifiCallback.Stub cb = new IWifiCallback.Stub() { }; if (iWifiService == null) { @@ -983,166 +978,6 @@ public class DebugActivity extends AbstractGBActivity { } } - private void doHttp() { - final IHttpServiceCallback.Stub cb = new IHttpServiceCallback.Stub() { - - @Override - public void onGet(Bundle bundle) throws RemoteException { - LOG.info("cenas: {}", bundle); - } - }; - - if (ihttpService == null) { - LOG.info("connecting"); - ServiceConnection mConnection = new ServiceConnection() { - // Called when the connection with the service is established. - public void onServiceConnected(ComponentName className, IBinder service) { - LOG.info("onServiceConnected"); - - // Following the preceding example for an AIDL interface, - // this gets an instance of the IRemoteInterface, which we can use to call on the service. - ihttpService = IHttpService.Stub.asInterface(service); - } - - // Called when the connection with the service disconnects unexpectedly. - public void onServiceDisconnected(ComponentName className) { - LOG.error("Service has unexpectedly disconnected"); - ihttpService = null; - } - }; - Intent intent = new Intent("nodomain.freeyourgadget.internethelper.HttpService"); - intent.setPackage("nodomain.freeyourgadget.internethelper"); - boolean res = this.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - if (res) { - LOG.info("Bound to HttpService"); - } else { - LOG.warn("Could not bind to HttpService"); - } - } else if (i == 0) { - try { - final int version = ihttpService.version(); - LOG.info("version = {}", version); - } catch (RemoteException e) { - LOG.error("version {} failed", i ,e); - } - i++; - } else if (i == 1) { - try { - ihttpService.get("http://example.com", cb); - LOG.info("get = {}", client); - } catch (RemoteException e) { - LOG.error("get {} failed", i ,e); - } - i++; - } else { - LOG.info("wtf {}", i); - } - } - - private void doFtp() { - final IFtpServiceCallback.Stub cb = new IFtpServiceCallback.Stub() { - @Override - public void onConnect(boolean success, String msg) throws RemoteException { - LOG.info("onConnect {} {}", success, msg); - } - - @Override - public void onLogin(boolean success, String msg) throws RemoteException { - LOG.info("onLogin {} {}", success, msg); - } - - @Override - public void onList(String path, List directories, List files) throws RemoteException { - LOG.info("onList {} {} {}", path, directories, files); - } - - @Override - public void onUpload(String path, boolean success, String msg) throws RemoteException { - LOG.info("onUpload"); - } - - @Override - public void onDownload(String path, boolean success, String msg) throws RemoteException { - LOG.info("onDownload"); - } - }; - - if (iFtpService == null) { - LOG.info("connecting"); - ServiceConnection mConnection = new ServiceConnection() { - // Called when the connection with the service is established. - public void onServiceConnected(ComponentName className, IBinder service) { - LOG.info("onServiceConnected"); - - // Following the preceding example for an AIDL interface, - // this gets an instance of the IRemoteInterface, which we can use to call on the service. - iFtpService = IFtpService.Stub.asInterface(service); - } - - // Called when the connection with the service disconnects unexpectedly. - public void onServiceDisconnected(ComponentName className) { - LOG.error("Service has unexpectedly disconnected"); - iFtpService = null; - } - }; - Intent intent = new Intent("nodomain.freeyourgadget.internethelper.ftp.FtpService"); - intent.setPackage("nodomain.freeyourgadget.internethelper"); - boolean res = this.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - if (res) { - LOG.info("Bound to NetworkService"); - } else { - LOG.warn("Could not bind to NetworkService"); - } - } else if (i == 0) { - try { - final int version = iFtpService.version(); - LOG.info("version = {}", version); - } catch (RemoteException e) { - LOG.error("cenas {} failed", i ,e); - } - i++; - } else if (i == 1) { - try { - client = iFtpService.createClient(); - LOG.info("client = {}", client); - } catch (RemoteException e) { - LOG.error("cenas {} failed", i ,e); - } - i++; - } else if (i == 2) { - try { - iFtpService.connect(client, "10.0.1.12", 8710, cb); - LOG.info("connected"); - } catch (RemoteException e) { - LOG.error("connected {} failed", i ,e); - } - i++; - } else if (i == 3) { - i++; - try { - iFtpService.login(client, "gadgetbridge", "cenas123", cb); - } catch (RemoteException e) { - LOG.error("login {} failed", i ,e); - } - } else if (i == 4) { - i++; - try { - iFtpService.list(client, "/", cb); - } catch (RemoteException e) { - LOG.error("disconnect {} failed", i ,e); - } - } else if (i == 5) { - i++; - try { - iFtpService.disconnect(client); - } catch (RemoteException e) { - LOG.error("disconnect {} failed", i ,e); - } - } else { - LOG.info("wtf {}", i); - } - }*/ - private void shareLog() { String fileName = GBApplication.getLogPath(); if (fileName != null && fileName.length() > 0) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/musicfiles/MusicFilesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/musicfiles/MusicFilesActivity.java index f3371cdd6..3c176f195 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/musicfiles/MusicFilesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/musicfiles/MusicFilesActivity.java @@ -16,6 +16,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities.musicfiles; +import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -34,6 +35,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.Objects; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -49,6 +51,8 @@ public class MusicFilesActivity extends AbstractGBActivity { public static final String ACTION_STATUS = "nodomain.freeyourgadget.gadgetbridge.activities.musicfiles.action_status"; public static final String ACTION_STOPPED = "nodomain.freeyourgadget.gadgetbridge.activities.musicfiles.action_stopped"; + private ProgressDialog activityFullSyncDialog; + private GBDevice gbDevice; final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -100,7 +104,7 @@ public class MusicFilesActivity extends AbstractGBActivity { final ActivityResultLauncher activityResultLauncher = this.registerForActivityResult( new ActivityResultContracts.GetMultipleContents(), - uris -> GBApplication.deviceService(gbDevice).onMusicFilesUpload(uris.toArray(new Uri[0])) + uris -> GBApplication.deviceService(gbDevice).onMusicFilesUpload(new ArrayList<>(uris)) ); final FloatingActionButton fab = findViewById(R.id.fab); @@ -110,6 +114,7 @@ public class MusicFilesActivity extends AbstractGBActivity { @Override protected void onDestroy() { super.onDestroy(); + GBApplication.deviceService(gbDevice).onMusicFilesStop(); LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java index 2532dc94a..c23ac15f2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java @@ -97,7 +97,7 @@ public interface EventHandler { void onMusicFilesReq(); - void onMusicFilesUpload(Uri[] uris); + void onMusicFilesUpload(ArrayList uris); void onMusicFilesStop(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 1121216d3..a35bb0dc3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -374,9 +374,9 @@ public class GBDeviceService implements DeviceService { } @Override - public void onMusicFilesUpload(Uri[] uris) { + public void onMusicFilesUpload(ArrayList uris) { Intent intent = createIntent().setAction(ACTION_MUSIC_FILES_UPLOAD) - .putExtra(EXTRA_MUSIC_FILES, uris); + .putParcelableArrayListExtra(EXTRA_MUSIC_FILES, uris); invokeService(intent); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 7f6624a8d..e5e99a695 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -843,7 +843,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { * Upload the music files represented by the URIs to the device. */ @Override - public void onMusicFilesUpload(Uri[] uris) { + public void onMusicFilesUpload(ArrayList uris) { } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 2be73c459..113a5e92f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -832,7 +832,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere deviceSupport.onMusicFilesReq(); break; case ACTION_MUSIC_FILES_UPLOAD: - final Uri[] uris = (Uri[]) intent.getParcelableArrayExtra(EXTRA_MUSIC_FILES); + final ArrayList uris = intent.getParcelableArrayListExtra(EXTRA_MUSIC_FILES); deviceSupport.onMusicFilesUpload(uris); break; case ACTION_MUSIC_FILES_STOP: diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index 3dc80b1ec..29a82312f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -303,7 +303,7 @@ public class ServiceDeviceSupport implements DeviceSupport { } @Override - public void onMusicFilesUpload(Uri[] uris) { + public void onMusicFilesUpload(ArrayList uris) { if (checkBusy("music files upload")) { return; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java index 589f8b9b2..39e738ae0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java @@ -16,6 +16,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami; +import static org.apache.commons.lang3.ArrayUtils.add; import static org.apache.commons.lang3.ArrayUtils.subarray; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Service.*; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.SUCCESS; @@ -54,6 +55,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -101,6 +103,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.UpdateFirmwareOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.UpdateFirmwareOperation2021; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.AbstractZeppOsService; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.ZeppOsMusicFilesCoordinator; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.operations.ZeppOsAgpsUpdateOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.operations.ZeppOsGpxRouteUploadOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAgpsService; @@ -571,6 +574,63 @@ public abstract class Huami2021Support extends HuamiSupport implements ZeppOsFil musicService.sendMusicState(musicSpec, musicStateSpec); } + private ZeppOsMusicFilesCoordinator musicFilesCoordinator; + + @Override + public void onMusicFilesStart() { + if (musicFilesCoordinator == null) { + musicFilesCoordinator = new ZeppOsMusicFilesCoordinator(getContext()); + } + + wifiService.setCallback(new ZeppOsWifiService.Callback() { + @Override + public void onWifiHotspotStart() { + LOG.debug("onWifiHotspotStart"); + ftpServerService.startFtpServer("/mnt/data"); + } + + @Override + public void onWifiHotspotStop() { + LOG.debug("onWifiHotspotStop"); + } + }); + final String ssid = getDevicePrefs().getString(DeviceSettingsPreferenceConst.WIFI_HOTSPOT_SSID, "Huami2021"); + final String password = getDevicePrefs().getString(DeviceSettingsPreferenceConst.WIFI_HOTSPOT_PASSWORD, "p4ssw0rd"); + + ftpServerService.setCallback(new ZeppOsFtpServerService.Callback() { + @Override + public void onFtpServerStart(final String address, final String username) { + LOG.debug("onFtpServerStart {} {}", address, username); + } + + @Override + public void onFtpServerStop() { + LOG.debug("onFtpServerStop"); + } + }); + + wifiService.startWifiHotspot(ssid, password); + } + + @Override + public void onMusicFilesReq() { + + } + + @Override + public void onMusicFilesUpload(final ArrayList uris) { + musicFilesCoordinator.connectFtp("192.168.43.1", "anonymous"); + musicFilesCoordinator.uploadFiles(uris); + } + + @Override + public void onMusicFilesStop() { + ftpServerService.stopFtpServer(); + ftpServerService.removeCallback(); + wifiService.stopWifiHotspot(); + wifiService.removeCallback(); + } + @Override public void onEnableRealtimeSteps(final boolean enable) { final byte[] cmd = {STEPS_CMD_ENABLE_REALTIME, bool(enable)}; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/zeppos/ZeppOsMusicFilesCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/zeppos/ZeppOsMusicFilesCoordinator.java index 3af68e006..93c642d0a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/zeppos/ZeppOsMusicFilesCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/zeppos/ZeppOsMusicFilesCoordinator.java @@ -63,6 +63,12 @@ public class ZeppOsMusicFilesCoordinator { LOG.info("onServiceConnected: {}", className); iFtpService = IFtpService.Stub.asInterface(service); + try { + ftpClient = iFtpService.createClient(ftpCallback); + iFtpService.connect(ftpClient, "192.168.43.1", 5210); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } public void onServiceDisconnected(final ComponentName className) { @@ -76,7 +82,7 @@ public class ZeppOsMusicFilesCoordinator { public void onConnect(boolean success, String msg) throws RemoteException { LOG.info("onConnect {} {}", success, msg); if (success) { - iFtpService.login(ftpClient, "gadgetbridge", "cenas123"); + iFtpService.login(ftpClient, "anonymous", ""); } } @@ -107,7 +113,13 @@ public class ZeppOsMusicFilesCoordinator { this.internetHelper = new InternetHelper(mContext); } - public void initFtp() { + private String address; + private String username; + + public void connectFtp(final String address, final String username) { + this.address = address; + this.username = username; + final Intent intent = new Intent("nodomain.freeyourgadget.internethelper.FtpService"); intent.setPackage(internetHelper.getPackageName()); boolean res = mContext.bindService(intent, mFtpConnection, Context.BIND_AUTO_CREATE); @@ -118,15 +130,15 @@ public class ZeppOsMusicFilesCoordinator { } } - public void destroy() { + public void destroyFtp() { mContext.unbindService(mFtpConnection); } public void uploadFiles(final List uriList) { - if (iFtpService == null || ftpClient == null) { - LOG.error("No ftp client"); - return; - } + //if (iFtpService == null || ftpClient == null) { + // LOG.error("No ftp client"); + // return; + //} final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); @@ -173,7 +185,7 @@ public class ZeppOsMusicFilesCoordinator { final String targetName = md5 + "." + FileUtils.getExtension(uri.toString()); - filesToUpload.put(uri, "/" + targetName); + filesToUpload.put(uri, "/mnt/data/Downloads/Music/list/" + targetName); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { @@ -184,10 +196,17 @@ public class ZeppOsMusicFilesCoordinator { } public void uploadNextFile() { - //try { - // iFtpService.upload(ftpClient, uri.toString(), "/cenas.mp3"); - //} catch (RemoteException e) { - // LOG.error("oops", e); - //} + if (filesToUpload.isEmpty()) { + LOG.info("No more files to upload"); + return; + } + + for (final Map.Entry entry : filesToUpload.entrySet()) { + try { + iFtpService.upload(ftpClient, entry.getKey().toString(), entry.getValue()); + } catch (RemoteException e) { + LOG.error("oops", e); + } + } } }