Unverified Commit f7c37d83 authored by Javier Guerra's avatar Javier Guerra Committed by GitHub

Merge pull request #20 from openconnectivity/develop

Merge develop into master
parents 2531f329 b3726be5
......@@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.android.tools.build:gradle:3.4.2'
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4'
// NOTE: Do not place your application dependencies here; they belong
......
......@@ -30,7 +30,7 @@ android {
minSdkVersion 21
targetSdkVersion 28
versionCode 13
versionName "2.7.0"
versionName "2.8.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
compileOptions {
......
-----BEGIN CERTIFICATE-----
MIIEEzCCA7mgAwIBAgIJAI0K+3tTsk0AMAoGCCqGSM49BAMCMFsxDDAKBgNVBAoM
MIIEEzCCA7mgAwIBAgIJAI0K+3tTsk07MAoGCCqGSM49BAMCMFsxDDAKBgNVBAoM
A09DRjEiMCAGA1UECwwZS3lyaW8gVGVzdCBJbmZyYXN0cnVjdHVyZTEnMCUGA1UE
AwweS3lyaW8gVEVTVCBJbnRlcm1lZGlhdGUgQ0EwMDAyMB4XDTE5MTAyNDA5NDg1
NFoXDTE5MTEyMzA5NDg1NFowYTEMMAoGA1UECgwDT0NGMSIwIAYDVQQLDBlLeXJp
AwweS3lyaW8gVEVTVCBJbnRlcm1lZGlhdGUgQ0EwMDAyMB4XDTE5MTEyODEzMzYw
OVoXDTE5MTIyODEzMzYwOVowYTEMMAoGA1UECgwDT0NGMSIwIAYDVQQLDBlLeXJp
byBUZXN0IEluZnJhc3RydWN0dXJlMS0wKwYDVQQDDCQxZTFiZWJmYi04ZjAzLTQ3
ODUtNWZhNy0xYjcwNGU2NTQzNjAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATW
d0t/5GahEMUSb8dhaOIZdTDHDTelbWWfjSxA6OhcMy1uKGewCg7e2R2ZTK7ZM/th
KSXuMywN0JXA6BoW9on8o4ICXjCCAlowCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMC
ODUtNWZhNy0xYjcwNGU2NTQzNjAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQS
rNS0ha8XBiRD+Q7nL+R3uX7f5FPgQO75Wh9PqaiVLhMFewF/Yrbr+KhCdj8e6MNz
WGDbVtMVc59RBHyvgzbho4ICXjCCAlowCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMC
A4gwKQYDVR0lBCIwIAYIKwYBBQUHAwIGCCsGAQUFBwMBBgorBgEEAYLefAEGMB0G
A1UdDgQWBBS+4P5iaPJfppBg66266sma6Ffe9jAfBgNVHSMEGDAWgBQZc2oEGgsH
A1UdDgQWBBR1GbdeJoLZj6iMx9ZDNEv+aoECrjAfBgNVHSMEGDAWgBQZc2oEGgsH
cE9TeVM2h/wMunyuCzCBlgYIKwYBBQUHAQEEgYkwgYYwXQYIKwYBBQUHMAKGUWh0
dHA6Ly90ZXN0cGtpLmt5cmlvLmNvbS9vY2YvY2FjZXJ0cy9CQkU2NEY5QTdFRTM3
RDI5QTA1RTRCQjc3NTk1RjMwOEJFNDFFQjA3LmNydDAlBggrBgEFBQcwAYYZaHR0
......@@ -19,6 +19,6 @@ AjBgBgorBgEEAYORVgEABFIwUDAJAgECAgEAAgEAMDYMGTEuMy42LjEuNC4xLjUx
NDE0LjAuMC4xLjAMGTEuMy42LjEuNC4xLjUxNDE0LjAuMC4yLjAMBE9UR0MMBURF
S1JBMCoGCisGAQQBg5FWAQEEHDAaBgsrBgEEAYORVgEBAAYLKwYBBAGDkVYBAQEw
MAYKKwYBBAGDkVYBAgQiMCAMDjEuMy42LjEuNC4xLjcxDAlEaXNjb3ZlcnkMAzEu
MDAKBggqhkjOPQQDAgNIADBFAiEA3Ay4oPSGwARJWub9/k58xiqARpRKjCDaGGZi
mHTurqYCIC/e7Y9NAMiweZZ2JaGAYXC7T8YTqAFneT9jaq2o3c9m
MDAKBggqhkjOPQQDAgNIADBFAiAP9ttApmZfcFoipNra7ZqFa1kdD7JxmD84fuMH
XXyTBgIhAIIrpiVkOxAQqTlfDpJZk3F8byz/x2c9xpNeQEZTllMc
-----END CERTIFICATE-----
......@@ -2,7 +2,7 @@
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIDUCAKRYHFbz7MVYj4LASsOxX54sYcVNbE4MLwIa/0j/oAoGCCqGSM49
AwEHoUQDQgAE1ndLf+RmoRDFEm/HYWjiGXUwxw03pW1ln40sQOjoXDMtbihnsAoO
3tkdmUyu2TP7YSkl7jMsDdCVwOgaFvaJ/A==
MHcCAQEEIDFeXNSayEnCQIlEjbV+4vGKeqRAmjnspnA8ICW0FnAwoAoGCCqGSM49
AwEHoUQDQgAEEqzUtIWvFwYkQ/kO5y/kd7l+3+RT4EDu+VofT6molS4TBXsBf2K2
6/ioQnY/HujDc1hg21bTFXOfUQR8r4M24Q==
-----END EC PRIVATE KEY-----
......@@ -76,8 +76,9 @@ public class DoxsRepository {
} else if (oxm == OcfOxmType.OC_OXMTYPE_RDP) {
ret = OCObt.requestRandomPin(uuid, (OCUuid ocUuid, int status) -> {
if (status >= 0) {
Timber.d("Successfully request Random PIN " + OCUuidUtil.uuidToString(ocUuid));
String pin = randomPinHandler.handler();
String id = OCUuidUtil.uuidToString(ocUuid);
Timber.d("Successfully request Random PIN " + id);
String pin = randomPinHandler.handler(id);
if (OCObt.performRandomPinOtm(uuid, pin, handler) != -1){
emitter.onComplete();
} else {
......
......@@ -65,6 +65,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
......@@ -203,7 +204,10 @@ public class IotivityRepository {
deviceDao.insert(new DeviceEntity(deviceId, device.getName(), endpoints, DeviceType.UNOWNED, Device.NOTHING_PERMITS));
}
unownedDevices.add(new Device(DeviceType.UNOWNED, deviceId, new OcDeviceInfo(), endpoints, Device.NOTHING_PERMITS));
Device device1 = new Device(DeviceType.UNOWNED, deviceId, new OcDeviceInfo(), endpoints, Device.NOTHING_PERMITS);
if (!unownedDevices.contains(device1)) {
unownedDevices.add(device1);
}
};
int ret;
......@@ -241,7 +245,10 @@ public class IotivityRepository {
deviceDao.insert(new DeviceEntity(deviceId, device.getName(), endpoints, DeviceType.OWNED_BY_SELF, Device.FULL_PERMITS));
}
ownedDevices.add(new Device(DeviceType.OWNED_BY_SELF, deviceId, new OcDeviceInfo(), endpoints, Device.FULL_PERMITS));
Device device1 = new Device(DeviceType.OWNED_BY_SELF, deviceId, new OcDeviceInfo(), endpoints, Device.FULL_PERMITS);
if (!ownedDevices.contains(device1)) {
ownedDevices.add(device1);
}
};
int ret;
......@@ -595,6 +602,38 @@ public class IotivityRepository {
});
}
public Completable post(String host, String uri, String deviceId, Map<String, Object> values) {
return Completable.create(emitter -> {
OCEndpoint ep = OCEndpointUtil.stringToEndpoint(host, new String[1]);
OCUuid uuid = OCUuidUtil.stringToUuid(deviceId);
OCEndpointUtil.setDi(ep, uuid);
OCResponseHandler handler = (OCClientResponse response) -> {
OCStatus code = response.getCode();
if (code == OCStatus.OC_STATUS_OK
|| code == OCStatus.OC_STATUS_CHANGED) {
emitter.onComplete();
} else {
emitter.onError(new Exception("POST " + uri + " error - code: " + code));
}
};
if (OCMain.initPost(uri, ep, null, handler, OCQos.HIGH_QOS)) {
CborEncoder root = OCRep.beginRootObject();
parseOCRepresentionToCbor(root, values);
OCRep.endRootObject();
if (!OCMain.doPost()) {
emitter.onError(new Exception("Do POST " + uri + " error"));
}
} else {
emitter.onError(new Exception("Init POST " + uri + " error"));
}
OCEndpointUtil.freeEndpoint(ep);
});
}
private void parseOCRepresentionToCbor(CborEncoder parent, OCRepresentation rep, Object valueArray) {
while (rep != null) {
switch (rep.getType()) {
......@@ -619,6 +658,9 @@ public class IotivityRepository {
case OC_REP_STRING_ARRAY:
OCRep.setStringArray(parent, rep.getName(), (String[])valueArray);
break;
case OC_REP_BOOL_ARRAY:
OCRep.setBooleanArray(parent, rep.getName(), (boolean[])valueArray);
break;
default:
break;
}
......@@ -627,6 +669,46 @@ public class IotivityRepository {
}
}
private void parseOCRepresentionToCbor(CborEncoder parent, Map<String, Object> values) {
for (String key : values.keySet()) {
if (values.get(key) instanceof Boolean) {
OCRep.setBoolean(parent, key, (boolean)values.get(key));
} else if (values.get(key) instanceof Integer) {
OCRep.setLong(parent, key, (Integer)values.get(key));
} else if (values.get(key) instanceof Double) {
OCRep.setDouble(parent, key, (Double)values.get(key));
} else if (values.get(key) instanceof String) {
OCRep.setTextString(parent, key, (String)values.get(key));
} else if (values.get(key) instanceof List) {
if (((List) values.get(key)).get(0) instanceof String) {
String[] ret = new String[((List<String>)values.get(key)).size()];
for (int i=0; i< ((List<String>)values.get(key)).size(); i++) {
ret[i] = ((List<String>)values.get(key)).get(i);
}
OCRep.setStringArray(parent, key, ret);
} else if (((List) values.get(key)).get(0) instanceof Integer) {
long[] ret = new long[((List<Integer>)values.get(key)).size()];
for (int i=0; i< ((List<Integer>)values.get(key)).size(); i++) {
ret[i] = ((List<Integer>)values.get(key)).get(i);
}
OCRep.setLongArray(parent, key, ret);
} else if (((List) values.get(key)).get(0) instanceof Double) {
double[] ret = new double[((List<Double>)values.get(key)).size()];
for (int i=0; i< ((List<Double>)values.get(key)).size(); i++) {
ret[i] = ((List<Double>)values.get(key)).get(i);
}
OCRep.setDoubleArray(parent, key, ret);
} else if (((List) values.get(key)).get(0) instanceof Boolean) {
boolean[] ret = new boolean[((List<Boolean>)values.get(key)).size()];
for (int i=0; i< ((List<Boolean>)values.get(key)).size(); i++) {
ret[i] = ((List<Boolean>)values.get(key)).get(i);
}
OCRep.setBooleanArray(parent, key, ret);
}
}
}
}
public void close() {
Timber.d("Calling OCMain.mainShutdown()");
OCMain.mainShutdown();
......
......@@ -39,6 +39,7 @@ public class SerializableResource implements Serializable {
private List<String> types;
private List<String> interfaces;
Map<String, Object> properties = new HashMap<>();
Map<String, Boolean> propertiesAccess = new HashMap<>();
private boolean observing = false;
private boolean observable = true;
......@@ -99,6 +100,9 @@ public class SerializableResource implements Serializable {
case OC_REP_BOOL:
properties.put(ocRepresentation.getName(), ocRepresentation.getValue().getBool());
break;
case OC_REP_BOOL_ARRAY:
properties.put(ocRepresentation.getName(), OCRep.ocArrayToBooleanArray(ocRepresentation.getValue().getArray()));
break;
case OC_REP_STRING:
properties.put(ocRepresentation.getName(), ocRepresentation.getValue().getString());
break;
......@@ -125,6 +129,16 @@ public class SerializableResource implements Serializable {
}
}
public Map<String, Boolean> getPropertiesAccess() {
return this.propertiesAccess;
}
public void setPropertiesAccess(List<DynamicUiProperty> properties) {
for (DynamicUiProperty property : properties) {
propertiesAccess.put(property.getName(), property.isReadOnly());
}
}
public boolean isObserving() {
return this.observing;
}
......
......@@ -239,4 +239,14 @@ public class Device implements Comparable<Device>, Serializable {
return res;
}
@Override
public boolean equals(Object device) {
boolean same = false;
if (device != null && device instanceof Device) {
same = this.deviceId.equals(((Device)device).getDeviceId());
}
return same;
}
}
package org.openconnectivity.otgc.domain.usecase;
import org.openconnectivity.otgc.data.repository.DoxsRepository;
import org.openconnectivity.otgc.data.repository.IotivityRepository;
import org.openconnectivity.otgc.data.repository.PreferencesRepository;
import org.openconnectivity.otgc.domain.model.devicelist.Device;
import org.openconnectivity.otgc.utils.constant.OcfOxmType;
import org.openconnectivity.otgc.utils.rx.SchedulersFacade;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import io.reactivex.Single;
public class OnboardDevicesUseCase {
/* Repositories */
private final IotivityRepository iotivityRepository;
private final DoxsRepository doxsRepository;
private final PreferencesRepository settingRepository;
/* Scheduler */
private final SchedulersFacade schedulersFacade;
@Inject
public OnboardDevicesUseCase(IotivityRepository iotivityRepository,
DoxsRepository doxsRepository,
PreferencesRepository settingRepository,
SchedulersFacade schedulersFacade) {
this.iotivityRepository = iotivityRepository;
this.doxsRepository = doxsRepository;
this.settingRepository = settingRepository;
this.schedulersFacade = schedulersFacade;
}
public Single<Device> execute(Device device, List<OcfOxmType> oxms) {
int it1 = oxms.size() - 1;
if (it1 < 0) {
return null;
}
return executeOnboard(device, oxms.get(it1))
.onErrorResumeNext(error1 -> {
int it2 = it1 - 1;
if (it2 < 0) {
return null;
}
return iotivityRepository.scanUnownedDevices()
.filter(device1 -> device.getDeviceId().equals(device1.getDeviceId()))
.firstOrError()
.flatMap(device1 ->
executeOnboard(device1, oxms.get(it2))
.onErrorResumeNext(error -> {
int it3 = it1 - 2;
if (it3 < 0) {
return null;
}
return iotivityRepository.scanUnownedDevices()
.filter(device2 -> device.getDeviceId().equals(device2.getDeviceId()))
.firstOrError()
.flatMap(device2 -> executeOnboard(device2, oxms.get(it3)));
})
);
});
}
private Single<Device> executeOnboard(Device deviceToOnboard, OcfOxmType oxm) {
int delay = settingRepository.getRequestsDelay();
final Single<Device> getUpdatedOcSecureResource = iotivityRepository.scanOwnedDevices()
.filter(device -> deviceToOnboard.getDeviceId().equals(device.getDeviceId())
|| deviceToOnboard.equalsHosts(device))
.singleOrError();
return doxsRepository.doOwnershipTransfer(deviceToOnboard.getDeviceId(), oxm)
.delay(2 * delay, TimeUnit.SECONDS, schedulersFacade.ui())
.andThen(getUpdatedOcSecureResource
.onErrorResumeNext(error -> getUpdatedOcSecureResource
.retry(2)
.onErrorResumeNext(Single.error(error)))
);
}
}
......@@ -27,6 +27,8 @@ import org.openconnectivity.otgc.data.repository.IotivityRepository;
import org.openconnectivity.otgc.domain.model.client.SerializableResource;
import org.openconnectivity.otgc.domain.model.devicelist.Device;
import java.util.Map;
import javax.inject.Inject;
import io.reactivex.Completable;
......@@ -43,4 +45,9 @@ public class PostRequestUseCase {
return iotivityRepository.getSecureEndpoint(device)
.flatMapCompletable(endpoint -> iotivityRepository.post(endpoint, resource.getUri(), device.getDeviceId(), rep, valueArray));
}
public Completable execute(Device device, SerializableResource resource, Map<String, Object> values) {
return iotivityRepository.getSecureEndpoint(device)
.flatMapCompletable(endpoint -> iotivityRepository.post(endpoint, resource.getUri(), device.getDeviceId(), values));
}
}
......@@ -77,7 +77,7 @@ public class UiFromSwaggerUseCase {
uiElement.setPath(pathEntry.getKey());
String definitionName = getSchemaTitle(pathEntry.getValue());
if (definitionName != null && !definitionName.isEmpty()) {
uiElement.setResourceTypes(getResourceTypes(jsonSwagger, definitionName));
uiElement.setResourceTypes(getResourceTypes(swagger, definitionName));
uiElement.setInterfaces(getInterfaces(swagger, definitionName));
uiElement.setProperties(getProperties(swagger, definitionName));
uiElement.setSupportedOperations(getSupportedOperations(pathEntry.getValue()));
......@@ -100,20 +100,11 @@ public class UiFromSwaggerUseCase {
return schemaTitle;
}
private List<String> getResourceTypes(JSONObject jsonSwagger, String definitionName) throws JSONException {
List<String> resourceTypes = new ArrayList<>();
private List<String> getResourceTypes(Swagger swagger, String definitionName) {
ArrayProperty interfaces = (ArrayProperty) swagger.getDefinitions().get(definitionName).getProperties().get("rt");
StringProperty rtItems = (StringProperty) interfaces.getItems();
JSONArray jsonRt = jsonSwagger.getJSONObject("definitions")
.getJSONObject(definitionName)
.getJSONObject("properties")
.getJSONObject("rt")
.getJSONArray("default");
for (int i = 0; i < jsonRt.length(); i++) {
resourceTypes.add(jsonRt.getString(i));
}
return resourceTypes;
return rtItems.getEnum();
}
private List<String> getInterfaces(Swagger swagger, String definitionName) {
......
......@@ -23,5 +23,5 @@
package org.openconnectivity.otgc.utils.handler;
public interface OCSetRandomPinHandler {
public String handler();
public String handler(String uuid);
}
......@@ -217,6 +217,7 @@ public class GenericClientActivity extends AppCompatActivity implements HasSuppo
for (DynamicUiElement uiElement : uiElements) {
SerializableResource resource = new SerializableResource();
resource.setUri(uiElement.getPath());
resource.setPropertiesAccess(uiElement.getProperties());
resource.setResourceTypes(uiElement.getResourceTypes());
resource.setResourceInterfaces(uiElement.getInterfaces());
......
......@@ -37,6 +37,7 @@ import org.openconnectivity.otgc.utils.rx.SchedulersFacade;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import androidx.appcompat.view.ActionMode;
import androidx.recyclerview.selection.SelectionTracker;
......@@ -67,63 +68,106 @@ public class ActionModeController implements ActionMode.Callback {
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
MenuItem linkMenuItem = menu.findItem(R.id.action_pairwise);
MenuItem unlinkMenuItem = menu.findItem(R.id.action_unlink);
if (mSelectionTracker.hasSelection() && mSelectionTracker.getSelection().size() == 2) {
Device server = null;
Device client = null;
Iterator<Device> deviceIterable = mSelectionTracker.getSelection().iterator();
while (deviceIterable.hasNext()) {
Device device = deviceIterable.next();
if (device.getDeviceRole().equals(DeviceRole.SERVER)
&& device.getDeviceType().equals(DeviceType.OWNED_BY_SELF)) {
server = device;
} else if (device.getDeviceRole().equals(DeviceRole.CLIENT)
&& device.getDeviceType().equals(DeviceType.OWNED_BY_SELF)) {
client = device;
MenuItem onboardMenuItem = menu.findItem(R.id.action_onboard);
if (mSelectionTracker.hasSelection()) {
boolean areUnowned = true;
Iterator<Device> itDevice = mSelectionTracker.getSelection().iterator();
while (itDevice.hasNext()) {
Device d = itDevice.next();
if (d.getDeviceType() != DeviceType.UNOWNED) {
areUnowned = false;
break;
}
}
if (server != null && client != null) {
String serverId = server.getDeviceId();
final Device c = client;
final Device s = server;
// Create dialog
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle(R.string.dialog_wait_title);
builder.setMessage(R.string.dialog_wait_message);
AlertDialog waitDialog = builder.create();
new CompositeDisposable().add(retrieveLinkedDevicesUseCase.execute(c)
.onErrorReturnItem(new ArrayList<>())
.subscribeOn(new SchedulersFacade().io())
.observeOn(new SchedulersFacade().ui())
.doOnSubscribe(__ -> waitDialog.show())
.doFinally(() -> waitDialog.dismiss())
.subscribe(
linkClientDevices -> {
if (serverId != null) {
if (linkClientDevices.contains(serverId)) {
unlinkMenuItem.setOnMenuItemClickListener(menuItem -> {
actionMode.finish();
return sMyMenuItemClickListener.onMenuItemClick(menuItem, c, s);
});
unlinkMenuItem.setVisible(true);
} else {
linkMenuItem.setOnMenuItemClickListener(menuItem -> {
actionMode.finish();
return sMyMenuItemClickListener.onMenuItemClick(menuItem, c, s);
});
linkMenuItem.setVisible(true);
}
}
},
throwable -> Toast.makeText(mContext, R.string.devices_link_error, Toast.LENGTH_SHORT)
));
if (!areUnowned && mSelectionTracker.getSelection().size() == 2) {
Device server = null;
Device client = null;
Iterator<Device> deviceIterable = mSelectionTracker.getSelection().iterator();
while (deviceIterable.hasNext()) {
Device device = deviceIterable.next();
if (device.getDeviceRole().equals(DeviceRole.SERVER)
&& device.getDeviceType().equals(DeviceType.OWNED_BY_SELF)) {
server = device;
} else if (device.getDeviceRole().equals(DeviceRole.CLIENT)
&& device.getDeviceType().equals(DeviceType.OWNED_BY_SELF)) {
client = device;
}
}
if (server != null && client != null) {
String serverId = server.getDeviceId();
final Device c = client;
final Device s = server;
// Create dialog
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle(R.string.dialog_wait_title);
builder.setMessage(R.string.dialog_wait_message);
AlertDialog waitDialog = builder.create();
new CompositeDisposable().add(retrieveLinkedDevicesUseCase.execute(c)
.onErrorReturnItem(new ArrayList<>())
.subscribeOn(new SchedulersFacade().io())
.observeOn(new SchedulersFacade().ui())
.doOnSubscribe(__ -> waitDialog.show())
.doFinally(() -> waitDialog.dismiss())
.subscribe(
linkClientDevices -> {
if (serverId != null) {
if (linkClientDevices.contains(serverId)) {
unlinkMenuItem.setOnMenuItemClickListener(menuItem -> {
actionMode.finish();
return sMyMenuItemClickListener.onMenuItemClick(menuItem, c, s);
});
unlinkMenuItem.setVisible(true);
linkMenuItem.setVisible(false);
onboardMenuItem.setVisible(false);
} else {
linkMenuItem.setOnMenuItemClickListener(menuItem -> {
actionMode.finish();
return sMyMenuItemClickListener.onMenuItemClick(menuItem, c, s);
});
linkMenuItem.setVisible(true);
unlinkMenuItem.setVisible(false);
onboardMenuItem.setVisible(false);
}
}
},
throwable -> Toast.makeText(mContext, R.string.devices_link_error, Toast.LENGTH_SHORT)
));
} else {
linkMenuItem.setVisible(false);
unlinkMenuItem.setVisible(false);
onboardMenuItem.setVisible(false);
}
} else if (areUnowned) {
onboardMenuItem.setOnMenuItemClickListener(menuItem -> {
List<Device> devices = new ArrayList<>();
Iterator<Device> deviceIterator = mSelectionTracker.getSelection().iterator();
while (deviceIterator.hasNext()) {
devices.add(deviceIterator.next());
}
actionMode.finish();
return sMyMenuItemClickListener.onMenuItemClick(menuItem, devices);
});
onboardMenuItem.setVisible(true);
linkMenuItem.setVisible(false);
unlinkMenuItem.setVisible(false);
} else {
linkMenuItem.setVisible(false);
unlinkMenuItem.setVisible(false);
onboardMenuItem.setVisible(false);
}
} else {
linkMenuItem.setVisible(false);
unlinkMenuItem.setVisible(false);
onboardMenuItem.setVisible(false);
}
return true;
}
......@@ -144,5 +188,6 @@ public class ActionModeController implements ActionMode.Callback {
public interface MyMenuItemClickListener {
boolean onMenuItemClick(MenuItem menuItem, Device client, Device server);
boolean onMenuItemClick(MenuItem menuItem, List<Device> devices);
}