diff --git a/play-services-basement/src/main/kotlin/com/google/android/gms/dynamic/ObjectWrapper.kt b/play-services-basement/src/main/kotlin/com/google/android/gms/dynamic/ObjectWrapper.kt index 06c131abef..b86ff01f57 100644 --- a/play-services-basement/src/main/kotlin/com/google/android/gms/dynamic/ObjectWrapper.kt +++ b/play-services-basement/src/main/kotlin/com/google/android/gms/dynamic/ObjectWrapper.kt @@ -14,9 +14,6 @@ * limitations under the License. */ -package org.microg.gms.kotlin - -import com.google.android.gms.dynamic.IObjectWrapper -import com.google.android.gms.dynamic.ObjectWrapper +package com.google.android.gms.dynamic inline fun IObjectWrapper?.unwrap(): T? = ObjectWrapper.unwrapTyped(this, T::class.java) diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index 0f3758b82f..4bc46c381d 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -45,6 +45,7 @@ dependencies { implementation project(':play-services-base-core-ui') implementation project(':play-services-conscrypt-provider-core') implementation project(':play-services-location-core') + implementation project(':play-services-vision-core') withNearbyImplementation project(':play-services-nearby-core') withNearbyImplementation project(':play-services-nearby-core-ui') implementation project(':play-services-core-proto') diff --git a/play-services-core/src/main/java/com/google/android/gms/chimera/container/DynamiteLoaderImpl.java b/play-services-core/src/main/java/com/google/android/gms/chimera/container/DynamiteLoaderImpl.java index fffca37f60..d4a272af2c 100644 --- a/play-services-core/src/main/java/com/google/android/gms/chimera/container/DynamiteLoaderImpl.java +++ b/play-services-core/src/main/java/com/google/android/gms/chimera/container/DynamiteLoaderImpl.java @@ -28,12 +28,14 @@ import org.microg.gms.common.Constants; +import java.lang.reflect.Field; + public class DynamiteLoaderImpl extends IDynamiteLoader.Stub { private static final String TAG = "GmsDynamiteLoaderImpl"; @Override public IObjectWrapper createModuleContext(IObjectWrapper wrappedContext, String moduleId, int minVersion) throws RemoteException { - Log.d(TAG, "unimplemented Method: createModuleContext for " + moduleId + " at version " + minVersion + ", returning gms context"); + Log.d(TAG, "createModuleContext for " + moduleId + " at version " + minVersion); final Context context = (Context) ObjectWrapper.unwrap(wrappedContext); try { return ObjectWrapper.wrap(new ContextWrapper(context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY)) { @@ -55,6 +57,12 @@ public int getModuleVersion(IObjectWrapper context, String moduleId) throws Remo @Override public int getModuleVersion2(IObjectWrapper context, String moduleId, boolean updateConfigIfRequired) throws RemoteException { + try { + return Class.forName("com.google.android.gms.dynamite.descriptors." + moduleId + ".ModuleDescriptor").getDeclaredField("MODULE_VERSION").getInt(null); + } catch (Exception e) { + Log.w(TAG, "No such module known: " + moduleId); + } + if (moduleId.equals("com.google.android.gms.firebase_database")) { Log.d(TAG, "returning temp fix module version for " + moduleId + ". Firebase Database will not be functional!"); return com.google.android.gms.dynamite.descriptors.com.google.android.gms.firebase_database.ModuleDescriptor.MODULE_VERSION; diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 3f6756db83..5af3e40fba 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -50,7 +50,7 @@ import com.mapbox.mapboxsdk.maps.Style import com.mapbox.mapboxsdk.plugins.annotation.* import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND -import org.microg.gms.kotlin.unwrap +import com.google.android.gms.dynamic.unwrap import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MapContext diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt index c36e57ed34..ab22186dc5 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt @@ -25,7 +25,7 @@ import com.google.android.gms.maps.internal.IProjectionDelegate import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.VisibleRegion import com.mapbox.mapboxsdk.maps.Projection -import org.microg.gms.kotlin.unwrap +import com.google.android.gms.dynamic.unwrap import org.microg.gms.maps.mapbox.utils.toGms import org.microg.gms.maps.mapbox.utils.toMapbox import kotlin.math.roundToInt @@ -77,4 +77,4 @@ class ProjectionImpl(private val projection: Projection, private val withoutTilt companion object { private val TAG = "GmsMapProjection" } -} \ No newline at end of file +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt index 5d298d8faa..06da365780 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt @@ -26,7 +26,7 @@ import com.google.android.gms.maps.model.internal.IMarkerDelegate import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager import com.mapbox.mapboxsdk.plugins.annotation.Symbol import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions -import org.microg.gms.kotlin.unwrap +import com.google.android.gms.dynamic.unwrap import org.microg.gms.maps.mapbox.GoogleMapImpl import org.microg.gms.maps.mapbox.utils.toMapbox diff --git a/play-services-vision-api/build.gradle b/play-services-vision-api/build.gradle new file mode 100644 index 0000000000..820e8ef116 --- /dev/null +++ b/play-services-vision-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-vision' + +dependencies { + api project(':play-services-basement') + api project(':play-services-base-api') + + implementation "androidx.annotation:annotation:$annotationVersion" +} diff --git a/play-services-vision-api/src/main/AndroidManifest.xml b/play-services-vision-api/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..e678c13bb0 --- /dev/null +++ b/play-services-vision-api/src/main/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + diff --git a/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/Barcode.aidl b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/Barcode.aidl new file mode 100644 index 0000000000..b9dd77cd19 --- /dev/null +++ b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/Barcode.aidl @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.barcode; + +parcelable Barcode; diff --git a/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/BarcodeDetectorOptions.aidl b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/BarcodeDetectorOptions.aidl new file mode 100644 index 0000000000..f42791da3b --- /dev/null +++ b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/BarcodeDetectorOptions.aidl @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.barcode.internal.client; + +parcelable BarcodeDetectorOptions; diff --git a/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/INativeBarcodeDetector.aidl b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/INativeBarcodeDetector.aidl new file mode 100644 index 0000000000..86b2d15ea1 --- /dev/null +++ b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/INativeBarcodeDetector.aidl @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.barcode.internal.client; + +import com.google.android.gms.vision.barcode.Barcode; +import com.google.android.gms.vision.barcode.internal.client.BarcodeDetectorOptions; +import com.google.android.gms.vision.internal.FrameMetadataParcel; +import com.google.android.gms.dynamic.IObjectWrapper; + +interface INativeBarcodeDetector { + Barcode[] detectBytes(IObjectWrapper byteBuffer, in FrameMetadataParcel metadata) = 0; + Barcode[] detectBitmap(IObjectWrapper bitmap, in FrameMetadataParcel metadata) = 1; + void close() = 2; +} diff --git a/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/INativeBarcodeDetectorCreator.aidl b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/INativeBarcodeDetectorCreator.aidl new file mode 100644 index 0000000000..b5e2495d7b --- /dev/null +++ b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/barcode/internal/client/INativeBarcodeDetectorCreator.aidl @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.barcode.internal.client; + +import com.google.android.gms.vision.barcode.internal.client.BarcodeDetectorOptions; +import com.google.android.gms.vision.barcode.internal.client.INativeBarcodeDetector; +import com.google.android.gms.dynamic.IObjectWrapper; + +interface INativeBarcodeDetectorCreator { + INativeBarcodeDetector create(IObjectWrapper context, in BarcodeDetectorOptions options) = 0; +} diff --git a/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/internal/FrameMetadataParcel.aidl b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/internal/FrameMetadataParcel.aidl new file mode 100644 index 0000000000..c6ccd58c46 --- /dev/null +++ b/play-services-vision-api/src/main/aidl/com/google/android/gms/vision/internal/FrameMetadataParcel.aidl @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.internal; + +parcelable FrameMetadataParcel; diff --git a/play-services-vision-api/src/main/java/com/google/android/gms/vision/barcode/Barcode.java b/play-services-vision-api/src/main/java/com/google/android/gms/vision/barcode/Barcode.java new file mode 100644 index 0000000000..0a4364d028 --- /dev/null +++ b/play-services-vision-api/src/main/java/com/google/android/gms/vision/barcode/Barcode.java @@ -0,0 +1,593 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + * Notice: Portions of this file are reproduced from work created and shared by Google and used + * according to terms described in the Creative Commons 4.0 Attribution License. + * See https://developers.google.com/readme/policies for details. + */ + +package com.google.android.gms.vision.barcode; + +import android.graphics.Point; +import android.graphics.Rect; + +import androidx.annotation.Nullable; + +import org.microg.gms.common.PublicApi; +import org.microg.safeparcel.AutoSafeParcelable; + +/** + * Barcode represents a single recognized barcode and its value. + *

+ * The barcode's raw, unmodified, and uninterpreted content is returned in the {@link #rawValue} field, while the barcode type (i.e. its encoding) can be found in the {@link #format} field. + *

+ * Barcodes that contain structured data (commonly done with QR codes) are parsed and iff valid, the {@link #valueFormat} field is set to one of the value format constants (e.g. {@link #GEO}) and the corresponding field is set (e.g. {@link #geoPoint}). + */ +@PublicApi +public class Barcode extends AutoSafeParcelable { + /** + * Barcode value format constant for contact information. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int CONTACT_INFO = 1; + /** + * Barcode value format constant for email message details. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int EMAIL = 2; + /** + * Barcode value format constant for ISBNs. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int ISBN = 3; + /** + * Barcode value format constant for phone numbers. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int PHONE = 4; + /** + * Barcode value format constant for product codes. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int PRODUCT = 5; + /** + * Barcode value format constant for SMS details. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int SMS = 6; + /** + * Barcode value format constant for plain text. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int TEXT = 7; + /** + * Barcode value format constant for URLs/bookmarks. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int URL = 8; + /** + * Barcode value format constant for WiFi access point details. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int WIFI = 9; + /** + * Barcode value format constant for geographic coordinates. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int GEO = 10; + /** + * Barcode value format constant for calendar events. + * Specifies the format of a Barcode value via the {@link #valueFormat} field. + */ + public static final int CALENDAR_EVENT = 11; + public static final int DRIVER_LICENSE = 12; + + /** + * Barcode format constant representing the union of all supported formats. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize. + * This is also the default setting. + */ + public static final int ALL_FORMATS = 0; + /** + * Barcode format constant for Code 128. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int CODE_128 = 1; + /** + * Barcode format constant for Code 39. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int CODE_39 = 2; + /** + * Barcode format constant for Code 93. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int CODE_93 = 4; + /** + * Barcode format constant for Codebar. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int CODABAR = 8; + /** + * Barcode format constant for Data Matrix. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int DATA_MATRIX = 16; + /** + * Barcode format constant for EAN-13. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int EAN_13 = 32; + /** + * Barcode format constant for EAN-8. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int EAN_8 = 64; + /** + * Barcode format constant for ITF (Interleaved Two-of-Five). + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int ITF = 128; + /** + * Barcode format constant for QR Code. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int QR_CODE = 256; + /** + * Barcode format constant for UPC-A. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int UPC_A = 512; + /** + * Barcode format constant for UPC-E. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int UPC_E = 1024; + /** + * Barcode format constant for PDF-417. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int PDF417 = 2048; + /** + * Barcode format constant for AZTEC. + * Pass into {@link BarcodeDetector.Builder#setBarcodeFormats(int)} to select formats to recognize, + * and also specifies a detected Barcode's {@link #format} via the format field. + */ + public static final int AZTEC = 4096; + + @Field(1) + private final int versionCode = 1; + /** + * Barcode format, for example {@link #EAN_13}. + *

+ * Note that this field may contain values not present in the current set of format constants. + * When mapping this value to something else, it is advisable to have a default/fallback case. + */ + @Field(2) + public int format; + /** + * Barcode value as it was encoded in the barcode. Structured values are not parsed, for example: 'MEBKM:TITLE:Google;URL://www.google.com;;' Does not include the supplement value. + */ + @Field(3) + public String rawValue; + /** + * Barcode value in a user-friendly format. + * May omit some of the information encoded in the barcode. + * For example, in the case above the display_value might be '//www.google.com'. + * If {@link #valueFormat}=={@link #TEXT}, this field will be equal to {@link #rawValue}. + * This value may be multiline, for example, when line breaks are encoded into the original {@link #TEXT} barcode value. + * May include the supplement value. + */ + @Field(4) + public String displayValue; + /** + * Format of the barcode value. For example, {@link #TEXT}, {@link #PRODUCT}, {@link #URL}, etc. + *

+ * Note that this field may contain values not present in the current set of value format constants. + * When mapping this value to something else, it is advisable to have a default/fallback case. + */ + @Field(5) + public int valueFormat; + /** + * 4 corner points in clockwise direction starting with top-left. + * Due to the possible perspective distortions, this is not necessarily a rectangle. + */ + @Field(6) + public Point[] cornerPoints; + /** + * Parsed email details (set iff {@link #valueFormat} is {@link #EMAIL}). + */ + @Nullable + @Field(7) + public Barcode.Email email; + /** + * Parsed phone details (set iff {@link #valueFormat} is {@link #PHONE}). + */ + @Nullable + @Field(8) + public Barcode.Phone phone; + /** + * Parsed SMS details (set iff {@link #valueFormat} is {@link #SMS}). + */ + @Nullable + @Field(9) + public Barcode.Sms sms; + /** + * Parsed WiFi AP details (set iff {@link #valueFormat} is {@link #WIFI}). + */ + @Nullable + @Field(10) + public Barcode.WiFi wifi; + /** + * Parsed URL bookmark details (set iff {@link #valueFormat} is {@link #URL}). + */ + @Nullable + @Field(11) + public Barcode.UrlBookmark url; + /** + * Parsed geo coordinates (set iff {@link #valueFormat} is {@link #GEO}). + */ + @Nullable + @Field(12) + public Barcode.GeoPoint geoPoint; + /** + * Parsed calendar event details (set iff {@link #valueFormat} is {@link #CALENDAR_EVENT}). + */ + @Nullable + @Field(13) + public Barcode.CalendarEvent calendarEvent; + /** + * Parsed contact details (set iff {@link #valueFormat} is {@link #CONTACT_INFO}). + */ + @Nullable + @Field(14) + public Barcode.ContactInfo contactInfo; + /** + * Parsed driver's license details (set iff {@link #valueFormat} is {@link #DRIVER_LICENSE}). + */ + @Nullable + @Field(15) + public Barcode.DriverLicense driverLicense; + /** + * Barcode value as it was encoded in the barcode as byte array. + */ + @Field(16) + public byte[] rawBytes; + /** + * If outputUnrecognizedBarcodes is set, isRecognized can be set to false to indicate failure in decoding the detected barcode. + */ + @Field(17) + public boolean isRecognized; + + /** + * Returns the barcode's axis-aligned bounding box. + */ + public Rect getBoundingBox() { + int left = Integer.MAX_VALUE, top = Integer.MIN_VALUE, right = Integer.MIN_VALUE, bottom = Integer.MAX_VALUE; + for (Point point : cornerPoints) { + left = Math.min(left, point.x); + top = Math.max(top, point.y); + right = Math.max(right, point.x); + bottom = Math.min(bottom, point.y); + } + return new Rect(left, top, right, bottom); + } + + /** + * An address. + */ + public static class Address extends AutoSafeParcelable { + /** + * Address type. + */ + public static final int UNKNOWN = 0; + public static final int WORK = 1; + public static final int HOME = 2; + + @Field(1) + private int versionCode = 1; + @Field(2) + public int type; + /** + * Formatted address, multiple lines when appropriate. This field always contains at least one line. + */ + @Field(3) + public String[] addressLines; + + public static Creator

CREATOR = new AutoCreator<>(Address.class); + } + + /** + * DateTime data type used in calendar events. If hours/minutes/seconds are not specified in the barcode value, they will be set to -1. + */ + public static class CalendarDateTime extends AutoSafeParcelable { + @Field(1) + private int versionCode = 1; + @Field(2) + public int year; + @Field(3) + public int month; + @Field(4) + public int day; + @Field(5) + public int hours; + @Field(6) + public int minutes; + @Field(7) + public int seconds; + @Field(8) + public boolean isUtc; + @Field(9) + public String rawValue; + + public static Creator CREATOR = new AutoCreator<>(CalendarDateTime.class); + } + + /** + * A calendar event extracted from QRCode. + */ + public static class CalendarEvent extends AutoSafeParcelable { + @Field(1) + private int versionCode = 1; + @Field(2) + public String summary; + @Field(3) + public String description; + @Field(4) + public String location; + @Field(5) + public String organizer; + @Field(6) + public String status; + @Field(7) + public Barcode.CalendarDateTime start; + @Field(8) + public Barcode.CalendarDateTime end; + + public static Creator CREATOR = new AutoCreator<>(CalendarEvent.class); + } + + /** + * A person's or organization's business card. For example a VCARD. + */ + public static class ContactInfo extends AutoSafeParcelable { + @Field(1) + private int versionCode = 1; + @Field(2) + public Barcode.PersonName name; + @Field(3) + public String organization; + @Field(4) + public String title; + @Field(5) + public Barcode.Phone[] phones; + @Field(6) + public Barcode.Email[] emails; + @Field(7) + public String[] urls; + @Field(8) + public Barcode.Address[] addresses; + + public static Creator CREATOR = new AutoCreator<>(ContactInfo.class); + } + + /** + * A driver license or ID card. + */ + public static class DriverLicense extends AutoSafeParcelable { + @Field(1) + private int versionCode = 1; + /** + * "DL" for driver licenses, "ID" for ID cards. + */ + @Field(2) + public String documentType; + /** + * Holder's first name. + */ + @Field(3) + public String firstName; + @Field(4) + public String middleName; + @Field(5) + public String lastName; + /** + * Gender. 1 - male, 2 - female. + */ + @Field(6) + public String gender; + /** + * Holder's street address. + */ + @Field(7) + public String addressStreet; + @Field(8) + public String addressCity; + @Field(9) + public String addressState; + @Field(10) + public String addressZip; + /** + * Driver license ID number. + */ + @Field(11) + public String licenseNumber; + /** + * The date format depends on the issuing country. MMDDYYYY for the US, YYYYMMDD for Canada. + */ + @Field(12) + public String issueDate; + @Field(13) + public String expiryDate; + @Field(14) + public String birthDate; + /** + * Country in which DL/ID was issued. US = "USA", Canada = "CAN". + */ + @Field(15) + public String issuingCountry; + + public static Creator CREATOR = new AutoCreator<>(DriverLicense.class); + } + + /** + * An email message from a 'MAILTO:' or similar QRCode type. + */ + public static class Email extends AutoSafeParcelable { + /** + * Email type. + */ + public static final int UNKNOWN = 0; + public static final int WORK = 1; + public static final int HOME = 2; + + @Field(1) + private int versionCode = 1; + @Field(2) + public int type; + @Field(3) + public String address; + @Field(4) + public String subject; + @Field(5) + public String body; + + public static Creator CREATOR = new AutoCreator<>(Email.class); + } + + /** + * GPS coordinates from a 'GEO:' or similar QRCode type. + */ + public static class GeoPoint extends AutoSafeParcelable { + @Field(1) + private int versionCode = 1; + @Field(2) + public double lat; + @Field(3) + public double lng; + + public static Creator CREATOR = new AutoCreator<>(GeoPoint.class); + } + + /** + * A person's name, both formatted version and individual name components. + */ + public static class PersonName extends AutoSafeParcelable { + @Field(1) + private int versionCode = 1; + /** + * Properly formatted name. + */ + @Field(2) + public String formattedName; + /** + * Designates a text string to be set as the kana name in the phonebook. Used for Japanese contacts. + */ + @Field(3) + public String pronunciation; + @Field(4) + public String prefix; + @Field(5) + public String first; + @Field(6) + public String middle; + @Field(7) + public String last; + @Field(8) + public String suffix; + + public static Creator CREATOR = new AutoCreator<>(PersonName.class); + } + + /** + * A phone number from a 'TEL:' or similar QRCode type. + */ + public static class Phone extends AutoSafeParcelable { + /** + * Phone type. + */ + public static final int UNKNOWN = 0; + public static final int WORK = 1; + public static final int HOME = 2; + public static final int FAX = 3; + public static final int MOBILE = 4; + + @Field(1) + private int versionCode = 1; + @Field(2) + public int type; + @Field(3) + public String number; + + public static Creator CREATOR = new AutoCreator<>(Phone.class); + } + + /** + * An sms message from an 'SMS:' or similar QRCode type. + */ + public static class Sms extends AutoSafeParcelable { + @Field(1) + private int versionCode = 1; + @Field(2) + public String message; + @Field(3) + public String phoneNumber; + + public static Creator CREATOR = new AutoCreator<>(Sms.class); + } + + /** + * A URL and title from a 'MEBKM:' or similar QRCode type. + */ + public static class UrlBookmark extends AutoSafeParcelable { + @Field(1) + private int versionCode = 1; + @Field(2) + public String title; + /** + * Bookmark URL. Note that some common errors may be corrected here. For example, "http//...", "http:...", etc. will be replaced with "//". + */ + @Field(3) + public String url; + + public static Creator CREATOR = new AutoCreator<>(UrlBookmark.class); + } + + /** + * A wifi network parameters from a 'WIFI:' or similar QRCode type. + */ + public static class WiFi extends AutoSafeParcelable { + /** + * WiFi encryption type. + */ + public static final int OPEN = 1; + public static final int WPA = 2; + public static final int WEP = 3; + + @Field(1) + private int versionCode = 1; + @Field(2) + public String ssid; + @Nullable + @Field(3) + public String password; + @Field(4) + public int encryptionType; + + public static Creator CREATOR = new AutoCreator<>(WiFi.class); + } + + public static final Creator CREATOR = new AutoCreator<>(Barcode.class); +} diff --git a/play-services-vision-api/src/main/java/com/google/android/gms/vision/barcode/internal/client/BarcodeDetectorOptions.java b/play-services-vision-api/src/main/java/com/google/android/gms/vision/barcode/internal/client/BarcodeDetectorOptions.java new file mode 100644 index 0000000000..2a2e29f171 --- /dev/null +++ b/play-services-vision-api/src/main/java/com/google/android/gms/vision/barcode/internal/client/BarcodeDetectorOptions.java @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.barcode.internal.client; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class BarcodeDetectorOptions extends AutoSafeParcelable { + @Field(1) + public int versionCode = 1; + @Field(2) + public int formats; + + public static Creator CREATOR = new AutoCreator<>(BarcodeDetectorOptions.class); +} diff --git a/play-services-vision-api/src/main/java/com/google/android/gms/vision/internal/FrameMetadataParcel.java b/play-services-vision-api/src/main/java/com/google/android/gms/vision/internal/FrameMetadataParcel.java new file mode 100644 index 0000000000..75e1488abd --- /dev/null +++ b/play-services-vision-api/src/main/java/com/google/android/gms/vision/internal/FrameMetadataParcel.java @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.internal; + +import org.microg.safeparcel.AutoSafeParcelable; + +public class FrameMetadataParcel extends AutoSafeParcelable { + @Field(1) + private final int versionCode = 1; + @Field(2) + public int width; + @Field(3) + public int height; + @Field(4) + public int id; + @Field(5) + public long timestampMillis; + @Field(6) + public int rotation; + + public static Creator CREATOR = new AutoCreator<>(FrameMetadataParcel.class); +} diff --git a/play-services-vision-core/build.gradle b/play-services-vision-core/build.gradle new file mode 100644 index 0000000000..ac0c876c9a --- /dev/null +++ b/play-services-vision-core/build.gradle @@ -0,0 +1,44 @@ +/* + * 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' + +dependencies { + api project(':play-services-vision-api') + + implementation project(':play-services-base-core') + implementation "androidx.annotation:annotation:$annotationVersion" + implementation 'com.google.zxing:core:3.4.1' +} + +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 service implementation for play-services-vision' diff --git a/play-services-vision-core/src/main/AndroidManifest.xml b/play-services-vision-core/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..a695ed90ab --- /dev/null +++ b/play-services-vision-core/src/main/AndroidManifest.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/play-services-vision-core/src/main/java/com/google/android/gms/dynamite/descriptors/com/google/android/gms/vision/barcode/ModuleDescriptor.java b/play-services-vision-core/src/main/java/com/google/android/gms/dynamite/descriptors/com/google/android/gms/vision/barcode/ModuleDescriptor.java new file mode 100644 index 0000000000..c14c155416 --- /dev/null +++ b/play-services-vision-core/src/main/java/com/google/android/gms/dynamite/descriptors/com/google/android/gms/vision/barcode/ModuleDescriptor.java @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.dynamite.descriptors.com.google.android.gms.vision.barcode; + +public class ModuleDescriptor { + public static final String MODULE_ID = "com.google.android.gms.vision.barcode"; + public static final int MODULE_VERSION = 1; +} diff --git a/play-services-vision-core/src/main/java/com/google/android/gms/dynamite/descriptors/com/google/android/gms/vision/dynamite/ModuleDescriptor.java b/play-services-vision-core/src/main/java/com/google/android/gms/dynamite/descriptors/com/google/android/gms/vision/dynamite/ModuleDescriptor.java new file mode 100644 index 0000000000..1e1583472c --- /dev/null +++ b/play-services-vision-core/src/main/java/com/google/android/gms/dynamite/descriptors/com/google/android/gms/vision/dynamite/ModuleDescriptor.java @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.dynamite.descriptors.com.google.android.gms.vision.dynamite; + +public class ModuleDescriptor { + public static final String MODULE_ID = "com.google.android.gms.vision.dynamite"; + public static final int MODULE_VERSION = 1; +} diff --git a/play-services-vision-core/src/main/kotlin/com/google/android/gms/vision/barcode/ChimeraNativeBarcodeDetectorCreator.kt b/play-services-vision-core/src/main/kotlin/com/google/android/gms/vision/barcode/ChimeraNativeBarcodeDetectorCreator.kt new file mode 100644 index 0000000000..a6ee5fee21 --- /dev/null +++ b/play-services-vision-core/src/main/kotlin/com/google/android/gms/vision/barcode/ChimeraNativeBarcodeDetectorCreator.kt @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.barcode + +import android.content.Context +import androidx.annotation.Keep +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.vision.barcode.internal.client.BarcodeDetectorOptions +import com.google.android.gms.vision.barcode.internal.client.INativeBarcodeDetector +import com.google.android.gms.vision.barcode.internal.client.INativeBarcodeDetectorCreator +import com.google.android.gms.dynamic.unwrap +import org.microg.gms.vision.barcode.BarcodeDetector + +@Keep +class ChimeraNativeBarcodeDetectorCreator : INativeBarcodeDetectorCreator.Stub() { + override fun create(context: IObjectWrapper, options: BarcodeDetectorOptions): INativeBarcodeDetector { + return BarcodeDetector(context.unwrap()!!, options) + } +} diff --git a/play-services-vision-core/src/main/kotlin/com/google/android/gms/vision/client/DynamiteNativeBarcodeDetectorCreator.kt b/play-services-vision-core/src/main/kotlin/com/google/android/gms/vision/client/DynamiteNativeBarcodeDetectorCreator.kt new file mode 100644 index 0000000000..606e9292f8 --- /dev/null +++ b/play-services-vision-core/src/main/kotlin/com/google/android/gms/vision/client/DynamiteNativeBarcodeDetectorCreator.kt @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.google.android.gms.vision.client + +import android.content.Context +import androidx.annotation.Keep +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.unwrap +import com.google.android.gms.vision.barcode.internal.client.BarcodeDetectorOptions +import com.google.android.gms.vision.barcode.internal.client.INativeBarcodeDetector +import com.google.android.gms.vision.barcode.internal.client.INativeBarcodeDetectorCreator +import org.microg.gms.vision.barcode.BarcodeDetector + +@Keep +class ChimeraNativeBarcodeDetectorCreator : INativeBarcodeDetectorCreator.Stub() { + override fun create(context: IObjectWrapper, options: BarcodeDetectorOptions): INativeBarcodeDetector { + return BarcodeDetector(context.unwrap()!!, options) + } +} diff --git a/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/BarcodeDetector.kt b/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/BarcodeDetector.kt new file mode 100644 index 0000000000..e5c5957030 --- /dev/null +++ b/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/BarcodeDetector.kt @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.vision.barcode + +import android.content.Context +import android.graphics.Bitmap +import android.util.Log +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.unwrap +import com.google.android.gms.vision.barcode.Barcode +import com.google.android.gms.vision.barcode.internal.client.BarcodeDetectorOptions +import com.google.android.gms.vision.barcode.internal.client.INativeBarcodeDetector +import com.google.android.gms.vision.internal.FrameMetadataParcel +import com.google.zxing.* +import com.google.zxing.aztec.AztecReader +import com.google.zxing.common.HybridBinarizer +import com.google.zxing.datamatrix.DataMatrixReader +import com.google.zxing.multi.MultipleBarcodeReader +import com.google.zxing.multi.qrcode.QRCodeMultiReader +import com.google.zxing.oned.* +import com.google.zxing.pdf417.PDF417Reader +import java.nio.ByteBuffer +import java.nio.IntBuffer + +private const val TAG = "GmsVisionBarcode" + +class BarcodeDetector(val context: Context, val options: BarcodeDetectorOptions) : INativeBarcodeDetector.Stub() { + override fun detectBitmap(wrappedBitmap: IObjectWrapper, metadata: FrameMetadataParcel): Array { + val bitmap = wrappedBitmap.unwrap() ?: return emptyArray() + val frameBuf: IntBuffer = IntBuffer.allocate(bitmap.byteCount) + bitmap.copyPixelsToBuffer(frameBuf) + return detectFromSource(RGBLuminanceSource(metadata.width, metadata.height, frameBuf.array())) + } + + override fun detectBytes(wrappedByteBuffer: IObjectWrapper, metadata: FrameMetadataParcel): Array { + return detectFromSource(DirectLuminanceSource(metadata.width, metadata.height, wrappedByteBuffer.unwrap() + ?: return emptyArray())) + } + + private fun mayDecodeType(image: BinaryBitmap, type: Int, reader: () -> Reader): List { + return if ((options.formats and type) != 0 || options.formats == Barcode.ALL_FORMATS) { + reader().run { + try { + if (this is MultipleBarcodeReader) { + decodeMultiple(image).map { it.toGms() } + } else { + listOf(decode(image).toGms()) + } + } catch (e: NotFoundException) { + emptyList() + } catch (e: FormatException) { + emptyList() + } catch (e: ChecksumException) { + emptyList() + } catch (e: Exception) { + Log.w(TAG, "Exception with $this: $e") + emptyList() + } + } + } else { + emptyList() + } + } + + private fun detectFromImage(image: BinaryBitmap, results: MutableList): Int { + var resultsSize = results.size + results.addAll(mayDecodeType(image, Barcode.CODE_128) { Code128Reader() }) + results.addAll(mayDecodeType(image, Barcode.CODE_39) { Code39Reader() }) + results.addAll(mayDecodeType(image, Barcode.CODABAR) { CodaBarReader() }) + results.addAll(mayDecodeType(image, Barcode.DATA_MATRIX) { DataMatrixReader() }) + results.addAll(mayDecodeType(image, Barcode.EAN_13) { EAN13Reader() }) + results.addAll(mayDecodeType(image, Barcode.EAN_8) { EAN8Reader() }) + results.addAll(mayDecodeType(image, Barcode.ITF) { ITFReader() }) + results.addAll(mayDecodeType(image, Barcode.QR_CODE) { QRCodeMultiReader() }) + results.addAll(mayDecodeType(image, Barcode.UPC_A) { UPCAReader() }) + results.addAll(mayDecodeType(image, Barcode.UPC_E) { UPCEReader() }) + results.addAll(mayDecodeType(image, Barcode.PDF417) { PDF417Reader() }) + results.addAll(mayDecodeType(image, Barcode.AZTEC) { AztecReader() }) + return results.size - resultsSize + } + + private fun detectFromSource(source: LuminanceSource): Array { + val results = arrayListOf() + try { + detectFromImage(BinaryBitmap(HybridBinarizer(source)), results) + detectFromImage(BinaryBitmap(HybridBinarizer(source.invert())), results) + } catch (e: Exception) { + Log.w(TAG, e) + } + + return results.distinctBy { it.rawValue }.toTypedArray() + } + + override fun close() { + Log.d(TAG, "close()") + } +} diff --git a/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/DirectLuminanceSource.kt b/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/DirectLuminanceSource.kt new file mode 100644 index 0000000000..f0a5fce0b1 --- /dev/null +++ b/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/DirectLuminanceSource.kt @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.vision.barcode + +import com.google.zxing.LuminanceSource +import java.nio.ByteBuffer + +class DirectLuminanceSource(width: Int, height: Int, val bytes: ByteBuffer) : LuminanceSource(width, height) { + override fun getRow(y: Int, row: ByteArray?): ByteArray { + val row = row?.takeIf { it.size >= width } ?: ByteArray(width) + bytes.position(width * y) + bytes.get(row, 0, width) + return row + } + + override fun getMatrix(): ByteArray { + return bytes.array() + } + +} diff --git a/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/Extensions.kt b/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/Extensions.kt new file mode 100644 index 0000000000..19f270d2c2 --- /dev/null +++ b/play-services-vision-core/src/main/kotlin/org/microg/gms/vision/barcode/Extensions.kt @@ -0,0 +1,200 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.vision.barcode + +import android.graphics.Point +import com.google.android.gms.vision.barcode.Barcode +import com.google.zxing.BarcodeFormat +import com.google.zxing.Result +import com.google.zxing.ResultPoint +import com.google.zxing.client.result.* +import java.util.* + +fun BarcodeFormat.toGms(): Int = when (this) { + BarcodeFormat.AZTEC -> Barcode.AZTEC + BarcodeFormat.CODABAR -> Barcode.CODABAR + BarcodeFormat.CODE_128 -> Barcode.CODE_128 + BarcodeFormat.CODE_39 -> Barcode.CODE_39 + BarcodeFormat.CODE_93 -> Barcode.CODE_93 + BarcodeFormat.DATA_MATRIX -> Barcode.DATA_MATRIX + BarcodeFormat.EAN_13 -> Barcode.EAN_13 + BarcodeFormat.EAN_8 -> Barcode.EAN_8 + BarcodeFormat.ITF -> Barcode.ITF + BarcodeFormat.PDF_417 -> Barcode.PDF417 + BarcodeFormat.QR_CODE -> Barcode.QR_CODE + BarcodeFormat.UPC_A -> Barcode.UPC_A + BarcodeFormat.UPC_E -> Barcode.UPC_E + else -> Barcode.ALL_FORMATS +} + +fun ParsedResultType.toGms(): Int = when (this) { + ParsedResultType.ADDRESSBOOK -> Barcode.CONTACT_INFO + ParsedResultType.CALENDAR -> Barcode.CALENDAR_EVENT + ParsedResultType.EMAIL_ADDRESS -> Barcode.EMAIL + ParsedResultType.GEO -> Barcode.GEO + ParsedResultType.ISBN -> Barcode.ISBN + ParsedResultType.PRODUCT -> Barcode.PRODUCT + ParsedResultType.SMS -> Barcode.SMS + ParsedResultType.TEL -> Barcode.PHONE + ParsedResultType.TEXT -> Barcode.TEXT + ParsedResultType.URI -> Barcode.URL + ParsedResultType.WIFI -> Barcode.WIFI + else -> Barcode.TEXT +} + +fun AddressBookParsedResult.toGms(): Barcode.ContactInfo { + val contactInfo = Barcode.ContactInfo() + // TODO: contactInfo.name + contactInfo.organization = org + contactInfo.title = title + contactInfo.phones = phoneNumbers.orEmpty().mapIndexed { i, a -> + Barcode.Phone().apply { + type = when (phoneTypes?.getOrNull(i)) { + "WORK" -> Barcode.Phone.WORK + "HOME" -> Barcode.Phone.HOME + "FAX" -> Barcode.Phone.FAX + "MOBILE" -> Barcode.Phone.MOBILE + else -> Barcode.Phone.UNKNOWN + } + number = a + } + }.toTypedArray() + contactInfo.emails = emails.orEmpty().mapIndexed { i, a -> + Barcode.Email().apply { + type = when (emailTypes?.getOrNull(i)) { + "WORK" -> Barcode.Email.WORK + "HOME" -> Barcode.Email.HOME + else -> Barcode.Email.UNKNOWN + } + address = a + } + }.toTypedArray() + contactInfo.urls = urLs + contactInfo.addresses = addresses.orEmpty().mapIndexed { i, a -> + Barcode.Address().apply { + type = when (addressTypes?.getOrNull(i)) { + "WORK" -> Barcode.Address.WORK + "HOME" -> Barcode.Address.HOME + else -> Barcode.Address.UNKNOWN + } + addressLines = a.split("\n").toTypedArray() + } + }.toTypedArray() + + return contactInfo +} + +fun CalendarParsedResult.toGms(): Barcode.CalendarEvent { + fun createDateTime(timestamp: Long, isAllDay: Boolean) = Barcode.CalendarDateTime().apply { + val calendar = Calendar.getInstance() + calendar.time = Date(timestamp) + year = calendar.get(Calendar.YEAR) + month = calendar.get(Calendar.MONTH) + day = calendar.get(Calendar.DAY_OF_MONTH) + if (isAllDay) { + hours = -1 + minutes = -1 + seconds = -1 + } else { + hours = calendar.get(Calendar.HOUR_OF_DAY) + minutes = calendar.get(Calendar.MINUTE) + seconds = calendar.get(Calendar.SECOND) + } + } + + + val event = Barcode.CalendarEvent() + event.summary = summary + event.description = description + event.location = location + event.organizer = organizer + event.start = createDateTime(startTimestamp, isStartAllDay) + event.end = createDateTime(endTimestamp, isEndAllDay) + return event +} + +fun EmailAddressParsedResult.toGms(): Barcode.Email { + val email = Barcode.Email() + email.address = tos?.getOrNull(0) + email.subject = subject + email.body = body + return email +} + +fun GeoParsedResult.toGms(): Barcode.GeoPoint { + val geo = Barcode.GeoPoint() + geo.lat = latitude + geo.lng = longitude + return geo +} + +fun TelParsedResult.toGms(): Barcode.Phone { + val phone = Barcode.Phone() + phone.number = number + return phone +} + +fun SMSParsedResult.toGms(): Barcode.Sms { + val sms = Barcode.Sms() + sms.message = body + sms.phoneNumber = numbers?.getOrNull(0) + return sms +} + +fun WifiParsedResult.toGms(): Barcode.WiFi { + val wifi = Barcode.WiFi() + wifi.ssid = ssid + wifi.password = password + wifi.encryptionType = when (networkEncryption) { + "OPEN" -> Barcode.WiFi.OPEN + "WEP" -> Barcode.WiFi.WEP + "WPA" -> Barcode.WiFi.WPA + "WPA2" -> Barcode.WiFi.WPA + else -> 0 + } + return wifi +} + +fun URIParsedResult.toGms(): Barcode.UrlBookmark { + val url = Barcode.UrlBookmark() + url.url = uri + url.title = title + return url +} + +fun ResultPoint.toPoint(): Point = Point(x.toInt(), y.toInt()) +fun Result.toGms(): Barcode { + val barcode = Barcode() + barcode.format = barcodeFormat.toGms() + barcode.rawBytes = rawBytes + barcode.rawValue = text + barcode.cornerPoints = resultPoints.map { it.toPoint() }.toTypedArray() + + val parsed = ResultParser.parseResult(this) + + barcode.displayValue = parsed.displayResult + barcode.valueFormat = parsed.type.toGms() + when (parsed) { + is EmailAddressParsedResult -> + barcode.email = parsed.toGms() + is TelParsedResult -> + barcode.phone = parsed.toGms() + is SMSParsedResult -> + barcode.sms = parsed.toGms() + is WifiParsedResult -> + barcode.wifi = parsed.toGms() + is URIParsedResult -> + barcode.url = parsed.toGms() + is GeoParsedResult -> + barcode.geoPoint = parsed.toGms() + is CalendarParsedResult -> + barcode.calendarEvent = parsed.toGms() + is AddressBookParsedResult -> + barcode.contactInfo = parsed.toGms() + } + + return barcode +} diff --git a/play-services-vision/build.gradle b/play-services-vision/build.gradle new file mode 100644 index 0000000000..f7253b98be --- /dev/null +++ b/play-services-vision/build.gradle @@ -0,0 +1,33 @@ +/* + * 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 implementation of play-services-vision' + +dependencies { + api project(':play-services-base') + api project(':play-services-vision-api') +} diff --git a/play-services-vision/src/main/AndroidManifest.xml b/play-services-vision/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..b6ffe81998 --- /dev/null +++ b/play-services-vision/src/main/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + diff --git a/settings.gradle b/settings.gradle index a2b243351c..2ce0cff3bd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,6 +9,7 @@ include ':play-services-cast-framework-api' include ':play-services-iid-api' include ':play-services-location-api' include ':play-services-nearby-api' +include ':play-services-vision-api' include ':play-services-wearable-api' include ':play-services-api' @@ -24,6 +25,7 @@ include ':play-services-maps-core-mapbox' include ':play-services-maps-core-vtm' include ':play-services-maps-core-vtm:vtm-microg-theme' include ':play-services-nearby-core' +include ':play-services-vision-core' include ':play-services-base-core-ui' include ':play-services-nearby-core-ui' @@ -42,6 +44,7 @@ include ':play-services-gcm' include ':play-services-iid' include ':play-services-location' include ':play-services-nearby' +include ':play-services-vision' include ':play-services-wearable' include ':play-services'