Pebble: Allow stopping apps though PebbleKit messages (also in the API)

This commit is contained in:
Andreas Shimokawa 2015-09-13 21:44:26 +02:00
parent 6fff4fb7ba
commit 95e22a4e32
11 changed files with 35 additions and 26 deletions

View File

@ -114,7 +114,7 @@ public class AppManagerActivity extends Activity {
@Override
public void onItemClick(AdapterView parent, View v, int position, long id) {
UUID uuid = appList.get(position).getUUID();
GBApplication.deviceService().onAppStart(uuid);
GBApplication.deviceService().onAppStart(uuid, true);
}
});

View File

@ -34,7 +34,7 @@ public interface EventHandler {
void onAppInfoReq();
void onAppStart(UUID uuid);
void onAppStart(UUID uuid, boolean start);
void onAppDelete(UUID uuid);

View File

@ -11,8 +11,8 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
public class GBDeviceService implements DeviceService {
@ -150,9 +150,10 @@ public class GBDeviceService implements DeviceService {
}
@Override
public void onAppStart(UUID uuid) {
public void onAppStart(UUID uuid, boolean start) {
Intent intent = createIntent().setAction(ACTION_STARTAPP)
.putExtra(EXTRA_APP_UUID, uuid);
.putExtra(EXTRA_APP_UUID, uuid)
.putExtra(EXTRA_APP_START, start);
invokeService(intent);
}

View File

@ -45,6 +45,7 @@ public interface DeviceService extends EventHandler {
static final String EXTRA_MUSIC_ALBUM = "music_album";
static final String EXTRA_MUSIC_TRACK = "music_track";
static final String EXTRA_APP_UUID = "app_uuid";
static final String EXTRA_APP_START = "app_start";
static final String EXTRA_URI = "uri";
static final String EXTRA_ALARMS = "alarms";
static final String EXTRA_PERFORM_PAIR = "perform_pair";

View File

@ -26,7 +26,6 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
@ -51,6 +50,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SE
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_START;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_STARTAPP;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_ALARMS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_START;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_UUID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_COMMAND;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_PHONENUMBER;
@ -183,7 +183,7 @@ public class DeviceCommunicationService extends Service {
case ACTION_NOTIFICATION_GENERIC: {
String title = intent.getStringExtra(EXTRA_NOTIFICATION_TITLE);
String body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY);
int handle = intent.getIntExtra(EXTRA_NOTIFICATION_HANDLE,-1);
int handle = intent.getIntExtra(EXTRA_NOTIFICATION_HANDLE, -1);
NotificationKind notificationKind = (NotificationKind) intent.getSerializableExtra(EXTRA_NOTIFICATION_KIND);
mDeviceSupport.onGenericNotification(title, body, handle, notificationKind);
break;
@ -247,7 +247,8 @@ public class DeviceCommunicationService extends Service {
break;
case ACTION_STARTAPP: {
UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID);
mDeviceSupport.onAppStart(uuid);
boolean start = intent.getBooleanExtra(EXTRA_APP_START, true);
mDeviceSupport.onAppStart(uuid, start);
break;
}
case ACTION_DELETEAPP: {
@ -273,6 +274,7 @@ public class DeviceCommunicationService extends Service {
/**
* For testing!
*
* @param factory
*/
public void setDeviceSupportFactory(DeviceSupportFactory factory) {
@ -282,6 +284,7 @@ public class DeviceCommunicationService extends Service {
/**
* Disposes the current DeviceSupport instance (if any) and sets a new device support instance
* (if not null).
*
* @param deviceSupport
*/
private void setDeviceSupport(@Nullable DeviceSupport deviceSupport) {

View File

@ -178,11 +178,11 @@ public class ServiceDeviceSupport implements DeviceSupport {
}
@Override
public void onAppStart(UUID uuid) {
public void onAppStart(UUID uuid, boolean start) {
if (checkBusy("app start")) {
return;
}
delegate.onAppStart(uuid);
delegate.onAppStart(uuid, start);
}
@Override

View File

@ -574,7 +574,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
}
@Override
public void onAppStart(UUID uuid) {
public void onAppStart(UUID uuid, boolean start) {
// not supported
}

View File

@ -88,9 +88,10 @@ public class PebbleIoThread extends GBDeviceIoThread {
UUID uuid;
switch (action) {
case PEBBLEKIT_ACTION_APP_START:
case PEBBLEKIT_ACTION_APP_STOP:
uuid = (UUID) intent.getSerializableExtra("uuid");
if (uuid != null) {
write(mPebbleProtocol.encodeAppStart(uuid));
write(mPebbleProtocol.encodeAppStart(uuid, action == PEBBLEKIT_ACTION_APP_START));
}
break;
case PEBBLEKIT_ACTION_APP_SEND:

View File

@ -67,6 +67,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
static final short ENDPOINT_PUTBYTES = (short) 48879;
static final byte APPRUNSTATE_START = 1;
static final byte APPRUNSTATE_STOP = 2;
static final byte BLOBDB_INSERT = 1;
static final byte BLOBDB_DELETE = 4;
@ -877,19 +878,20 @@ public class PebbleProtocol extends GBDeviceProtocol {
}
@Override
public byte[] encodeAppStart(UUID uuid) {
public byte[] encodeAppStart(UUID uuid, boolean start) {
if (isFw3x) {
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_APPRUNSTATE);
buf.order(ByteOrder.BIG_ENDIAN);
buf.putShort(LENGTH_APPRUNSTATE);
buf.putShort(ENDPOINT_APPRUNSTATE);
buf.put(APPRUNSTATE_START);
buf.put(start ? APPRUNSTATE_START : APPRUNSTATE_STOP);
buf.putLong(uuid.getMostSignificantBits());
buf.putLong(uuid.getLeastSignificantBits());
return buf.array();
} else {
ArrayList<Pair<Integer, Object>> pairs = new ArrayList<>();
pairs.add(new Pair<>(1, (Object) 1)); // launch
int param = start ? 1 : 0;
pairs.add(new Pair<>(1, (Object) param));
return encodeApplicationMessagePush(ENDPOINT_LAUNCHER, uuid, pairs);
}
}

View File

@ -5,23 +5,23 @@ import org.slf4j.LoggerFactory;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler;
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
/**
* An abstract base class for devices speaking a serial protocol, like via
* an rfcomm bluetooth socket or a TCP socket.
*
* <p/>
* This class uses two helper classes to deal with that:
* - GBDeviceIoThread, which creates and maintains the actual socket connection and implements the transport layer
* - GBDeviceProtocol, which implements the encoding and decoding of messages, i.e. the actual device specific protocol
*
* <p/>
* Note that these two classes need to be implemented in a device specific way.
*
* <p/>
* This implementation implements all methods of {@link EventHandler}, calls the {@link GBDeviceProtocol device protocol}
* to create the device specific message for the respective events and sends them to the device via {@link #sendToDevice(byte[])}.
*/
@ -85,6 +85,7 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport
/**
* Sends the given message to the device. This implementation delegates the
* writing to the {@link #getDeviceIOThread device io thread}
*
* @param bytes the message to send to the device
*/
protected void sendToDevice(byte[] bytes) {
@ -149,8 +150,8 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport
}
@Override
public void onAppStart(UUID uuid) {
byte[] bytes = gbDeviceProtocol.encodeAppStart(uuid);
public void onAppStart(UUID uuid, boolean start) {
byte[] bytes = gbDeviceProtocol.encodeAppStart(uuid, start);
sendToDevice(bytes);
}

View File

@ -2,9 +2,9 @@ package nodomain.freeyourgadget.gadgetbridge.service.serial;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
public abstract class GBDeviceProtocol {
@ -48,7 +48,7 @@ public abstract class GBDeviceProtocol {
return null;
}
public byte[] encodeAppStart(UUID uuid) {
public byte[] encodeAppStart(UUID uuid, boolean start) {
return null;
}