From 3d2c7e95237ee6bc8308f57627fb3530f3dbaf85 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 31 Jan 2021 12:13:03 -0600 Subject: [PATCH] Add DroidGuard service API and client --- play-services-droidguard-api/build.gradle | 35 +++++++ .../src/main/AndroidManifest.xml | 7 ++ .../internal/DroidGuardInitReply.aidl | 3 + .../internal/DroidGuardResultsRequest.aidl | 3 + .../internal/IDroidGuardCallbacks.aidl | 5 + .../internal/IDroidGuardHandle.aidl | 13 +++ .../internal/IDroidGuardService.aidl | 14 +++ .../internal/DroidGuardInitReply.java | 48 ++++++++++ .../internal/DroidGuardResultsRequest.java | 93 +++++++++++++++++++ play-services-droidguard/build.gradle | 42 +++++++++ .../src/main/AndroidManifest.xml | 7 ++ .../gms/droidguard/DroidGuardApiClient.kt | 25 +++++ .../microg/gms/droidguard/DroidGuardClient.kt | 13 +++ .../gms/droidguard/DroidGuardClientImpl.kt | 33 +++++++ .../microg/gms/droidguard/DroidGuardHandle.kt | 54 +++++++++++ settings.gradle | 2 + 16 files changed, 397 insertions(+) create mode 100644 play-services-droidguard-api/build.gradle create mode 100644 play-services-droidguard-api/src/main/AndroidManifest.xml create mode 100644 play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/DroidGuardInitReply.aidl create mode 100644 play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/DroidGuardResultsRequest.aidl create mode 100644 play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardCallbacks.aidl create mode 100644 play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardHandle.aidl create mode 100644 play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardService.aidl create mode 100644 play-services-droidguard-api/src/main/java/com/google/android/gms/droidguard/internal/DroidGuardInitReply.java create mode 100644 play-services-droidguard-api/src/main/java/com/google/android/gms/droidguard/internal/DroidGuardResultsRequest.java create mode 100644 play-services-droidguard/build.gradle create mode 100644 play-services-droidguard/src/main/AndroidManifest.xml create mode 100644 play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardApiClient.kt create mode 100644 play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardClient.kt create mode 100644 play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardClientImpl.kt create mode 100644 play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardHandle.kt diff --git a/play-services-droidguard-api/build.gradle b/play-services-droidguard-api/build.gradle new file mode 100644 index 00000000..41829087 --- /dev/null +++ b/play-services-droidguard-api/build.gradle @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +apply plugin: 'com.android.library' +apply plugin: 'maven-publish' +apply plugin: 'signing' + +android { + compileSdkVersion androidCompileSdk + buildToolsVersion "$androidBuildVersionTools" + + defaultConfig { + versionName version + minSdkVersion androidMinSdk + targetSdkVersion androidTargetSdk + } + + compileOptions { + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + } +} + +apply from: '../gradle/publish-android.gradle' + +description = 'microG API for play-services-droidguard' + +dependencies { + api project(':play-services-basement') + api project(':play-services-base-api') + + implementation "androidx.annotation:annotation:$annotationVersion" +} diff --git a/play-services-droidguard-api/src/main/AndroidManifest.xml b/play-services-droidguard-api/src/main/AndroidManifest.xml new file mode 100644 index 00000000..30563293 --- /dev/null +++ b/play-services-droidguard-api/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/DroidGuardInitReply.aidl b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/DroidGuardInitReply.aidl new file mode 100644 index 00000000..48cd159f --- /dev/null +++ b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/DroidGuardInitReply.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.droidguard.internal; + +parcelable DroidGuardInitReply; diff --git a/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/DroidGuardResultsRequest.aidl b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/DroidGuardResultsRequest.aidl new file mode 100644 index 00000000..9fff3a8d --- /dev/null +++ b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/DroidGuardResultsRequest.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.droidguard.internal; + +parcelable DroidGuardResultsRequest; diff --git a/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardCallbacks.aidl b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardCallbacks.aidl new file mode 100644 index 00000000..7e4aa680 --- /dev/null +++ b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardCallbacks.aidl @@ -0,0 +1,5 @@ +package com.google.android.gms.droidguard.internal; + +interface IDroidGuardCallbacks { + void onResult(in byte[] res); +} diff --git a/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardHandle.aidl b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardHandle.aidl new file mode 100644 index 00000000..649f2fd8 --- /dev/null +++ b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardHandle.aidl @@ -0,0 +1,13 @@ +package com.google.android.gms.droidguard.internal; + +import com.google.android.gms.droidguard.internal.DroidGuardInitReply; +import com.google.android.gms.droidguard.internal.DroidGuardResultsRequest; + +interface IDroidGuardHandle { + void init(String flow) = 0; + DroidGuardInitReply initWithRequest(String flow, in DroidGuardResultsRequest request) = 4; + + byte[] guard(in Map map) = 1; + + void close() = 2; +} diff --git a/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardService.aidl b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardService.aidl new file mode 100644 index 00000000..2e604453 --- /dev/null +++ b/play-services-droidguard-api/src/main/aidl/com/google/android/gms/droidguard/internal/IDroidGuardService.aidl @@ -0,0 +1,14 @@ +package com.google.android.gms.droidguard.internal; + +import com.google.android.gms.droidguard.internal.IDroidGuardCallbacks; +import com.google.android.gms.droidguard.internal.IDroidGuardHandle; +import com.google.android.gms.droidguard.internal.DroidGuardResultsRequest; + +interface IDroidGuardService { + void guard(IDroidGuardCallbacks callbacks, String flow, in Map map) = 0; + void guardWithRequest(IDroidGuardCallbacks callbacks, String flow, in Map map, in DroidGuardResultsRequest request) = 3; + + IDroidGuardHandle getHandle() = 1; + + int getClientTimeoutMillis() = 2; +} diff --git a/play-services-droidguard-api/src/main/java/com/google/android/gms/droidguard/internal/DroidGuardInitReply.java b/play-services-droidguard-api/src/main/java/com/google/android/gms/droidguard/internal/DroidGuardInitReply.java new file mode 100644 index 00000000..02b93b0d --- /dev/null +++ b/play-services-droidguard-api/src/main/java/com/google/android/gms/droidguard/internal/DroidGuardInitReply.java @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.droidguard.internal; + +import android.os.Parcel; +import android.os.ParcelFileDescriptor; +import android.os.Parcelable; + +public class DroidGuardInitReply implements Parcelable { + public ParcelFileDescriptor pfd; + public Parcelable object; + + public DroidGuardInitReply(ParcelFileDescriptor pfd, Parcelable object) { + this.pfd = pfd; + this.object = object; + } + + @Override + public int describeContents() { + return (pfd != null ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0) | (object != null ? object.describeContents() : 0); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(pfd, flags); + dest.writeParcelable(object, flags); + } + + public final static Creator CREATOR = new Creator() { + @Override + public DroidGuardInitReply createFromParcel(Parcel source) { + ParcelFileDescriptor pfd = source.readParcelable(ParcelFileDescriptor.class.getClassLoader()); + Parcelable object = source.readParcelable(getClass().getClassLoader()); + if (pfd != null && object != null) { + return new DroidGuardInitReply(pfd, object); + } + return null; + } + + @Override + public DroidGuardInitReply[] newArray(int size) { + return new DroidGuardInitReply[size]; + } + }; +} diff --git a/play-services-droidguard-api/src/main/java/com/google/android/gms/droidguard/internal/DroidGuardResultsRequest.java b/play-services-droidguard-api/src/main/java/com/google/android/gms/droidguard/internal/DroidGuardResultsRequest.java new file mode 100644 index 00000000..162a6bfc --- /dev/null +++ b/play-services-droidguard-api/src/main/java/com/google/android/gms/droidguard/internal/DroidGuardResultsRequest.java @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.droidguard.internal; + +import android.net.Network; +import android.os.Build; +import android.os.Bundle; +import android.os.ParcelFileDescriptor; + +import androidx.annotation.RequiresApi; + +import org.microg.gms.common.Constants; +import org.microg.safeparcel.AutoSafeParcelable; + +public class DroidGuardResultsRequest extends AutoSafeParcelable { + private static final String KEY_APP_ARCHITECTURE = "appArchitecture"; + private static final String KEY_CLIENT_VERSION = "clientVersion"; + private static final String KEY_FD = "fd"; + private static final String KEY_NETWORK_TO_USE = "networkToUse"; + private static final String KEY_TIMEOUT_MS = "timeoutMs"; + public static final String KEY_OPEN_HANDLES = "openHandles"; + + @Field(2) + public Bundle bundle; + + public DroidGuardResultsRequest() { + bundle = new Bundle(); + String arch; + try { + arch = System.getProperty("os.arch"); + } catch (Exception ignored) { + arch = "?"; + } + bundle.putString(KEY_APP_ARCHITECTURE, arch); + setClientVersion(Constants.GMS_VERSION_CODE); + } + + public String getAppArchitecture() { + return bundle.getString(KEY_APP_ARCHITECTURE); + } + + public int getTimeoutMillis() { + return bundle.getInt(KEY_TIMEOUT_MS, 60000); + } + + public DroidGuardResultsRequest setTimeoutMillis(int millis) { + bundle.putInt(KEY_TIMEOUT_MS, millis); + return this; + } + + public int getClientVersion() { + return bundle.getInt(KEY_CLIENT_VERSION); + } + + public DroidGuardResultsRequest setClientVersion(int clientVersion) { + bundle.putInt(KEY_CLIENT_VERSION, clientVersion); + return this; + } + + public ParcelFileDescriptor getFd() { + return bundle.getParcelable(KEY_FD); + } + + public DroidGuardResultsRequest setFd(ParcelFileDescriptor fd) { + bundle.putParcelable(KEY_FD, fd); + return this; + } + + public int getOpenHandles() { + return bundle.getInt(KEY_OPEN_HANDLES); + } + + public DroidGuardResultsRequest setOpenHandles(int openHandles) { + bundle.putInt(KEY_OPEN_HANDLES, openHandles); + return this; + } + + @RequiresApi(api = 21) + public Network getNetworkToUse() { + return bundle.getParcelable(KEY_NETWORK_TO_USE); + } + + @RequiresApi(api = 21) + public DroidGuardResultsRequest setNetworkToUse(Network networkToUse) { + bundle.putParcelable(KEY_NETWORK_TO_USE, networkToUse); + return this; + } + + public static final Creator CREATOR = new AutoCreator<>(DroidGuardResultsRequest.class); +} diff --git a/play-services-droidguard/build.gradle b/play-services-droidguard/build.gradle new file mode 100644 index 00000000..a473f2d5 --- /dev/null +++ b/play-services-droidguard/build.gradle @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'maven-publish' +apply plugin: 'signing' + +android { + compileSdkVersion androidCompileSdk + buildToolsVersion "$androidBuildVersionTools" + + defaultConfig { + versionName version + minSdkVersion androidMinSdk + targetSdkVersion androidTargetSdk + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + compileOptions { + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + } +} + +apply from: '../gradle/publish-android.gradle' + +description = 'microG implementation of play-services-droidguard' + +dependencies { + api project(':play-services-base') + api project(':play-services-droidguard-api') + + implementation "androidx.annotation:annotation:$annotationVersion" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" +} diff --git a/play-services-droidguard/src/main/AndroidManifest.xml b/play-services-droidguard/src/main/AndroidManifest.xml new file mode 100644 index 00000000..4d4b7873 --- /dev/null +++ b/play-services-droidguard/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardApiClient.kt b/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardApiClient.kt new file mode 100644 index 00000000..a9aa7a85 --- /dev/null +++ b/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardApiClient.kt @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.droidguard + +import android.content.Context +import android.os.IBinder +import com.google.android.gms.droidguard.internal.IDroidGuardHandle +import com.google.android.gms.droidguard.internal.IDroidGuardService +import org.microg.gms.common.GmsClient +import org.microg.gms.common.GmsService +import org.microg.gms.common.api.ConnectionCallbacks +import org.microg.gms.common.api.OnConnectionFailedListener + +class DroidGuardApiClient(context: Context, connectionCallbacks: ConnectionCallbacks, onConnectionFailedListener: OnConnectionFailedListener) : GmsClient(context, connectionCallbacks, onConnectionFailedListener, GmsService.DROIDGUARD.ACTION) { + init { + serviceId = GmsService.DROIDGUARD.SERVICE_ID + } + + override fun interfaceFromBinder(binder: IBinder): IDroidGuardService = IDroidGuardService.Stub.asInterface(binder) + + fun getHandle() = serviceInterface.handle +} diff --git a/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardClient.kt b/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardClient.kt new file mode 100644 index 00000000..adcaa45b --- /dev/null +++ b/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardClient.kt @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.droidguard + +import com.google.android.gms.droidguard.internal.IDroidGuardHandle +import com.google.android.gms.tasks.Task + +interface DroidGuardClient { + fun getHandle(): Task +} diff --git a/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardClientImpl.kt b/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardClientImpl.kt new file mode 100644 index 00000000..49f3fc63 --- /dev/null +++ b/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardClientImpl.kt @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.droidguard + +import android.content.Context +import android.os.Looper +import com.google.android.gms.common.api.Api +import com.google.android.gms.common.api.Api.ApiOptions.NoOptions +import com.google.android.gms.common.api.GoogleApi +import com.google.android.gms.tasks.Task +import org.microg.gms.common.api.ApiClientBuilder +import org.microg.gms.common.api.ApiClientSettings +import org.microg.gms.common.api.ConnectionCallbacks +import org.microg.gms.common.api.OnConnectionFailedListener + +class DroidGuardClientImpl(context: Context) : GoogleApi(context, API), DroidGuardClient { + companion object { + private val API = Api(ApiClientBuilder { _: NoOptions?, context: Context, _: Looper?, _: ApiClientSettings?, callbacks: ConnectionCallbacks, connectionFailedListener: OnConnectionFailedListener -> DroidGuardApiClient(context, callbacks, connectionFailedListener) }) + } + + override fun getHandle(): Task { + return scheduleTask { client: DroidGuardApiClient, completionSource -> + try { + completionSource.setResult(DroidGuardHandle(client.getHandle())) + } catch (e: Exception) { + completionSource.setException(e) + } + } + } +} diff --git a/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardHandle.kt b/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardHandle.kt new file mode 100644 index 00000000..07e4fd39 --- /dev/null +++ b/play-services-droidguard/src/main/kotlin/org/microg/gms/droidguard/DroidGuardHandle.kt @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.droidguard + +import com.google.android.gms.droidguard.internal.DroidGuardResultsRequest +import com.google.android.gms.droidguard.internal.IDroidGuardHandle + +class DroidGuardHandle(private val handle: IDroidGuardHandle) { + private var state = 0 + + fun init(flow: String) { + if (state != 0) throw IllegalStateException("init() already called") + try { + handle.initWithRequest(flow, DroidGuardResultsRequest().setOpenHandles(openHandles++)) + state = 1 + } catch (e: Exception) { + state = -1 + throw e + } + } + + fun guard(map: Map): ByteArray { + if (state != 1) throw IllegalStateException("init() must be called before guard()") + try { + return handle.guard(map) + } catch (e: Exception) { + state = -1 + throw e + } + } + + fun close() { + if (state != 1) throw IllegalStateException("init() must be called before close()") + try { + handle.close() + openHandles-- + state = 2 + } catch (e: Exception) { + state = -1 + throw e + } + } + + fun finalize() { + if (state == 1) close() + } + + companion object { + private var openHandles = 0 + } +} diff --git a/settings.gradle b/settings.gradle index 1ed21081..cdbee860 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,6 +6,7 @@ include ':play-services-appinvite-api' include ':play-services-base-api' include ':play-services-cast-api' include ':play-services-cast-framework-api' +include ':play-services-droidguard-api' include ':play-services-iid-api' include ':play-services-location-api' include ':play-services-nearby-api' @@ -41,6 +42,7 @@ include ':play-services-core' include ':play-services-base' include ':play-services-cast' +include ':play-services-droidguard' include ':play-services-gcm' include ':play-services-iid' include ':play-services-location'