1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2025-02-12 18:06:47 +01:00

support removing apps/watchfaces

This commit is contained in:
Andreas Shimokawa 2015-03-26 18:11:47 +01:00
parent 67a5917597
commit 42e53c3c8d
7 changed files with 156 additions and 27 deletions

View File

@ -6,6 +6,10 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.Bundle; import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView; import android.widget.ListView;
import java.util.ArrayList; import java.util.ArrayList;
@ -15,15 +19,8 @@ import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAppAdapter;
public class AppManagerActivity extends Activity { public class AppManagerActivity extends Activity {
private final String TAG = this.getClass().getSimpleName();
public static final String ACTION_REFRESH_APPLIST public static final String ACTION_REFRESH_APPLIST
= "nodomain.freeyourgadget.gadgetbride.appmanager.action.refresh_applist"; = "nodomain.freeyourgadget.gadgetbride.appmanager.action.refresh_applist";
ListView appListView;
GBDeviceAppAdapter mGBDeviceAppAdapter;
final List<GBDeviceApp> appList = new ArrayList<>();
private BroadcastReceiver mReceiver = new BroadcastReceiver() { private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@ -31,16 +28,25 @@ public class AppManagerActivity extends Activity {
if (action.equals(ControlCenter.ACTION_QUIT)) { if (action.equals(ControlCenter.ACTION_QUIT)) {
finish(); finish();
} else if (action.equals(ACTION_REFRESH_APPLIST)) { } else if (action.equals(ACTION_REFRESH_APPLIST)) {
appList.clear();
int appCount = intent.getIntExtra("app_count", 0); int appCount = intent.getIntExtra("app_count", 0);
for (Integer i = 0; i < appCount; i++) { for (Integer i = 0; i < appCount; i++) {
String appName = intent.getStringExtra("app_name" + i.toString()); String appName = intent.getStringExtra("app_name" + i.toString());
String appCreator = intent.getStringExtra("app_creator" + i.toString()); String appCreator = intent.getStringExtra("app_creator" + i.toString());
appList.add(new GBDeviceApp(appName, appCreator, "")); int id = intent.getIntExtra("app_id" + i.toString(), -1);
int index = intent.getIntExtra("app_index" + i.toString(), -1);
appList.add(new GBDeviceApp(id, index, appName, appCreator, ""));
} }
mGBDeviceAppAdapter.notifyDataSetChanged(); mGBDeviceAppAdapter.notifyDataSetChanged();
} }
} }
}; };
final List<GBDeviceApp> appList = new ArrayList<>();
private final String TAG = this.getClass().getSimpleName();
private ListView appListView;
private GBDeviceAppAdapter mGBDeviceAppAdapter;
private GBDeviceApp selectedApp = null;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -50,6 +56,7 @@ public class AppManagerActivity extends Activity {
appListView = (ListView) findViewById(R.id.appListView); appListView = (ListView) findViewById(R.id.appListView);
mGBDeviceAppAdapter = new GBDeviceAppAdapter(this, appList); mGBDeviceAppAdapter = new GBDeviceAppAdapter(this, appList);
appListView.setAdapter(this.mGBDeviceAppAdapter); appListView.setAdapter(this.mGBDeviceAppAdapter);
registerForContextMenu(appListView);
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(ControlCenter.ACTION_QUIT); filter.addAction(ControlCenter.ACTION_QUIT);
@ -61,6 +68,33 @@ public class AppManagerActivity extends Activity {
startService(startIntent); startService(startIntent);
} }
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(
R.menu.appmanager_context, menu);
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) menuInfo;
selectedApp = appList.get(acmi.position);
menu.setHeaderTitle(selectedApp.getName());
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.appmanager_app_delete:
if (selectedApp != null) {
Intent deleteIntent = new Intent(this, BluetoothCommunicationService.class);
deleteIntent.setAction(BluetoothCommunicationService.ACTION_DELETEAPP);
deleteIntent.putExtra("app_id", selectedApp.getId());
deleteIntent.putExtra("app_index", selectedApp.getIndex());
startService(deleteIntent);
}
return true;
default:
return super.onContextItemSelected(item);
}
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();

View File

@ -31,6 +31,7 @@ import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommand; import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommand;
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandAppInfo; import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandAppInfo;
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandAppManagementResult;
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandCallControl; import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandCallControl;
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandMusicControl; import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandMusicControl;
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandVersionInfo; import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandVersionInfo;
@ -57,6 +58,8 @@ public class BluetoothCommunicationService extends Service {
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.request_versioninfo"; = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.request_versioninfo";
public static final String ACTION_REQUEST_APPINFO public static final String ACTION_REQUEST_APPINFO
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.request_appinfo"; = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.request_appinfo";
public static final String ACTION_DELETEAPP
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.deleteapp";
private static final String TAG = "BluetoothCommunicationService"; private static final String TAG = "BluetoothCommunicationService";
private static final int NOTIFICATION_ID = 1; private static final int NOTIFICATION_ID = 1;
@ -128,14 +131,14 @@ public class BluetoothCommunicationService extends Service {
switch (deviceCmd.commandClass) { switch (deviceCmd.commandClass) {
case MUSIC_CONTROL: case MUSIC_CONTROL:
Log.i(TAG, "Got command for MUSIC_CONTROL"); Log.i(TAG, "Got command for MUSIC_CONTROL");
GBDeviceCommandMusicControl musicCmd = (GBDeviceCommandMusicControl)deviceCmd; GBDeviceCommandMusicControl musicCmd = (GBDeviceCommandMusicControl) deviceCmd;
Intent musicIntent = new Intent(GBMusicControlReceiver.ACTION_MUSICCONTROL); Intent musicIntent = new Intent(GBMusicControlReceiver.ACTION_MUSICCONTROL);
musicIntent.putExtra("command", musicCmd.command.ordinal()); musicIntent.putExtra("command", musicCmd.command.ordinal());
sendBroadcast(musicIntent); sendBroadcast(musicIntent);
break; break;
case CALL_CONTROL: case CALL_CONTROL:
Log.i(TAG, "Got command for CALL_CONTROL"); Log.i(TAG, "Got command for CALL_CONTROL");
GBDeviceCommandCallControl callCmd = (GBDeviceCommandCallControl)deviceCmd; GBDeviceCommandCallControl callCmd = (GBDeviceCommandCallControl) deviceCmd;
Intent callIntent = new Intent(GBCallControlReceiver.ACTION_CALLCONTROL); Intent callIntent = new Intent(GBCallControlReceiver.ACTION_CALLCONTROL);
callIntent.putExtra("command", callCmd.command.ordinal()); callIntent.putExtra("command", callCmd.command.ordinal());
sendBroadcast(callIntent); sendBroadcast(callIntent);
@ -145,22 +148,43 @@ public class BluetoothCommunicationService extends Service {
if (gbdevice == null) { if (gbdevice == null) {
return; return;
} }
GBDeviceCommandVersionInfo infoCmd = (GBDeviceCommandVersionInfo)deviceCmd; GBDeviceCommandVersionInfo infoCmd = (GBDeviceCommandVersionInfo) deviceCmd;
gbdevice.setFirmwareVersion(infoCmd.fwVersion); gbdevice.setFirmwareVersion(infoCmd.fwVersion);
sendDeviceUpdateIntent(); sendDeviceUpdateIntent();
break; break;
case APP_INFO: case APP_INFO:
Log.i(TAG, "Got command for APP_INFO"); Log.i(TAG, "Got command for APP_INFO");
GBDeviceCommandAppInfo appInfoCmd = (GBDeviceCommandAppInfo)deviceCmd; GBDeviceCommandAppInfo appInfoCmd = (GBDeviceCommandAppInfo) deviceCmd;
Intent appInfoIntent = new Intent(AppManagerActivity.ACTION_REFRESH_APPLIST); Intent appInfoIntent = new Intent(AppManagerActivity.ACTION_REFRESH_APPLIST);
int appCount = appInfoCmd.apps.length; int appCount = appInfoCmd.apps.length;
appInfoIntent.putExtra("app_count", appCount); appInfoIntent.putExtra("app_count", appCount);
for (Integer i = 0; i < appCount; i++) { for (Integer i = 0; i < appCount; i++) {
appInfoIntent.putExtra("app_name" + i.toString(), appInfoCmd.apps[i].getName()); appInfoIntent.putExtra("app_name" + i.toString(), appInfoCmd.apps[i].getName());
appInfoIntent.putExtra("app_creator" + i.toString(), appInfoCmd.apps[i].getCreator()); appInfoIntent.putExtra("app_creator" + i.toString(), appInfoCmd.apps[i].getCreator());
appInfoIntent.putExtra("app_id" + i.toString(), appInfoCmd.apps[i].getId());
appInfoIntent.putExtra("app_index" + i.toString(), appInfoCmd.apps[i].getIndex());
} }
sendBroadcast(appInfoIntent); sendBroadcast(appInfoIntent);
break; break;
case APP_MANAGEMENT_RES:
GBDeviceCommandAppManagementResult appMgmtRes = (GBDeviceCommandAppManagementResult) deviceCmd;
switch (appMgmtRes.type) {
case DELETE:
switch (appMgmtRes.result) {
case FAILURE:
Log.i(TAG, "failure removing app"); // TODO: report to AppManager
break;
case SUCCESS:
// refresh app list
mBtSocketIoThread.write(PebbleProtocol.encodeAppInfoReq());
break;
default:
break;
}
break;
default:
break;
}
default: default:
break; break;
} }
@ -276,6 +300,10 @@ public class BluetoothCommunicationService extends Service {
} }
} else if (action.equals(ACTION_REQUEST_APPINFO)) { } else if (action.equals(ACTION_REQUEST_APPINFO)) {
mBtSocketIoThread.write(PebbleProtocol.encodeAppInfoReq()); mBtSocketIoThread.write(PebbleProtocol.encodeAppInfoReq());
} else if (action.equals(ACTION_DELETEAPP)) {
int id = intent.getIntExtra("app_id", -1);
int index = intent.getIntExtra("app_index", -1);
mBtSocketIoThread.write(PebbleProtocol.encodeAppDelete(id, index));
} else if (action.equals(ACTION_START)) { } else if (action.equals(ACTION_START)) {
startForeground(NOTIFICATION_ID, createNotification("Gadgetbridge running")); startForeground(NOTIFICATION_ID, createNotification("Gadgetbridge running"));
mStarted = true; mStarted = true;

View File

@ -4,8 +4,12 @@ public class GBDeviceApp {
private final String name; private final String name;
private final String creator; private final String creator;
private final String version; private final String version;
private final int id;
private final int index;
public GBDeviceApp(String name, String creator, String version) { public GBDeviceApp(int id, int index, String name, String creator, String version) {
this.id = id;
this.index = index;
this.name = name; this.name = name;
this.creator = creator; this.creator = creator;
this.version = version; this.version = version;
@ -22,4 +26,12 @@ public class GBDeviceApp {
public String getVersion() { public String getVersion() {
return version; return version;
} }
public int getId() {
return id;
}
public int getIndex() {
return index;
}
} }

View File

@ -9,7 +9,8 @@ public abstract class GBDeviceCommand {
MUSIC_CONTROL, MUSIC_CONTROL,
CALL_CONTROL, CALL_CONTROL,
APP_INFO, APP_INFO,
VERSION_INFO VERSION_INFO,
APP_MANAGEMENT_RES,
} }
} }

View File

@ -0,0 +1,21 @@
package nodomain.freeyourgadget.gadgetbridge.protocol;
public class GBDeviceCommandAppManagementResult extends GBDeviceCommand {
public Result result = Result.UNKNOWN;
public CommandType type = CommandType.UNKNOWN;
public GBDeviceCommandAppManagementResult() {
commandClass = CommandClass.APP_MANAGEMENT_RES;
}
public enum CommandType {
UNKNOWN,
DELETE,
}
public enum Result {
UNKNOWN,
SUCCESS,
FAILURE,
}
}

View File

@ -69,10 +69,14 @@ public class PebbleProtocol {
static final byte FIRMWAREVERSION_GETVERSION = 0; static final byte FIRMWAREVERSION_GETVERSION = 0;
static final byte APPMANAGER_GETAPPBANKSTATUS = 1; static final byte APPMANAGER_GETAPPBANKSTATUS = 1;
static final byte APPMANAGER_REMOVEAPP = 2;
static final int APPMANAGER_RES_SUCCESS = 1;
static final short LENGTH_PREFIX = 4; static final short LENGTH_PREFIX = 4;
static final short LENGTH_SETTIME = 9; static final short LENGTH_SETTIME = 5;
static final short LENGTH_PHONEVERSION = 21; static final short LENGTH_REMOVEAPP = 9;
static final short LENGTH_PHONEVERSION = 17;
static final byte PHONEVERSION_APPVERSION_MAGIC = 2; // increase this if pebble complains static final byte PHONEVERSION_APPVERSION_MAGIC = 2; // increase this if pebble complains
@ -166,9 +170,9 @@ public class PebbleProtocol {
ts = System.currentTimeMillis() / 1000; ts = System.currentTimeMillis() / 1000;
ts += SimpleTimeZone.getDefault().getOffset(ts) / 1000; ts += SimpleTimeZone.getDefault().getOffset(ts) / 1000;
} }
ByteBuffer buf = ByteBuffer.allocate(LENGTH_SETTIME); ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_SETTIME);
buf.order(ByteOrder.BIG_ENDIAN); buf.order(ByteOrder.BIG_ENDIAN);
buf.putShort((short) (LENGTH_SETTIME - LENGTH_PREFIX)); buf.putShort(LENGTH_SETTIME);
buf.putShort(ENDPOINT_TIME); buf.putShort(ENDPOINT_TIME);
buf.put(TIME_SETTIME); buf.put(TIME_SETTIME);
buf.putInt((int) ts); buf.putInt((int) ts);
@ -222,10 +226,22 @@ public class PebbleProtocol {
return encodeMessage(ENDPOINT_APPMANAGER, APPMANAGER_GETAPPBANKSTATUS, 0, null); return encodeMessage(ENDPOINT_APPMANAGER, APPMANAGER_GETAPPBANKSTATUS, 0, null);
} }
public static byte[] encodePhoneVersion(byte os) { public static byte[] encodeAppDelete(int id, int index) {
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PHONEVERSION); ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REMOVEAPP);
buf.order(ByteOrder.BIG_ENDIAN); buf.order(ByteOrder.BIG_ENDIAN);
buf.putShort((short) (LENGTH_PHONEVERSION - LENGTH_PREFIX)); buf.putShort(LENGTH_REMOVEAPP);
buf.putShort(ENDPOINT_APPMANAGER);
buf.put(APPMANAGER_REMOVEAPP);
buf.putInt(id);
buf.putInt(index);
return buf.array();
}
public static byte[] encodePhoneVersion(byte os) {
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_PHONEVERSION);
buf.order(ByteOrder.BIG_ENDIAN);
buf.putShort(LENGTH_PHONEVERSION);
buf.putShort(ENDPOINT_PHONEVERSION); buf.putShort(ENDPOINT_PHONEVERSION);
buf.put((byte) 0x01); buf.put((byte) 0x01);
buf.putInt(-1); //0xffffffff buf.putInt(-1); //0xffffffff
@ -296,7 +312,6 @@ public class PebbleProtocol {
buf.get(versionString, 0, 32); buf.get(versionString, 0, 32);
versionCmd.fwVersion = new String(versionString).trim(); versionCmd.fwVersion = new String(versionString).trim();
Log.i(TAG, "Got firmware version: " + versionCmd.fwVersion);
cmd = versionCmd; cmd = versionCmd;
break; break;
case ENDPOINT_APPMANAGER: case ENDPOINT_APPMANAGER:
@ -310,23 +325,38 @@ public class PebbleProtocol {
appInfoCmd.apps = new GBDeviceApp[banksUsed]; appInfoCmd.apps = new GBDeviceApp[banksUsed];
for (int i = 0; i < banksUsed; i++) { for (int i = 0; i < banksUsed; i++) {
buf.getInt(); // id int id = buf.getInt();
buf.getInt(); // index int index = buf.getInt();
buf.get(appName, 0, 32); buf.get(appName, 0, 32);
buf.get(creatorName, 0, 32); buf.get(creatorName, 0, 32);
int flags = buf.getInt(); int flags = buf.getInt();
Short appVersion = buf.getShort(); Short appVersion = buf.getShort();
appInfoCmd.apps[i] = new GBDeviceApp(new String(appName).trim(), new String(creatorName).trim(), appVersion.toString()); appInfoCmd.apps[i] = new GBDeviceApp(id, index, new String(appName).trim(), new String(creatorName).trim(), appVersion.toString());
} }
cmd = appInfoCmd; cmd = appInfoCmd;
break; break;
case APPMANAGER_REMOVEAPP:
GBDeviceCommandAppManagementResult deleteRes = new GBDeviceCommandAppManagementResult();
deleteRes.type = GBDeviceCommandAppManagementResult.CommandType.DELETE;
int result = buf.getInt();
switch (result) {
case APPMANAGER_RES_SUCCESS:
deleteRes.result = GBDeviceCommandAppManagementResult.Result.SUCCESS;
break;
default:
deleteRes.result = GBDeviceCommandAppManagementResult.Result.FAILURE;
break;
}
cmd = deleteRes;
break;
default: default:
Log.i(TAG, "Unknown APPMANAGER command" + pebbleCmd); Log.i(TAG, "Unknown APPMANAGER command" + pebbleCmd);
break; break;
} }
break; break;
default: default:
return null; break;
} }
return cmd; return cmd;

View File

@ -8,9 +8,12 @@
<string name="action_quit">Quit</string> <string name="action_quit">Quit</string>
<string name="action_refresh" >Refresh</string> <string name="action_refresh" >Refresh</string>
<string name="title_activity_appmanager">App Manager</string>
<string name="title_activity_debug">Debug</string> <string name="title_activity_debug">Debug</string>
<!-- Strings related to AppManager -->
<string name="title_activity_appmanager">App Manager</string>
<string name="appmananger_app_delete">Delete</string>
<!-- Strings related to Settings --> <!-- Strings related to Settings -->
<string name="title_activity_settings">Settings</string> <string name="title_activity_settings">Settings</string>
<string name="pref_header_general">General Settings</string> <string name="pref_header_general">General Settings</string>