This commit is contained in:
José Rebelo 2023-08-22 21:34:08 +01:00
parent c3ee43b8d3
commit ab2f916db6
9 changed files with 109 additions and 190 deletions

View File

@ -127,12 +127,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.PendingIntentUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
import nodomain.freeyourgadget.gadgetbridge.util.WidgetPreferenceStorage; import nodomain.freeyourgadget.gadgetbridge.util.WidgetPreferenceStorage;
//import nodomain.freeyourgadget.internethelper.IFtpService; import nodomain.freeyourgadget.internethelper.aidl.wifi.IWifiService;
//import nodomain.freeyourgadget.internethelper.IFtpServiceCallback; import nodomain.freeyourgadget.internethelper.aidl.wifi.IWifiCallback;
//import nodomain.freeyourgadget.internethelper.IHttpService;
//import nodomain.freeyourgadget.internethelper.IHttpServiceCallback;
//import nodomain.freeyourgadget.internethelper.IWifiService;
//import nodomain.freeyourgadget.internethelper.IWifiServiceCallback;
public class DebugActivity extends AbstractGBActivity { public class DebugActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(DebugActivity.class); private static final Logger LOG = LoggerFactory.getLogger(DebugActivity.class);
@ -922,18 +918,17 @@ public class DebugActivity extends AbstractGBActivity {
return; return;
} }
doWiFi();
//GBApplication.deviceService().onTestNewFunction(); //GBApplication.deviceService().onTestNewFunction();
} }
/*
IFtpService iFtpService;
IHttpService ihttpService;
IWifiService iWifiService; IWifiService iWifiService;
String client; String client;
int i = 0; int i = 0;
private void doWiFi() { private void doWiFi() {
final IWifiServiceCallback.Stub cb = new IWifiServiceCallback.Stub() { final IWifiCallback.Stub cb = new IWifiCallback.Stub() {
}; };
if (iWifiService == null) { 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<String> directories, List<String> 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() { private void shareLog() {
String fileName = GBApplication.getLogPath(); String fileName = GBApplication.getLogPath();
if (fileName != null && fileName.length() > 0) { if (fileName != null && fileName.length() > 0) {

View File

@ -16,6 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.musicfiles; package nodomain.freeyourgadget.gadgetbridge.activities.musicfiles;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -34,6 +35,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; 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_STATUS = "nodomain.freeyourgadget.gadgetbridge.activities.musicfiles.action_status";
public static final String ACTION_STOPPED = "nodomain.freeyourgadget.gadgetbridge.activities.musicfiles.action_stopped"; public static final String ACTION_STOPPED = "nodomain.freeyourgadget.gadgetbridge.activities.musicfiles.action_stopped";
private ProgressDialog activityFullSyncDialog;
private GBDevice gbDevice; private GBDevice gbDevice;
final BroadcastReceiver mReceiver = new BroadcastReceiver() { final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@ -100,7 +104,7 @@ public class MusicFilesActivity extends AbstractGBActivity {
final ActivityResultLauncher<String> activityResultLauncher = this.registerForActivityResult( final ActivityResultLauncher<String> activityResultLauncher = this.registerForActivityResult(
new ActivityResultContracts.GetMultipleContents(), 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); final FloatingActionButton fab = findViewById(R.id.fab);
@ -110,6 +114,7 @@ public class MusicFilesActivity extends AbstractGBActivity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
GBApplication.deviceService(gbDevice).onMusicFilesStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver); LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
} }

View File

@ -97,7 +97,7 @@ public interface EventHandler {
void onMusicFilesReq(); void onMusicFilesReq();
void onMusicFilesUpload(Uri[] uris); void onMusicFilesUpload(ArrayList<Uri> uris);
void onMusicFilesStop(); void onMusicFilesStop();

View File

@ -374,9 +374,9 @@ public class GBDeviceService implements DeviceService {
} }
@Override @Override
public void onMusicFilesUpload(Uri[] uris) { public void onMusicFilesUpload(ArrayList<Uri> uris) {
Intent intent = createIntent().setAction(ACTION_MUSIC_FILES_UPLOAD) Intent intent = createIntent().setAction(ACTION_MUSIC_FILES_UPLOAD)
.putExtra(EXTRA_MUSIC_FILES, uris); .putParcelableArrayListExtra(EXTRA_MUSIC_FILES, uris);
invokeService(intent); invokeService(intent);
} }

View File

@ -843,7 +843,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
* Upload the music files represented by the URIs to the device. * Upload the music files represented by the URIs to the device.
*/ */
@Override @Override
public void onMusicFilesUpload(Uri[] uris) { public void onMusicFilesUpload(ArrayList<Uri> uris) {
} }

View File

@ -832,7 +832,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
deviceSupport.onMusicFilesReq(); deviceSupport.onMusicFilesReq();
break; break;
case ACTION_MUSIC_FILES_UPLOAD: case ACTION_MUSIC_FILES_UPLOAD:
final Uri[] uris = (Uri[]) intent.getParcelableArrayExtra(EXTRA_MUSIC_FILES); final ArrayList<Uri> uris = intent.getParcelableArrayListExtra(EXTRA_MUSIC_FILES);
deviceSupport.onMusicFilesUpload(uris); deviceSupport.onMusicFilesUpload(uris);
break; break;
case ACTION_MUSIC_FILES_STOP: case ACTION_MUSIC_FILES_STOP:

View File

@ -303,7 +303,7 @@ public class ServiceDeviceSupport implements DeviceSupport {
} }
@Override @Override
public void onMusicFilesUpload(Uri[] uris) { public void onMusicFilesUpload(ArrayList<Uri> uris) {
if (checkBusy("music files upload")) { if (checkBusy("music files upload")) {
return; return;
} }

View File

@ -16,6 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami; 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 org.apache.commons.lang3.ArrayUtils.subarray;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Service.*; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Service.*;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.SUCCESS; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.SUCCESS;
@ -54,6 +55,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; 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.UpdateFirmwareOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.UpdateFirmwareOperation2021; 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.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.ZeppOsAgpsUpdateOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.operations.ZeppOsGpxRouteUploadOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.operations.ZeppOsGpxRouteUploadOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAgpsService; 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); 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<Uri> uris) {
musicFilesCoordinator.connectFtp("192.168.43.1", "anonymous");
musicFilesCoordinator.uploadFiles(uris);
}
@Override
public void onMusicFilesStop() {
ftpServerService.stopFtpServer();
ftpServerService.removeCallback();
wifiService.stopWifiHotspot();
wifiService.removeCallback();
}
@Override @Override
public void onEnableRealtimeSteps(final boolean enable) { public void onEnableRealtimeSteps(final boolean enable) {
final byte[] cmd = {STEPS_CMD_ENABLE_REALTIME, bool(enable)}; final byte[] cmd = {STEPS_CMD_ENABLE_REALTIME, bool(enable)};

View File

@ -63,6 +63,12 @@ public class ZeppOsMusicFilesCoordinator {
LOG.info("onServiceConnected: {}", className); LOG.info("onServiceConnected: {}", className);
iFtpService = IFtpService.Stub.asInterface(service); 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) { public void onServiceDisconnected(final ComponentName className) {
@ -76,7 +82,7 @@ public class ZeppOsMusicFilesCoordinator {
public void onConnect(boolean success, String msg) throws RemoteException { public void onConnect(boolean success, String msg) throws RemoteException {
LOG.info("onConnect {} {}", success, msg); LOG.info("onConnect {} {}", success, msg);
if (success) { if (success) {
iFtpService.login(ftpClient, "gadgetbridge", "cenas123"); iFtpService.login(ftpClient, "anonymous", "");
} }
} }
@ -107,7 +113,13 @@ public class ZeppOsMusicFilesCoordinator {
this.internetHelper = new InternetHelper(mContext); 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"); final Intent intent = new Intent("nodomain.freeyourgadget.internethelper.FtpService");
intent.setPackage(internetHelper.getPackageName()); intent.setPackage(internetHelper.getPackageName());
boolean res = mContext.bindService(intent, mFtpConnection, Context.BIND_AUTO_CREATE); 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); mContext.unbindService(mFtpConnection);
} }
public void uploadFiles(final List<Uri> uriList) { public void uploadFiles(final List<Uri> uriList) {
if (iFtpService == null || ftpClient == null) { //if (iFtpService == null || ftpClient == null) {
LOG.error("No ftp client"); // LOG.error("No ftp client");
return; // return;
} //}
final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
@ -173,7 +185,7 @@ public class ZeppOsMusicFilesCoordinator {
final String targetName = md5 + "." + FileUtils.getExtension(uri.toString()); 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) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@ -184,10 +196,17 @@ public class ZeppOsMusicFilesCoordinator {
} }
public void uploadNextFile() { public void uploadNextFile() {
//try { if (filesToUpload.isEmpty()) {
// iFtpService.upload(ftpClient, uri.toString(), "/cenas.mp3"); LOG.info("No more files to upload");
//} catch (RemoteException e) { return;
// LOG.error("oops", e); }
//}
for (final Map.Entry<Uri, String> entry : filesToUpload.entrySet()) {
try {
iFtpService.upload(ftpClient, entry.getKey().toString(), entry.getValue());
} catch (RemoteException e) {
LOG.error("oops", e);
}
}
} }
} }