diff --git a/.gitignore b/.gitignore
index 3f4fefdb58cd598656922125e157f27fb1cb1a9c..2ca193d01231f71851fed9e47216071e80f4e03a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@
/build
/captures
.externalNativeBuild
+/iotivity-base-release/*.aar
diff --git a/build.gradle b/build.gradle
index 1aef4ddcff72af1737cbeb0897c30bb0f46376fd..eb23364c5de2555070e406ad4a94fd90febfe05f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.2.0'
+ classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
diff --git a/gradle.properties b/gradle.properties
index aac7c9b4614ccfde6c721f24994cf30885a791d0..e4c1a659d9934604460aaa909e42e30ab53953de 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,3 +15,7 @@ org.gradle.jvmargs=-Xmx1536m
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
+
+# Android X: https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.enableJetifier=true
+android.useAndroidX=true
diff --git a/otgc/build.gradle b/otgc/build.gradle
index a5b9ee11fcb0bcc35b93bdf4e6475dcfb71a6e71..698520b559bc74fe89881274d4cba01609f0e783 100644
--- a/otgc/build.gradle
+++ b/otgc/build.gradle
@@ -2,29 +2,36 @@ apply plugin: 'com.android.application'
apply plugin: 'jacoco'
project.ext {
- supportLibraryVersion = "27.1.1"
- daggerVersion = "2.15"
- butterKnifeVersion = "8.8.1"
+ appCompatVersion = "1.0.2"
+ supportLibraryVersion = "1.0.0"
+ constraintLayoutVersion = "1.1.3"
+ materialVersion = "1.1.0-alpha01"
+ lifecycleVersion = "2.0.0"
+ roomVersion = "2.0.0"
+ daggerVersion = "2.17"
+ butterKnifeVersion = "9.0.0-rc2"
rxJavaVersion = "2.1.0"
rxAndroidVersion = "2.0.1"
- lifecycleVersion = "1.1.1"
timberVersion = "4.7.0"
- roomVersion = "1.1.1"
swaggerParserVersion = "1.0.38"
gsonVersion = "2.8.0"
cborVersion = "3.3.0"
spongyCastleVersion = "1.58.0.0"
+ junitVersion = "4.12"
+ mockitoVersion = "1.10.19"
+ testRunnerVersion = "1.1.1-alpha01"
+ espressoVersion = "3.1.1-alpha01"
}
android {
- compileSdkVersion 27
+ compileSdkVersion 28
defaultConfig {
applicationId "org.openconnectivity.otgc"
minSdkVersion 21
- targetSdkVersion 27
+ targetSdkVersion 28
versionCode 13
- versionName "1.2.0"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ versionName "1.3.0"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@@ -45,61 +52,56 @@ android {
}
dependencies {
- implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation "com.android.support:appcompat-v7:$project.supportLibraryVersion"
- implementation "com.android.support:design:$project.supportLibraryVersion"
- implementation "com.android.support:cardview-v7:$project.supportLibraryVersion"
- implementation "com.android.support:support-v4:$project.supportLibraryVersion"
-
- // Dagger core
+ // local modules
+ implementation project(':iotivity-base-release')
+ implementation project(':easy-setup-core')
+ // AndroidX: Support Library
+ implementation "androidx.appcompat:appcompat:$project.appCompatVersion"
+ implementation "androidx.recyclerview:recyclerview:$project.supportLibraryVersion"
+ implementation "androidx.recyclerview:recyclerview-selection:$project.supportLibraryVersion"
+ implementation "androidx.cardview:cardview:$project.supportLibraryVersion"
+ implementation "androidx.legacy:legacy-support-v4:$project.supportLibraryVersion"
+ // AndroidX: ConstraintLayout
+ implementation "androidx.constraintlayout:constraintlayout:$project.constraintLayoutVersion"
+ // Material Components
+ implementation "com.google.android.material:material:$project.materialVersion"
+ // AndroidX: Lifecycle
+ implementation "androidx.lifecycle:lifecycle-runtime:$project.lifecycleVersion"
+ implementation "androidx.lifecycle:lifecycle-extensions:$project.lifecycleVersion"
+ annotationProcessor "androidx.lifecycle:lifecycle-compiler:$project.lifecycleVersion"
+ // AndroidX: Room
+ implementation "androidx.room:room-runtime:$project.roomVersion"
+ implementation "androidx.room:room-rxjava2:$project.roomVersion"
+ annotationProcessor "androidx.room:room-compiler:$project.roomVersion"
+ // Dagger
implementation "com.google.dagger:dagger:$project.daggerVersion"
annotationProcessor "com.google.dagger:dagger-compiler:$project.daggerVersion"
-
- // Dagger Android
implementation "com.google.dagger:dagger-android:$project.daggerVersion"
implementation "com.google.dagger:dagger-android-support:$project.daggerVersion"
annotationProcessor "com.google.dagger:dagger-android-processor:$project.daggerVersion"
-
// ButterKnife
implementation "com.jakewharton:butterknife:$project.butterKnifeVersion"
annotationProcessor "com.jakewharton:butterknife-compiler:$project.butterKnifeVersion"
-
// ReactiveX
implementation "io.reactivex.rxjava2:rxjava:$project.rxJavaVersion"
implementation "io.reactivex.rxjava2:rxandroid:$project.rxAndroidVersion"
-
// Timber
implementation "com.jakewharton.timber:timber:$project.timberVersion"
-
- // Lifecycle
- implementation "android.arch.lifecycle:runtime:$project.lifecycleVersion"
- implementation "android.arch.lifecycle:extensions:$project.lifecycleVersion"
- annotationProcessor "android.arch.lifecycle:compiler:$project.lifecycleVersion"
-
// Swagger
implementation "io.swagger:swagger-parser:$project.swaggerParserVersion"
-
- // Room
- implementation "android.arch.persistence.room:runtime:$project.roomVersion"
- implementation "android.arch.persistence.room:rxjava2:$project.roomVersion"
- annotationProcessor "android.arch.persistence.room:compiler:$project.roomVersion"
-
// Gson
implementation "com.google.code.gson:gson:$project.gsonVersion"
-
// CBOR
implementation "com.upokecenter:cbor:$project.cborVersion"
-
- // Bouncy Castle Provider
+ // Spongy Castle
implementation "com.madgag.spongycastle:core:$project.spongyCastleVersion"
implementation "com.madgag.spongycastle:prov:$project.spongyCastleVersion"
implementation "com.madgag.spongycastle:bcpkix-jdk15on:$project.spongyCastleVersion"
-
- implementation 'com.android.support.constraint:constraint-layout:1.1.2'
- testImplementation 'junit:junit:4.12'
- testImplementation 'org.mockito:mockito-core:1.10.19'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
- implementation project(':iotivity-base-release')
- implementation project(':easy-setup-core')
+ // JUnit
+ testImplementation "junit:junit:$project.junitVersion"
+ // Mockito
+ testImplementation "org.mockito:mockito-core:$project.mockitoVersion"
+ // AndroidX: Test
+ androidTestImplementation "androidx.test:runner:$project.testRunnerVersion"
+ androidTestImplementation "androidx.test.espresso:espresso-core:$project.espressoVersion"
}
diff --git a/otgc/src/androidTest/java/org/openconnectivity/otgc/accesscontrol/data/repository/AmsRepositoryTest.java b/otgc/src/androidTest/java/org/openconnectivity/otgc/accesscontrol/data/repository/AmsRepositoryTest.java
index 9c10d003ebb88f0308688c9893171b51dcacf873..cd83baecea5c8facbd5df2272c42d2f4bf384651 100644
--- a/otgc/src/androidTest/java/org/openconnectivity/otgc/accesscontrol/data/repository/AmsRepositoryTest.java
+++ b/otgc/src/androidTest/java/org/openconnectivity/otgc/accesscontrol/data/repository/AmsRepositoryTest.java
@@ -22,7 +22,7 @@
package org.openconnectivity.otgc.accesscontrol.data.repository;
-import android.support.test.InstrumentationRegistry;
+import androidx.test.InstrumentationRegistry;
import org.iotivity.base.AceSubjectType;
import org.iotivity.base.OcException;
diff --git a/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/persistence/UserDaoTest.java b/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/persistence/UserDaoTest.java
index 3d10a98c1f6d4e9102ab6b6eeb59529e21b1608d..bc4eed694b628fdcb6febf29cd9331dc796b40fd 100644
--- a/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/persistence/UserDaoTest.java
+++ b/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/persistence/UserDaoTest.java
@@ -22,10 +22,10 @@
package org.openconnectivity.otgc.common.data.persistence;
-import android.arch.persistence.room.EmptyResultSetException;
-import android.arch.persistence.room.Room;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.room.EmptyResultSetException;
+import androidx.room.Room;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
diff --git a/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/IORepositoryTest.java b/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/IORepositoryTest.java
index 2a0ebe5578c916ffc2397116865cb13929de7244..ac525d64ac746e825d5fe150bcb2b3cf3b00746a 100644
--- a/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/IORepositoryTest.java
+++ b/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/IORepositoryTest.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.common.data.repository;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
diff --git a/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/PlatformRepositoryTest.java b/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/PlatformRepositoryTest.java
index 8352a81d5e78df3d4b9fc975a4612a1408c961e4..96629af115355d12dab4d7fe7dc11807ef308ac5 100644
--- a/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/PlatformRepositoryTest.java
+++ b/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/PlatformRepositoryTest.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.common.data.repository;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
import org.iotivity.base.OcException;
import org.junit.Before;
diff --git a/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/ProvisioningRepositoryTest.java b/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/ProvisioningRepositoryTest.java
index 05e5fef33e309a67592f4a08d082794f788fef60..f647c59028bcd8706cc3aa1b5a39afe1e0645620 100644
--- a/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/ProvisioningRepositoryTest.java
+++ b/otgc/src/androidTest/java/org/openconnectivity/otgc/common/data/repository/ProvisioningRepositoryTest.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.common.data.repository;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
diff --git a/otgc/src/main/AndroidManifest.xml b/otgc/src/main/AndroidManifest.xml
index fc1466187b65e87e0da12b428cf2bf31c97296a4..04cfef10b92e6985ea626f93606c571586d0321a 100644
--- a/otgc/src/main/AndroidManifest.xml
+++ b/otgc/src/main/AndroidManifest.xml
@@ -69,6 +69,11 @@
android:name=".client.presentation.view.GenericClientActivity"
android:configChanges="orientation|screenSize"
android:parentActivityName=".devicelist.presentation.view.DeviceListActivity" />
+
> execute(String deviceId) {
return iotivityRepository.getDeviceCoapIpv6Host(deviceId)
- .flatMap(iotivityRepository::findResource)
+ .flatMap(iotivityRepository::findResources)
.map(ocResources -> {
List verticalResources = new ArrayList<>();
for (OcResource ocResource : ocResources) {
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AccessControlActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AccessControlActivity.java
index ebb323e2b3c90a75b1bdd34356364572630fb1b4..4011665f95f6ef4778d8069642db3e68eba8fc43 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AccessControlActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AccessControlActivity.java
@@ -22,17 +22,17 @@
package org.openconnectivity.otgc.accesscontrol.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.NonNull;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AccessControlAdapter.java b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AccessControlAdapter.java
index 681d39665daa8352f29e46856d3cd6881f93a394..7dc81d851214d2080c819491097aec57ae583cd5 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AccessControlAdapter.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AccessControlAdapter.java
@@ -23,9 +23,9 @@
package org.openconnectivity.otgc.accesscontrol.presentation.view;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.v7.util.SortedList;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.SortedList;
+import androidx.recyclerview.widget.RecyclerView;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AceActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AceActivity.java
index 083bf425bb2a5e21f5a0ff458328e12b5e362eec..e1f0d8fbe5c969a33c4e92c2494ade1a2d853c9b 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AceActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/view/AceActivity.java
@@ -22,14 +22,14 @@
package org.openconnectivity.otgc.accesscontrol.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.util.SparseBooleanArray;
import android.view.MenuItem;
import android.view.View;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/viewmodel/AccessControlViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/viewmodel/AccessControlViewModel.java
index 7b6556ae3b72ae961afcbeadcf83dbfec12ab8a3..0a17342b8af4e77b345cdcce7c7786c2640e88fe 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/viewmodel/AccessControlViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/viewmodel/AccessControlViewModel.java
@@ -22,9 +22,9 @@
package org.openconnectivity.otgc.accesscontrol.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
import org.iotivity.base.OicSecAce;
import org.openconnectivity.otgc.accesscontrol.domain.usecase.DeleteAclUseCase;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/viewmodel/AceViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/viewmodel/AceViewModel.java
index a55027606158d44bd56a3abdefbc6797d6a27dc6..105d18c643f72d88ffb36ce53069ffd350ae855d 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/viewmodel/AceViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/accesscontrol/presentation/viewmodel/AceViewModel.java
@@ -22,15 +22,13 @@
package org.openconnectivity.otgc.accesscontrol.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
import org.openconnectivity.otgc.accesscontrol.domain.usecase.CreateAclUseCase;
import org.openconnectivity.otgc.accesscontrol.domain.usecase.RetrieveVerticalResourcesUseCase;
import org.openconnectivity.otgc.accesscontrol.domain.usecase.UpdateAclUseCase;
-import org.openconnectivity.otgc.client.domain.model.SerializableResource;
-import org.openconnectivity.otgc.client.domain.usecase.GetResourcesUseCase;
import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelError;
import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelErrorType;
import org.openconnectivity.otgc.common.domain.rx.SchedulersFacade;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/data/repository/ResourceRepository.java b/otgc/src/main/java/org/openconnectivity/otgc/client/data/repository/ResourceRepository.java
index 66bb2ca6b8c82311347c7367f120c7068e95988e..dfa1062d67240728f16037a9bc485f8d9baa301c 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/data/repository/ResourceRepository.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/data/repository/ResourceRepository.java
@@ -32,10 +32,14 @@ import org.iotivity.base.OcException;
import org.iotivity.base.OcHeaderOption;
import org.iotivity.base.OcRepresentation;
import org.iotivity.base.OcResource;
+import org.iotivity.base.OicSecResr;
import org.iotivity.base.QualityOfService;
+import org.openconnectivity.otgc.common.constant.OcfResourceType;
import javax.inject.Inject;
import javax.inject.Singleton;
+
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -103,6 +107,26 @@ public class ResourceRepository {
emitter.onComplete();
});
}
+
+ public List getVerticalResources(List ocResources) {
+ List resources = new ArrayList<>();
+ for (OcResource resource : ocResources) {
+ for (String resourceType : resource.getResourceTypes()) {
+ if (OcfResourceType.isVerticalResourceType(resourceType)) {
+ OicSecResr res = new OicSecResr();
+ res.setHref(resource.getUri());
+ List types = resource.getResourceTypes();
+ res.setTypes(types);
+ res.setTypeLen(types.size());
+ List interfaces = resource.getResourceInterfaces();
+ res.setInterfaces(interfaces);
+ res.setInterfaceLen(interfaces.size());
+ resources.add(res);
+ }
+ }
+ }
+ return resources;
+ }
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/domain/model/SerializableResource.java b/otgc/src/main/java/org/openconnectivity/otgc/client/domain/model/SerializableResource.java
index f5f35b795bdea6c34e1322c00b96d6348dd00532..2a8e9fa66ec7e7e9302985d153d3232513c6eb8e 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/domain/model/SerializableResource.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/domain/model/SerializableResource.java
@@ -22,7 +22,7 @@
package org.openconnectivity.otgc.client.domain.model;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import org.iotivity.base.OcResource;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/domain/usecase/UiFromSwaggerUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/client/domain/usecase/UiFromSwaggerUseCase.java
index a5a283e250a5aae6d22aa23620dcd49eb9535d35..eb63f3b7dd22bb5c759c2fc999f5d18cf1f646d7 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/domain/usecase/UiFromSwaggerUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/domain/usecase/UiFromSwaggerUseCase.java
@@ -23,7 +23,7 @@
package org.openconnectivity.otgc.client.domain.usecase;
import android.os.Build;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import org.json.JSONArray;
import org.json.JSONException;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/DeviceInfoAdapter.java b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/DeviceInfoAdapter.java
index 17107289f1b6715a3f01dc6b320e6b71079469da..eed4eacb20875cba931c9ea7fc29f105f9e4b449 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/DeviceInfoAdapter.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/DeviceInfoAdapter.java
@@ -23,8 +23,8 @@
package org.openconnectivity.otgc.client.presentation.view;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/GenericClientActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/GenericClientActivity.java
index 47875aee611a219936b326e3cc5377066e5d85cb..c3c925cbfb8cbb7cec8821427dca7e94c30ce662 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/GenericClientActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/GenericClientActivity.java
@@ -21,20 +21,20 @@
*/
package org.openconnectivity.otgc.client.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.DividerItemDecoration;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.appcompat.widget.Toolbar;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/IntrospectedFragment.java b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/IntrospectedFragment.java
index e083f0664518e79cd2d18bd1d8ceb8e07317aeb9..2e9436853467864150fb16a064b872a9008e8baa 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/IntrospectedFragment.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/IntrospectedFragment.java
@@ -22,12 +22,12 @@
package org.openconnectivity.otgc.client.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.Fragment;
-import android.support.v4.content.ContextCompat;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.core.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/ResourceFragment.java b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/ResourceFragment.java
index 2e2189161ec875c7de3e77d3d781942329dbad43..a5529ed4f33e4bbbbbc71327164a444d060e5826 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/ResourceFragment.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/view/ResourceFragment.java
@@ -22,22 +22,23 @@
package org.openconnectivity.otgc.client.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
+
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.Fragment;
-import android.support.v4.content.ContextCompat;
-import android.text.Editable;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.core.content.ContextCompat;
import android.text.InputType;
-import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
+import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
@@ -53,6 +54,7 @@ import org.openconnectivity.otgc.di.Injectable;
import java.text.DecimalFormat;
import java.text.NumberFormat;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -211,6 +213,41 @@ public class ResourceFragment extends Fragment implements Injectable {
} else {
((TextView) mViews.get(entry.getKey())).setText(numberFormat.format(entry.getValue()));
}
+ } else if (entry.getValue() instanceof String) {
+ if (isViewEnabled(response.getResourceInterfaces())) {
+ ((EditText) mViews.get(entry.getKey())).setText(entry.getValue().toString());
+ } else {
+ ((TextView) mViews.get(entry.getKey())).setText(entry.getValue().toString());
+ }
+ } else if (entry.getValue() instanceof String[]) {
+ List list = Arrays.asList((String[]) entry.getValue());
+ ArrayAdapter dataAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, list);
+ dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ ((Spinner) mViews.get(entry.getKey())).setAdapter(dataAdapter);
+ } else if (entry.getValue() instanceof int[]) {
+ LinearLayout layout = ((LinearLayout)mViews.get(entry.getKey()));
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ int i = 0;
+ for (int value : (int[])entry.getValue()) {
+ if (isViewEnabled(response.getResourceInterfaces())) {
+ ((EditText)layout.getChildAt(i)).setText(numberFormat.format(value));
+ } else {
+ ((TextView)layout.getChildAt(i)).setText(numberFormat.format(value));
+ }
+ i++;
+ }
+ } else if (entry.getValue() instanceof double[]) {
+ LinearLayout layout = ((LinearLayout)mViews.get(entry.getKey()));
+ NumberFormat numberFormat = new DecimalFormat("0.0");
+ int i = 0;
+ for (double value : (double[])entry.getValue()) {
+ if (isViewEnabled(response.getResourceInterfaces())) {
+ ((EditText)layout.getChildAt(i)).setText(numberFormat.format(value));
+ } else {
+ ((TextView)layout.getChildAt(i)).setText(numberFormat.format(value));
+ }
+ i++;
+ }
}
} else {
View view = null;
@@ -240,24 +277,12 @@ public class ResourceFragment extends Fragment implements Injectable {
et.setInputType(InputType.TYPE_CLASS_NUMBER);
NumberFormat numberFormat = NumberFormat.getInstance();
et.setText(numberFormat.format(entry.getValue()));
- et.addTextChangedListener(new TextWatcher() {
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
-
- }
-
- @Override
- public void afterTextChanged(Editable s) {
+ et.setOnFocusChangeListener((v, hasFocus) -> {
+ if (!hasFocus) {
Integer number;
try {
- number = Integer.valueOf(s.toString());
+ number = Integer.valueOf(et.getText().toString());
} catch (NumberFormatException e) {
return;
}
@@ -287,6 +312,26 @@ public class ResourceFragment extends Fragment implements Injectable {
et.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
NumberFormat numberFormat = new DecimalFormat("0.0");
et.setText(numberFormat.format(entry.getValue()));
+ et.setOnFocusChangeListener((v, hasFocus) -> {
+ if (!hasFocus) {
+ Double number;
+
+ try {
+ number = Double.valueOf(et.getText().toString());
+ } catch (NumberFormatException e) {
+ return;
+ }
+
+ OcRepresentation rep = new OcRepresentation();
+ try {
+ rep.setValue(entry.getKey(), number);
+ } catch (OcException e) {
+ return;
+ }
+ mViewModel.postRequest(mDeviceId, mResource.getUri(), mResource.getResourceTypes(), mResource.getResourceInterfaces(),
+ rep);
+ }
+ });
view = et;
} else {
@@ -296,6 +341,131 @@ public class ResourceFragment extends Fragment implements Injectable {
view = tv;
}
+ } else if (entry.getValue() instanceof String) {
+ if (isViewEnabled(response.getResourceInterfaces())) {
+ EditText et = new EditText(getContext());
+ et.setInputType(InputType.TYPE_CLASS_TEXT);
+ et.setText(String.valueOf(entry.getValue()));
+ et.setOnFocusChangeListener((v, hasFocus) -> {
+ if (!hasFocus) {
+ OcRepresentation rep = new OcRepresentation();
+ try {
+ rep.setValue(entry.getKey(), et.getText().toString());
+ } catch (OcException e) {
+ return;
+ }
+ mViewModel.postRequest(mDeviceId, mResource.getUri(), mResource.getResourceTypes(), mResource.getResourceInterfaces(),
+ rep);
+ }
+ });
+
+ view = et;
+ } else {
+ TextView tv = new TextView(getContext());
+ tv.setText(String.valueOf(entry.getValue()));
+
+ view = tv;
+ }
+ } else if (entry.getValue() instanceof String[]) {
+ List list = Arrays.asList((String[]) entry.getValue());
+ ArrayAdapter dataAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, list);
+ dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+
+ // attaching data adapter to list view
+ Spinner spinner = new Spinner(getContext());
+ spinner.setAdapter(dataAdapter);
+
+ view = spinner;
+ } else if (entry.getValue() instanceof int[]) {
+ LinearLayout layout = new LinearLayout(getContext());
+ layout.setOrientation(LinearLayout.HORIZONTAL);
+ for (int value : (int[]) entry.getValue()) {
+ if (isViewEnabled(response.getResourceInterfaces())) {
+ EditText et = new EditText(getContext());
+ et.setInputType(InputType.TYPE_CLASS_NUMBER);
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ et.setText(numberFormat.format(value));
+ et.setOnFocusChangeListener((v, hasFocus) -> {
+ if (!hasFocus) {
+ int[] ret = new int[layout.getChildCount()];
+ for (int i = 0; i < layout.getChildCount(); i++) {
+ EditText tmp = (EditText) layout.getChildAt(i);
+ Integer number;
+ try {
+ number = Integer.valueOf(tmp.getText().toString());
+ } catch (NumberFormatException e) {
+ return;
+ }
+ ret[i] = number;
+ }
+
+ OcRepresentation rep = new OcRepresentation();
+ try {
+ rep.setValue(entry.getKey(), ret);
+ } catch (OcException e) {
+ return;
+ }
+ mViewModel.postRequest(mDeviceId, mResource.getUri(), mResource.getResourceTypes(), mResource.getResourceInterfaces(),
+ rep);
+ }
+ });
+
+ layout.addView(et);
+ } else {
+ TextView tv = new TextView(getContext());
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ tv.setText(numberFormat.format(value));
+
+ layout.addView(tv);
+ }
+ }
+
+ view = layout;
+ } else if (entry.getValue() instanceof double[]) {
+ LinearLayout layout = new LinearLayout(getContext());
+ layout.setOrientation(LinearLayout.HORIZONTAL);
+ for (double value : (double[]) entry.getValue()) {
+ if (isViewEnabled(response.getResourceInterfaces())) {
+ EditText et = new EditText(getContext());
+ et.setInputType(InputType.TYPE_CLASS_NUMBER);
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ et.setText(numberFormat.format(value));
+ et.setOnFocusChangeListener((v, hasFocus) -> {
+ if (!hasFocus) {
+ double[] ret = new double[layout.getChildCount()];
+ for (int i = 0; i < layout.getChildCount(); i++) {
+ EditText tmp = (EditText) layout.getChildAt(i);
+ Double number;
+ try {
+ number = Double.valueOf(tmp.getText().toString());
+ } catch (NumberFormatException e) {
+ return;
+ }
+ ret[i] = number;
+ }
+
+ OcRepresentation rep = new OcRepresentation();
+ try {
+ rep.setValue(entry.getKey(), ret);
+ } catch (OcException e) {
+ return;
+ }
+ mViewModel.postRequest(mDeviceId, mResource.getUri(), mResource.getResourceTypes(), mResource.getResourceInterfaces(),
+ rep);
+ }
+ });
+
+ layout.addView(et);
+ } else {
+ TextView tv = new TextView(getContext());
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ tv.setText(numberFormat.format(value));
+
+ layout.addView(tv);
+ }
+ }
+
+ view = layout;
}
if (view != null) {
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/viewmodel/GenericClientViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/viewmodel/GenericClientViewModel.java
index 09e3178786948941db137417aa1d8f89210acf58..f83be8a743d4866aeff891057086fe1b5978b7eb 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/viewmodel/GenericClientViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/viewmodel/GenericClientViewModel.java
@@ -21,8 +21,8 @@
*/
package org.openconnectivity.otgc.client.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
import org.openconnectivity.otgc.client.domain.model.DynamicUiElement;
import org.openconnectivity.otgc.client.domain.model.SerializableResource;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/viewmodel/ResourceViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/viewmodel/ResourceViewModel.java
index 4d69410186706132b4965a38586769f52bc409e7..93cad59a03e1e594a2a1397a622ed9ed86066729 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/viewmodel/ResourceViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/client/presentation/viewmodel/ResourceViewModel.java
@@ -22,9 +22,9 @@
package org.openconnectivity.otgc.client.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
import org.iotivity.base.OcRepresentation;
import org.openconnectivity.otgc.client.domain.usecase.CancelObservation;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/constant/OcfResourceType.java b/otgc/src/main/java/org/openconnectivity/otgc/common/constant/OcfResourceType.java
index 65831c2177e6d14565b6a2a28ea4671579d1e680..ed9509f0b918aee36ba0cccf8154865b21d57091 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/constant/OcfResourceType.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/constant/OcfResourceType.java
@@ -22,6 +22,9 @@
package org.openconnectivity.otgc.common.constant;
+import java.util.ArrayList;
+import java.util.List;
+
public class OcfResourceType {
private OcfResourceType() {
@@ -30,12 +33,24 @@ public class OcfResourceType {
private static final String OIC_WK_PREFIX = "oic.wk.";
public static final String DEVICE = OIC_WK_PREFIX + "d";
+ public static final String DEVICE_CONF = OIC_WK_PREFIX + "con";
public static final String PLATFORM = OIC_WK_PREFIX + "p";
+ public static final String PLATFORM_CONF = OIC_WK_PREFIX + "con.p";
+ public static final String RES = OIC_WK_PREFIX + "res";
+ public static final String RESOURCE_DIRECTORY = OIC_WK_PREFIX + "rd";
+ public static final String MAINTENANCE = OIC_WK_PREFIX + "mnt";
public static final String INTROSPECTION = OIC_WK_PREFIX + "introspection";
public static final String INTROSPECTION_PAYLOAD = OIC_WK_PREFIX + "introspection.payload";
private static final String OIC_RT_PREFIX = "oic.r.";
+ public static final String ICON = OIC_RT_PREFIX + "icon";
public static final String DOXM = OIC_RT_PREFIX + "doxm";
+ public static final String PSTAT = OIC_RT_PREFIX + "pstat";
+ public static final String ACL2 = OIC_RT_PREFIX + "acl2";
+ public static final String CRED = OIC_RT_PREFIX + "cred";
+ public static final String CRL = OIC_RT_PREFIX + "crl";
+ public static final String CSR = OIC_RT_PREFIX + "csr";
+ public static final String ROLES = OIC_RT_PREFIX + "roles";
public static final String ACCELERATION_SENSOR = OIC_RT_PREFIX + "sensor.acceleration";
public static final String ACTIVITY_COUNT_SENSOR = OIC_RT_PREFIX + "sensor.activity.count";
public static final String AIR_QUALITY = OIC_RT_PREFIX + "airquality";
@@ -122,4 +137,30 @@ public class OcfResourceType {
public static final String WATER_SENSOR = OIC_RT_PREFIX + "sensor.water";
public static final String WEIGHT = OIC_RT_PREFIX + "weight";
+ private static final List NON_VERTICAL_RESOURCE_TYPES;
+ static {
+ NON_VERTICAL_RESOURCE_TYPES = new ArrayList<>();
+
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.DEVICE);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.DEVICE_CONF);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.PLATFORM);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.PLATFORM_CONF);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.RES);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.RESOURCE_DIRECTORY);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.MAINTENANCE);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.ICON);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.INTROSPECTION);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.INTROSPECTION_PAYLOAD);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.DOXM);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.PSTAT);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.ACL2);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.CRED);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.CRL);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.CSR);
+ NON_VERTICAL_RESOURCE_TYPES.add(OcfResourceType.ROLES);
+ }
+
+ public static boolean isVerticalResourceType(String resourceType) {
+ return !NON_VERTICAL_RESOURCE_TYPES.contains(resourceType);
+ }
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/entity/DeviceEntity.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/entity/DeviceEntity.java
index 07eb8c04802fec75a500024affdcacec075c5cb8..99d080479a033bf7ccd9bd023893572e03ec5cc7 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/entity/DeviceEntity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/entity/DeviceEntity.java
@@ -22,10 +22,10 @@
package org.openconnectivity.otgc.common.data.entity;
-import android.arch.persistence.room.ColumnInfo;
-import android.arch.persistence.room.Entity;
-import android.arch.persistence.room.PrimaryKey;
-import android.support.annotation.NonNull;
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+import androidx.annotation.NonNull;
import java.util.List;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/entity/UserEntity.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/entity/UserEntity.java
index b1f8f1810c72a7c52ce253be978e01525b485088..466ccf2b2d6667b1d24f6cca2cc8f8fb44bf36fa 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/entity/UserEntity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/entity/UserEntity.java
@@ -22,11 +22,11 @@
package org.openconnectivity.otgc.common.data.entity;
-import android.arch.persistence.room.ColumnInfo;
-import android.arch.persistence.room.Entity;
-import android.arch.persistence.room.Ignore;
-import android.arch.persistence.room.PrimaryKey;
-import android.support.annotation.NonNull;
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.Ignore;
+import androidx.room.PrimaryKey;
+import androidx.annotation.NonNull;
import java.util.UUID;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/dao/DeviceDao.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/dao/DeviceDao.java
index 7513b9ab2c6b7bff17570cf211a94cc046aae8ee..0a08c951d52dba4f92cbd4196501382834e3f577 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/dao/DeviceDao.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/dao/DeviceDao.java
@@ -22,11 +22,11 @@
package org.openconnectivity.otgc.common.data.persistence.dao;
-import android.arch.persistence.room.Dao;
-import android.arch.persistence.room.Insert;
-import android.arch.persistence.room.OnConflictStrategy;
-import android.arch.persistence.room.Query;
-import android.arch.persistence.room.Update;
+import androidx.room.Dao;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
+import androidx.room.Update;
import org.openconnectivity.otgc.common.data.entity.DeviceEntity;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/dao/UserDao.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/dao/UserDao.java
index ecf255de1c4eaaae64437138a9cfb86a39854533..f26fc5f96b7dd5ef09f466901d8a206dba8a4db7 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/dao/UserDao.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/dao/UserDao.java
@@ -22,10 +22,10 @@
package org.openconnectivity.otgc.common.data.persistence.dao;
-import android.arch.persistence.room.Dao;
-import android.arch.persistence.room.Insert;
-import android.arch.persistence.room.OnConflictStrategy;
-import android.arch.persistence.room.Query;
+import androidx.room.Dao;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
import org.openconnectivity.otgc.common.data.entity.UserEntity;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/database/Converters.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/database/Converters.java
index 685c477acecbb6f5210f4b9619ab5075df59eaa0..9c37242249c056651a15949dd89f8f6204bf7ceb 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/database/Converters.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/database/Converters.java
@@ -22,7 +22,7 @@
package org.openconnectivity.otgc.common.data.persistence.database;
-import android.arch.persistence.room.TypeConverter;
+import androidx.room.TypeConverter;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.gson.Gson;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/database/OtgcDb.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/database/OtgcDb.java
index 2d813ab5e545c80353ebd6469e355f1900fd4129..181e23666f84156c1150b389cfe257a25387651b 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/database/OtgcDb.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/persistence/database/OtgcDb.java
@@ -22,9 +22,9 @@
package org.openconnectivity.otgc.common.data.persistence.database;
-import android.arch.persistence.room.Database;
-import android.arch.persistence.room.RoomDatabase;
-import android.arch.persistence.room.TypeConverters;
+import androidx.room.Database;
+import androidx.room.RoomDatabase;
+import androidx.room.TypeConverters;
import org.openconnectivity.otgc.common.data.entity.DeviceEntity;
import org.openconnectivity.otgc.common.data.entity.UserEntity;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/IotivityRepository.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/IotivityRepository.java
index fc8fec21845f809b4420b3368a34d955e8e152a3..7f39cafd32b3cdeb010085a30819dd17cfd89348 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/IotivityRepository.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/IotivityRepository.java
@@ -24,7 +24,7 @@ package org.openconnectivity.otgc.common.data.repository;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import android.util.ArrayMap;
import org.iotivity.base.ErrorCode;
@@ -38,9 +38,14 @@ import org.iotivity.base.OcResource;
import org.iotivity.base.OcSecureResource;
import org.iotivity.base.OxmType;
+import org.iotivity.ca.CaInterface;
+import org.iotivity.ca.OicCipher;
import org.openconnectivity.otgc.common.constant.OcfResourceType;
import org.openconnectivity.otgc.common.data.entity.DeviceEntity;
import org.openconnectivity.otgc.common.data.persistence.dao.DeviceDao;
+import org.openconnectivity.otgc.common.domain.model.OcDevice;
+import org.openconnectivity.otgc.devicelist.domain.model.Device;
+import org.openconnectivity.otgc.devicelist.domain.model.DeviceType;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -50,6 +55,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -88,7 +94,6 @@ public class IotivityRepository {
private final DeviceDao deviceDao;
private List mUnownedDevices = new ArrayList<>();
- private List mOwnedDevices = new ArrayList<>();
@Inject
public IotivityRepository(Context ctx, DeviceDao deviceDao) {
@@ -112,13 +117,16 @@ public class IotivityRepository {
}
}
- public Observable scanUnownedDevices() {
+ public Observable scanUnownedDevices() {
return Observable.create(emitter -> {
try {
mUnownedDevices = OcProvisioning.discoverUnownedDevices(getDiscoveryTimeout());
for (OcSecureResource ocSecureResource : mUnownedDevices) {
- emitter.onNext(ocSecureResource);
+ emitter.onNext(new Device(DeviceType.UNOWNED,
+ ocSecureResource.getDeviceID(),
+ new OcDevice(),
+ ocSecureResource));
}
} catch (OcException e) {
Timber.e(e);
@@ -128,37 +136,47 @@ public class IotivityRepository {
});
}
- public Observable scanOwnedDevices() {
- return Observable.create(emitter -> {
- try {
- mOwnedDevices = OcProvisioning.discoverOwnedDevices(getDiscoveryTimeout());
-
- for (OcSecureResource ocSecureResource : mOwnedDevices) {
- emitter.onNext(ocSecureResource);
- }
- } catch (OcException e) {
- Timber.e(e);
- emitter.onError(e);
+ public Observable scanOwnedDevices() {
+ return findObsResources("")
+ .timeout(getDiscoveryTimeout() + 5_00L, TimeUnit.SECONDS)
+ .map(ocResources -> ocResources.get(0))
+ .filter(ocResource -> {
+ boolean isNotUnowned = true;
+ for (OcSecureResource secureResource : mUnownedDevices) {
+ if (secureResource.getDeviceID().equals(ocResource.getServerId())) {
+ isNotUnowned = false;
+ }
+ }
+ return isNotUnowned;
+ })
+ .filter(ocResource -> !ocResource.getServerId().equals(getDeviceId()))
+ .flatMapSingle(ocResource -> findDeviceInUnicast(ocResource.getServerId()));
}
- emitter.onComplete();
- });
- }
- private Observable> findObsResources(String host) {
- return Observable.create(emitter -> {
- try {
- OcPlatform.findResources(host,
- OcPlatform.WELL_KNOWN_QUERY,
- CONNECTIVITY_TYPES,
+ private Observable> findObsResources(String host) {
+ return Observable.create(emitter -> {
+ try {
+ OcPlatform.findResources(host,
+ OcPlatform.WELL_KNOWN_QUERY,
+ CONNECTIVITY_TYPES,
new OcPlatform.OnResourcesFoundListener() {
@Override
public void onResourcesFound(OcResource[] ocResources) {
DeviceEntity device = deviceDao.findById(ocResources[0].getServerId()).blockingGet();
+ List hosts = new ArrayList<>();
+ for (OcResource ocResource : ocResources) {
+ for (String host : ocResource.getAllHosts()) {
+ if (!hosts.contains(host)) {
+ hosts.add(host);
+ }
+ }
+ }
+
if (device == null) {
- deviceDao.insert(new DeviceEntity(ocResources[0].getServerId(), "", ocResources[0].getAllHosts()));
+ deviceDao.insert(new DeviceEntity(ocResources[0].getServerId(), "", hosts));
} else {
- deviceDao.update(new DeviceEntity(device.getId(), device.getName(), ocResources[0].getAllHosts()));
+ deviceDao.update(new DeviceEntity(device.getId(), device.getName(), hosts));
}
emitter.onNext(Arrays.asList(ocResources));
}
@@ -197,46 +215,68 @@ public class IotivityRepository {
return findObsResources("").ignoreElements();
}
- public Observable scanOwnedByOtherDevices() {
- return findObsResources("")
- .map(ocResources -> ocResources.get(0))
- .filter(ocResource -> {
- boolean isNotUnowned = true;
- for (OcSecureResource secureResource : mUnownedDevices) {
- if (secureResource.getDeviceID().equals(ocResource.getServerId())) {
- isNotUnowned = false;
- }
- }
- return isNotUnowned;
- })
- .filter(ocResource -> {
- boolean isNotOwned = true;
- for (OcSecureResource secureResource : mOwnedDevices) {
- if (secureResource.getDeviceID().equals(ocResource.getServerId())) {
- isNotOwned = false;
- }
- }
- return isNotOwned;
- })
- .filter(ocResource -> !ocResource.getServerId().equals(getDeviceId()))
- .flatMapSingle(ocResource -> findOcSecureResource(ocResource.getServerId()));
- }
-
private String getDeviceId() {
ByteBuffer bb = ByteBuffer.wrap(OcPlatform.getDeviceId());
UUID uuid = new UUID(bb.getLong(), bb.getLong());
return uuid.toString();
}
- public Single findOcSecureResource(@NonNull String deviceId) {
+ private OcSecureResource getOcSecureResource(@NonNull String deviceId, boolean filterOwnedByMe) {
+ try {
+ String host = getDeviceCoapsIpv6Host(deviceId).blockingGet();
+ if (host != null) {
+ String address;
+ int port;
+ EnumSet connType = EnumSet.of(OcConnectivityType.CT_ADAPTER_IP);
+
+ if (host.contains(".")) {
+ connType.add(OcConnectivityType.CT_IP_USE_V4);
+ address = host.split("//")[1].split(":")[0];
+ port = Integer.valueOf(host.split("//")[1].split(":")[1]);
+ } else {
+ connType.add(OcConnectivityType.CT_IP_USE_V6);
+ address = host.split("\\[")[1].split("]")[0].replace("%25", "%");
+ port = Integer.valueOf(host.split("]")[1].split(":")[1]);
+ }
+
+ return OcProvisioning.discoverSingleDeviceInSecureUnicast(filterOwnedByMe, getDiscoveryTimeout(), deviceId, address, port, connType);
+ }
+ } catch (OcException|NullPointerException e) {
+ Timber.e(e);
+ return null;
+ }
+
+ return null;
+ }
+
+ public void setPreferredCiphersuite(OicCipher cipher) {
+ CaInterface.setCipherSuite(cipher, OcConnectivityType.CT_ADAPTER_IP);
+ }
+
+ private Single retrieveOcSecureResource(@NonNull String deviceId, @NonNull OicCipher cipher) {
return Single.create(emitter -> {
- try {
- OcSecureResource ocSecureResource =
- OcProvisioning.discoverSingleDevice(getDiscoveryTimeout(), deviceId);
+ setPreferredCiphersuite(cipher);
+ OcSecureResource ocSecureResource = getOcSecureResource(deviceId, false);
+ if (ocSecureResource != null) {
emitter.onSuccess(ocSecureResource);
- } catch (OcException e) {
- Timber.e(e);
- emitter.onError(e);
+ } else {
+ emitter.onError(new Exception("Find OcSecureResource has failed"));
+ }
+ });
+ }
+
+ public Single findOcSecureResource(@NonNull String deviceId) {
+ return retrieveOcSecureResource(deviceId, OicCipher.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256)
+ .onErrorResumeNext(error -> retrieveOcSecureResource(deviceId, OicCipher.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8));
+ }
+
+ public Single findDeviceInUnicast(@NonNull String deviceId) {
+ return Single.create(emitter -> {
+ OcSecureResource ocSecureResource = getOcSecureResource(deviceId, true);
+ if (ocSecureResource != null) {
+ emitter.onSuccess(new Device(DeviceType.OWNED_BY_SELF, ocSecureResource.getDeviceID(), new OcDevice(), ocSecureResource));
+ } else {
+ emitter.onSuccess(new Device(DeviceType.OWNED_BY_OTHER, deviceId, new OcDevice(), null));
}
});
}
@@ -310,7 +350,7 @@ public class IotivityRepository {
});
}
- public Single> findResource(String host) {
+ public Single> findResources(String host) {
return Single.create(emitter -> {
try {
OcPlatform.findResources(host,
@@ -329,8 +369,8 @@ public class IotivityRepository {
Timber.d(throwable);
} else {
Timber.e(throwable);
- emitter.onError(throwable);
}
+ emitter.onError(throwable);
}
});
} catch (OcException ex) {
@@ -577,7 +617,7 @@ public class IotivityRepository {
return coapsIpv6Host;
}
- private int getDiscoveryTimeout() {
+ public int getDiscoveryTimeout() {
SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(ctx);
return Integer.parseInt(
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/PermissionRepository.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/PermissionRepository.java
index 53e93df65511227582792957ec0fa3e9bee0617d..8e1ac8b1c22be24aaf44938b98d902bf35df8f74 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/PermissionRepository.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/PermissionRepository.java
@@ -25,7 +25,7 @@ package org.openconnectivity.otgc.common.data.repository;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.support.v4.content.ContextCompat;
+import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.List;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/WlanRepository.java b/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/WlanRepository.java
index 21b3cc541b4c9a11eb7e9c6113b0fbad97a40cc9..470c7b7dba9342ff8b1e65c626a7ec8bb04d7e3f 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/WlanRepository.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/data/repository/WlanRepository.java
@@ -38,7 +38,7 @@ import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConfiguration.PairwiseCipher;
import android.net.wifi.WifiConfiguration.Protocol;
import android.net.wifi.WifiManager;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import org.openconnectivity.otgc.common.data.model.WifiAdapterNotEnabledException;
import org.openconnectivity.otgc.common.data.model.WifiNetworkNotEnabledException;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/domain/usecase/InitializeIotivityUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/common/domain/usecase/InitializeIotivityUseCase.java
index 0bcdceae4e0758f0fe8a9991b6bf3fa338cf1ce4..fbccf7824f59a6143ee99cd80366160f8f5eb88e 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/domain/usecase/InitializeIotivityUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/domain/usecase/InitializeIotivityUseCase.java
@@ -22,7 +22,7 @@
package org.openconnectivity.otgc.common.domain.usecase;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
import com.upokecenter.cbor.CBOREncodeOptions;
import com.upokecenter.cbor.CBORObject;
@@ -132,7 +132,10 @@ public class InitializeIotivityUseCase {
setDeviceUuid(jsonObject, uuid);
X509Certificate caCertificate = mIORepository.getAssetAsX509Certificate(CRT_FILE).blockingGet();
PrivateKey caPrivateKey = mIORepository.getAssetAsPrivateKey(PRIVATE_KEY_FILE).blockingGet();
- addTrustCa(jsonObject, uuid, bytesToHex(caCertificate.getEncoded()));
+ ASN1Sequence pkSeqCa = (ASN1Sequence)ASN1Sequence.fromByteArray(caPrivateKey.getEncoded());
+ PrivateKeyInfo pkInfoCa = PrivateKeyInfo.getInstance(pkSeqCa);
+ ECPrivateKey devPrivateKeyCa = ECPrivateKey.getInstance(pkInfoCa.parsePrivateKey());
+ addTrustCa(jsonObject, uuid,bytesToHex(devPrivateKeyCa.getEncoded()), bytesToHex(caCertificate.getEncoded()));
// public/private key pair that we are creating certificate for
ECGenParameterSpec ecParamSpec = new ECGenParameterSpec("secp256r1");
@@ -227,8 +230,8 @@ public class InitializeIotivityUseCase {
jsonObject.getJSONObject("doxm").put("deviceuuid", deviceUuid);
}
- private void addTrustCa(JSONObject jsonObject, String deviceUuid, String derCertificate) throws JSONException {
- addCertificate(jsonObject, deviceUuid, 2, derCertificate, null, "oic.sec.cred.trustca");
+ private void addTrustCa(JSONObject jsonObject, String deviceUuid, String rawPrivateKey, String derCertificate) throws JSONException {
+ addCertificate(jsonObject, deviceUuid, 2, derCertificate, rawPrivateKey, "oic.sec.cred.trustca");
}
private void addCert(JSONObject jsonObject, String deviceUuid, String rawPrivateKey, String derCertificate) throws JSONException {
@@ -256,7 +259,7 @@ public class InitializeIotivityUseCase {
credObject.put("publicdata", publicDataObject);
if (rawPrivateKey != null &&
- (credUsage.equals("oic.sec.cred.cert") || credUsage.equals("oic.sec.cred.mfgcert"))) {
+ (credUsage.equals("oic.sec.cred.cert") || credUsage.equals("oic.sec.cred.mfgcert") || credUsage.equals("oic.sec.cred.trustca"))) {
JSONObject privateDataObject = new JSONObject();
privateDataObject.put("encoding", "oic.sec.encoding.raw");
privateDataObject.put("data", rawPrivateKey);
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/logger/FileLoggingTree.java b/otgc/src/main/java/org/openconnectivity/otgc/common/logger/FileLoggingTree.java
index 73bd49187d531696387c79f1fa7ad0242353114f..8e3b24c81c1fe228311697c47049e2f42d47eb2e 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/logger/FileLoggingTree.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/logger/FileLoggingTree.java
@@ -20,7 +20,9 @@
package org.openconnectivity.otgc.common.logger;
import android.content.Context;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
+
+import android.os.Environment;
import android.util.Log;
import android.util.SparseArray;
@@ -52,6 +54,55 @@ public class FileLoggingTree extends Timber.DebugTree {
public FileLoggingTree(Context context) {
mContext = context;
+
+ storeLogsInFile();
+ }
+
+ private void storeLogsInFile()
+ {
+ if ( isExternalStorageWritable() ) {
+ String fileNameTimeStamp = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
+
+ File appDirectory = new File( mContext.getExternalFilesDir(null).toString() );
+ File logDirectory = new File( appDirectory + "/log" );
+ File logFile = new File( logDirectory, "logcat" + fileNameTimeStamp + ".html");
+
+ // create app folder
+ if ( !appDirectory.exists() ) {
+ appDirectory.mkdir();
+ }
+
+ // create log folder
+ if ( !logDirectory.exists() ) {
+ logDirectory.mkdir();
+ }
+
+ // clear the previous logcat and then write the new one to the file
+ try {
+ Process process = Runtime.getRuntime().exec("logcat -c");
+ process = Runtime.getRuntime().exec("logcat -f " + logFile);
+ } catch ( IOException e ) {
+ Timber.e(e);
+ }
+
+ } else if ( isExternalStorageReadable() ) {
+ // only readable
+ } else {
+ // not accessible
+ }
+ }
+
+ /* Checks if external storage is available for read and write */
+ public boolean isExternalStorageWritable() {
+ String state = Environment.getExternalStorageState();
+ return Environment.MEDIA_MOUNTED.equals( state );
+ }
+
+ /* Checks if external storage is available to at least read */
+ public boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ return ( Environment.MEDIA_MOUNTED.equals( state ) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals( state ) );
}
@Override
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/view/EmptyRecyclerView.java b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/view/EmptyRecyclerView.java
index 05ce12f6e805f2780f5a327886b3ff467d63dba9..321e0eba1544a5a19d239d8522cc717744335a2c 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/view/EmptyRecyclerView.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/view/EmptyRecyclerView.java
@@ -23,8 +23,8 @@
package org.openconnectivity.otgc.common.presentation.view;
import android.content.Context;
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/view/RecyclerWithSwipeFragment.java b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/view/RecyclerWithSwipeFragment.java
index e49242458beae9cdf60dae5e9137e9c3d3061ac1..a085e04d0e478cd17372caa005355fcfb4f26b1d 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/view/RecyclerWithSwipeFragment.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/view/RecyclerWithSwipeFragment.java
@@ -21,14 +21,15 @@
*/
package org.openconnectivity.otgc.common.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.Fragment;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.core.content.ContextCompat;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/BaseViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/BaseViewModel.java
index 672a01a854c74b3ba40dc3460f1ea4d29511f6e4..441caabcb51dbc8a064ce8553ce6bf14702d145b 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/BaseViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/BaseViewModel.java
@@ -1,8 +1,8 @@
package org.openconnectivity.otgc.common.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
import io.reactivex.disposables.CompositeDisposable;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/Response.java b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/Response.java
index 4dcfbc6b128a23d09a4bcf92c4df60e09713e6a5..035fcdcda373153205575a532a02b3f879e1e138 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/Response.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/Response.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.common.presentation.viewmodel;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
/**
* a generic class that describes a data with a status
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/ViewModelError.java b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/ViewModelError.java
index 3a056d8d3ff0c1dcf7dc190ec6f8c7f608b8d602..c1b5f47831bd53309f631476e1ab4ebd048a3228 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/ViewModelError.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/ViewModelError.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.common.presentation.viewmodel;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
public class ViewModelError {
@NonNull private final ViewModelErrorType mType;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/ViewModelFactory.java b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/ViewModelFactory.java
index d424a5a2c608364e8dc39a57f251a658f9b1ea56..4b8c2edb1758cb7878310929766b19fe31569b0a 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/ViewModelFactory.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/common/presentation/viewmodel/ViewModelFactory.java
@@ -22,9 +22,9 @@
package org.openconnectivity.otgc.common.presentation.viewmodel;
-import android.arch.lifecycle.ViewModel;
-import android.arch.lifecycle.ViewModelProvider;
-import android.support.annotation.NonNull;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.annotation.NonNull;
import java.util.Map;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredActivity.java
index 144857b0a09d797027d58c5cd57f225d5487535f..b1c733bc7151570878c34d11a3025559ed911157 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredActivity.java
@@ -22,14 +22,14 @@
package org.openconnectivity.otgc.credential.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioButton;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredentialAdapter.java b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredentialAdapter.java
index b9232841b34834251ab75da73f309fc716e82b65..aaa481aa2e46f38b8692136339ff73962494864c 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredentialAdapter.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredentialAdapter.java
@@ -23,9 +23,9 @@
package org.openconnectivity.otgc.credential.presentation.view;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.v7.util.SortedList;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.SortedList;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredentialsActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredentialsActivity.java
index 06ad9d55e209cb471a667bf1f3eea89c671a95ab..303ea78957ee7ef2d7447f21922d0be53c24f342 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredentialsActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/view/CredentialsActivity.java
@@ -22,17 +22,17 @@
package org.openconnectivity.otgc.credential.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.NonNull;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/viewmodel/CredViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/viewmodel/CredViewModel.java
index cb96214b1d152a0bbf521548469ef5c61398885c..e9179ff97a5c3d77233bc15c0d7de0e572a19033 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/viewmodel/CredViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/viewmodel/CredViewModel.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.credential.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
import org.openconnectivity.otgc.common.domain.rx.SchedulersFacade;
import org.openconnectivity.otgc.common.presentation.viewmodel.BaseViewModel;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/viewmodel/CredentialsViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/viewmodel/CredentialsViewModel.java
index d0e01ab3ee04538d67634c85e6bd34b09e5dceee..5f42dac6e31f9f74482f5090f64a217e4d419c39 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/viewmodel/CredentialsViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/credential/presentation/viewmodel/CredentialsViewModel.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.credential.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
import org.iotivity.base.OicSecCred;
import org.openconnectivity.otgc.common.presentation.viewmodel.BaseViewModel;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/data/repository/DoxsRepository.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/data/repository/DoxsRepository.java
index 8770fc83654e2c5037c7404d9523f92899bfee9c..a8b32c9c1a734427caf07d16bd6a439cc930b8c0 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/data/repository/DoxsRepository.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/data/repository/DoxsRepository.java
@@ -22,11 +22,20 @@
package org.openconnectivity.otgc.devicelist.data.repository;
+import org.iotivity.base.AceSubjectType;
+import org.iotivity.base.CredType;
+import org.iotivity.base.KeySize;
import org.iotivity.base.OcException;
import org.iotivity.base.OcSecureResource;
+import org.iotivity.base.OicSecAce;
+import org.iotivity.base.OicSecAceSubject;
+import org.iotivity.base.OicSecAcl;
+import org.iotivity.base.OicSecResr;
import org.iotivity.base.OxmType;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.List;
import javax.inject.Inject;
@@ -96,4 +105,45 @@ public class DoxsRepository {
emitter.onComplete();
});
}
+
+ public Completable pairwiseDevices(OcSecureResource clientResource, OcSecureResource serverResource, List resources) {
+ return Completable.create(emitter -> {
+ try {
+ // Create ACE to allow client to manage the server
+ List aces = new ArrayList<>();
+ OicSecAceSubject subject = new OicSecAceSubject(AceSubjectType.SUBJECT_UUID.getValue(), clientResource.getDeviceID(), null, null);
+ OicSecAce ace = new OicSecAce(0, subject, 31, resources, new ArrayList<>());
+ aces.add(ace);
+ OicSecAcl acl = new OicSecAcl(null, aces);
+
+ EnumSet credTypes = EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY);
+ clientResource.provisionPairwiseDevices(credTypes, KeySize.OWNER_PSK_LENGTH_256, null, serverResource, acl, (results, hasError) ->
+ {
+ if (hasError == 0) {
+ emitter.onComplete();
+ } else {
+ emitter.onError(new IOException("Link Devices Exception"));
+ }
+ });
+ } catch (OcException e) {
+ emitter.onError(e);
+ }
+ });
+ }
+
+
+ public Completable unlinkDevices(OcSecureResource serverOcSecureResource, OcSecureResource clientOcSecureResource) {
+ return Completable.create(emitter ->
+ serverOcSecureResource.unlinkDevices(
+ clientOcSecureResource,
+ (provisionResults, hasError) -> {
+ if (hasError == 0) {
+ emitter.onComplete();
+ } else {
+ emitter.onError(new IOException("Error"));
+ }
+ }
+ )
+ );
+ }
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/data/repository/EasySetupRepository.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/data/repository/EasySetupRepository.java
index c2beb3f8e2ccff716fde49501291f4a09bafcb82..f6cda7180a57606ec02334f57e991d08839c0b97 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/data/repository/EasySetupRepository.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/data/repository/EasySetupRepository.java
@@ -24,7 +24,7 @@ package org.openconnectivity.otgc.devicelist.data.repository;
import android.content.Context;
import android.os.Build;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import org.iotivity.base.OcResource;
import org.iotivity.service.easysetup.mediator.DeviceProp;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/model/Device.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/model/Device.java
index 824b98e9614fbd5ac17434d60f6a6a03e9a89005..56b05e2459a7c6309d85800f1dace03e1cc4865d 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/model/Device.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/model/Device.java
@@ -30,6 +30,7 @@ import org.openconnectivity.otgc.common.domain.model.OcDevice;
public class Device {
private DeviceType mType;
+ private Role mRole;
private String mDeviceId;
private OcDevice mDeviceInfo;
private OcSecureResource mOcSecureResource;
@@ -38,6 +39,7 @@ public class Device {
super();
this.mType = type;
+ this.mRole = Role.UNKNOWN;
this.mDeviceId = deviceId;
this.mDeviceInfo = deviceInfo;
this.mOcSecureResource = ocSecureResource;
@@ -51,6 +53,14 @@ public class Device {
this.mType = type;
}
+ public Role getRole() {
+ return mRole;
+ }
+
+ public void setRole(Role role) {
+ this.mRole = role;
+ }
+
public String getDeviceId() {
return mDeviceId;
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/model/Role.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/model/Role.java
new file mode 100644
index 0000000000000000000000000000000000000000..94398ba884047e8dd58f573ea4366c0e21f83d68
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/model/Role.java
@@ -0,0 +1,29 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.devicelist.domain.model;
+
+public enum Role {
+ CLIENT,
+ SERVER,
+ UNKNOWN
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/GetDeviceRoleUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/GetDeviceRoleUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..d645cd4f3339cd870a838da89154c0851e655930
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/GetDeviceRoleUseCase.java
@@ -0,0 +1,66 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.devicelist.domain.usecase;
+
+import org.iotivity.base.OcResource;
+import org.openconnectivity.otgc.common.constant.OcfResourceType;
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+import org.openconnectivity.otgc.devicelist.domain.model.Role;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import io.reactivex.Single;
+
+public class GetDeviceRoleUseCase {
+ private final IotivityRepository mIotivityRepository;
+
+ @Inject
+ GetDeviceRoleUseCase(IotivityRepository iotivityRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ }
+
+ public Single execute(String deviceId) {
+ return mIotivityRepository.getDeviceCoapIpv6Host(deviceId)
+ .flatMap(mIotivityRepository::findResources)
+ .timeout(mIotivityRepository.getDiscoveryTimeout() + 5_00L, TimeUnit.SECONDS)
+ .map(ocResources -> {
+ Role deviceRole = Role.CLIENT;
+ for (OcResource resource : ocResources) {
+ for (String resourceType : resource.getResourceTypes()) {
+ if (OcfResourceType.isVerticalResourceType(resourceType)) {
+ deviceRole = Role.SERVER;
+ break;
+ }
+ }
+
+ if (deviceRole.equals(Role.SERVER)) {
+ break;
+ }
+ }
+
+ return deviceRole;
+ });
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/OffboardUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/OffboardUseCase.java
index a139ee7a882f4298ca73a303e2c893c671039714..09e89c2bfb8e86d3fbc28d43f43520f441849125 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/OffboardUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/OffboardUseCase.java
@@ -26,8 +26,6 @@ import org.iotivity.base.OcSecureResource;
import org.openconnectivity.otgc.common.data.repository.PreferencesRepository;
import org.openconnectivity.otgc.devicelist.data.repository.DoxsRepository;
import org.openconnectivity.otgc.devicelist.domain.model.Device;
-import org.openconnectivity.otgc.devicelist.domain.model.DeviceType;
-import org.openconnectivity.otgc.common.domain.model.OcDevice;
import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
import java.util.concurrent.TimeUnit;
@@ -51,11 +49,11 @@ public class OffboardUseCase {
}
public Single execute(OcSecureResource deviceToOffboard) {
- final Single getUpdatedOcSecureResource =
+ final Single getUpdatedOcSecureResource =
iotivityRepository.scanUnownedDevices()
- .filter(ocSecureResource ->
- (ocSecureResource.getDeviceID().equals(deviceToOffboard.getDeviceID())
- || ocSecureResource.getIpAddr().equals(deviceToOffboard.getIpAddr())))
+ .filter(device ->
+ (device.getDeviceId().equals(deviceToOffboard.getDeviceID())
+ || device.getOcSecureResource().getIpAddr().equals(deviceToOffboard.getIpAddr())))
.singleOrError();
return mDoxsRepository.resetDevice(deviceToOffboard,
@@ -64,12 +62,6 @@ public class OffboardUseCase {
.andThen(getUpdatedOcSecureResource)
.onErrorResumeNext(error -> getUpdatedOcSecureResource
.retry(2)
- .onErrorResumeNext(Single.error(error)))
- .map(ocSecureResource ->
- new Device(DeviceType.UNOWNED,
- ocSecureResource.getDeviceID(),
- new OcDevice(),
- ocSecureResource)
- );
+ .onErrorResumeNext(Single.error(error)));
}
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/OnboardUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/OnboardUseCase.java
index 5ff765d9aab91fa4e4c5b0d1fc5183da2d4de8a0..b4941b3059dd69101c9a50e6cb09df45a526c473 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/OnboardUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/OnboardUseCase.java
@@ -25,7 +25,6 @@ import org.iotivity.base.OcSecureResource;
import org.openconnectivity.otgc.devicelist.data.repository.DoxsRepository;
import org.openconnectivity.otgc.devicelist.domain.model.Device;
import org.openconnectivity.otgc.devicelist.domain.model.DeviceType;
-import org.openconnectivity.otgc.common.domain.model.OcDevice;
import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
import java.util.concurrent.TimeUnit;
@@ -33,6 +32,7 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import io.reactivex.Single;
+import io.reactivex.Observable;
public class OnboardUseCase {
private final DoxsRepository mDoxsRepository;
@@ -46,23 +46,17 @@ public class OnboardUseCase {
}
public Single execute(OcSecureResource deviceToOnboard) {
- final Single getUpdatedOcSecureResource =
- iotivityRepository.scanOwnedDevices()
- .filter(ocSecureResource ->
- (ocSecureResource.getDeviceID().equals(deviceToOnboard.getDeviceID())
- || ocSecureResource.getIpAddr().equals(deviceToOnboard.getIpAddr())))
- .singleOrError();
+ final Single getUpdatedOcSecureResource = Observable.concat(iotivityRepository.scanOwnedDevices(), iotivityRepository.scanUnownedDevices())
+ .filter(device -> device.getType() == DeviceType.OWNED_BY_SELF
+ && (device.getDeviceId().equals(deviceToOnboard.getDeviceID())
+ || device.getOcSecureResource().getIpAddr().equals(deviceToOnboard.getIpAddr())))
+ .singleOrError();
return mDoxsRepository.doOwnershipTransfer(deviceToOnboard)
.delay(1, TimeUnit.SECONDS)
.andThen(getUpdatedOcSecureResource)
.onErrorResumeNext(error -> getUpdatedOcSecureResource
.retry(2)
- .onErrorResumeNext(Single.error(error)))
- .map(ocSecureResource ->
- new Device(DeviceType.OWNED_BY_SELF,
- ocSecureResource.getDeviceID(),
- new OcDevice(),
- ocSecureResource));
+ .onErrorResumeNext(Single.error(error)));
}
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/PairwiseDevicesUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/PairwiseDevicesUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c7d4056b1c40e7d4048bb79549271236b084991
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/PairwiseDevicesUseCase.java
@@ -0,0 +1,60 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.devicelist.domain.usecase;
+
+import org.iotivity.base.OcSecureResource;
+import org.openconnectivity.otgc.client.data.repository.ResourceRepository;
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+import org.openconnectivity.otgc.devicelist.data.repository.DoxsRepository;
+
+import javax.inject.Inject;
+
+import io.reactivex.Completable;
+import io.reactivex.Single;
+
+public class PairwiseDevicesUseCase {
+ private final IotivityRepository mIotivityRepository;
+ private final DoxsRepository mDoxsRepository;
+ private final ResourceRepository mResourceRepository;
+
+ @Inject
+ PairwiseDevicesUseCase(IotivityRepository iotivityRepository,
+ DoxsRepository doxsRepository,
+ ResourceRepository resourceRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ this.mDoxsRepository = doxsRepository;
+ this.mResourceRepository = resourceRepository;
+ }
+
+ public Completable execute(String serverId, String clientId) {
+ Single clientSecureResource = mIotivityRepository.findOcSecureResource(clientId);
+ Single serverSecureResource = mIotivityRepository.findOcSecureResource(serverId);
+
+ return mIotivityRepository.getDeviceCoapIpv6Host(serverId)
+ .flatMap(mIotivityRepository::findResources)
+ .map(mResourceRepository::getVerticalResources)
+ .flatMapCompletable(resources -> Single.concat(clientSecureResource, serverSecureResource).toList()
+ .flatMapCompletable(ocSecureResources -> mDoxsRepository.pairwiseDevices(ocSecureResources.get(0), ocSecureResources.get(1), resources)));
+
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/ScanDevicesUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/ScanDevicesUseCase.java
index ae9e3cb6e9130d08af29c6317ee503f5cbd01ba2..2e7e8d1262b592c7d4ccc46d5d384a4a2cd58fe0 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/ScanDevicesUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/ScanDevicesUseCase.java
@@ -22,8 +22,6 @@
package org.openconnectivity.otgc.devicelist.domain.usecase;
import org.openconnectivity.otgc.devicelist.domain.model.Device;
-import org.openconnectivity.otgc.devicelist.domain.model.DeviceType;
-import org.openconnectivity.otgc.common.domain.model.OcDevice;
import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
import javax.inject.Inject;
@@ -39,33 +37,11 @@ public class ScanDevicesUseCase {
}
public Observable execute() {
- Observable unownedObservable = mIotivityRepository.scanUnownedDevices()
- .map(ocSecureResource ->
- new Device(DeviceType.UNOWNED,
- ocSecureResource.getDeviceID(),
- new OcDevice(),
- ocSecureResource)
- );
-
- Observable ownedObservable = mIotivityRepository.scanOwnedDevices()
- .map(ocSecureResource ->
- new Device(DeviceType.OWNED_BY_SELF,
- ocSecureResource.getDeviceID(),
- new OcDevice(),
- ocSecureResource)
- );
-
- Observable ownedByOtherObservable = mIotivityRepository.scanOwnedByOtherDevices()
- .map(ocSecureResource ->
- new Device(
- DeviceType.OWNED_BY_OTHER,
- ocSecureResource.getDeviceID(),
- new OcDevice(),
- ocSecureResource)
- );
+ Observable unownedObservable = mIotivityRepository.scanUnownedDevices();
+ Observable ownedObservable = mIotivityRepository.scanOwnedDevices();
return mIotivityRepository.scanHosts()
.andThen(Observable.concat(unownedObservable,
- ownedObservable, ownedByOtherObservable));
+ ownedObservable));
}
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/SetRfotmModeUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/SetRfotmModeUseCase.java
index 97e4218c01625f6473907bd880020e81e3b63eb5..b456223af0ecfce2a64b73772fa3df3b564eddc4 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/SetRfotmModeUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/SetRfotmModeUseCase.java
@@ -27,6 +27,7 @@ import org.openconnectivity.otgc.common.data.repository.PreferencesRepository;
import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
import org.openconnectivity.otgc.common.data.repository.ProvisioningRepository;
import org.openconnectivity.otgc.devicelist.data.repository.DoxsRepository;
+import org.openconnectivity.otgc.devicelist.domain.model.DeviceType;
import java.util.concurrent.TimeUnit;
@@ -59,9 +60,10 @@ public class SetRfotmModeUseCase {
public Completable execute() {
return iotivityRepository.scanOwnedDevices()
- .flatMapCompletable(ocSecureResource ->
+ .filter(device -> device.getType() == DeviceType.OWNED_BY_SELF)
+ .flatMapCompletable(device ->
mDoxsRepository.resetDevice(
- ocSecureResource,
+ device.getOcSecureResource(),
mPreferencesRepository.getDiscoveryTimeout()))
.delay(500, TimeUnit.MILLISECONDS)
.andThen(mProvisioningRepository.resetSvrDb())
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/UnlinkDevicesUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/UnlinkDevicesUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a6373715949ba9f6be49a5bf9c77598a5d9c63f
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/domain/usecase/UnlinkDevicesUseCase.java
@@ -0,0 +1,52 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.devicelist.domain.usecase;
+
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+import org.openconnectivity.otgc.devicelist.data.repository.DoxsRepository;
+
+import javax.inject.Inject;
+
+import io.reactivex.Completable;
+
+public class UnlinkDevicesUseCase {
+ private final IotivityRepository mIotivityRepository;
+ private final DoxsRepository mDoxsRepository;
+
+ @Inject
+ UnlinkDevicesUseCase(IotivityRepository iotivityRepository,
+ DoxsRepository doxsRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ this.mDoxsRepository = doxsRepository;
+ }
+
+ public Completable execute(String serverId, String clientId) {
+ return mIotivityRepository.findOcSecureResource(serverId)
+ .flatMapCompletable(serverOcSecureResource ->
+ mDoxsRepository.unlinkDevices(
+ serverOcSecureResource,
+ mIotivityRepository.findOcSecureResource(clientId).blockingGet()
+ )
+ );
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/ActionModeController.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/ActionModeController.java
new file mode 100644
index 0000000000000000000000000000000000000000..628a4bc219755af583159e1cd4107321c35494ed
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/ActionModeController.java
@@ -0,0 +1,125 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.devicelist.presentation.view;
+
+import android.content.Context;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import org.iotivity.base.OcException;
+import org.openconnectivity.otgc.R;
+import org.openconnectivity.otgc.devicelist.domain.model.Device;
+import org.openconnectivity.otgc.devicelist.domain.model.DeviceType;
+import org.openconnectivity.otgc.devicelist.domain.model.Role;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import androidx.appcompat.view.ActionMode;
+import androidx.recyclerview.selection.SelectionTracker;
+import timber.log.Timber;
+
+public class ActionModeController implements ActionMode.Callback {
+ private final Context mContext;
+ private final SelectionTracker mSelectionTracker;
+ private static MyMenuItemClickListener sMyMenuItemClickListener;
+
+ public ActionModeController(Context context, SelectionTracker selectionTracker) {
+ this.mContext = context;
+ this.mSelectionTracker = selectionTracker;
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
+ actionMode.getMenuInflater().inflate(R.menu.menu_devices_selection, menu); // Inflate the menu over action mode
+ return true;
+ }
+
+ @Override
+ 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 deviceIterable = mSelectionTracker.getSelection().iterator();
+ while (deviceIterable.hasNext()) {
+ Device device = deviceIterable.next();
+ if (device.getRole().equals(Role.SERVER) && device.getType().equals(DeviceType.OWNED_BY_SELF)) {
+ server = device;
+ } else if (device.getRole().equals(Role.CLIENT) && device.getType().equals(DeviceType.OWNED_BY_SELF)) {
+ client = device;
+ }
+ }
+
+ if (server != null && client != null) {
+ try {
+ List serverLinkedDevices = server.getOcSecureResource().getLinkedDevices();
+ List clientLinkedDevices = client.getOcSecureResource().getLinkedDevices();
+
+ String serverId = server.getDeviceId();
+ String clientId = client.getDeviceId();
+ if (serverLinkedDevices.contains(clientId)
+ && clientLinkedDevices.contains(serverId)) {
+ unlinkMenuItem.setOnMenuItemClickListener(menuItem -> {
+ actionMode.finish();
+ return sMyMenuItemClickListener.onMenuItemClick(menuItem, serverId, clientId);
+ });
+ unlinkMenuItem.setVisible(true);
+ } else {
+ linkMenuItem.setOnMenuItemClickListener(menuItem -> {
+ actionMode.finish();
+ return sMyMenuItemClickListener.onMenuItemClick(menuItem, serverId, clientId);
+ });
+ linkMenuItem.setVisible(true);
+ }
+ } catch (OcException e) {
+ Timber.e(e);
+ }
+ }
+ } else {
+ linkMenuItem.setVisible(false);
+ unlinkMenuItem.setVisible(false);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode actionMode) {
+ mSelectionTracker.clearSelection();
+ }
+
+ public static void setOnMenuItemClickListener(MyMenuItemClickListener myMenuItemClickListener) {
+ sMyMenuItemClickListener = myMenuItemClickListener;
+ }
+
+ public interface MyMenuItemClickListener {
+ boolean onMenuItemClick(MenuItem menuItem, String serverId, String clientId);
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DeviceListActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DeviceListActivity.java
index 8646008517e204615ea2596b7064d8e68b5ccde5..ee4f5d69e34afd800712d19b12755ec9e2fb8134 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DeviceListActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DeviceListActivity.java
@@ -22,13 +22,13 @@
package org.openconnectivity.otgc.devicelist.presentation.view;
import android.app.AlertDialog;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import androidx.fragment.app.Fragment;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.view.ContextThemeWrapper;
import android.view.Menu;
import android.view.MenuItem;
@@ -193,6 +193,8 @@ public class DeviceListActivity extends AppCompatActivity implements HasSupportF
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.devices_fragment);
if (fragment instanceof RecyclerWithSwipeFragment) {
((RecyclerWithSwipeFragment) fragment).onSwipeRefresh();
+ } else if (fragment instanceof DoxsFragment) {
+ ((DoxsFragment) fragment).onSwipeRefresh();
}
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DoxsFragment.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DoxsFragment.java
index 12d8673761116937ec104005ff19e6c31edef61f..b3520cbc135ee5f6a91f233f1bfde704cd5f5f37 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DoxsFragment.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DoxsFragment.java
@@ -23,12 +23,28 @@
package org.openconnectivity.otgc.devicelist.presentation.view;
import android.app.AlertDialog;
-import android.arch.lifecycle.ViewModelProviders;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.view.ActionMode;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
-import android.support.annotation.NonNull;
-import android.support.design.widget.TextInputEditText;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.NonNull;
+import com.google.android.material.textfield.TextInputEditText;
+
+import androidx.recyclerview.selection.OnDragInitiatedListener;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.selection.StorageStrategy;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
@@ -37,7 +53,7 @@ import org.iotivity.base.OxmType;
import org.openconnectivity.otgc.R;
import org.openconnectivity.otgc.accesscontrol.presentation.view.AccessControlActivity;
import org.openconnectivity.otgc.client.presentation.view.GenericClientActivity;
-import org.openconnectivity.otgc.common.presentation.view.RecyclerWithSwipeFragment;
+import org.openconnectivity.otgc.common.presentation.view.EmptyRecyclerView;
import org.openconnectivity.otgc.common.presentation.viewmodel.CommonError;
import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelError;
import org.openconnectivity.otgc.credential.presentation.view.CredentialsActivity;
@@ -46,14 +62,27 @@ import org.openconnectivity.otgc.common.presentation.UiUtils;
import org.openconnectivity.otgc.common.presentation.viewmodel.Response;
import org.openconnectivity.otgc.devicelist.presentation.viewmodel.SharedViewModel;
import org.openconnectivity.otgc.devicelist.presentation.viewmodel.DoxsViewModel;
+import org.openconnectivity.otgc.di.Injectable;
+import org.openconnectivity.otgc.linkedroles.presentation.view.LinkedRolesActivity;
import org.openconnectivity.otgc.wlanscan.domain.model.WifiNetwork;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import javax.inject.Inject;
+
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+import butterknife.BindView;
+import butterknife.ButterKnife;
import timber.log.Timber;
-public class DoxsFragment extends RecyclerWithSwipeFragment implements DoxsViewModel.SelectOxMListener {
+public class DoxsFragment extends Fragment implements DoxsViewModel.SelectOxMListener, Injectable {
+
+ @BindView(R.id.swipe_refresh_devices) SwipeRefreshLayout mSwipeToRefreshView;
+ @BindView(R.id.recycler_ocf_devices) EmptyRecyclerView mRecyclerView;
+
+ @Inject ViewModelProvider.Factory mViewModelFactory;
private DoxsListAdapter mAdapter;
@@ -69,12 +98,87 @@ public class DoxsFragment extends RecyclerWithSwipeFragment implements DoxsViewM
private AlertDialog mConnectWifiDialog = null;
+ private SelectionTracker mSelectionTracker;
+ private ActionMode mActionMode;
+
public DoxsFragment() {
// Required empty public constructor
}
@Override
- public RecyclerView.Adapter getAdapter() {
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.fragment_recycler_with_swipe, container, false);
+ ButterKnife.bind(this, rootView);
+
+ initViews();
+
+ return rootView;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ initViewModel();
+ }
+
+ private void initViews() {
+ mRecyclerView.setHasFixedSize(true);
+ mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+ mRecyclerView.setAdapter(getAdapter());
+ mRecyclerView.setEmptyView(null);
+
+ if (getContext() != null) {
+ mSwipeToRefreshView.setColorSchemeColors(ContextCompat.getColor(getContext(), R.color.colorPrimary));
+ }
+
+ mSwipeToRefreshView.setOnRefreshListener(() -> {
+ mSwipeToRefreshView.setRefreshing(false);
+ onSwipeRefresh();
+ });
+
+ mSelectionTracker = new SelectionTracker.Builder<>(
+ "my-selection-id",
+ mRecyclerView,
+ new MyItemKeyProvider(1, mAdapter.mDataset),
+ new MyItemLookup(mRecyclerView),
+ StorageStrategy.createLongStorage()
+ ).withOnDragInitiatedListener(e -> {
+ Timber.d("onDragInitiated");
+ return true;
+ }).build();
+
+ mAdapter.setSelectionTracker(mSelectionTracker);
+
+ mSelectionTracker.addObserver(new SelectionTracker.SelectionObserver() {
+ @Override
+ public void onSelectionChanged() {
+ super.onSelectionChanged();
+ if (mSelectionTracker.hasSelection()) {
+ if (mActionMode == null) {
+ ActionModeController actionController = new ActionModeController(getActivity(), mSelectionTracker);
+ ActionModeController.setOnMenuItemClickListener((menuItem, serverId, clientId) -> {
+ if (menuItem.getItemId() == R.id.action_pairwise) {
+ mViewModel.pairwiseDevices(serverId, clientId);
+ } else if (menuItem.getItemId() == R.id.action_unlink) {
+ mViewModel.unlinkDevices(serverId, clientId);
+ }
+
+ return true;
+ });
+ mActionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionController);
+ } else {
+ mActionMode.invalidate();
+ }
+ mActionMode.setTitle(Integer.toString(mSelectionTracker.getSelection().size()));
+ } else if (mActionMode != null) {
+ mActionMode.finish();
+ mActionMode = null;
+ }
+ }
+ });
+ }
+
+ private RecyclerView.Adapter getAdapter() {
mAdapter = new DoxsListAdapter(getContext());
DoxsListAdapter.setOnItemClickListener((position, v) -> {
/*switch (mAdapter.mDataset.get(position).getType()) {
@@ -97,9 +201,7 @@ public class DoxsFragment extends RecyclerWithSwipeFragment implements DoxsViewM
mViewModel.doOwnershipTransfer(mAdapter.mDataset.get(position).getOcSecureResource());
break;
case R.id.img_btn_generic_client:
- launchGenericClientView(
- mAdapter.mDataset.get(position).getOcSecureResource().getIpAddr(),
- mAdapter.mDataset.get(position).getDeviceId());
+ launchGenericClientView(mAdapter.mDataset.get(position).getDeviceId());
break;
}
});
@@ -124,6 +226,13 @@ public class DoxsFragment extends RecyclerWithSwipeFragment implements DoxsViewM
credIntent.putExtra("deviceId", mAdapter.mDataset.get(position).getDeviceId());
startActivity(credIntent);
break;
+ case R.id.button_roles:
+ Intent rolesIntent = new Intent(getActivity(), LinkedRolesActivity.class);
+ rolesIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ rolesIntent.putExtra("deviceId", mAdapter.mDataset.get(position).getDeviceId());
+ rolesIntent.putExtra("deviceRole", mAdapter.mDataset.get(position).getRole().toString());
+ startActivity(rolesIntent);
+ break;
case R.id.menu_item_wifi_easy_setup:
mViewModel.getScanResponse().observe(this, this::processScan);
positionWifiEasySetupItem = position;
@@ -141,9 +250,8 @@ public class DoxsFragment extends RecyclerWithSwipeFragment implements DoxsViewM
return mAdapter;
}
- @Override
- public void initViewModel() {
- mViewModel = ViewModelProviders.of(this, getViewModelFactory()).get(DoxsViewModel.class);
+ private void initViewModel() {
+ mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(DoxsViewModel.class);
mViewModel.setOxmListener(this);
@@ -157,11 +265,10 @@ public class DoxsFragment extends RecyclerWithSwipeFragment implements DoxsViewM
mViewModel.getConnectWifiEasySetupResponse().observe(this, this::processConnectWifiEasySetupResponse);
if (getActivity() != null) {
- mSharedViewModel = ViewModelProviders.of(getActivity(), getViewModelFactory()).get(SharedViewModel.class);
+ mSharedViewModel = ViewModelProviders.of(getActivity(), mViewModelFactory).get(SharedViewModel.class);
}
}
- @Override
public void onSwipeRefresh() {
mAdapter.clearItems();
mViewModel.onScanRequested();
@@ -222,6 +329,8 @@ public class DoxsFragment extends RecyclerWithSwipeFragment implements DoxsViewM
case SCAN_DEVICES:
Toast.makeText(getActivity(), R.string.devices_error_scanning_devices, Toast.LENGTH_SHORT).show();
break;
+ case PAIRWISE_DEVICES:
+ Toast.makeText(getActivity(), R.string.devices_error_pairing_devices, Toast.LENGTH_SHORT).show();
default:
break;
}
@@ -380,10 +489,9 @@ public class DoxsFragment extends RecyclerWithSwipeFragment implements DoxsViewM
}
}
- private void launchGenericClientView(String ipAddress, String deviceId) {
+ private void launchGenericClientView(String deviceId) {
Intent intent = new Intent(getActivity(), GenericClientActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra("IpAddress", ipAddress);
intent.putExtra("DeviceId", deviceId);
startActivity(intent);
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DoxsListAdapter.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DoxsListAdapter.java
index 009b0e549d1ddca381042f750d331d8c583532cb..90b632e357170ede01f56357b01863253b86b090 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DoxsListAdapter.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/DoxsListAdapter.java
@@ -23,11 +23,13 @@ package org.openconnectivity.otgc.devicelist.presentation.view;
import android.content.Context;
import android.graphics.Rect;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.util.SortedList;
-import android.support.v7.widget.PopupMenu;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.recyclerview.selection.ItemDetailsLookup;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.widget.SortedList;
+import androidx.appcompat.widget.PopupMenu;
+import androidx.recyclerview.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -40,6 +42,7 @@ import android.widget.TextView;
import org.openconnectivity.otgc.R;
import org.openconnectivity.otgc.devicelist.domain.model.Device;
import org.openconnectivity.otgc.devicelist.domain.model.DeviceType;
+import org.openconnectivity.otgc.devicelist.domain.model.Role;
import butterknife.BindView;
import butterknife.ButterKnife;
@@ -47,18 +50,21 @@ import butterknife.ButterKnife;
public class DoxsListAdapter extends RecyclerView.Adapter {
SortedList mDataset;
private Context mContext;
+ private SelectionTracker mSelectionTracker;
private static MyClickListener sMyClickListener;
private static MyMenuItemClickListener sMyMenuItemClickListener;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
- public static class DoxsListViewHolder extends RecyclerView.ViewHolder
- implements View.OnClickListener, PopupMenu.OnMenuItemClickListener {
+ public class DoxsListViewHolder extends RecyclerView.ViewHolder
+ implements View.OnClickListener, PopupMenu.OnMenuItemClickListener, ViewHolderWithDetails {
// each data item is just a string in this case
+ @BindView(R.id.card_view) View mView;
@BindView(R.id.line_device_type) View mLineDeviceType;
@BindView(R.id.text_device_name) TextView mDeviceName;
@BindView(R.id.text_device_uuid) TextView mDeviceUuid;
+ @BindView(R.id.text_device_role) TextView mDeviceRole;
@BindView(R.id.text_device_type) TextView mDeviceType;
//@BindView(R.id.img_btn_bottom_right) ImageButton mImageButton;
@BindView(R.id.img_btn_popup_menu) ImageButton mPopupButton;
@@ -105,6 +111,15 @@ public class DoxsListAdapter extends RecyclerView.Adapter {
PopupMenu popupMenu = new PopupMenu(mContext, holder.mPopupButton);
popupMenu.inflate(R.menu.menu_owned_devices);
popupMenu.setOnMenuItemClickListener(holder);
- if (mDataset.get(position).getType().equals(DeviceType.OWNED_BY_OTHER)) {
+ if (device.getType().equals(DeviceType.OWNED_BY_OTHER)) {
popupMenu.getMenu().findItem(R.id.menu_item_set_device_name).setVisible(false);
}
@@ -213,7 +241,7 @@ public class DoxsListAdapter extends RecyclerView.Adapter itemList;
+
+ public MyItemKeyProvider(int scope, SortedList itemList) {
+ super(scope);
+ this.itemList = itemList;
+ }
+
+ @Nullable
+ @Override
+ public Object getKey(int position) {
+ return itemList.get(position);
+ }
+
+ @Override
+ public int getPosition(@NonNull Object key) {
+ return itemList.indexOf((Device)key);
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/MyItemLookup.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/MyItemLookup.java
new file mode 100644
index 0000000000000000000000000000000000000000..c84e7801c7f1edab950a53893a791bd79c7dd710
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/MyItemLookup.java
@@ -0,0 +1,53 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.devicelist.presentation.view;
+
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.selection.ItemDetailsLookup;
+import androidx.recyclerview.widget.RecyclerView;
+
+public class MyItemLookup extends ItemDetailsLookup {
+ private final RecyclerView recyclerView;
+
+ public MyItemLookup(RecyclerView recyclerView) {
+ this.recyclerView = recyclerView;
+ }
+
+ @Nullable
+ @Override
+ public ItemDetails getItemDetails(@NonNull MotionEvent e) {
+ View view = recyclerView.findChildViewUnder(e.getX(), e.getY());
+ if (view != null) {
+ RecyclerView.ViewHolder viewHolder = recyclerView.getChildViewHolder(view);
+ if (viewHolder instanceof DoxsListAdapter.DoxsListViewHolder) {
+ return ((DoxsListAdapter.DoxsListViewHolder) viewHolder).getItemDetails();
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/ViewHolderWithDetails.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/ViewHolderWithDetails.java
new file mode 100644
index 0000000000000000000000000000000000000000..1da9846ffee79c3a0bed2ff8a60d770a89a02778
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/view/ViewHolderWithDetails.java
@@ -0,0 +1,29 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.devicelist.presentation.view;
+
+import androidx.recyclerview.selection.ItemDetailsLookup;
+
+public interface ViewHolderWithDetails {
+ ItemDetailsLookup.ItemDetails getItemDetails();
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/DeviceListViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/DeviceListViewModel.java
index 8ceb127024f7a00b2d80087e05af44206ff81510..b20166e8df39b579125c8f323b96a63fe3ab99c2 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/DeviceListViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/DeviceListViewModel.java
@@ -21,9 +21,9 @@
*/
package org.openconnectivity.otgc.devicelist.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
import org.iotivity.base.OcProvisioning;
import org.openconnectivity.otgc.common.domain.model.NetworkDisconnectedException;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/DoxsViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/DoxsViewModel.java
index c272e87b6fd01b9839137d0b9d8f331d5f442529..07f2fdba009c17455054531e61bc45968586630a 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/DoxsViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/DoxsViewModel.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.devicelist.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
import org.iotivity.base.OcSecureResource;
import org.iotivity.base.OxmType;
@@ -36,15 +36,18 @@ import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelError;
import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelErrorType;
import org.openconnectivity.otgc.devicelist.domain.model.DeviceType;
import org.openconnectivity.otgc.common.domain.usecase.GetDeviceNameUseCase;
+import org.openconnectivity.otgc.devicelist.domain.usecase.GetDeviceRoleUseCase;
import org.openconnectivity.otgc.devicelist.domain.usecase.GetOTMethodsUseCase;
import org.openconnectivity.otgc.devicelist.domain.usecase.OnboardUseCase;
import org.openconnectivity.otgc.devicelist.domain.model.Device;
import org.openconnectivity.otgc.common.presentation.viewmodel.Response;
import org.openconnectivity.otgc.devicelist.domain.usecase.OffboardUseCase;
+import org.openconnectivity.otgc.devicelist.domain.usecase.PairwiseDevicesUseCase;
import org.openconnectivity.otgc.devicelist.domain.usecase.ScanDevicesUseCase;
import org.openconnectivity.otgc.devicelist.domain.usecase.SetDeviceNameUseCase;
import org.openconnectivity.otgc.devicelist.domain.usecase.SetOTMethodUseCase;
import org.openconnectivity.otgc.common.domain.rx.SchedulersFacade;
+import org.openconnectivity.otgc.devicelist.domain.usecase.UnlinkDevicesUseCase;
import org.openconnectivity.otgc.devicelist.domain.usecase.WiFiEasySetupUseCase;
import org.openconnectivity.otgc.wlanscan.domain.model.WifiNetwork;
import org.openconnectivity.otgc.wlanscan.domain.usecase.RegisterScanResultsReceiverUseCase;
@@ -67,6 +70,9 @@ public class DoxsViewModel extends BaseViewModel {
private final GetDeviceNameUseCase mGetDeviceNameUseCase;
private final ScanWiFiNetworksUseCase mScanWiFiNetworksUseCase;
private final WiFiEasySetupUseCase mWiFiEasySetupUseCase;
+ private final GetDeviceRoleUseCase mGetDeviceRoleUseCase;
+ private final PairwiseDevicesUseCase mPairwiseDevicesUseCase;
+ private final UnlinkDevicesUseCase mUnlinkDevicesUseCase;
private final SchedulersFacade mSchedulersFacade;
@@ -92,6 +98,9 @@ public class DoxsViewModel extends BaseViewModel {
GetDeviceNameUseCase getDeviceNameUseCase,
ScanWiFiNetworksUseCase scanWiFiNetworksUseCase,
WiFiEasySetupUseCase wiFiEasySetupUseCase,
+ GetDeviceRoleUseCase getDeviceRoleUseCase,
+ PairwiseDevicesUseCase pairwiseDevicesUseCase,
+ UnlinkDevicesUseCase unlinkDevicesUseCase,
SchedulersFacade schedulersFacade) {
this.mCheckConnectionUseCase = checkConnectionUseCase;
this.mScanDevicesUseCase = scanDevicesUseCase;
@@ -104,6 +113,9 @@ public class DoxsViewModel extends BaseViewModel {
this.mGetDeviceNameUseCase = getDeviceNameUseCase;
this.mScanWiFiNetworksUseCase = scanWiFiNetworksUseCase;
this.mWiFiEasySetupUseCase = wiFiEasySetupUseCase;
+ this.mGetDeviceRoleUseCase = getDeviceRoleUseCase;
+ this.mPairwiseDevicesUseCase = pairwiseDevicesUseCase;
+ this.mUnlinkDevicesUseCase = unlinkDevicesUseCase;
this.mSchedulersFacade = schedulersFacade;
@@ -146,8 +158,12 @@ public class DoxsViewModel extends BaseViewModel {
.map(device -> {
device.setDeviceInfo(mGetDeviceInfoUseCase.execute(device.getDeviceId()).blockingGet());
return device;
- })
- .map(device -> {
+ }).map(device -> {
+ device.setRole(
+ mGetDeviceRoleUseCase.execute(device.getDeviceId()).blockingGet());
+
+ return device;
+ }).map(device -> {
if (device.getType().equals(DeviceType.OWNED_BY_SELF)) {
String storedDeviceName = mGetDeviceNameUseCase.execute(device.getDeviceId()).blockingGet();
if (storedDeviceName != null && !storedDeviceName.isEmpty()) {
@@ -191,6 +207,12 @@ public class DoxsViewModel extends BaseViewModel {
device.setDeviceInfo(mGetDeviceInfoUseCase.execute(device.getDeviceId()).blockingGet());
return device;
}))
+ .map(device -> {
+ device.setRole(
+ mGetDeviceRoleUseCase.execute(device.getDeviceId()).blockingGet());
+
+ return device;
+ })
.subscribeOn(mSchedulersFacade.io())
.observeOn(mSchedulersFacade.ui())
.doOnSubscribe(__ -> otmResponse.setValue(Response.loading()))
@@ -263,11 +285,37 @@ public class DoxsViewModel extends BaseViewModel {
);
}
+ public void pairwiseDevices(String serverId, String clientId) {
+ mDisposables.add(mPairwiseDevicesUseCase.execute(serverId, clientId)
+ .subscribeOn(mSchedulersFacade.io())
+ .observeOn(mSchedulersFacade.ui())
+ .doOnSubscribe(__ -> mProcessing.setValue(true))
+ .doFinally(() -> mProcessing.setValue(false))
+ .subscribe(
+ () -> {},
+ throwable -> mError.setValue(new ViewModelError(Error.PAIRWISE_DEVICES, null))
+ ));
+ }
+
+ public void unlinkDevices(String serverId, String clientId) {
+ mDisposables.add(mUnlinkDevicesUseCase.execute(serverId, clientId)
+ .subscribeOn(mSchedulersFacade.io())
+ .observeOn(mSchedulersFacade.ui())
+ .doOnSubscribe(__ -> mProcessing.setValue(true))
+ .doFinally(() -> mProcessing.setValue(false))
+ .subscribe(
+ () -> {},
+ throwable -> mError.setValue(new ViewModelError(Error.UNLINK_DEVICES, null))
+ ));
+ }
+
public interface SelectOxMListener {
OxmType onGetOxM(List supportedOxm);
}
public enum Error implements ViewModelErrorType {
- SCAN_DEVICES
+ SCAN_DEVICES,
+ PAIRWISE_DEVICES,
+ UNLINK_DEVICES
}
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/SharedViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/SharedViewModel.java
index 7085892e2a4dbcece0a4883db572eaa5c8d8bc5b..ad747d85d55d600a998a147f4ec231fded73f7f4 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/SharedViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/devicelist/presentation/viewmodel/SharedViewModel.java
@@ -21,10 +21,10 @@
*/
package org.openconnectivity.otgc.devicelist.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
-import android.support.annotation.NonNull;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+import androidx.annotation.NonNull;
import javax.inject.Inject;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/di/AppInjector.java b/otgc/src/main/java/org/openconnectivity/otgc/di/AppInjector.java
index 27a5f40c9911c0db1c8bb3389d84471643d14d37..613308f33ae8e6ad116ed3086e3374a7692a73f2 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/di/AppInjector.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/di/AppInjector.java
@@ -25,9 +25,9 @@ package org.openconnectivity.otgc.di;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
import org.openconnectivity.otgc.App;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/di/AppModule.java b/otgc/src/main/java/org/openconnectivity/otgc/di/AppModule.java
index bf1faa671e9719f6b2005d639d7b0bc616924445..005bf963e3cbe31205c37afa07c7896b49afc916 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/di/AppModule.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/di/AppModule.java
@@ -20,7 +20,7 @@
package org.openconnectivity.otgc.di;
import android.app.Application;
-import android.arch.persistence.room.Room;
+import androidx.room.Room;
import android.content.Context;
import org.openconnectivity.otgc.common.data.persistence.dao.DeviceDao;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/di/BuildersModule.java b/otgc/src/main/java/org/openconnectivity/otgc/di/BuildersModule.java
index cef9a131c8d9aa5bb7332657cfeb6d875ffd637d..5ff8f4d22acdca4284f0adf59c5421af29210940 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/di/BuildersModule.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/di/BuildersModule.java
@@ -27,6 +27,7 @@ import org.openconnectivity.otgc.credential.presentation.view.CredActivity;
import org.openconnectivity.otgc.credential.presentation.view.CredentialsActivity;
import org.openconnectivity.otgc.devicelist.DeviceListBuildersModule;
import org.openconnectivity.otgc.devicelist.presentation.view.DeviceListActivity;
+import org.openconnectivity.otgc.linkedroles.presentation.view.LinkedRolesActivity;
import org.openconnectivity.otgc.login.presentation.view.LoginActivity;
import org.openconnectivity.otgc.splash.presentation.view.SplashActivity;
import org.openconnectivity.otgc.wlanscan.presentation.view.WlanScanActivity;
@@ -63,4 +64,7 @@ public interface BuildersModule {
@ContributesAndroidInjector(modules = ClientBuildersModule.class)
abstract GenericClientActivity bindGenericClientActivity();
+
+ @ContributesAndroidInjector
+ abstract LinkedRolesActivity bindLinkedRolesActivity();
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/di/ViewModelKey.java b/otgc/src/main/java/org/openconnectivity/otgc/di/ViewModelKey.java
index 31c22aa877ab84480738c01b6f7fa16073bc8e29..b5d269a274b0a8ff8577edd0e9346b8070440833 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/di/ViewModelKey.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/di/ViewModelKey.java
@@ -22,7 +22,7 @@
package org.openconnectivity.otgc.di;
-import android.arch.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModel;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/di/ViewModelModule.java b/otgc/src/main/java/org/openconnectivity/otgc/di/ViewModelModule.java
index 1624b14575412e5e97c5ce947eda8e1e088dbd09..53252775bd4419d558e4d463ef668e19dfdb3604 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/di/ViewModelModule.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/di/ViewModelModule.java
@@ -22,8 +22,8 @@
package org.openconnectivity.otgc.di;
-import android.arch.lifecycle.ViewModel;
-import android.arch.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
import org.openconnectivity.otgc.accesscontrol.presentation.viewmodel.AccessControlViewModel;
import org.openconnectivity.otgc.accesscontrol.presentation.viewmodel.AceViewModel;
@@ -35,6 +35,7 @@ import org.openconnectivity.otgc.credential.presentation.viewmodel.CredentialsVi
import org.openconnectivity.otgc.devicelist.presentation.viewmodel.DeviceListViewModel;
import org.openconnectivity.otgc.devicelist.presentation.viewmodel.SharedViewModel;
import org.openconnectivity.otgc.devicelist.presentation.viewmodel.DoxsViewModel;
+import org.openconnectivity.otgc.linkedroles.presentation.viewmodel.LinkedRolesViewModel;
import org.openconnectivity.otgc.login.presentation.viewmodel.LoginViewModel;
import org.openconnectivity.otgc.splash.presentation.viewmodel.SplashViewModel;
import org.openconnectivity.otgc.wlanscan.presentation.viewmodel.WlanScanViewModel;
@@ -100,6 +101,11 @@ abstract class ViewModelModule {
@ViewModelKey(GenericClientViewModel.class)
abstract ViewModel bindGenericClientViewModel(GenericClientViewModel genericClientViewModel);
+ @Binds
+ @IntoMap
+ @ViewModelKey(LinkedRolesViewModel.class)
+ abstract ViewModel bindLinkedRolesViewModel(LinkedRolesViewModel linkedRolesViewModel);
+
@Binds
@IntoMap
@ViewModelKey(ResourceViewModel.class)
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/LinkRolesForClientUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/LinkRolesForClientUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..2102eb34b50c781ab65a4b49e7de3f62b3b94662
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/LinkRolesForClientUseCase.java
@@ -0,0 +1,47 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.domain.usecase;
+
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+import org.openconnectivity.otgc.credential.data.repository.CmsRepository;
+
+import javax.inject.Inject;
+
+import io.reactivex.Completable;
+
+public class LinkRolesForClientUseCase {
+ private final IotivityRepository mIotivityRepository;
+ private final CmsRepository mCmsRepository;
+
+ @Inject
+ public LinkRolesForClientUseCase(IotivityRepository iotivityRepository,
+ CmsRepository cmsRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ this.mCmsRepository = cmsRepository;
+ }
+
+ public Completable execute(String deviceId, String roleId, String roleAuthority) {
+ return mIotivityRepository.findOcSecureResource(deviceId)
+ .flatMapCompletable(ocSecureResource -> mCmsRepository.provisionRoleCertificate(ocSecureResource, roleId, roleAuthority));
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/LinkRolesForServerUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/LinkRolesForServerUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c0f982b9dda82df68ddb91b21563a5223a6e271
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/LinkRolesForServerUseCase.java
@@ -0,0 +1,67 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.domain.usecase;
+
+import org.iotivity.base.AceSubjectRole;
+import org.iotivity.base.AceSubjectType;
+import org.iotivity.base.OicSecAce;
+import org.iotivity.base.OicSecAceSubject;
+import org.openconnectivity.otgc.accesscontrol.data.repository.AmsRepository;
+import org.openconnectivity.otgc.client.data.repository.ResourceRepository;
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+
+import java.util.ArrayList;
+
+import javax.inject.Inject;
+
+import io.reactivex.Completable;
+
+public class LinkRolesForServerUseCase {
+ private final IotivityRepository mIotivityRepository;
+ private final AmsRepository mAmsRepository;
+ private final ResourceRepository mResourceRepository;
+
+ @Inject
+ public LinkRolesForServerUseCase(IotivityRepository iotivityRepository,
+ AmsRepository amsRepository,
+ ResourceRepository resourceRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ this.mAmsRepository = amsRepository;
+ this.mResourceRepository = resourceRepository;
+ }
+
+ public Completable execute(String deviceId, String roleId, String roleAuthority) {
+ return mIotivityRepository.getDeviceCoapIpv6Host(deviceId)
+ .flatMap(mIotivityRepository::findResources)
+ .map(mResourceRepository::getVerticalResources)
+ .flatMapCompletable(resources -> mIotivityRepository.findOcSecureResource(deviceId)
+ .flatMapCompletable(ocSecureResource -> {
+ AceSubjectRole role = new AceSubjectRole(roleId, roleAuthority);
+ OicSecAceSubject subject = new OicSecAceSubject(AceSubjectType.SUBJECT_ROLE.getValue(), null, role, null);
+
+ OicSecAce ace = new OicSecAce(0, subject, 31, resources, new ArrayList<>());
+ return mAmsRepository.provisionAcl(ocSecureResource, ace);
+ })
+ );
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/RetrieveLinkedRolesForClientUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/RetrieveLinkedRolesForClientUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..26403529c8107eb75a049bf052fd0b81ccceb990
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/RetrieveLinkedRolesForClientUseCase.java
@@ -0,0 +1,62 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.domain.usecase;
+
+import org.iotivity.base.OicSecCred;
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+import org.openconnectivity.otgc.credential.data.repository.CmsRepository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import io.reactivex.Single;
+
+public class RetrieveLinkedRolesForClientUseCase {
+ private final IotivityRepository mIotivityRepository;
+ private final CmsRepository mCmsRepository;
+
+ @Inject
+ public RetrieveLinkedRolesForClientUseCase(IotivityRepository iotivityRepository,
+ CmsRepository cmsRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ this.mCmsRepository = cmsRepository;
+ }
+
+ public Single> execute(String deviceId) {
+ return mIotivityRepository.findOcSecureResource(deviceId)
+ .flatMap(mCmsRepository::getCredentials)
+ .map(credentials -> {
+ List roles = new ArrayList<>();
+
+ for (OicSecCred cred : credentials.getOicSecCreds()) {
+ if (cred.getRole() != null) {
+ roles.add(cred.getRole().getId());
+ }
+ }
+
+ return roles;
+ });
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/RetrieveLinkedRolesForServerUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/RetrieveLinkedRolesForServerUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..c78b57ab6c48ac03e2645341418705a4ad8624d2
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/RetrieveLinkedRolesForServerUseCase.java
@@ -0,0 +1,62 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.domain.usecase;
+
+import org.iotivity.base.OicSecAce;
+import org.openconnectivity.otgc.accesscontrol.data.repository.AmsRepository;
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import io.reactivex.Single;
+
+public class RetrieveLinkedRolesForServerUseCase {
+ private final IotivityRepository mIotivityRepository;
+ private final AmsRepository mAmsRepository;
+
+ @Inject
+ public RetrieveLinkedRolesForServerUseCase(IotivityRepository iotivityRepository,
+ AmsRepository amsRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ this.mAmsRepository = amsRepository;
+ }
+
+ public Single> execute(String deviceId) {
+ return mIotivityRepository.findOcSecureResource(deviceId)
+ .flatMap(mAmsRepository::getAcl)
+ .map(acl -> {
+ List roles = new ArrayList<>();
+
+ for(OicSecAce ace : acl.getOicSecAces()) {
+ if (ace.getSubject().getRole() != null) {
+ roles.add(ace.getSubject().getRole().getId());
+ }
+ }
+
+ return roles;
+ });
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/UnlinkRoleForClientUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/UnlinkRoleForClientUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..7be3217821a82955773eb9c7d3bb85cf40e07833
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/UnlinkRoleForClientUseCase.java
@@ -0,0 +1,62 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.domain.usecase;
+
+import org.iotivity.base.OicSecCred;
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+import org.openconnectivity.otgc.credential.data.repository.CmsRepository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import io.reactivex.Completable;
+
+public class UnlinkRoleForClientUseCase {
+ private final IotivityRepository mIotivityRepository;
+ private final CmsRepository mCmsRepository;
+
+ @Inject
+ public UnlinkRoleForClientUseCase(IotivityRepository iotivityRepository,
+ CmsRepository cmsRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ this.mCmsRepository = cmsRepository;
+ }
+
+ public Completable execute(String deviceId, String roleId) {
+ return mIotivityRepository.findOcSecureResource(deviceId)
+ .flatMapCompletable(ocSecureResource -> mCmsRepository.getCredentials(ocSecureResource)
+ .flatMapCompletable(oicSecCreds -> {
+ List deleteCredList = new ArrayList<>();
+ for (OicSecCred cred : oicSecCreds.getOicSecCreds()) {
+ if (cred.getRole() != null && cred.getRole().getId().equals(roleId)) {
+ deleteCredList.add(mCmsRepository.deleteCredential(ocSecureResource, cred.getCredID()));
+ }
+ }
+
+ return Completable.merge(deleteCredList);
+ })
+ );
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/UnlinkRoleForServerUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/UnlinkRoleForServerUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..4941bf06c419bccaa77e265d59870ef818633772
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/domain/usecase/UnlinkRoleForServerUseCase.java
@@ -0,0 +1,63 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.domain.usecase;
+
+import org.iotivity.base.OicSecAce;
+import org.openconnectivity.otgc.accesscontrol.data.repository.AmsRepository;
+import org.openconnectivity.otgc.common.data.repository.IotivityRepository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import io.reactivex.Completable;
+
+public class UnlinkRoleForServerUseCase {
+ private final IotivityRepository mIotivityRepository;
+ private final AmsRepository mAmsRepository;
+
+ @Inject
+ public UnlinkRoleForServerUseCase(IotivityRepository iotivityRepository,
+ AmsRepository amsRepository) {
+ this.mIotivityRepository = iotivityRepository;
+ this.mAmsRepository = amsRepository;
+ }
+
+ public Completable execute(String deviceId, String roleId) {
+ return mIotivityRepository.findOcSecureResource(deviceId)
+ .flatMapCompletable(ocSecureResource -> mAmsRepository.getAcl(ocSecureResource)
+ .flatMapCompletable(oicSecAcl -> {
+ List deleteAceList = new ArrayList<>();
+ for (OicSecAce ace : oicSecAcl.getOicSecAces()) {
+ if (ace.getSubject().getRole() != null && ace.getSubject().getRole().getId().equals(roleId)) {
+ deleteAceList.add(mAmsRepository.deleteAcl(ocSecureResource, ace.getAceID()));
+ }
+ }
+
+ return Completable.merge(deleteAceList);
+ })
+ );
+
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/view/LinkedRolesActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/view/LinkedRolesActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1ee556e3341bc09e1d24d4fbdb0e5a90a97bcf3
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/view/LinkedRolesActivity.java
@@ -0,0 +1,199 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.presentation.view;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.ContextThemeWrapper;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+
+import org.openconnectivity.otgc.R;
+import org.openconnectivity.otgc.common.presentation.view.EmptyRecyclerView;
+import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelError;
+import org.openconnectivity.otgc.devicelist.domain.model.Role;
+import org.openconnectivity.otgc.di.Injectable;
+import org.openconnectivity.otgc.linkedroles.presentation.viewmodel.LinkedRolesViewModel;
+
+import javax.inject.Inject;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import timber.log.Timber;
+
+public class LinkedRolesActivity extends AppCompatActivity implements Injectable {
+ @Inject
+ ViewModelProvider.Factory mViewModelFactory;
+
+ @BindView(R.id.progress_bar) ProgressBar mProgressBar;
+ @BindView(R.id.toolbar) Toolbar mToolbar;
+ @BindView(R.id.recycler_ocf_roles) EmptyRecyclerView mRecyclerView;
+ @BindView(R.id.floating_button_roles_add) FloatingActionButton mFloatingActionButton;
+
+ @OnClick(R.id.floating_button_roles_add)
+ protected void onAddPressed() {
+ AlertDialog.Builder alertDialog = new AlertDialog.Builder(new ContextThemeWrapper(LinkedRolesActivity.this, R.style.AppTheme));
+ alertDialog.setTitle(LinkedRolesActivity.this.getString(R.string.linked_roles_dialog_add_role_title));
+
+ LinearLayout layout = new LinearLayout(LinkedRolesActivity.this);
+ layout.setOrientation(LinearLayout.VERTICAL);
+ final EditText etRoleIdInput = new EditText(LinkedRolesActivity.this);
+ etRoleIdInput.setHint(R.string.linked_roles_dialog_role_id_hint);
+ final EditText etRoleAuthorityInput = new EditText(LinkedRolesActivity.this);
+ etRoleAuthorityInput.setHint(R.string.linked_roles_dialog_role_authority_hint);
+ layout.addView(etRoleIdInput);
+ layout.addView(etRoleAuthorityInput);
+ layout.setPadding(50, 40, 50, 10);
+
+ alertDialog.setView(layout);
+ alertDialog.setPositiveButton(LinkedRolesActivity.this.getString(R.string.linked_roles_dialog_add_role_yes_option), (dialog, which) -> {
+ dialog.dismiss();
+ if (!etRoleIdInput.getText().toString().isEmpty()) {
+ mViewModel.addLinkedRole(mDeviceId, mDeviceRole, etRoleIdInput.getText().toString(), etRoleAuthorityInput.getText().toString());
+ } else {
+ Timber.d("Fiil role ID input text");
+ }
+ });
+ alertDialog.setNegativeButton(LinkedRolesActivity.this.getString(R.string.linked_roles_dialog_add_role_no_option), (dialog, which) -> dialog.dismiss()).show();
+ }
+
+ private LinkedRolesViewModel mViewModel;
+ private LinkedRolesAdapter mAdapter;
+
+ private String mDeviceId;
+ private Role mDeviceRole;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_linked_roles);
+
+ ButterKnife.bind(this);
+ initViews();
+ initViewModel();
+
+ Intent intent = getIntent();
+ mDeviceId = intent.getStringExtra("deviceId");
+ mDeviceRole = Role.valueOf(intent.getStringExtra("deviceRole"));
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mViewModel.retrieveLinkedRoles(mDeviceId, mDeviceRole);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+ if (id == android.R.id.home) {
+ onBackPressed();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void initViews() {
+ setSupportActionBar(mToolbar);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+ mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(RecyclerView view, int dx, int dy) {
+ super.onScrolled(view, dx, dy);
+ if (dy > 0 && mFloatingActionButton.getVisibility() == View.VISIBLE) {
+ mFloatingActionButton.hide();
+ } else if (dy < 0 && mFloatingActionButton.getVisibility() != View.VISIBLE) {
+ mFloatingActionButton.show();
+ }
+ }
+ });
+
+ mAdapter = new LinkedRolesAdapter(this);
+ LinkedRolesAdapter.setOnDeleteClickListener((position, v) ->
+ mViewModel.deleteLinkedRole(mDeviceId, mDeviceRole, mAdapter.mDataset.get(position))
+ );
+
+ mRecyclerView.setAdapter(mAdapter);
+ }
+
+ private void initViewModel() {
+ mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(LinkedRolesViewModel.class);
+
+ mViewModel.isProcessing().observe(this, this::handleProcessing);
+ mViewModel.getError().observe(this, this::handleError);
+
+ mViewModel.getLinkedRoles().observe(this, this::processLinkedRoles);
+ mViewModel.getDeletedRoleId().observe(this, this::processDeletedRoleId);
+ }
+
+ private void handleProcessing(@NonNull Boolean isProcessing) {
+ mProgressBar.setVisibility(isProcessing ? View.VISIBLE : View.GONE);
+ }
+
+ private void handleError(@NonNull ViewModelError error) {
+ int errorId = 0;
+ switch ((LinkedRolesViewModel.Error)error.getType()) {
+ case RETRIEVE:
+ errorId = R.string.linked_roles_error_retrieve;
+ break;
+ case DELETE:
+ default:
+ break;
+ }
+
+ if (errorId != 0) {
+ Toast.makeText(this, errorId, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void processLinkedRoles(@NonNull String role) {
+ mAdapter.addItem(role);
+ }
+
+ private void processDeletedRoleId(@NonNull String roleId) {
+ mAdapter.deleteItemById(roleId);
+ }
+
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/view/LinkedRolesAdapter.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/view/LinkedRolesAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..5bb1c42c7738b1c4797759f4fd39bb3650e65863
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/view/LinkedRolesAdapter.java
@@ -0,0 +1,157 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.presentation.view;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import org.openconnectivity.otgc.R;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.SortedList;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+public class LinkedRolesAdapter extends RecyclerView.Adapter {
+ SortedList mDataset;
+ private static LinkedRolesAdapter.DeleteClickListener sDeleteClickListener;
+
+ public static class LinkedRolesViewHolder extends RecyclerView.ViewHolder
+ implements View.OnClickListener {
+ @BindView(R.id.text_role_id) TextView mRoleId;
+ @BindView(R.id.img_btn_delete_role) ImageButton mDeleteButton;
+
+ private LinkedRolesViewHolder(View itemView) {
+ super(itemView);
+ ButterKnife.bind(this, itemView);
+
+ mDeleteButton.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View v) {
+ sDeleteClickListener.onDeleteClick(getAdapterPosition(), v);
+ }
+ }
+
+ LinkedRolesAdapter(Context context) {
+ mDataset = new SortedList<>(String.class, new SortedList.Callback() {
+ @Override
+ public int compare(String a1, String a2) {
+ return a1.compareTo(a2);
+ }
+
+ @Override
+ public void onChanged(int position, int count) {
+ notifyItemRangeChanged(position, count);
+ }
+
+ @Override
+ public boolean areContentsTheSame(String oldItem, String newItem) {
+ // TODO: Improve
+ return oldItem.equals(newItem);
+ }
+
+ @Override
+ public boolean areItemsTheSame(String item1, String item2) {
+ return item1.equals(item2);
+ }
+
+ @Override
+ public void onInserted(int position, int count) {
+ notifyItemRangeInserted(position, count);
+ }
+
+ @Override
+ public void onRemoved(int position, int count) {
+ notifyItemRangeRemoved(position, count);
+ }
+
+ @Override
+ public void onMoved(int fromPosition, int toPosition) {
+ notifyItemMoved(fromPosition, toPosition);
+ }
+ });
+ }
+
+ public static void setOnDeleteClickListener(LinkedRolesAdapter.DeleteClickListener deleteClickListener) {
+ sDeleteClickListener = deleteClickListener;
+ }
+
+ // Create new views (invoked by the layout manager)
+ @Override
+ @NonNull
+ public LinkedRolesAdapter.LinkedRolesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ // Create a new view
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_role, parent, false);
+
+ return new LinkedRolesAdapter.LinkedRolesViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull LinkedRolesViewHolder holder, int position) {
+ String role = mDataset.get(position);
+
+ if (role != null) {
+ holder.mRoleId.setText(role);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return mDataset != null ? mDataset.size() : 0;
+ }
+
+ public void clearItems() {
+ mDataset.beginBatchedUpdates();
+ while (mDataset.size() > 0) {
+ mDataset.removeItemAt(mDataset.size() - 1);
+ }
+ mDataset.endBatchedUpdates();
+ }
+
+ public void addItem(String item) {
+ if (item != null) {
+ mDataset.add(item);
+ }
+ }
+
+ public void deleteItemById(String roleId) {
+ for (int i = 0; i < mDataset.size(); i++) {
+ if (mDataset.get(i).equals(roleId)) {
+ mDataset.removeItemAt(i);
+ break;
+ }
+ }
+ }
+
+ public interface DeleteClickListener {
+ void onDeleteClick(int position, View v);
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/viewmodel/LinkedRolesViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/viewmodel/LinkedRolesViewModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d1901dbc5f4cacde2a5c7b8db0406a23ae01252
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/linkedroles/presentation/viewmodel/LinkedRolesViewModel.java
@@ -0,0 +1,172 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2019 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * ******************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ******************************************************************
+ */
+
+package org.openconnectivity.otgc.linkedroles.presentation.viewmodel;
+
+import org.openconnectivity.otgc.accesscontrol.presentation.viewmodel.AccessControlViewModel;
+import org.openconnectivity.otgc.common.domain.rx.SchedulersFacade;
+import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelError;
+import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelErrorType;
+import org.openconnectivity.otgc.devicelist.domain.model.Role;
+import org.openconnectivity.otgc.linkedroles.domain.usecase.LinkRolesForClientUseCase;
+import org.openconnectivity.otgc.linkedroles.domain.usecase.LinkRolesForServerUseCase;
+import org.openconnectivity.otgc.linkedroles.domain.usecase.RetrieveLinkedRolesForClientUseCase;
+import org.openconnectivity.otgc.linkedroles.domain.usecase.RetrieveLinkedRolesForServerUseCase;
+import org.openconnectivity.otgc.linkedroles.domain.usecase.UnlinkRoleForClientUseCase;
+import org.openconnectivity.otgc.linkedroles.domain.usecase.UnlinkRoleForServerUseCase;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+import io.reactivex.Completable;
+import io.reactivex.Single;
+import io.reactivex.disposables.CompositeDisposable;
+
+public class LinkedRolesViewModel extends ViewModel {
+
+ private final RetrieveLinkedRolesForClientUseCase mRetrieveRolesForClientUseCase;
+ private final RetrieveLinkedRolesForServerUseCase mRetrieveRolesForServerUseCase;
+ private final LinkRolesForClientUseCase mLinkRolesForClientUseCase;
+ private final LinkRolesForServerUseCase mLinkRolesForServerUseCase;
+ private final UnlinkRoleForClientUseCase mUnlinkRoleForClientUseCase;
+ private final UnlinkRoleForServerUseCase mUnlinkRoleForServerUseCase;
+
+ private final SchedulersFacade mSchedulersFacade;
+ private final CompositeDisposable mDisposables = new CompositeDisposable();
+
+ private final MutableLiveData mProcessing = new MutableLiveData<>();
+ private final MutableLiveData mError = new MutableLiveData<>();
+
+ private final MutableLiveData mLinkedRoles = new MutableLiveData<>();
+ private final MutableLiveData mDeletedRoleId = new MutableLiveData<>();
+
+ @Inject
+ LinkedRolesViewModel(SchedulersFacade schedulersFacade,
+ RetrieveLinkedRolesForClientUseCase retrieveLinkedRolesForClientUseCase,
+ RetrieveLinkedRolesForServerUseCase retrieveLinkedRolesForServerUseCase,
+ LinkRolesForClientUseCase linkRolesForClientUseCase,
+ LinkRolesForServerUseCase linkRolesForServerUseCase,
+ UnlinkRoleForClientUseCase unlinkRoleForClientUseCase,
+ UnlinkRoleForServerUseCase unlinkRoleForServerUseCase) {
+ this.mSchedulersFacade = schedulersFacade;
+
+ this.mRetrieveRolesForClientUseCase = retrieveLinkedRolesForClientUseCase;
+ this.mRetrieveRolesForServerUseCase = retrieveLinkedRolesForServerUseCase;
+ this.mLinkRolesForClientUseCase = linkRolesForClientUseCase;
+ this.mLinkRolesForServerUseCase = linkRolesForServerUseCase;
+ this.mUnlinkRoleForClientUseCase = unlinkRoleForClientUseCase;
+ this.mUnlinkRoleForServerUseCase = unlinkRoleForServerUseCase;
+ }
+
+ @Override
+ protected void onCleared() {
+ mDisposables.clear();
+ }
+
+ public LiveData isProcessing() {
+ return mProcessing;
+ }
+
+ public LiveData getError() {
+ return mError;
+ }
+
+ public LiveData getLinkedRoles() {
+ return mLinkedRoles;
+ }
+
+ public LiveData getDeletedRoleId() {
+ return mDeletedRoleId;
+ }
+
+
+ public void retrieveLinkedRoles(String deviceId, Role deviceRole) {
+ Single> useCase;
+
+ if (deviceRole.equals(Role.CLIENT)) {
+ useCase = mRetrieveRolesForClientUseCase.execute(deviceId);
+ } else {
+ useCase = mRetrieveRolesForServerUseCase.execute(deviceId);
+ }
+ mDisposables.add(useCase
+ .subscribeOn(mSchedulersFacade.io())
+ .observeOn(mSchedulersFacade.ui())
+ .doOnSubscribe(__ -> mProcessing.setValue(true))
+ .doFinally(() -> mProcessing.setValue(false))
+ .subscribe(
+ linkedRoles -> {
+ for (String role : linkedRoles) {
+ mLinkedRoles.setValue(role);
+ }
+ },
+ throwable -> mError.setValue(new ViewModelError(LinkedRolesViewModel.Error.RETRIEVE, null))
+ ));
+ }
+
+ public void addLinkedRole(String deviceId, Role deviceRole, String roleId, String roleAuthority) {
+ Completable useCase;
+ if (deviceRole.equals(Role.CLIENT)) {
+ useCase = mLinkRolesForClientUseCase.execute(deviceId, roleId, roleAuthority);
+ } else {
+ useCase = mLinkRolesForServerUseCase.execute(deviceId, roleId, roleAuthority);
+ }
+
+ mDisposables.add(useCase
+ .subscribeOn(mSchedulersFacade.io())
+ .observeOn(mSchedulersFacade.ui())
+ .doOnSubscribe(__ -> mProcessing.setValue(true))
+ .doFinally(() -> mProcessing.setValue(false))
+ .subscribe(
+ () -> retrieveLinkedRoles(deviceId, deviceRole),
+ throwable -> mError.setValue(new ViewModelError(Error.CREATE, null))
+ ));
+ }
+
+ public void deleteLinkedRole(String deviceId, Role deviceRole, String roleId) {
+ Completable useCase;
+ if (deviceRole.equals(Role.CLIENT)) {
+ useCase = mUnlinkRoleForClientUseCase.execute(deviceId, roleId);
+ } else {
+ useCase = mUnlinkRoleForServerUseCase.execute(deviceId, roleId);
+ }
+
+ mDisposables.add(useCase
+ .subscribeOn(mSchedulersFacade.io())
+ .observeOn(mSchedulersFacade.ui())
+ .doOnSubscribe(__ -> mProcessing.setValue(true))
+ .doFinally(() -> mProcessing.setValue(false))
+ .subscribe(
+ () -> mDeletedRoleId.setValue(roleId),
+ throwable -> mError.setValue(new ViewModelError(Error.DELETE, null))
+ ));
+ }
+
+ public enum Error implements ViewModelErrorType {
+ CREATE,
+ RETRIEVE,
+ DELETE
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/login/presentation/view/LoginActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/login/presentation/view/LoginActivity.java
index 75d4353a087452875321885120d99702345aba9a..435ccee4596d4cd6ddb918de0a275d612256276e 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/login/presentation/view/LoginActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/login/presentation/view/LoginActivity.java
@@ -19,14 +19,14 @@
* ******************************************************************/
package org.openconnectivity.otgc.login.presentation.view;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
-import android.support.design.widget.TextInputEditText;
-import android.support.v7.app.AppCompatActivity;
+import androidx.annotation.NonNull;
+import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.textfield.TextInputEditText;
+import androidx.appcompat.app.AppCompatActivity;
import android.text.Editable;
import android.view.View;
import android.view.Window;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/login/presentation/viewmodel/LoginViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/login/presentation/viewmodel/LoginViewModel.java
index 3fb997133d9fdcd90503d4359c73ecddbe79bcba..115d2b20a7a6415ed684b2bcfd607ac62deafbb9 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/login/presentation/viewmodel/LoginViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/login/presentation/viewmodel/LoginViewModel.java
@@ -19,9 +19,9 @@
* ******************************************************************/
package org.openconnectivity.otgc.login.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelError;
import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelErrorType;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/logviewer/presentation/view/LogViewerActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/logviewer/presentation/view/LogViewerActivity.java
index 9188e94029c62677f59e5504ee0bb959ab422251..3f0b5c184451ac01e1a8d3c023a9c7cfb0a2ae68 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/logviewer/presentation/view/LogViewerActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/logviewer/presentation/view/LogViewerActivity.java
@@ -22,9 +22,15 @@
package org.openconnectivity.otgc.logviewer.presentation.view;
-import android.support.v7.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatActivity;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
import android.os.Bundle;
import android.webkit.WebView;
+import android.widget.Switch;
+
+import org.openconnectivity.otgc.R;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -32,13 +38,31 @@ import java.util.Locale;
public class LogViewerActivity extends AppCompatActivity {
+ @BindView(R.id.logviewer_iotivity_switch) Switch logSwitch;
+ @BindView(R.id.logviewer_webview) WebView webView;
+
+ private String iotivityLog = "";
+ private String otgcLog = "";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- WebView webView = new WebView(this);
- setContentView(webView);
+ setContentView(R.layout.activity_logviewer);
+ ButterKnife.bind(this);
String fileNameTimeStamp = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
- webView.loadUrl("file:///" + getExternalFilesDir(null).toString() + "/" + fileNameTimeStamp + ".html");
+ otgcLog = "file:///" + getExternalFilesDir(null).toString() + "/" + fileNameTimeStamp + ".html";
+ iotivityLog = "file:///" + getExternalFilesDir(null).toString() + "/log/logcat" + fileNameTimeStamp + ".html";
+
+ logSwitch.setOnClickListener(v -> loadWebView() );
+ webView.loadUrl(iotivityLog);
+ }
+
+ private void loadWebView() {
+ if (logSwitch.isChecked()) {
+ webView.loadUrl(iotivityLog);
+ } else {
+ webView.loadUrl(otgcLog);
+ }
}
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/settings/presentation/view/AppCompatPreferenceActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/settings/presentation/view/AppCompatPreferenceActivity.java
index 1b67b0e47d124be3dd7c3113e7bb3f8722857c99..fdd1c725c9e31a5fb32264455a2ac004bdf615a2 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/settings/presentation/view/AppCompatPreferenceActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/settings/presentation/view/AppCompatPreferenceActivity.java
@@ -25,12 +25,12 @@ package org.openconnectivity.otgc.settings.presentation.view;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatDelegate;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatDelegate;
+import androidx.appcompat.widget.Toolbar;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/settings/presentation/view/SettingsActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/settings/presentation/view/SettingsActivity.java
index f5309aef24ae1763de9503708eb8b8c55f14aef0..e433797fc6cb814c1652fd8b15196d644fc5e047 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/settings/presentation/view/SettingsActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/settings/presentation/view/SettingsActivity.java
@@ -33,7 +33,7 @@ import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.widget.Toolbar;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MenuItem;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/splash/presentation/view/SplashActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/splash/presentation/view/SplashActivity.java
index 72f25beef84168f069561ea564883fe8c90c6024..f13e41bbb2928fa71623b0b6de78eb7f5b5126e9 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/splash/presentation/view/SplashActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/splash/presentation/view/SplashActivity.java
@@ -24,18 +24,18 @@ package org.openconnectivity.otgc.splash.presentation.view;
import android.Manifest;
import android.app.Dialog;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.ActivityOptionsCompat;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
+import androidx.core.app.ActivityOptionsCompat;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
-import android.support.v7.view.ContextThemeWrapper;
+import androidx.appcompat.view.ContextThemeWrapper;
import android.view.View;
import android.widget.TextView;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/splash/presentation/viewmodel/SplashViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/splash/presentation/viewmodel/SplashViewModel.java
index e848af33ff5bdf33df34440ceacd8e78895b84eb..05f369eae5b9574c82301173cd1a18f0ee673e2e 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/splash/presentation/viewmodel/SplashViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/splash/presentation/viewmodel/SplashViewModel.java
@@ -22,10 +22,10 @@
package org.openconnectivity.otgc.splash.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
-import android.arch.persistence.room.EmptyResultSetException;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+import androidx.room.EmptyResultSetException;
import org.openconnectivity.otgc.common.presentation.viewmodel.ViewModelError;
import org.openconnectivity.otgc.common.domain.rx.SchedulersFacade;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/domain/usecase/ConnectToWiFiUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/domain/usecase/ConnectToWiFiUseCase.java
index 0c4ac0676b146beee0fc9034b849b546ecd60315..9d6ff011d55c31b6759e15e25b9de6ff4e825c5b 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/domain/usecase/ConnectToWiFiUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/domain/usecase/ConnectToWiFiUseCase.java
@@ -56,13 +56,7 @@ public class ConnectToWiFiUseCase {
return wlanRepository.isWifiEnabled()
.andThen(wlanRepository.getWifiConfiguration(network.getName()))
- .flatMap(config -> {
- if (config == null) {
- return configureWifiNetwork;
- } else {
- return Single.just(config);
- }
- })
+ .onErrorResumeNext(configureWifiNetwork)
.flatMapCompletable(wlanRepository::connectToWifi);
}
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/view/WlanScanActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/view/WlanScanActivity.java
index 70b0acb7cb060f2447e56353c0a10af7a693f4ed..efbbf73be6d2c9c6ce9003fae33857e284ff3bef 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/view/WlanScanActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/view/WlanScanActivity.java
@@ -22,20 +22,20 @@
package org.openconnectivity.otgc.wlanscan.presentation.view;
import android.app.AlertDialog;
-import android.arch.lifecycle.ViewModelProvider;
-import android.arch.lifecycle.ViewModelProviders;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
//import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiManager;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.design.widget.TextInputEditText;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.NonNull;
+import com.google.android.material.textfield.TextInputEditText;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/view/WlanScanAdapter.java b/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/view/WlanScanAdapter.java
index 3e2c6879f362c418458a4bfbcea3468284349411..f4c0932cb60a80386769ed825e00bc147f25536c 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/view/WlanScanAdapter.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/view/WlanScanAdapter.java
@@ -24,9 +24,9 @@ package org.openconnectivity.otgc.wlanscan.presentation.view;
import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/viewmodel/WlanScanViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/viewmodel/WlanScanViewModel.java
index 13b37b4604d72465b0a584bb92f0f1b5169ee379..9d202aebd6d20006b4a78fb4404475f1b68e0ba9 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/viewmodel/WlanScanViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/wlanscan/presentation/viewmodel/WlanScanViewModel.java
@@ -22,9 +22,9 @@
package org.openconnectivity.otgc.wlanscan.presentation.viewmodel;
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.arch.lifecycle.ViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
import android.net.wifi.SupplicantState;
import org.openconnectivity.otgc.common.domain.usecase.CheckConnectionUseCase;
diff --git a/otgc/src/main/res/color/device_background.xml b/otgc/src/main/res/color/device_background.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a31029a6d9b5561f6ddabd08cd30d42dd097dad8
--- /dev/null
+++ b/otgc/src/main/res/color/device_background.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/otgc/src/main/res/drawable-v23/ic_ocf_logo_white.xml b/otgc/src/main/res/drawable-v23/ic_ocf_logo_white.xml
new file mode 100644
index 0000000000000000000000000000000000000000..607c8c1d689c42cb5622d4d2372ecd83cbc7620c
--- /dev/null
+++ b/otgc/src/main/res/drawable-v23/ic_ocf_logo_white.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/otgc/src/main/res/drawable-v23/splash.xml b/otgc/src/main/res/drawable-v23/splash.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b6e6f6eb7a018599e0105e9aa6d1acaf4c5be39a
--- /dev/null
+++ b/otgc/src/main/res/drawable-v23/splash.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/otgc/src/main/res/drawable/splash.xml b/otgc/src/main/res/drawable/splash.xml
index b6e6f6eb7a018599e0105e9aa6d1acaf4c5be39a..2b36bb0751ecfc11363e53c07b55cf1e00fe7bc5 100644
--- a/otgc/src/main/res/drawable/splash.xml
+++ b/otgc/src/main/res/drawable/splash.xml
@@ -23,8 +23,10 @@
-
+ android:drawable="@color/white1" />
+ -
+
+
\ No newline at end of file
diff --git a/otgc/src/main/res/layout/activity_access_control.xml b/otgc/src/main/res/layout/activity_access_control.xml
index 8dbd48c54d97baba03aa0316d857888cd2fe92e1..43a166dd8a00e2a54a78752b9a7c22fb6b1b30a5 100644
--- a/otgc/src/main/res/layout/activity_access_control.xml
+++ b/otgc/src/main/res/layout/activity_access_control.xml
@@ -21,14 +21,14 @@
~ ******************************************************************
-->
-
-
@@ -41,14 +41,14 @@
-
+
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/otgc/src/main/res/layout/activity_ace.xml b/otgc/src/main/res/layout/activity_ace.xml
index 1922eef426c57e03e529a67fb1aa57df692c72f8..9f70afde5d3faa5265cf0959161dc730ae493f12 100644
--- a/otgc/src/main/res/layout/activity_ace.xml
+++ b/otgc/src/main/res/layout/activity_ace.xml
@@ -21,14 +21,14 @@
~ ******************************************************************
-->
-
-
@@ -41,7 +41,7 @@
-
+
-
-
-
+
-
-
-
-
+
-
-
+
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/otgc/src/main/res/layout/activity_cred.xml b/otgc/src/main/res/layout/activity_cred.xml
index fbc75ff4da0721facef10108b66720718ba09cf0..860a1611140a14c957b82b37f2deb0c24fd8c308 100644
--- a/otgc/src/main/res/layout/activity_cred.xml
+++ b/otgc/src/main/res/layout/activity_cred.xml
@@ -21,14 +21,14 @@
~ ******************************************************************
-->
-
-
@@ -41,7 +41,7 @@
-
+
-
-
-
-
+
-
-
+
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/otgc/src/main/res/layout/activity_credentials.xml b/otgc/src/main/res/layout/activity_credentials.xml
index 3432ee71981c21ab5d727875794f4be8873ff6c3..78ea7be0127d22a1daa744afa3aaa36fb44e27d4 100644
--- a/otgc/src/main/res/layout/activity_credentials.xml
+++ b/otgc/src/main/res/layout/activity_credentials.xml
@@ -21,14 +21,14 @@
~ ******************************************************************
-->
-
-
@@ -41,14 +41,14 @@
-
+
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/otgc/src/main/res/layout/activity_devices.xml b/otgc/src/main/res/layout/activity_devices.xml
index 6374709020405134dd5c6bb6312221f96c6846be..0e435781969c0fcdf9508e53bd902fc1d35f0958 100644
--- a/otgc/src/main/res/layout/activity_devices.xml
+++ b/otgc/src/main/res/layout/activity_devices.xml
@@ -21,14 +21,14 @@
~ ******************************************************************
-->
-
-
@@ -41,13 +41,13 @@
-
+
-
-
+
diff --git a/otgc/src/main/res/layout/activity_generic_client.xml b/otgc/src/main/res/layout/activity_generic_client.xml
index 38c482dd9a81800df6082f07c208cc80ec1c4f74..47ed2e3fb795ccff69f51ebd2d56202575a19f7a 100644
--- a/otgc/src/main/res/layout/activity_generic_client.xml
+++ b/otgc/src/main/res/layout/activity_generic_client.xml
@@ -21,7 +21,7 @@
~ ******************************************************************
-->
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/otgc/src/main/res/layout/activity_linked_roles.xml b/otgc/src/main/res/layout/activity_linked_roles.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d16804ad9fc41d696f67d87f099a16266b9e9ed1
--- /dev/null
+++ b/otgc/src/main/res/layout/activity_linked_roles.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/otgc/src/main/res/layout/activity_login.xml b/otgc/src/main/res/layout/activity_login.xml
index 33167ae9724469098fadc77d09f840b306209f86..e365db91722c65d9aa6f96c6ed6fa5ad33834670 100644
--- a/otgc/src/main/res/layout/activity_login.xml
+++ b/otgc/src/main/res/layout/activity_login.xml
@@ -37,10 +37,10 @@
android:adjustViewBounds="true"
android:layout_marginBottom="@dimen/login_logo_margin_bottom"
android:src="@drawable/ocf_logo_horizontal" />
-
-
-
-
+
-
-
+
Wi-Fi Easy Setup ha fallado
Dispositivo configurado y conectado mediante Wi-Fi Easy Setup
+ Desconocido
+ Servidor
+ Cliente
+ Error al emparejar dispositivos
+ Emparejar
+ Por favor, selecciona al menos un recurso
+ No se puede recuperar el nombre del dispositivo de la base de datos
+ Roles vinculados
+ Error al recuperar los roles vinculados
+ Nuevo rol
+ AƱadir
+ Cancelar
+ ID de rol
+ Autoridad de rol
\ No newline at end of file
diff --git a/otgc/src/main/res/values/strings.xml b/otgc/src/main/res/values/strings.xml
index 62e94c65610f8db2738200ac559b99aff7c7611f..088bf3bfc4329f2c1ffb8dc52f734d78d171d9d1 100644
--- a/otgc/src/main/res/values/strings.xml
+++ b/otgc/src/main/res/values/strings.xml
@@ -67,10 +67,15 @@
Show log
Settings
Sign out
+ Pairwise
Unnamed
+ Unknown
+ Server
+ Client
No standard device types
Access Control
Credentials
+ Roles
Offboard
Set device name
Wi-Fi Easy Setup
@@ -88,6 +93,7 @@
Offboarding
Resetting device…
Error scanning devices
+ Error pairing devices
Ownership transfer failed
Offboard failed
Error setting RFOTM mode
@@ -120,7 +126,7 @@
All resources
Error creating ACE
Error updating ACE
- Please select at least one resource to add
+ Please, select at least one resource to add
Credentials
Install identity certificate
@@ -172,6 +178,14 @@
POST request failed
PUT request failed
+ Linked roles
+ Error retrieving linked roles
+ New role
+ Add
+ Cancel
+ Role ID
+ Role authority
+
Settings
IoTivity
@@ -187,4 +201,6 @@
Powered by:
DEKRA Testing and Certification, S.A.U.
+ IoTivity Logs
+
diff --git a/otgc/src/main/res/values/styles.xml b/otgc/src/main/res/values/styles.xml
index 3bc5e691ac3927fdce96a85b797feeaa22b28ae9..5cf24e2bbd9ac86de200366c5827c16976dd3396 100644
--- a/otgc/src/main/res/values/styles.xml
+++ b/otgc/src/main/res/values/styles.xml
@@ -33,9 +33,17 @@
- @style/AppTheme.Dialog
+
+
+ - true
+
+
+ - @color/colorAccent