Improvements to the install activity #30

- made it independent of Mi fw and Pebble fw + app classes
- automatically connect to the last used device
- some other small fixes/improvements
master
cpfeiffer 2015-08-06 02:17:38 +02:00
parent 8dee55198e
commit 2a2eae068a
14 changed files with 274 additions and 67 deletions

View File

@ -18,28 +18,25 @@ import android.widget.Toast;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PBWReader;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class FwAppInstallerActivity extends Activity {
public class FwAppInstallerActivity extends Activity implements InstallActivity {
private static final Logger LOG = LoggerFactory.getLogger(FwAppInstallerActivity.class);
TextView fwAppInstallTextView;
Button installButton;
// FIXME: abstraction for these would make code cleaner in this class
private PBWReader mPBWReader = null;
private MiBandFWHelper mFwReader = null;
private TextView fwAppInstallTextView;
private Button installButton;
private Uri uri;
private GBDevice device;
private InstallHandler installHandler;
private boolean mayConnect;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@ -48,31 +45,43 @@ public class FwAppInstallerActivity extends Activity {
if (action.equals(ControlCenter.ACTION_QUIT)) {
finish();
} else if (action.equals(GBDevice.ACTION_DEVICE_CHANGED)) {
GBDevice dev = intent.getParcelableExtra("device");
if (dev.getType() == DeviceType.PEBBLE && mPBWReader != null) {
if (mPBWReader.isFirmware()) {
String hwRevision = mPBWReader.getHWRevision();
if (hwRevision != null && hwRevision.equals(dev.getHardwareVersion()) && dev.isConnected()) {
installButton.setEnabled(true);
device = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
if (device != null) {
if (!device.isConnected()) {
if (mayConnect) {
GB.toast(FwAppInstallerActivity.this, getString(R.string.connecting), Toast.LENGTH_SHORT, GB.INFO);
connect();
} else {
installButton.setEnabled(false);
setInfoText(getString(R.string.not_connected));
}
} else {
installButton.setEnabled(dev.isConnected());
validateInstallation();
}
} else if (dev.getType() == DeviceType.MIBAND && mFwReader != null) {
installButton.setEnabled(dev.isInitialized());
}
}
}
};
private void connect() {
Intent startIntent = new Intent(FwAppInstallerActivity.this, DeviceCommunicationService.class);
startIntent.setAction(DeviceCommunicationService.ACTION_CONNECT);
startIntent.putExtra(GBDevice.EXTRA_DEVICE, device);
startService(startIntent);
}
private void validateInstallation() {
if (installHandler != null) {
installHandler.validateInstallation(this, device);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_appinstaller);
getActionBar().setDisplayHomeAsUpEnabled(true);
mayConnect = true;
fwAppInstallTextView = (TextView) findViewById(R.id.debugTextView);
installButton = (Button) findViewById(R.id.installButton);
IntentFilter filter = new IntentFilter();
@ -80,48 +89,44 @@ public class FwAppInstallerActivity extends Activity {
filter.addAction(GBDevice.ACTION_DEVICE_CHANGED);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter);
final Uri uri = getIntent().getData();
mPBWReader = new PBWReader(uri, getApplicationContext());
if (mPBWReader.isValid()) {
GBDeviceApp app = mPBWReader.getGBDeviceApp();
if (mPBWReader.isFirmware()) {
fwAppInstallTextView.setText(getString(R.string.firmware_install_warning, mPBWReader.getHWRevision()));
} else if (app != null) {
fwAppInstallTextView.setText(getString(R.string.app_install_info, app.getName(), app.getVersion(), app.getCreator()));
}
} else {
mPBWReader = null;
try {
mFwReader = new MiBandFWHelper(uri, getApplicationContext());
fwAppInstallTextView.setText(getString(R.string.fw_upgrade_notice, mFwReader.getHumanFirmwareVersion()));
if (mFwReader.isFirmwareWhitelisted()) {
fwAppInstallTextView.append(" " + getString(R.string.miband_firmware_known));
} else {
fwAppInstallTextView.append(" " + getString(R.string.miband_firmware_unknown_warning) + " " +
getString(R.string.miband_firmware_suggest_whitelist, mFwReader.getFirmwareVersion()));
}
} catch (IOException ex) {
GB.toast(getApplicationContext(), "Firmware cannot be installed: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR);
}
}
installButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent startIntent = new Intent(FwAppInstallerActivity.this, DeviceCommunicationService.class);
startIntent.setAction(DeviceCommunicationService.ACTION_INSTALL);
startIntent.putExtra("uri", uri.toString());
startIntent.putExtra("uri", uri);
startService(startIntent);
}
});
Intent versionInfoIntent = new Intent(this, DeviceCommunicationService.class);
versionInfoIntent.setAction(DeviceCommunicationService.ACTION_REQUEST_VERSIONINFO);
startService(versionInfoIntent);
uri = getIntent().getData();
installHandler = findInstallHandlerFor(uri);
if (installHandler == null) {
setInfoText(getString(R.string.installer_activity_unable_to_find_handler));
setInstallEnabled(false);
} else {
setInfoText(getString(R.string.installer_activity_wait_while_determining_status));
setInstallEnabled(false);
// needed to get the device
Intent connectIntent = new Intent(this, DeviceCommunicationService.class);
connectIntent.setAction(DeviceCommunicationService.ACTION_CONNECT);
startService(connectIntent);
Intent versionInfoIntent = new Intent(this, DeviceCommunicationService.class);
versionInfoIntent.setAction(DeviceCommunicationService.ACTION_REQUEST_VERSIONINFO);
startService(versionInfoIntent);
}
}
private InstallHandler findInstallHandlerFor(Uri uri) {
for (DeviceCoordinator coordinator : DeviceHelper.getInstance().getAllCoordinators()) {
InstallHandler handler = coordinator.findInstallHandler(uri, this);
if (handler != null) {
return handler;
}
}
return null;
}
@Override
@ -139,4 +144,14 @@ public class FwAppInstallerActivity extends Activity {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
super.onDestroy();
}
@Override
public void setInfoText(String text) {
fwAppInstallTextView.setText(text);
}
@Override
public void setInstallEnabled(boolean enable) {
installButton.setEnabled(device != null && device.isConnected() && enable);
}
}

View File

@ -0,0 +1,6 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
public interface InstallActivity {
public void setInfoText(String text);
public void setInstallEnabled(boolean enable);
}

View File

@ -1,10 +1,12 @@
package nodomain.freeyourgadget.gadgetbridge.devices;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
public interface DeviceCoordinator {
String EXTRA_DEVICE_MAC_ADDRESS = "nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate.EXTRA_MAC_ADDRESS";
@ -20,4 +22,6 @@ public interface DeviceCoordinator {
Class<? extends Activity> getPrimaryActivity();
SampleProvider getSampleProvider();
InstallHandler findInstallHandler(Uri uri, Context context);
}

View File

@ -0,0 +1,29 @@
package nodomain.freeyourgadget.gadgetbridge.devices;
import android.net.Uri;
import android.support.annotation.Nullable;
import nodomain.freeyourgadget.gadgetbridge.activities.FwAppInstallerActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
/**
* Interface for the UI side of certain kinds of installation of things on the
* gadget device. The actual element to install will be passed in the constructor.
*/
public interface InstallHandler {
/**
* Returns true if this handler is able to install the element.
*/
public boolean isValid();
/**
* Checks whether the installation of the 'element' on the device is possible
* and configures the InstallActivity accordingly (sets helpful texts,
* enables/disables the "Install" button, etc.
* @param installActivity the activity to interact with
* @param device the device to which the element shall be installed
*/
void validateInstallation(InstallActivity installActivity, GBDevice device);
}

View File

@ -1,6 +1,8 @@
package nodomain.freeyourgadget.gadgetbridge.devices;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
@ -66,4 +68,9 @@ public class UnknownDeviceCoordinator implements DeviceCoordinator {
public SampleProvider getSampleProvider() {
return sampleProvider;
}
@Override
public InstallHandler findInstallHandler(Uri uri, Context context) {
return null;
}
}

View File

@ -1,15 +1,19 @@
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Calendar;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
@ -54,6 +58,12 @@ public class MiBandCoordinator implements DeviceCoordinator {
return sampleProvider;
}
@Override
public InstallHandler findInstallHandler(Uri uri, Context context) {
MiBandFWInstallHandler handler = new MiBandFWInstallHandler(uri, context);
return handler.isValid() ? handler : null;
}
public static boolean hasValidUserInfo() {
String dummyMacAddress = MiBandService.MAC_ADDRESS_FILTER + ":00:00:00";
try {

View File

@ -12,6 +12,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
public class MiBandFWHelper {

View File

@ -0,0 +1,58 @@
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
import android.content.Context;
import android.net.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
public class MiBandFWInstallHandler implements InstallHandler {
private static final Logger LOG = LoggerFactory.getLogger(MiBandFWInstallHandler.class);
private final Context mContext;
private MiBandFWHelper helper;
private String errorMessage;
public MiBandFWInstallHandler(Uri uri, Context context) {
mContext = context;
try {
helper = new MiBandFWHelper(uri, mContext);
} catch (IOException e) {
errorMessage = e.getMessage();
LOG.warn(errorMessage, e);
}
}
@Override
public void validateInstallation(InstallActivity installActivity, GBDevice device) {
if (device.isBusy() || device.getType() != DeviceType.MIBAND || !device.isInitialized()) {
installActivity.setInfoText("Element cannot be installed");
installActivity.setInstallEnabled(false);
return;
}
StringBuilder builder = new StringBuilder(mContext.getString(R.string.fw_upgrade_notice, helper.getHumanFirmwareVersion()));
if (helper.isFirmwareWhitelisted()) {
builder.append(" ").append(mContext.getString(R.string.miband_firmware_known));
} else {
builder.append(" ").append(mContext.getString(R.string.miband_firmware_unknown_warning)).append(" ")
.append(mContext.getString(R.string.miband_firmware_suggest_whitelist, helper.getFirmwareVersion()));
}
installActivity.setInfoText(builder.toString());
installActivity.setInstallEnabled(true);
}
public boolean isValid() {
return helper != null;
}
}

View File

@ -0,0 +1,57 @@
package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
import android.content.Context;
import android.net.Uri;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
public class PBWInstallHandler implements InstallHandler {
private final Context mContext;
private final PBWReader mPBWReader;
private final Uri mUri;
public PBWInstallHandler(Uri uri, Context context) {
mContext = context;
mPBWReader = new PBWReader(uri, context);
mUri = uri;
}
@Override
public void validateInstallation(InstallActivity installActivity, GBDevice device) {
if (device.isBusy() || device.getType() != DeviceType.PEBBLE || !device.isConnected()) {
installActivity.setInfoText("Element cannot be installed");
installActivity.setInstallEnabled(false);
return;
}
if (mPBWReader.isFirmware()) {
String hwRevision = mPBWReader.getHWRevision();
if (hwRevision != null && hwRevision.equals(device.getHardwareVersion())) {
installActivity.setInfoText(mContext.getString(R.string.firmware_install_warning, hwRevision));
installActivity.setInstallEnabled(true);
} else {
installActivity.setInfoText(mContext.getString(R.string.pbw_install_handler_hw_revision_mismatch));
installActivity.setInstallEnabled(false);
}
} else {
GBDeviceApp app = mPBWReader.getGBDeviceApp();
if (app != null) {
installActivity.setInfoText(mContext.getString(R.string.app_install_info, app.getName(), app.getVersion(), app.getCreator()));
installActivity.setInstallEnabled(true);
} else {
installActivity.setInfoText(mContext.getString(R.string.pbw_install_handler_unable_to_install, mUri.getPath()));
installActivity.setInstallEnabled(false);
}
}
}
public boolean isValid() {
return mPBWReader.isValid();
}
}

View File

@ -173,7 +173,6 @@ public class PBWReader {
e.printStackTrace();
return null;
}
ZipInputStream zis = new ZipInputStream(fin);
ZipEntry ze;
try {
@ -183,7 +182,12 @@ public class PBWReader {
}
}
zis.close();
} catch (IOException e) {
} catch (Throwable e) {
try {
zis.close();
} catch (IOException e1) {
// ignore
}
e.printStackTrace();
}
return null;

View File

@ -1,9 +1,12 @@
package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import nodomain.freeyourgadget.gadgetbridge.activities.AppManagerActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
@ -45,4 +48,10 @@ public class PebbleCoordinator implements DeviceCoordinator {
public SampleProvider getSampleProvider() {
return sampleProvider;
}
@Override
public InstallHandler findInstallHandler(Uri uri, Context context) {
PBWInstallHandler installHandler = new PBWInstallHandler(uri, context);
return installHandler.isValid() ? installHandler : null;
}
}

View File

@ -143,7 +143,11 @@ public class DeviceCommunicationService extends Service {
case ACTION_CONNECT:
String btDeviceAddress = intent.getStringExtra(EXTRA_DEVICE_ADDRESS);
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
sharedPrefs.edit().putString("last_device_address", btDeviceAddress).apply();
if (btDeviceAddress == null) {
btDeviceAddress = sharedPrefs.getString("last_device_address", null);
} else {
sharedPrefs.edit().putString("last_device_address", btDeviceAddress).apply();
}
if (btDeviceAddress != null && !isConnected() && !isConnecting()) {
if (mDeviceSupport != null) {
@ -247,10 +251,10 @@ public class DeviceCommunicationService extends Service {
mDeviceSupport.onAppDelete(uuid);
break;
case ACTION_INSTALL:
String uriString = intent.getStringExtra("uri");
if (uriString != null) {
Uri uri = intent.getParcelableExtra("uri");
if (uri != null) {
LOG.info("will try to install app/fw");
mDeviceSupport.onInstallApp(Uri.parse(uriString));
mDeviceSupport.onInstallApp(uri);
}
break;
case ACTION_START:

View File

@ -77,5 +77,4 @@ public class DeviceHelper {
result.add(new PebbleCoordinator());
return result;
}
}

View File

@ -80,7 +80,7 @@
<string name="installing_binary_d_d">installing binary %1$d/%2$d</string>
<string name="installation_failed_">installation failed!</string>
<string name="installation_successful">installation successful</string>
<string name="firmware_install_warning">YOUR ARE TRYING TO INSTALL A FIRMWARE, PROCEED AT YOUR OWN RISK.\n\n\n This firmware is for HW Revision: %s</string>
<string name="firmware_install_warning">YOU ARE TRYING TO INSTALL A FIRMWARE, PROCEED AT YOUR OWN RISK.\n\n\n This firmware is for HW Revision: %s</string>
<string name="app_install_info">You are about to install the following app:\n\n\n%1$s Version %2$s by %3$s\n</string>
<string name="n_a">N/A</string>
<string name="initialized">initialized</string>
@ -161,4 +161,8 @@
<string name="dbaccess_error_executing">Error executing \'%1$s\'</string>
<string name="controlcenter_start_activitymonitor">Your Activity (ALPHA)</string>
<string name="cannot_connect">Cannot connect: %1$s</string>
<string name="installer_activity_unable_to_find_handler">Unable to find a handler to install this file.</string>
<string name="pbw_install_handler_unable_to_install">Unable to install the given file: $1%s</string>
<string name="pbw_install_handler_hw_revision_mismatch">Unable to install the given firmware: it doesn\'t match your Pebble\'s hardware revision.</string>
<string name="installer_activity_wait_while_determining_status">Please wait while determining the installation status...</string>
</resources>