diff --git a/build.gradle b/build.gradle index 2bb829fce8..3c4c176b44 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.google.gms:google-services:4.3.0' classpath 'io.fabric.tools:gradle:1.31.0' + classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.8" } } diff --git a/dependencies.gradle b/dependencies.gradle index cb15d49bfb..9e20d378c8 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -54,6 +54,10 @@ ext { crashlytics_version = '2.10.1' firebase_core_version = '17.0.1' + // Protobuf + + protobuf_java_version = '3.9.2' + protoc_version = '3.9.0' mainApplication = [ kotlin: "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version", @@ -113,4 +117,9 @@ ext { leakCanary: "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}", leakCanaryNoop: "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}", ] + + protobuf = [ + protobufJava: "com.google.protobuf:protobuf-java:$protobuf_java_version", + protoc: "com.google.protobuf:protoc:$protoc_version" + ] } \ No newline at end of file diff --git a/lib-middleware/build.gradle b/lib-middleware/build.gradle new file mode 100644 index 0000000000..89d4171d41 --- /dev/null +++ b/lib-middleware/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('lib.aar')) \ No newline at end of file diff --git a/lib-middleware/lib.aar b/lib-middleware/lib.aar new file mode 100644 index 0000000000..ad631b6e70 Binary files /dev/null and b/lib-middleware/lib.aar differ diff --git a/middleware/.gitignore b/middleware/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/middleware/.gitignore @@ -0,0 +1 @@ +/build diff --git a/middleware/build.gradle b/middleware/build.gradle new file mode 100644 index 0000000000..b000d2321c --- /dev/null +++ b/middleware/build.gradle @@ -0,0 +1,39 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' + +android { + def config = rootProject.extensions.getByName("ext") + + compileSdkVersion config["compile_sdk"] + + defaultConfig { + minSdkVersion config["min_sdk"] + targetSdkVersion config["target_sdk"] + testInstrumentationRunner config["test_runner"] + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + implementation project(':lib-middleware') + implementation project(':protobuf') + + def applicationDependencies = rootProject.ext.mainApplication + def unitTestDependencies = rootProject.ext.unitTesting + + implementation applicationDependencies.kotlin + implementation applicationDependencies.timber + + testImplementation unitTestDependencies.junit + testImplementation unitTestDependencies.kotlinTest + testImplementation unitTestDependencies.mockito +} \ No newline at end of file diff --git a/middleware/proguard-rules.pro b/middleware/proguard-rules.pro new file mode 100644 index 0000000000..f1b424510d --- /dev/null +++ b/middleware/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/middleware/src/main/AndroidManifest.xml b/middleware/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..06e42a2f0e --- /dev/null +++ b/middleware/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/middleware/src/main/res/values/strings.xml b/middleware/src/main/res/values/strings.xml new file mode 100644 index 0000000000..ee878c5487 --- /dev/null +++ b/middleware/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Middleware + diff --git a/protobuf/.gitignore b/protobuf/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/protobuf/.gitignore @@ -0,0 +1 @@ +/build diff --git a/protobuf/build.gradle b/protobuf/build.gradle new file mode 100644 index 0000000000..49a9449a07 --- /dev/null +++ b/protobuf/build.gradle @@ -0,0 +1,17 @@ +apply plugin: 'java-library' +apply plugin: 'com.google.protobuf' + +sourceSets{ + main.java.srcDirs += "${protobuf.generatedFilesBaseDir}/main/java" +} + +dependencies { + def protobufDependencies = rootProject.ext.protobuf + implementation protobufDependencies.protobufJava +} + +protobuf { + protoc { + artifact = rootProject.ext.protobuf.protoc + } +} \ No newline at end of file diff --git a/protobuf/src/main/proto/commands.proto b/protobuf/src/main/proto/commands.proto new file mode 100644 index 0000000000..49e8be694d --- /dev/null +++ b/protobuf/src/main/proto/commands.proto @@ -0,0 +1,240 @@ +syntax = "proto3"; +package anytype; +option go_package = "pb"; + +import "models.proto"; + +service ClientCommands { + rpc WalletCreate (WalletCreateRequest) returns (WalletCreateResponse); + rpc WalletRecover (WalletRecoverRequest) returns (WalletRecoverResponse); + rpc AccountCreate (AccountCreateRequest) returns (AccountCreateResponse); + rpc AccountSelect (AccountSelectRequest) returns (AccountSelectResponse); + rpc ImageGetBlob (ImageGetBlobRequest) returns (ImageGetBlobResponse); +} + +message WalletCreateRequest { + string rootPath = 1; +} + +message WalletCreateResponse { + Error error = 1; + string mnemonic = 2; + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + + FAILED_TO_CREATE_LOCAL_REPO = 101; + // ... + } + } +} + +message WalletRecoverRequest { + string rootPath = 1; + string mnemonic = 2; +} + +message WalletRecoverResponse { + Error error = 1; + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + + FAILED_TO_CREATE_LOCAL_REPO = 101; + } + } +} + +message AccountCreateRequest { + string username = 1; + string avatarLocalPath = 2; +} + +message AccountCreateResponse { + Error error = 1; + Account account = 2; + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + + ACCOUNT_CREATED_BUT_FAILED_TO_START_NODE = 101; + ACCOUNT_CREATED_BUT_FAILED_TO_SET_NAME = 102; + ACCOUNT_CREATED_BUT_FAILED_TO_SET_AVATAR = 103; + } + } +} + +// Start accounts search for recovered mnemonic +message AccountRecoverRequest { +} + +// Found accounts will come in event AccountAdd +message AccountRecoverResponse { + Error error = 1; + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + // ... + NO_ACCOUNTS_FOUND = 101; + NEED_TO_RECOVER_WALLET_FIRST = 102; + FAILED_TO_CREATE_LOCAL_REPO = 103; + LOCAL_REPO_EXISTS_BUT_CORRUPTED = 104; + FAILED_TO_RUN_NODE = 105; + } + } +} + +message AccountSelectRequest { + string id = 1; + // optional, set if this is the first request + string rootPath = 2; +} + +message AccountSelectResponse { + Error error = 1; + Account account = 2; + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + // ... + + FAILED_TO_CREATE_LOCAL_REPO = 101; + LOCAL_REPO_EXISTS_BUT_CORRUPTED = 102; + FAILED_TO_RUN_NODE = 103; + FAILED_TO_FIND_ACCOUNT_INFO = 104; + LOCAL_REPO_NOT_EXISTS_AND_MNEMONIC_NOT_SET = 105; + + } + } +} + +message AccountStartRequest { + string id = 1; +} + +message AccountStartResponse { + Error error = 1; + Account account = 2; + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + // ... + + LOCAL_REPO_DOESNT_EXIST = 101; + LOCAL_REPO_EXISTS_BUT_CORRUPTED = 102; + FAILED_TO_RUN_NODE = 103; + FAILED_TO_FIND_ACCOUNT_INFO = 104; + } + } +} + +message IpfsGetFileRequest { + string id = 1; +} + +message IpfsGetFileResponse { + Error error = 1; + bytes data = 2; + string media = 3; + string name = 4; + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + // ... + + NOT_FOUND = 101; + TIMOUT = 102; + } + } +} + +message IpfsGetDataRequest { + string id = 1; +} + +message IpfsGetDataResponse { + Error error = 1; + oneof data { + bytes content = 2; + IpfsLinks links = 3; + } + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + // ... + + NOT_FOUND = 101; + TIMOUT = 102; + } + } +} + +message ImageGetBlobRequest { + string id = 1; + ImageSize size = 2; +} + +message ImageGetBlobResponse { + Error error = 1; + bytes blob = 2; + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + // ... + + NOT_FOUND = 101; + TIMOUT = 102; + } + } +} diff --git a/protobuf/src/main/proto/events.proto b/protobuf/src/main/proto/events.proto new file mode 100644 index 0000000000..cee43d1938 --- /dev/null +++ b/protobuf/src/main/proto/events.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +package anytype; +option go_package = "pb"; + +import "models.proto"; + +// -------- Middle +message Event { + oneof message { + AccountAdd accountAdd = 1; + BlockCreate blockCreate = 102; + BlockUpdate blockUpdate = 103; + BlockRemove blockRemove = 104; + } +} + +message AccountAdd { + int64 index = 1; + Account account = 2; +} + +message BlockCreate { + string id = 1; + string docId = 2; + uint32 pos = 3; +} + +message BlockUpdate { + string id = 1; + string docId = 2; + // ... update info +} + +message BlockRemove { + string id = 1; + string docId = 2; +} diff --git a/protobuf/src/main/proto/models.proto b/protobuf/src/main/proto/models.proto new file mode 100644 index 0000000000..297b82be5a --- /dev/null +++ b/protobuf/src/main/proto/models.proto @@ -0,0 +1,113 @@ +syntax = "proto3"; +package anytype; +option go_package = "pb"; + +message Account { + string id = 1; + string name = 2; + Image avatar = 3; +} + +message IpfsLink { + string cid = 1; + string name = 2; + uint64 size = 3; +} + +enum ImageSize { + LARGE = 0; + SMALL = 1; + THUMB = 2; +} + +message Image { + string id = 1; + repeated ImageSize sizes = 2; +} + +message IpfsLinks { + repeated IpfsLink links = 1; +} + +message Accounts { + repeated Account accounts = 1; +} + +message State { + repeated DocumentHeader documentHeaders = 1; + string currentDocumentId = 2; +} + +message DocumentHeader { + string id = 1; + string name = 2; + string version = 3; + string icon = 4; +} + +message Document { + DocumentHeader header = 1; + repeated Block blocks = 2; +} + +message Text { + string content = 1; + repeated Mark marks = 2; + ContentType contentType = 3; +} + +message Mark { + MarkType type = 1; +} + +message Block { + string id = 1; + oneof content { + Text text = 11; + // ... + } +} + +enum StatusType { + SUCCESS = 0; + FAILURE = 1; + WRONG_MNEMONIC = 2; + NOT_FOUND = 3; + // ... +} + +enum MarkType { + B = 0; + I = 1; + S = 2; + KBD = 3; + A = 4; +} + +enum ContentType { + P = 0; + CODE = 1; + H_1 = 2; + H_2 = 3; + H_3 = 4; + H_4 = 5; + OL = 6; + UL = 7; + QUOTE = 8; + TOGGLE = 9; + CHECK = 10; +} + +enum BlockType { + H_GRID = 0; + V_GRID = 1; + EDITABLE = 2; + DIV = 3; + VIDEO = 4; + IMAGE = 5; + PAGE = 6; + NEW_PAGE = 7; + BOOK_MARK = 8; + FILE = 9; + DATA_VIEW = 10; +} diff --git a/settings.gradle b/settings.gradle index b5c816652e..f8fc4f7d34 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':core_utils', ':feature_editor', ':feature_desktop', ':feature_login' +include ':app', ':core_utils', ':feature_editor', ':feature_desktop', ':feature_login', ':lib-middleware', ':middleware', ':protobuf'