Skip to content

Commit

Permalink
Merge pull request #154 from NordicSemiconductor/feature/force-update
Browse files Browse the repository at this point in the history
Allowing reuploading images
  • Loading branch information
philips77 authored May 23, 2024
2 parents 7ef161a + 8568044 commit 0611295
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.runtime.mcumgr.sample.dialog;

import android.app.Dialog;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;

public class YesNoDialogFragment extends DialogFragment {
private static final String ARG_REQUEST_ID = "requestId";
private static final String ARG_TITLE_ID = "titleId";
private static final String ARG_QUESTION_ID = "questionId";

public interface Listener {
void onAnswer(final int requestId, final boolean yes);
}

public static DialogFragment getInstance(final int requestId,
@StringRes final int titleId, @StringRes final int questionId) {
final DialogFragment fragment = new YesNoDialogFragment();

final Bundle args = new Bundle();
args.putInt(ARG_REQUEST_ID, requestId);
args.putInt(ARG_TITLE_ID, titleId);
args.putInt(ARG_QUESTION_ID, questionId);
fragment.setArguments(args);

return fragment;
}

@NonNull
@Override
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
final Bundle args = requireArguments();
final int requestId = args.getInt(ARG_REQUEST_ID);

return new AlertDialog.Builder(requireContext())
.setTitle(args.getInt(ARG_TITLE_ID))
.setMessage(args.getInt(ARG_QUESTION_ID))
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
final Listener listener = (Listener) getParentFragment();
if (listener != null)
listener.onAnswer(requestId, true);
})
.setNegativeButton(android.R.string.cancel, (dialog, which) -> {
final Listener listener = (Listener) getParentFragment();
if (listener != null)
listener.onAnswer(requestId, false);
})
.create();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@
import io.runtime.mcumgr.sample.di.Injectable;
import io.runtime.mcumgr.sample.dialog.HelpDialogFragment;
import io.runtime.mcumgr.sample.dialog.SelectImageDialogFragment;
import io.runtime.mcumgr.sample.dialog.YesNoDialogFragment;
import io.runtime.mcumgr.sample.utils.StringUtils;
import io.runtime.mcumgr.sample.viewmodel.mcumgr.ImageUploadViewModel;
import io.runtime.mcumgr.sample.viewmodel.mcumgr.McuMgrViewModelFactory;

public class ImageUploadFragment extends FileBrowserFragment implements Injectable, SelectImageDialogFragment.OnImageSelectedListener {
public class ImageUploadFragment extends FileBrowserFragment implements Injectable,
SelectImageDialogFragment.OnImageSelectedListener, YesNoDialogFragment.Listener {
private static final int REQUEST_UPLOAD = 0;
private static final int REQUEST_OVERWRITE = 1;

@Inject
McuMgrViewModelFactory viewModelFactory;
Expand Down Expand Up @@ -127,6 +130,12 @@ public void onViewCreated(@NonNull final View view, @Nullable final Bundle saved
binding.actionCancel.setVisibility(View.GONE);
binding.actionPauseResume.setVisibility(View.GONE);
});
viewModel.getHashAlreadyFoundEvent().observe(getViewLifecycleOwner(), isActive -> {
final DialogFragment dialog = YesNoDialogFragment
.getInstance(REQUEST_OVERWRITE, R.string.image_overwrite_title,
isActive ? R.string.image_overwrite_active_message : R.string.image_overwrite_message);
dialog.show(getChildFragmentManager(), null);
});
viewModel.getBusyState().observe(getViewLifecycleOwner(), busy -> {
binding.actionSelectFile.setEnabled(!busy);
binding.actionUpload.setEnabled(isFileLoaded() && !busy);
Expand Down Expand Up @@ -208,7 +217,21 @@ protected void onFileLoadingFailed(final int error) {
public void onImageSelected(final int requestId, final int image) {
final byte[] data = getFileContent();
if (data != null) {
viewModel.upload(data, image);
viewModel.upload(data, image, false);
}
}

@Override
public void onAnswer(int requestId, boolean yes) {
if (requestId == REQUEST_OVERWRITE) {
final byte[] data = getFileContent();
if (data != null) {
if (yes) {
viewModel.upload(data, 0, true);
} else {
viewModel.onUploadCanceled();
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public boolean canCancel() {
private final MutableLiveData<Float> transferSpeedLiveData = new MutableLiveData<>();
private final SingleLiveEvent<McuMgrException> errorLiveData = new SingleLiveEvent<>();
private final SingleLiveEvent<Void> cancelledEvent = new SingleLiveEvent<>();
private final SingleLiveEvent<Boolean> hashAlreadyFound = new SingleLiveEvent<>();

private long uploadStartTimestamp;
private int initialBytes;
Expand Down Expand Up @@ -97,7 +98,12 @@ public LiveData<Void> getCancelledEvent() {
return cancelledEvent;
}

public void upload(@NonNull final byte[] data, final int image) {
@NonNull
public LiveData<Boolean> getHashAlreadyFoundEvent() {
return hashAlreadyFound;
}

public void upload(@NonNull final byte[] data, final int image, boolean force) {
if (controller != null) {
return;
}
Expand All @@ -117,7 +123,6 @@ public void upload(@NonNull final byte[] data, final int image) {
}
final byte[] hash = tmpHash;

requestHighConnectionPriority();
manager.list(new McuMgrCallback<>() {
@Override
public void onResponse(@NonNull final McuMgrImageStateResponse response) {
Expand All @@ -130,16 +135,13 @@ public void onResponse(@NonNull final McuMgrImageStateResponse response) {
}
}
// If yes, no need to send again.
if (theSameImage != null) {
if (theSameImage.slot == 0) {
errorLiveData.postValue(new McuMgrException("Firmware already active."));
} else {
// Firmware is identical to one on slot 1. No need to send anything.
stateLiveData.postValue(State.COMPLETE);
}
if (!force && theSameImage != null) {
hashAlreadyFound.postValue(theSameImage.active);
postReady();
return;
}

requestHighConnectionPriority();
// Otherwise, send the firmware. This may return NO MEMORY error if slot 1 is
// filled with an image with pending or confirmed flags set.
stateLiveData.postValue(State.UPLOADING);
Expand Down Expand Up @@ -229,16 +231,14 @@ public void onUploadCompleted() {

private void requestHighConnectionPriority() {
final McuMgrTransport transporter = manager.getTransporter();
if (transporter instanceof McuMgrBleTransport) {
final McuMgrBleTransport bleTransporter = (McuMgrBleTransport) transporter;
if (transporter instanceof McuMgrBleTransport bleTransporter) {
bleTransporter.requestConnPriority(ConnectionPriorityRequest.CONNECTION_PRIORITY_HIGH);
}
}

private void setLoggingEnabled(final boolean enabled) {
final McuMgrTransport transporter = manager.getTransporter();
if (transporter instanceof McuMgrBleTransport) {
final McuMgrBleTransport bleTransporter = (McuMgrBleTransport) transporter;
if (transporter instanceof McuMgrBleTransport bleTransporter) {
bleTransporter.setLoggingEnabled(enabled);
}
}
Expand Down
4 changes: 4 additions & 0 deletions sample/src/main/res/values/strings_image_upload.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
<item>Image 3 (3)</item>
</string-array>

<string name="image_overwrite_title">Overwrite?</string>
<string name="image_overwrite_message">The selected image is already on the device. Do you want to send it again?</string>
<string name="image_overwrite_active_message">The selected image is already active. Do you want to send it again?</string>

<string name="image_upload_status_ready">READY</string>
<string name="image_upload_status_validating">VALIDATING…</string>
<string name="image_upload_status_uploading">UPLOADING…</string>
Expand Down

0 comments on commit 0611295

Please sign in to comment.