Repo Created
This commit is contained in:
parent
eb305e2886
commit
a8c22c65db
4784 changed files with 329907 additions and 2 deletions
43
play-services-maps/build.gradle
Normal file
43
play-services-maps/build.gradle
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
|
||||
android {
|
||||
namespace "com.google.android.gms.maps"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
buildFeatures {
|
||||
aidl = true
|
||||
}
|
||||
|
||||
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-maps'
|
||||
|
||||
dependencies {
|
||||
// Dependencies from play-services-maps:18.1.0
|
||||
api "androidx.fragment:fragment:1.0.0"
|
||||
api project(":play-services-base")
|
||||
api project(":play-services-basement")
|
||||
|
||||
annotationProcessor project(":safe-parcel-processor")
|
||||
}
|
||||
61
play-services-maps/core/hms/build.gradle
Normal file
61
play-services-maps/core/hms/build.gradle
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
dependencies {
|
||||
implementation project(':play-services-base-core')
|
||||
implementation project(':play-services-maps')
|
||||
|
||||
implementation 'com.huawei.hms:maps:6.9.0.300'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "org.microg.gms.maps.hms"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
defaultConfig {
|
||||
versionName version
|
||||
minSdkVersion androidMinSdk
|
||||
targetSdkVersion androidTargetSdk
|
||||
buildConfigField "String", "HMSMAP_KEY", "\"${localProperties.getProperty("hmsmap.key", "")}\""
|
||||
|
||||
ndk {
|
||||
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'GradleCompatible'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = 1.8
|
||||
}
|
||||
}
|
||||
9
play-services-maps/core/hms/proguard-rules.pro
vendored
Normal file
9
play-services-maps/core/hms/proguard-rules.pro
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
-ignorewarnings
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes Exceptions
|
||||
-keepattributes InnerClasses
|
||||
-keepattributes Signature
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep class com.huawei.hianalytics.**{*;}
|
||||
-keep class com.huawei.updatesdk.**{*;}
|
||||
-keep class com.huawei.hms.**{*;}
|
||||
20
play-services-maps/core/hms/src/main/AndroidManifest.xml
Normal file
20
play-services-maps/core/hms/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<uses-sdk tools:overrideLibrary="com.huawei.hms.maps,com.huawei.android.hms.base,com.huawei.hms.feature.dynamic,com.huawei.hms.base.availableupdate,com.huawei.hms.stats,com.huawei.hms.base.ui,com.huawei.hms.base.device,com.huawei.hms.log,com.huawei.hmf.tasks,com.huawei.hms.framework.network.grs,com.huawei.hms.hatool,com.huawei.hms.framework.network.frameworkcompat,com.huawei.hms.framework.common" />
|
||||
|
||||
<application />
|
||||
|
||||
</manifest>
|
||||
1
play-services-maps/core/hms/src/main/assets/.gitignore
vendored
Normal file
1
play-services-maps/core/hms/src/main/assets/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
agconnect-services.json
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.dynamite.descriptors.com.google.android.gms.maps_dynamite;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@Keep
|
||||
public class ModuleDescriptor {
|
||||
public static final String MODULE_ID = "com.google.android.gms.maps_dynamite";
|
||||
public static final int MODULE_VERSION = 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.maps.internal;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import androidx.annotation.Keep;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.dynamic.IObjectWrapper;
|
||||
import com.google.android.gms.dynamic.ObjectWrapper;
|
||||
import com.google.android.gms.maps.GoogleMapOptions;
|
||||
import com.google.android.gms.maps.StreetViewPanoramaOptions;
|
||||
import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate;
|
||||
|
||||
import com.huawei.hms.maps.MapsInitializer;
|
||||
import org.microg.gms.maps.hms.CameraUpdateFactoryImpl;
|
||||
import org.microg.gms.maps.hms.MapFragmentImpl;
|
||||
import org.microg.gms.maps.hms.MapViewImpl;
|
||||
import org.microg.gms.maps.hms.StreetViewPanoramaFragmentImpl;
|
||||
import org.microg.gms.maps.hms.StreetViewPanoramaViewImpl;
|
||||
import org.microg.gms.maps.hms.model.BitmapDescriptorFactoryImpl;
|
||||
|
||||
@Keep
|
||||
public class CreatorImpl extends ICreator.Stub {
|
||||
private static final String TAG = "GmsMapCreator";
|
||||
|
||||
@Override
|
||||
public void init(IObjectWrapper resources) {
|
||||
initV2(resources, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMapFragmentDelegate newMapFragmentDelegate(IObjectWrapper activity) {
|
||||
return new MapFragmentImpl(ObjectWrapper.unwrapTyped(activity, Activity.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMapViewDelegate newMapViewDelegate(IObjectWrapper context, GoogleMapOptions options) {
|
||||
return new MapViewImpl(ObjectWrapper.unwrapTyped(context, Context.class), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICameraUpdateFactoryDelegate newCameraUpdateFactoryDelegate() {
|
||||
return new CameraUpdateFactoryImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBitmapDescriptorFactoryDelegate newBitmapDescriptorFactoryDelegate() {
|
||||
return BitmapDescriptorFactoryImpl.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initV2(IObjectWrapper resources, int flags) {
|
||||
BitmapDescriptorFactoryImpl.INSTANCE.initialize(ObjectWrapper.unwrapTyped(resources, Resources.class));
|
||||
//ResourcesContainer.set((Resources) ObjectWrapper.unwrap(resources));
|
||||
Log.d(TAG, "initV2 " + flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStreetViewPanoramaViewDelegate newStreetViewPanoramaViewDelegate(IObjectWrapper context, StreetViewPanoramaOptions options) {
|
||||
return new StreetViewPanoramaViewImpl(ObjectWrapper.unwrapTyped(context, Context.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStreetViewPanoramaFragmentDelegate newStreetViewPanoramaFragmentDelegate(IObjectWrapper activity) {
|
||||
return new StreetViewPanoramaFragmentImpl(ObjectWrapper.unwrapTyped(activity, Activity.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRendererType() throws RemoteException {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logInitialization(IObjectWrapper context, int preferredRenderer) throws RemoteException {
|
||||
Log.d(TAG, "HMS-based Map initialized (preferred renderer was " + preferredRenderer + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
||||
if (super.onTransact(code, data, reply, flags)) return true;
|
||||
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms
|
||||
|
||||
import android.graphics.Point
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.maps.internal.ICameraUpdateFactoryDelegate
|
||||
import com.google.android.gms.maps.model.CameraPosition
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.LatLngBounds
|
||||
import com.huawei.hms.maps.CameraUpdateFactory
|
||||
import org.microg.gms.maps.hms.utils.toHms
|
||||
import org.microg.gms.maps.hms.utils.toHmsZoom
|
||||
|
||||
class CameraUpdateFactoryImpl : ICameraUpdateFactoryDelegate.Stub() {
|
||||
|
||||
override fun zoomIn(): IObjectWrapper = ObjectWrapper.wrap(CameraUpdateFactory.zoomIn())
|
||||
override fun zoomOut(): IObjectWrapper = ObjectWrapper.wrap(CameraUpdateFactory.zoomOut())
|
||||
|
||||
override fun zoomTo(zoom: Float): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraUpdateFactory.zoomTo(toHmsZoom(zoom)))
|
||||
|
||||
override fun zoomBy(zoomDelta: Float): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraUpdateFactory.zoomBy(zoomDelta))
|
||||
|
||||
override fun zoomByWithFocus(zoomDelta: Float, x: Int, y: Int): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraUpdateFactory.zoomBy(zoomDelta, Point(x, y)))
|
||||
|
||||
override fun newCameraPosition(cameraPosition: CameraPosition): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraUpdateFactory.newCameraPosition(cameraPosition.toHms()))
|
||||
|
||||
override fun newLatLng(latLng: LatLng): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraUpdateFactory.newLatLng(latLng.toHms()))
|
||||
|
||||
override fun newLatLngZoom(latLng: LatLng, zoom: Float): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraUpdateFactory.newLatLngZoom(latLng.toHms(),
|
||||
toHmsZoom(zoom)
|
||||
))
|
||||
|
||||
override fun newLatLngBounds(bounds: LatLngBounds, padding: Int): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraUpdateFactory.newLatLngBounds(bounds.toHms(), padding))
|
||||
|
||||
override fun scrollBy(x: Float, y: Float): IObjectWrapper {
|
||||
Log.d(TAG, "scrollBy: $x, $y")
|
||||
// gms map: A positive value moves the camera downwards
|
||||
// hms map: A positive value moves the camera upwards
|
||||
return ObjectWrapper.wrap(CameraUpdateFactory.scrollBy(x, -y))
|
||||
}
|
||||
|
||||
override fun newLatLngBoundsWithSize(bounds: LatLngBounds, width: Int, height: Int, padding: Int): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraUpdateFactory.newLatLngBounds(bounds.toHms(), width, height, padding))
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsCameraUpdate"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,984 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.location.Location
|
||||
import android.os.*
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.annotation.Keep
|
||||
import androidx.collection.LongSparseArray
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.unwrap
|
||||
import com.google.android.gms.maps.GoogleMap.MAP_TYPE_TERRAIN
|
||||
import com.google.android.gms.maps.GoogleMapOptions
|
||||
import com.google.android.gms.maps.internal.*
|
||||
import com.google.android.gms.maps.model.*
|
||||
import com.google.android.gms.maps.model.internal.*
|
||||
import com.huawei.hms.maps.CameraUpdate
|
||||
import com.huawei.hms.maps.HuaweiMap
|
||||
import com.huawei.hms.maps.MapView
|
||||
import com.huawei.hms.maps.MapsInitializer
|
||||
import com.huawei.hms.maps.OnMapReadyCallback
|
||||
import com.huawei.hms.maps.TextureMapView
|
||||
import com.huawei.hms.maps.internal.IOnIndoorStateChangeListener
|
||||
import com.huawei.hms.maps.internal.IOnInfoWindowCloseListener
|
||||
import com.huawei.hms.maps.internal.IOnInfoWindowLongClickListener
|
||||
import com.huawei.hms.maps.internal.IOnPoiClickListener
|
||||
import com.huawei.hms.maps.model.Marker
|
||||
import org.microg.gms.maps.hms.model.*
|
||||
import org.microg.gms.maps.hms.utils.*
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
|
||||
private fun <T : Any> LongSparseArray<T>.values() = (0 until size()).mapNotNull { valueAt(it) }
|
||||
|
||||
fun runOnMainLooper(forceQueue: Boolean = false, method: () -> Unit) {
|
||||
if (!forceQueue && Looper.myLooper() == Looper.getMainLooper()) {
|
||||
method()
|
||||
} else {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
method()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) : IGoogleMapDelegate.Stub() {
|
||||
|
||||
internal val mapContext = MapContext(context)
|
||||
|
||||
val view: FrameLayout
|
||||
var map: HuaweiMap? = null
|
||||
private set
|
||||
val dpiFactor: Float
|
||||
get() = context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT
|
||||
|
||||
private var mapView: MapView? = null
|
||||
private var created = false
|
||||
private var initialized = false
|
||||
private var loaded = false
|
||||
private val mapLock = Object()
|
||||
private var latLngBounds: LatLngBounds? = null
|
||||
|
||||
private val internalOnInitializedCallbackList = CopyOnWriteArrayList<OnMapReadyCallback>()
|
||||
private val initializedCallbackList = CopyOnWriteArrayList<IOnMapReadyCallback>()
|
||||
private var loadedCallback: IOnMapLoadedCallback? = null
|
||||
private var cameraChangeListener: IOnCameraChangeListener? = null
|
||||
private var cameraMoveListener: IOnCameraMoveListener? = null
|
||||
private var cameraMoveCanceledListener: IOnCameraMoveCanceledListener? = null
|
||||
private var cameraMoveStartedListener: IOnCameraMoveStartedListener? = null
|
||||
private var cameraIdleListener: IOnCameraIdleListener? = null
|
||||
private var mapClickListener: IOnMapClickListener? = null
|
||||
private var mapLongClickListener: IOnMapLongClickListener? = null
|
||||
|
||||
private val groundOverlays = mutableMapOf<String, GroundOverlayImpl>()
|
||||
private val polylines = mutableMapOf<String, PolylineImpl>()
|
||||
private val polygons = mutableMapOf<String, PolygonImpl>()
|
||||
private val circles = mutableMapOf<String, CircleImpl>()
|
||||
private val tileOverlays = mutableMapOf<String, TileOverlayImpl>()
|
||||
|
||||
private var storedMapType: Int = options.mapType
|
||||
val waitingCameraUpdates = mutableListOf<CameraUpdate>()
|
||||
|
||||
private var markerId = 0L
|
||||
val markers = mutableMapOf<String, MarkerImpl>()
|
||||
|
||||
private var projectionImpl: ProjectionImpl? = null
|
||||
private var inDeveloperAnimation = false
|
||||
|
||||
init {
|
||||
BitmapDescriptorFactoryImpl.initialize(context.resources)
|
||||
runOnMainLooper {
|
||||
MapsInitializer.setApiKey(BuildConfig.HMSMAP_KEY)
|
||||
}
|
||||
|
||||
this.view = object : FrameLayout(mapContext) {
|
||||
private val fakeWatermark = ImageView(mapContext).apply {
|
||||
tag = "GoogleWatermark"
|
||||
visibility = GONE
|
||||
}
|
||||
private val fakeCompass = View(mapContext).apply {
|
||||
tag = "GoogleMapCompass"
|
||||
visibility = GONE
|
||||
}
|
||||
private val fakeZoomInButton = View(mapContext).apply {
|
||||
tag = "GoogleMapZoomInButton"
|
||||
visibility = GONE
|
||||
}
|
||||
private val fakeZoomOutButton = View(mapContext).apply {
|
||||
tag = "GoogleMapZoomOutButton"
|
||||
visibility = GONE
|
||||
}
|
||||
private val fakeMyLocationButton = View(mapContext).apply {
|
||||
tag = "GoogleMapMyLocationButton"
|
||||
visibility = GONE
|
||||
}
|
||||
|
||||
private val fakeZoomButtonRoot = LinearLayout(mapContext).apply {
|
||||
addView(fakeZoomInButton)
|
||||
addView(fakeZoomOutButton)
|
||||
visibility = GONE
|
||||
}
|
||||
|
||||
private val mapButtonRoot = RelativeLayout(mapContext).apply {
|
||||
addView(fakeZoomButtonRoot)
|
||||
addView(fakeMyLocationButton)
|
||||
addView(fakeCompass)
|
||||
addView(fakeWatermark)
|
||||
visibility = GONE
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
addView(mapButtonRoot)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
removeView(mapButtonRoot)
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun <T : View> findViewTraversal(@IdRes id: Int): T? {
|
||||
if (1 == id) {
|
||||
return try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
mapButtonRoot as T
|
||||
} catch (e: ClassCastException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
if (2 == id) {
|
||||
return try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fakeMyLocationButton as T
|
||||
} catch (e: ClassCastException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun <T : View> findViewWithTagTraversal(tag: Any): T? {
|
||||
if ("GoogleWatermark" == tag) {
|
||||
return try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fakeWatermark as T
|
||||
} catch (e: ClassCastException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
if ("GoogleMapCompass" == tag) {
|
||||
return try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fakeCompass as T
|
||||
} catch (e: ClassCastException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
if ("GoogleMapZoomInButton" == tag) {
|
||||
return try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fakeZoomInButton as T
|
||||
} catch (e: ClassCastException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
if ("GoogleMapZoomOutButton" == tag) {
|
||||
return try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fakeZoomOutButton as T
|
||||
} catch (e: ClassCastException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
if ("GoogleMapMyLocationButton" == tag) {
|
||||
return try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fakeMyLocationButton as T
|
||||
} catch (e: ClassCastException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCameraPosition(): CameraPosition {
|
||||
return map?.cameraPosition?.toGms() ?: CameraPosition(LatLng(0.0, 0.0), 0f, 0f, 0f)
|
||||
}
|
||||
override fun getMaxZoomLevel(): Float = toHmsZoom(map?.maxZoomLevel ?: 18.toFloat())
|
||||
override fun getMinZoomLevel(): Float = toHmsZoom(map?.minZoomLevel ?: 3.toFloat())
|
||||
|
||||
override fun moveCamera(cameraUpdate: IObjectWrapper?) {
|
||||
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
this.map?.moveCamera(update)
|
||||
} else {
|
||||
waitingCameraUpdates.add(update)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun animateCamera(cameraUpdate: IObjectWrapper?) {
|
||||
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
this.map?.animateCamera(update)
|
||||
} else {
|
||||
waitingCameraUpdates.add(update)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) {
|
||||
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
Log.d(TAG, "animateCameraWithCallback start ")
|
||||
inDeveloperAnimation = true
|
||||
this.map?.animateCamera(update, object : HuaweiMap.CancelableCallback {
|
||||
override fun onFinish() {
|
||||
Log.d(TAG, "animateCameraWithCallback onFinish: ")
|
||||
inDeveloperAnimation = false
|
||||
callback?.onFinish()
|
||||
}
|
||||
|
||||
override fun onCancel() {
|
||||
Log.d(TAG, "animateCameraWithCallback onCancel: ")
|
||||
inDeveloperAnimation = false
|
||||
callback?.onCancel()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
waitingCameraUpdates.add(update)
|
||||
afterInitialize { callback?.onFinish() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun animateCameraWithDurationAndCallback(
|
||||
cameraUpdate: IObjectWrapper?,
|
||||
duration: Int,
|
||||
callback: ICancelableCallback?
|
||||
) {
|
||||
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
Log.d(TAG, "animateCameraWithDurationAndCallback")
|
||||
this.map?.animateCamera(update, duration, callback?.toHms())
|
||||
} else {
|
||||
waitingCameraUpdates.add(update)
|
||||
afterInitialize { callback?.onFinish() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun stopAnimation() = map?.stopAnimation() ?: Unit
|
||||
|
||||
override fun setMapStyle(options: MapStyleOptions?): Boolean {
|
||||
Log.d(TAG, "setMapStyle: ")
|
||||
val bool = options?.toHms(mapContext).let {
|
||||
map?.setMapStyle(it)
|
||||
}
|
||||
Log.d(TAG, "setMapStyle: bool: $bool")
|
||||
return true == bool
|
||||
}
|
||||
|
||||
override fun setMinZoomPreference(minZoom: Float) = afterInitialize {
|
||||
it.setMinZoomPreference(toHmsZoom(minZoom))
|
||||
}
|
||||
|
||||
override fun setMaxZoomPreference(maxZoom: Float) = afterInitialize {
|
||||
it.setMaxZoomPreference(toHmsZoom(maxZoom))
|
||||
}
|
||||
|
||||
override fun resetMinMaxZoomPreference() = afterInitialize {
|
||||
it.setMinZoomPreference(3.toFloat())
|
||||
it.setMaxZoomPreference(18.toFloat())
|
||||
}
|
||||
|
||||
override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) = afterInitialize {
|
||||
if (latLngBounds == null || bounds == null || latLngBounds!! != bounds) {
|
||||
latLngBounds = bounds
|
||||
it.setLatLngBoundsForCameraTarget(bounds?.toHms())
|
||||
}
|
||||
}
|
||||
|
||||
override fun addPolyline(options: PolylineOptions): IPolylineDelegate? {
|
||||
val polyline = map?.addPolyline(options.toHms()) ?: return null
|
||||
val polylineImpl = PolylineImpl(polyline, options)
|
||||
polylines[polylineImpl.id] = polylineImpl
|
||||
return polylineImpl
|
||||
}
|
||||
|
||||
override fun addPolygon(options: PolygonOptions): IPolygonDelegate? {
|
||||
val polygon = map?.addPolygon(options.toHms()) ?: return null
|
||||
val polygonImpl = PolygonImpl(polygon)
|
||||
polygons[polygonImpl.id] = polygonImpl
|
||||
return polygonImpl
|
||||
}
|
||||
|
||||
override fun addMarker(options: MarkerOptions): IMarkerDelegate {
|
||||
val marker = MarkerImpl(this, "m${markerId++}", options)
|
||||
if (map != null) {
|
||||
marker.update()
|
||||
} else {
|
||||
markers[marker.id] = marker
|
||||
}
|
||||
return marker
|
||||
}
|
||||
|
||||
override fun addGroundOverlay(options: GroundOverlayOptions): IGroundOverlayDelegate? {
|
||||
Log.d(TAG, "Method: addGroundOverlay")
|
||||
if (options.width <= 0 && options.height <= 0 && options.bounds == null) {
|
||||
Log.w(TAG, "addGroundOverlay options Parameters do not meet requirements")
|
||||
return null
|
||||
}
|
||||
val groundOverlay = map?.addGroundOverlay(options.toHms()) ?: return null
|
||||
val groundOverlayImpl = GroundOverlayImpl(groundOverlay)
|
||||
groundOverlays[groundOverlayImpl.id] = groundOverlayImpl
|
||||
return groundOverlayImpl
|
||||
}
|
||||
|
||||
override fun addTileOverlay(options: TileOverlayOptions): ITileOverlayDelegate? {
|
||||
Log.d(TAG, "Method: addTileOverlay")
|
||||
val tileOverlay = map?.addTileOverlay(options.toHms()) ?: return null
|
||||
val tileOverlayImpl = TileOverlayImpl(tileOverlay)
|
||||
tileOverlays[tileOverlayImpl.id] = tileOverlayImpl
|
||||
return tileOverlayImpl
|
||||
}
|
||||
|
||||
override fun addCircle(options: CircleOptions): ICircleDelegate? {
|
||||
val circle = map?.addCircle(options.toHms()) ?: return null
|
||||
val circleImpl = CircleImpl(circle)
|
||||
circles[circleImpl.id] = circleImpl
|
||||
return circleImpl
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
map?.clear()
|
||||
}
|
||||
|
||||
|
||||
override fun getMapType(): Int {
|
||||
return map?.mapType ?: storedMapType
|
||||
}
|
||||
|
||||
override fun setMapType(type: Int) {
|
||||
storedMapType = type
|
||||
applyMapType()
|
||||
}
|
||||
|
||||
fun applyMapType() {
|
||||
// TODO: Serve map styles locally
|
||||
Log.d(TAG, "Method: applyMapType -> $storedMapType")
|
||||
when (storedMapType) {
|
||||
MAP_TYPE_TERRAIN -> map?.mapType = HuaweiMap.MAP_TYPE_TERRAIN
|
||||
// MAP_TYPE_SATELLITE, MAP_TYPE_HYBRID, MAP_TYPE_NONE, MAP_TYPE_NORMAL,
|
||||
else -> map?.mapType = HuaweiMap.MAP_TYPE_NORMAL
|
||||
}
|
||||
// map?.let { BitmapDescriptorFactoryImpl.registerMap(it) }
|
||||
}
|
||||
|
||||
override fun isTrafficEnabled(): Boolean {
|
||||
return map?.isTrafficEnabled ?: false
|
||||
}
|
||||
|
||||
override fun setTrafficEnabled(traffic: Boolean) = afterInitialize {
|
||||
Log.d(TAG, "setTrafficEnabled")
|
||||
it.isTrafficEnabled = traffic
|
||||
}
|
||||
|
||||
override fun isIndoorEnabled(): Boolean {
|
||||
Log.d(TAG, "isIndoorEnabled")
|
||||
return map?.isIndoorEnabled ?: false
|
||||
}
|
||||
|
||||
override fun setIndoorEnabled(indoor: Boolean) = afterInitialize {
|
||||
Log.d(TAG, "setIndoorEnabled")
|
||||
it.isIndoorEnabled = indoor
|
||||
}
|
||||
|
||||
override fun isMyLocationEnabled(): Boolean {
|
||||
return map?.isMyLocationEnabled ?: false
|
||||
}
|
||||
|
||||
override fun setMyLocationEnabled(myLocation: Boolean) = afterInitialize {
|
||||
Log.d(TAG, "setMyLocationEnabled $myLocation")
|
||||
it.isMyLocationEnabled = myLocation
|
||||
}
|
||||
|
||||
override fun getMyLocation(): Location? {
|
||||
Log.d(TAG, "deprecated Method: getMyLocation")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun setLocationSource(locationSource: ILocationSourceDelegate?) = afterInitialize {
|
||||
Log.d(TAG, "unimplemented Method: setLocationSource")
|
||||
}
|
||||
|
||||
override fun setContentDescription(desc: String?) = afterInitialize {
|
||||
Log.d(TAG, "setContentDescription desc -> $desc")
|
||||
it.setContentDescription(desc)
|
||||
}
|
||||
|
||||
override fun getUiSettings(): IUiSettingsDelegate =
|
||||
map?.uiSettings?.let { UiSettingsImpl(it, view) } ?: UiSettingsCache().also {
|
||||
internalOnInitializedCallbackList.add(it.getMapReadyCallback())
|
||||
}
|
||||
|
||||
override fun getProjection(): IProjectionDelegate {
|
||||
return projectionImpl ?: map?.projection?.let {
|
||||
val experiment = try {
|
||||
map?.cameraPosition?.tilt == 0.0f && map?.cameraPosition?.bearing == 0.0f
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e);false
|
||||
}
|
||||
ProjectionImpl(it, experiment)
|
||||
}?.also { projectionImpl = it } ?: DummyProjection()
|
||||
}
|
||||
|
||||
override fun setOnCameraChangeListener(listener: IOnCameraChangeListener?) = afterInitialize {
|
||||
Log.d(TAG, "setOnCameraChangeListener");
|
||||
cameraChangeListener = listener
|
||||
}
|
||||
|
||||
override fun setOnCircleClickListener(listener: IOnCircleClickListener?) = afterInitialize { hmap ->
|
||||
Log.d(TAG, "setOnCircleClickListener")
|
||||
hmap.setOnCircleClickListener { listener?.onCircleClick(circles[it.id]) }
|
||||
}
|
||||
|
||||
override fun setOnGroundOverlayClickListener(listener: IOnGroundOverlayClickListener?) =
|
||||
afterInitialize { hmap ->
|
||||
Log.d(TAG, "Method: setOnGroundOverlayClickListener")
|
||||
hmap.setOnGroundOverlayClickListener { listener?.onGroundOverlayClick(groundOverlays[it.id]) }
|
||||
}
|
||||
|
||||
override fun setOnInfoWindowLongClickListener(listener: com.google.android.gms.maps.internal.IOnInfoWindowLongClickListener?) =
|
||||
afterInitialize {
|
||||
Log.d(TAG, "Not yet implemented setInfoWindowLongClickListener")
|
||||
}
|
||||
|
||||
fun setOnIndoorStateChangeListener(listener: IOnIndoorStateChangeListener?) {
|
||||
Log.d(TAG, "unimplemented Method: setOnIndoorStateChangeListener")
|
||||
}
|
||||
|
||||
override fun setOnMapClickListener(listener: IOnMapClickListener?) = afterInitialize {
|
||||
mapClickListener = listener
|
||||
it.setOnMapClickListener { latlng ->
|
||||
try {
|
||||
mapClickListener?.onMapClick(latlng.toGms())
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setOnMapLongClickListener(listener: IOnMapLongClickListener?) = afterInitialize {
|
||||
mapLongClickListener = listener
|
||||
it.setOnMapLongClickListener { latlng ->
|
||||
try {
|
||||
mapLongClickListener?.onMapLongClick(latlng.toGms())
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setOnMarkerClickListener(listener: IOnMarkerClickListener?) = afterInitialize { hmap ->
|
||||
hmap.setOnMarkerClickListener {
|
||||
Log.d("GmsGoogleMap", "setOnMarkerClickListener marker id -> ${it.id}")
|
||||
listener?.onMarkerClick(markers[it.id]) ?: false
|
||||
}
|
||||
}
|
||||
|
||||
override fun setOnMarkerDragListener(listener: IOnMarkerDragListener?) = afterInitialize {
|
||||
it.setOnMarkerDragListener(object : HuaweiMap.OnMarkerDragListener {
|
||||
override fun onMarkerDragStart(p0: Marker?) {
|
||||
listener?.onMarkerDragStart(markers[p0?.id])
|
||||
}
|
||||
|
||||
override fun onMarkerDrag(p0: Marker?) {
|
||||
listener?.onMarkerDrag(markers[p0?.id])
|
||||
}
|
||||
|
||||
override fun onMarkerDragEnd(p0: Marker?) {
|
||||
listener?.onMarkerDragEnd(markers[p0?.id])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun setOnInfoWindowClickListener(listener: IOnInfoWindowClickListener?) = afterInitialize { hmap ->
|
||||
Log.d(TAG, "setOnInfoWindowClickListener")
|
||||
hmap.setOnInfoWindowClickListener { listener?.onInfoWindowClick(markers[it.id]) }
|
||||
}
|
||||
|
||||
fun setOnInfoWindowCloseListener(listener: IOnInfoWindowCloseListener?) {
|
||||
Log.d(TAG, "unimplemented Method: setOnInfoWindowCloseListener")
|
||||
}
|
||||
|
||||
fun setOnInfoWindowLongClickListener(listener: IOnInfoWindowLongClickListener?) {
|
||||
Log.d(TAG, "unimplemented Method: setOnInfoWindowLongClickListener")
|
||||
}
|
||||
|
||||
override fun setInfoWindowAdapter(adapter: IInfoWindowAdapter?) = afterInitialize {
|
||||
Log.d(TAG, "setInfoWindowAdapter")
|
||||
it.setInfoWindowAdapter(object : HuaweiMap.InfoWindowAdapter {
|
||||
override fun getInfoContents(p0: Marker?): View? {
|
||||
return adapter?.getInfoContents(markers[p0?.id]).unwrap<View>()
|
||||
}
|
||||
|
||||
override fun getInfoWindow(p0: Marker?): View? {
|
||||
return adapter?.getInfoWindow(markers[p0?.id]).unwrap<View>()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
override fun setOnMyLocationChangeListener(listener: IOnMyLocationChangeListener?) = afterInitialize {
|
||||
Log.d(TAG, "deprecated Method: setOnMyLocationChangeListener")
|
||||
}
|
||||
|
||||
override fun setOnMyLocationButtonClickListener(listener: IOnMyLocationButtonClickListener?) = afterInitialize {
|
||||
Log.d(TAG, "setOnMyLocationButtonClickListener")
|
||||
it.setOnMyLocationButtonClickListener { listener?.onMyLocationButtonClick() ?: false }
|
||||
}
|
||||
|
||||
override fun setOnMyLocationClickListener(listener: IOnMyLocationClickListener?) = afterInitialize { hmap ->
|
||||
Log.d(TAG, "setOnMyLocationClickListener")
|
||||
hmap.setOnMyLocationClickListener { listener?.onMyLocationClick(it) }
|
||||
}
|
||||
|
||||
fun setOnPoiClickListener(listener: IOnPoiClickListener?) {
|
||||
Log.d(TAG, "unimplemented Method: setOnPoiClickListener")
|
||||
}
|
||||
|
||||
override fun setOnPolygonClickListener(listener: IOnPolygonClickListener?) = afterInitialize { hmap ->
|
||||
Log.d(TAG, "setOnPolygonClickListener")
|
||||
hmap.setOnPolygonClickListener { listener?.onPolygonClick(polygons[it.id]) }
|
||||
}
|
||||
|
||||
override fun setOnInfoWindowCloseListener(listener: com.google.android.gms.maps.internal.IOnInfoWindowCloseListener?) =
|
||||
afterInitialize {
|
||||
Log.d(TAG, "Not yet implemented setInfoWindowCloseListener")
|
||||
}
|
||||
|
||||
|
||||
override fun setOnPolylineClickListener(listener: IOnPolylineClickListener?) = afterInitialize { hmap ->
|
||||
Log.d(TAG, "unimplemented Method: setOnPolylineClickListener")
|
||||
hmap.setOnPolylineClickListener { listener?.onPolylineClick(polylines[it.id]) }
|
||||
}
|
||||
|
||||
override fun snapshot(callback: ISnapshotReadyCallback, bitmap: IObjectWrapper?) = afterInitialize {
|
||||
Log.d(TAG, "snapshot")
|
||||
val hmsBitmap = bitmap.unwrap<Bitmap>() ?: return@afterInitialize
|
||||
val hmsCallback = HuaweiMap.SnapshotReadyCallback { p0 -> callback.onBitmapReady(p0) }
|
||||
it.snapshot(hmsCallback, hmsBitmap)
|
||||
}
|
||||
|
||||
override fun snapshotForTest(callback: ISnapshotReadyCallback) = afterInitialize {
|
||||
Log.d(TAG, "snapshotForTest")
|
||||
val hmsCallback = HuaweiMap.SnapshotReadyCallback { p0 -> callback.onBitmapReady(p0) }
|
||||
it.snapshot(hmsCallback)
|
||||
}
|
||||
|
||||
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) = afterInitialize {
|
||||
Log.d(TAG, "setPadding: $left $top $right $bottom")
|
||||
it.setPadding(left, top, right, bottom)
|
||||
}
|
||||
|
||||
override fun isBuildingsEnabled(): Boolean {
|
||||
Log.d(TAG, "isBuildingsEnabled")
|
||||
return map?.isBuildingsEnabled ?: true
|
||||
}
|
||||
|
||||
override fun setBuildingsEnabled(buildings: Boolean) = afterInitialize {
|
||||
Log.d(TAG, "setBuildingsEnabled: $buildings")
|
||||
it.isBuildingsEnabled = buildings
|
||||
}
|
||||
|
||||
override fun setOnMapLoadedCallback(callback: IOnMapLoadedCallback?) {
|
||||
if (callback != null) {
|
||||
synchronized(mapLock) {
|
||||
if (loaded) {
|
||||
Log.d(TAG, "Invoking callback instantly, as map is loaded")
|
||||
try {
|
||||
callback.onMapLoaded()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Delay callback invocation, as map is not yet loaded")
|
||||
loadedCallback = callback
|
||||
}
|
||||
}
|
||||
} else {
|
||||
loadedCallback = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun setCameraMoveStartedListener(listener: IOnCameraMoveStartedListener?) = afterInitialize { hmap ->
|
||||
Log.d(TAG, "setCameraMoveStartedListener")
|
||||
cameraMoveStartedListener = listener
|
||||
hmap.setOnCameraMoveStartedListener {
|
||||
if (it == HuaweiMap.OnCameraMoveStartedListener.REASON_DEVELOPER_ANIMATION && inDeveloperAnimation) {
|
||||
Log.d(TAG, "onCameraMoveStarted <inDeveloperAnimation> skipped: 1st ")
|
||||
return@setOnCameraMoveStartedListener
|
||||
}
|
||||
try {
|
||||
Log.d(TAG, "Listener: onCameraMoveStarted: ")
|
||||
cameraMoveStartedListener?.onCameraMoveStarted(it)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setCameraMoveListener(listener: IOnCameraMoveListener?) = afterInitialize {
|
||||
Log.d(TAG, "setCameraMoveListener")
|
||||
cameraMoveListener = listener
|
||||
it.setOnCameraMoveListener {
|
||||
try {
|
||||
Log.d(TAG, "Listener: onCameraMove: ")
|
||||
if (SDK_INT >= 26) {
|
||||
mapView?.let { it.parent?.onDescendantInvalidated(it, it) }
|
||||
}
|
||||
map?.let {
|
||||
val cameraPosition = it.cameraPosition
|
||||
val tilt = cameraPosition.tilt
|
||||
val bearing = cameraPosition.bearing
|
||||
val useFast = tilt < 1f && (bearing % 360f < 1f || bearing % 360f > 359f)
|
||||
projectionImpl?.updateProjectionState(it.projection, useFast)
|
||||
}
|
||||
cameraMoveListener?.onCameraMove()
|
||||
cameraChangeListener?.onCameraChange(map?.cameraPosition?.toGms())
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setCameraMoveCanceledListener(listener: IOnCameraMoveCanceledListener?) = afterInitialize {
|
||||
Log.d(TAG, "setCameraMoveCanceledListener")
|
||||
cameraMoveCanceledListener = listener
|
||||
it.setOnCameraMoveCanceledListener {
|
||||
try {
|
||||
Log.d(TAG, "setOnCameraMoveCanceledListener: ")
|
||||
cameraMoveCanceledListener?.onCameraMoveCanceled()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setCameraIdleListener(listener: IOnCameraIdleListener?) = afterInitialize {
|
||||
Log.d(TAG, "setCameraIdleListener")
|
||||
cameraIdleListener = listener
|
||||
}
|
||||
|
||||
override fun getTestingHelper(): IObjectWrapper? {
|
||||
Log.d(TAG, "unimplemented Method: getTestingHelper")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun setWatermarkEnabled(watermark: Boolean) {
|
||||
Log.d(TAG, "unimplemented Method: setWatermarkEnabled")
|
||||
}
|
||||
|
||||
override fun useViewLifecycleWhenInFragment(): Boolean {
|
||||
Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment")
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
if (!created) {
|
||||
Log.d(TAG_LOGO, "create: ${context.packageName},\n$options")
|
||||
MapsInitializer.initialize(mapContext)
|
||||
val mapView = runCatching {
|
||||
TextureMapView(mapContext, options.toHms())
|
||||
}.onFailure {
|
||||
Log.w(TAG, "onCreate: init TextureMapView error ", it)
|
||||
}.getOrDefault(MapView(mapContext, options.toHms())).apply { visibility = View.INVISIBLE }
|
||||
this.mapView = mapView
|
||||
view.addView(mapView)
|
||||
mapView.onCreate(savedInstanceState?.toHms())
|
||||
mapView.getMapAsync(this::initMap)
|
||||
|
||||
created = true
|
||||
runOnMainLooper(forceQueue = true) { tryRunUserInitializedCallbacks("onCreate") }
|
||||
}
|
||||
}
|
||||
|
||||
private fun fakeWatermark(method: () -> Unit) {
|
||||
Log.d(TAG_LOGO, "start -> $view")
|
||||
val view1 = view.getChildAt(0) as? ViewGroup
|
||||
val view2 = view1?.getChildAt(0) as? ViewGroup
|
||||
val view4 = view2?.getChildAt(1)
|
||||
Log.d(TAG_LOGO, view4?.toString() ?: "view4 is null")
|
||||
if (view4 is LinearLayout) {
|
||||
view4.visibility = View.GONE
|
||||
method()
|
||||
} else {
|
||||
Log.d(TAG_LOGO, "LinearLayout not found")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAllChildViews(view: View, index: Int): List<View>? {
|
||||
Log.d(TAG_LOGO, "getAllChildViews: $index, $view")
|
||||
if (view is LinearLayout) {
|
||||
Log.d(TAG_LOGO, "legal: $index")
|
||||
view.visibility = View.GONE
|
||||
}
|
||||
val allChildren: MutableList<View> = ArrayList()
|
||||
if (view is ViewGroup) {
|
||||
val vp = view
|
||||
for (i in 0 until vp.childCount) {
|
||||
val viewChild = vp.getChildAt(i)
|
||||
Log.d(TAG_LOGO, "child:$index, $i, $viewChild")
|
||||
allChildren.add(viewChild)
|
||||
allChildren.addAll(getAllChildViews(viewChild, index + 1)!!)
|
||||
}
|
||||
}
|
||||
return allChildren
|
||||
}
|
||||
|
||||
private fun initMap(map: HuaweiMap) {
|
||||
if (this.map != null && initialized) return
|
||||
|
||||
loaded = true
|
||||
this.map = map
|
||||
|
||||
map.setOnCameraIdleListener {
|
||||
Log.d(TAG, "initMap: onCameraIdle: ")
|
||||
try {
|
||||
cameraChangeListener?.onCameraChange(map.cameraPosition.toGms())
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
|
||||
try {
|
||||
cameraIdleListener?.onCameraIdle()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
|
||||
map.setOnCameraMoveListener {
|
||||
Log.d(TAG, "initMap: onCameraMove: ")
|
||||
try {
|
||||
cameraMoveListener?.onCameraMove()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
map.setOnCameraMoveStartedListener {
|
||||
Log.d(TAG, "initMap: onCameraMoveStarted: $it")
|
||||
try {
|
||||
cameraMoveStartedListener?.onCameraMoveStarted(it)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
map.setOnCameraMoveCanceledListener {
|
||||
Log.d(TAG, "initMap: onCameraMoveCanceled: ")
|
||||
try {
|
||||
cameraMoveCanceledListener?.onCameraMoveCanceled()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
map.setOnMapClickListener { latlng ->
|
||||
try {
|
||||
if (options.liteMode) {
|
||||
val parentView = view.parent?.parent
|
||||
// TODO hms not support disable click listener when liteMode, this just fix for teams
|
||||
if (parentView != null && parentView::class.qualifiedName.equals("com.microsoft.teams.location.ui.map.MapViewLite")) {
|
||||
val clickView = parentView as ViewGroup
|
||||
clickView.performClick()
|
||||
return@setOnMapClickListener
|
||||
}
|
||||
}
|
||||
mapClickListener?.onMapClick(latlng.toGms())
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
map.setOnMapLongClickListener { latlng ->
|
||||
try {
|
||||
if (options.liteMode) {
|
||||
val parentView = view.parent?.parent
|
||||
// TODO hms not support disable click listener when liteMode, this just fix for teams
|
||||
if (parentView != null && parentView::class.qualifiedName.equals("com.microsoft.teams.location.ui.map.MapViewLite")) {
|
||||
val clickView = parentView as ViewGroup
|
||||
clickView.performLongClick()
|
||||
return@setOnMapLongClickListener
|
||||
}
|
||||
}
|
||||
mapLongClickListener?.onMapLongClick(latlng.toGms())
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
|
||||
synchronized(mapLock) {
|
||||
initialized = true
|
||||
markers.filter { it.key.startsWith("m") }.forEach { it.value.update() }
|
||||
waitingCameraUpdates.forEach { map.moveCamera(it) }
|
||||
val initializedCallbacks = ArrayList(internalOnInitializedCallbackList)
|
||||
Log.d(TAG, "Invoking ${initializedCallbacks.size} internal callbacks now that the true map is initialized")
|
||||
for (callback in initializedCallbacks) {
|
||||
callback.onMapReady(map)
|
||||
}
|
||||
internalOnInitializedCallbackList.clear()
|
||||
fakeWatermark { Log.d(TAG_LOGO, "fakeWatermark success") }
|
||||
|
||||
mapView?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
tryRunUserInitializedCallbacks(tag = "initMap")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
mapView?.visibility = View.VISIBLE
|
||||
mapView?.onResume()
|
||||
}
|
||||
override fun onPause() = mapView?.onPause() ?: Unit
|
||||
override fun onDestroy() {
|
||||
Log.d(TAG, "onDestroy")
|
||||
initializedCallbackList.clear()
|
||||
internalOnInitializedCallbackList.clear()
|
||||
circles.map { it.value.remove() }
|
||||
circles.clear()
|
||||
polylines.map { it.value.remove() }
|
||||
polylines.clear()
|
||||
polygons.map { it.value.remove() }
|
||||
polygons.clear()
|
||||
markers.map { it.value.remove() }
|
||||
markers.clear()
|
||||
// BitmapDescriptorFactoryImpl.unregisterMap(map)
|
||||
view.removeView(mapView)
|
||||
// TODO can crash?
|
||||
mapView?.onDestroy()
|
||||
mapView = null
|
||||
|
||||
// Don't make it null; this object is not deleted immediately, and it may want to access map.* stuff
|
||||
//map = null
|
||||
|
||||
created = false
|
||||
initialized = false
|
||||
loaded = false
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
mapView?.onStart()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
mapView?.visibility = View.INVISIBLE
|
||||
mapView?.onStop()
|
||||
}
|
||||
|
||||
override fun onEnterAmbient(bundle: Bundle?) {
|
||||
Log.d(TAG, "unimplemented Method: onEnterAmbient")
|
||||
}
|
||||
|
||||
override fun onExitAmbient() {
|
||||
Log.d(TAG, "unimplemented Method: onExitAmbient")
|
||||
}
|
||||
|
||||
override fun onLowMemory() = mapView?.onLowMemory() ?: Unit
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
val newBundle = Bundle()
|
||||
mapView?.onSaveInstanceState(newBundle)
|
||||
outState.putAll(newBundle.toGms())
|
||||
}
|
||||
|
||||
fun getMapAsync(callback: IOnMapReadyCallback) {
|
||||
synchronized(mapLock) {
|
||||
initializedCallbackList.add(callback)
|
||||
}
|
||||
tryRunUserInitializedCallbacks("getMapAsync")
|
||||
}
|
||||
|
||||
private fun afterInitialize(runnable: (HuaweiMap) -> Unit) {
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
runnable(map!!)
|
||||
} else {
|
||||
internalOnInitializedCallbackList.add(OnMapReadyCallback {
|
||||
runnable(it)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var isInvokingInitializedCallbacks = AtomicBoolean(false)
|
||||
private fun tryRunUserInitializedCallbacks(tag: String = "") {
|
||||
|
||||
synchronized(mapLock) {
|
||||
if (initializedCallbackList.isEmpty()) return
|
||||
}
|
||||
|
||||
val runCallbacks = {
|
||||
val callbacks = synchronized(mapLock) {
|
||||
ArrayList(initializedCallbackList)
|
||||
.also { initializedCallbackList.clear() }
|
||||
}
|
||||
|
||||
callbacks.forEach {
|
||||
try {
|
||||
it.onMapReady(this)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (initialized && map != null) {
|
||||
Log.d("$TAG:$tag", "Invoking callback now, as map is initialized")
|
||||
val wasCallbackActive = isInvokingInitializedCallbacks.getAndSet(true)
|
||||
runOnMainLooper(forceQueue = wasCallbackActive) {
|
||||
runCallbacks()
|
||||
}
|
||||
if (!wasCallbackActive) isInvokingInitializedCallbacks.set(false)
|
||||
} else {
|
||||
Log.d(
|
||||
"$TAG:$tag",
|
||||
"Initialized callbacks could not be run at this point, as the map view has not been created yet."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
Log.d(TAG, "onTransact: $code, $data, $flags")
|
||||
true
|
||||
} else {
|
||||
Log.w(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "GmsGoogleMap"
|
||||
|
||||
private const val TAG_LOGO = "fakeWatermark"
|
||||
private const val MAX_TIMES = 300
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import android.view.ViewGroup
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.maps.GoogleMapOptions
|
||||
import com.google.android.gms.maps.internal.IGoogleMapDelegate
|
||||
import com.google.android.gms.maps.internal.IMapFragmentDelegate
|
||||
import com.google.android.gms.maps.internal.IOnMapReadyCallback
|
||||
|
||||
class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stub() {
|
||||
|
||||
private var map: GoogleMapImpl? = null
|
||||
private var options: GoogleMapOptions? = null
|
||||
private var readyCallbackList: MutableList<IOnMapReadyCallback> = mutableListOf()
|
||||
|
||||
override fun onInflate(activity: IObjectWrapper, options: GoogleMapOptions, savedInstanceState: Bundle?) {
|
||||
Log.d(TAG, "onInflate: $options")
|
||||
this.options = options
|
||||
map?.options = options
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
if (options == null) {
|
||||
options = savedInstanceState?.getParcelable("MapOptions")
|
||||
}
|
||||
if (options == null) {
|
||||
options = GoogleMapOptions()
|
||||
}
|
||||
Log.d(TAG, "onCreate $this : $options ")
|
||||
if (map == null) {
|
||||
map = GoogleMapImpl(activity, options ?: GoogleMapOptions())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(layoutInflater: IObjectWrapper, container: IObjectWrapper, savedInstanceState: Bundle?): IObjectWrapper {
|
||||
if (options == null) {
|
||||
options = savedInstanceState?.getParcelable("MapOptions")
|
||||
}
|
||||
Log.d(TAG, "onCreateView: ${options?.camera?.target}")
|
||||
if (map == null) {
|
||||
map = GoogleMapImpl(activity, options ?: GoogleMapOptions())
|
||||
}
|
||||
Log.d(TAG, "onCreateView $this : $options")
|
||||
map!!.onCreate(savedInstanceState)
|
||||
readyCallbackList.forEach { map!!.getMapAsync(it) }
|
||||
readyCallbackList.clear()
|
||||
val view = map!!.view
|
||||
val parent = view.parent as ViewGroup?
|
||||
parent?.removeView(view)
|
||||
return ObjectWrapper.wrap(view)
|
||||
}
|
||||
|
||||
override fun getMap(): IGoogleMapDelegate? = map
|
||||
override fun onEnterAmbient(bundle: Bundle?) = map?.onEnterAmbient(bundle) ?: Unit
|
||||
override fun onExitAmbient() = map?.onExitAmbient() ?: Unit
|
||||
override fun onStart() = map?.onStart() ?: Unit
|
||||
override fun onStop() = map?.onStop() ?: Unit
|
||||
override fun onResume() = map?.onResume() ?: Unit
|
||||
override fun onPause() = map?.onPause() ?: Unit
|
||||
override fun onLowMemory() = map?.onLowMemory() ?: Unit
|
||||
override fun isReady(): Boolean = this.map != null
|
||||
override fun getMapAsync(callback: IOnMapReadyCallback) {
|
||||
Log.d(TAG, "getMapAsync: map: $map")
|
||||
if (map == null) {
|
||||
readyCallbackList.add(callback)
|
||||
return
|
||||
}
|
||||
map?.getMapAsync(callback)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
Log.d(TAG, "onDestroyView: $this : $options")
|
||||
if (options?.useViewLifecycleInFragment == true) {
|
||||
map?.onDestroy()
|
||||
map = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
Log.d(TAG, "onDestroy: $this")
|
||||
map?.onDestroy()
|
||||
map = null
|
||||
options = null
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
if (options != null) {
|
||||
outState.putParcelable("MapOptions", options)
|
||||
}
|
||||
map?.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean {
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
return true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsMapFragment"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.maps.GoogleMapOptions
|
||||
import com.google.android.gms.maps.internal.IGoogleMapDelegate
|
||||
import com.google.android.gms.maps.internal.IMapViewDelegate
|
||||
import com.google.android.gms.maps.internal.IOnMapReadyCallback
|
||||
|
||||
class MapViewImpl(private val context: Context, options: GoogleMapOptions?) : IMapViewDelegate.Stub() {
|
||||
|
||||
private var options: GoogleMapOptions = options ?: GoogleMapOptions()
|
||||
private var map: GoogleMapImpl? = null
|
||||
private var readyCallbackList: MutableList<IOnMapReadyCallback> = mutableListOf()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Log.d(TAG, "onCreate: $options")
|
||||
if (map == null) {
|
||||
map = GoogleMapImpl(context, options)
|
||||
}
|
||||
map!!.onCreate(savedInstanceState)
|
||||
readyCallbackList.forEach { map!!.getMapAsync(it) }
|
||||
readyCallbackList.clear()
|
||||
}
|
||||
|
||||
override fun getMap(): IGoogleMapDelegate? = map
|
||||
override fun onEnterAmbient(bundle: Bundle?) = map?.onEnterAmbient(bundle) ?: Unit
|
||||
override fun onExitAmbient() = map?.onExitAmbient() ?: Unit
|
||||
override fun onStart() = map?.onStart() ?: Unit
|
||||
override fun onStop() = map?.onStop() ?: Unit
|
||||
override fun onResume() = map?.onResume() ?: Unit
|
||||
override fun onPause() = map?.onPause() ?: Unit
|
||||
override fun onDestroy() {
|
||||
map?.onDestroy()
|
||||
map = null
|
||||
}
|
||||
|
||||
override fun onLowMemory() = map?.onLowMemory() ?: Unit
|
||||
override fun onSaveInstanceState(outState: Bundle) = map?.onSaveInstanceState(outState) ?: Unit
|
||||
override fun getView(): IObjectWrapper = ObjectWrapper.wrap(map?.view)
|
||||
override fun getMapAsync(callback: IOnMapReadyCallback) {
|
||||
Log.d(TAG, "getMapAsync: map: $map")
|
||||
if (map == null) {
|
||||
readyCallbackList.add(callback)
|
||||
return
|
||||
}
|
||||
map?.getMapAsync(callback)
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsMapView"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms
|
||||
|
||||
import android.graphics.Point
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.dynamic.unwrap
|
||||
import com.google.android.gms.maps.internal.IProjectionDelegate
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.LatLngBounds
|
||||
import com.google.android.gms.maps.model.VisibleRegion
|
||||
import com.huawei.hms.maps.Projection
|
||||
import org.microg.gms.maps.hms.utils.toGms
|
||||
import org.microg.gms.maps.hms.utils.toHms
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private const val TAG = "GmsProjectionImpl"
|
||||
|
||||
class ProjectionImpl(private var projection: Projection, private var withoutTiltOrBearing: Boolean) : IProjectionDelegate.Stub() {
|
||||
private var lastVisibleRegion: VisibleRegion? = null
|
||||
private var visibleRegion = projection.visibleRegion
|
||||
|
||||
private var farLeft: Point? = visibleRegion.farLeft?.let { projection.toScreenLocation(it) }
|
||||
private var farRight: Point? = visibleRegion.farRight?.let { projection.toScreenLocation(it) }
|
||||
private var nearLeft: Point? = visibleRegion.nearLeft?.let { projection.toScreenLocation(it) }
|
||||
|
||||
private var farLeftLat = visibleRegion.farLeft?.latitude ?: 0.0
|
||||
private var nearLeftLat = visibleRegion.nearLeft?.latitude ?: 0.0
|
||||
private var farLeftLng = visibleRegion.farLeft?.longitude ?: 0.0
|
||||
private var farRightLng = visibleRegion.farRight?.longitude ?: 0.0
|
||||
private var farLeftX = farLeft?.x ?: 0
|
||||
private var farLeftY = farLeft?.y ?: 0
|
||||
private var farRightX = farRight?.x ?: (farLeftX + 1)
|
||||
private var nearLeftY = nearLeft?.y ?: (farLeftY + 1)
|
||||
|
||||
fun updateProjectionState(newProjection: Projection, useFastMode: Boolean) {
|
||||
Log.d(TAG, "updateProjectionState: useFastMode: $useFastMode")
|
||||
projection = newProjection
|
||||
visibleRegion = newProjection.visibleRegion
|
||||
withoutTiltOrBearing = useFastMode
|
||||
|
||||
farLeft = visibleRegion.farLeft?.let { projection.toScreenLocation(it) }
|
||||
farRight = visibleRegion.farRight?.let { projection.toScreenLocation(it) }
|
||||
nearLeft = visibleRegion.nearLeft?.let { projection.toScreenLocation(it) }
|
||||
|
||||
farLeftLat = visibleRegion.farLeft?.latitude ?: 0.0
|
||||
nearLeftLat = visibleRegion.nearLeft?.latitude ?: 0.0
|
||||
farLeftLng = visibleRegion.farLeft?.longitude ?: 0.0
|
||||
farRightLng = visibleRegion.farRight?.longitude ?: 0.0
|
||||
farLeftX = farLeft?.x ?: 0
|
||||
farLeftY = farLeft?.y ?: 0
|
||||
farRightX = farRight?.x ?: (farLeftX + 1)
|
||||
nearLeftY = nearLeft?.y ?: (farLeftY + 1)
|
||||
}
|
||||
|
||||
private fun isInvalid(): Boolean {
|
||||
return farLeftX == farRightX || farLeftY == nearLeftY || (farRightX == 1 && farLeftX == 0) || (nearLeftY == 1 && farLeftY == 0)
|
||||
}
|
||||
|
||||
override fun fromScreenLocation(obj: IObjectWrapper?): LatLng? = try {
|
||||
obj.unwrap<Point>()?.let {
|
||||
if (withoutTiltOrBearing && farLeft != null && farRight != null && nearLeft != null) {
|
||||
if (isInvalid()) {
|
||||
Log.w(TAG, "Invalid projection layout, fallback to SDK")
|
||||
projection.fromScreenLocation(Point(it)).toGms()
|
||||
} else {
|
||||
val xPercent = (it.x.toFloat() - farLeftX) / (farRightX - farLeftX)
|
||||
val yPercent = (it.y.toFloat() - farLeftY) / (nearLeftY - farLeftY)
|
||||
|
||||
val lon = farLeftLng + xPercent * (farRightLng - farLeftLng)
|
||||
val lat = farLeftLat + yPercent * (nearLeftLat - farLeftLat)
|
||||
|
||||
Log.d(TAG, "fromScreenLocation: $it -> lat: $lat lon: $lon")
|
||||
|
||||
LatLng(lat, lon)
|
||||
}
|
||||
} else {
|
||||
projection.fromScreenLocation(Point(it)).toGms()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "fromScreenLocation() error", e)
|
||||
LatLng(0.0, 0.0)
|
||||
}
|
||||
|
||||
override fun toScreenLocation(latLng: LatLng?): IObjectWrapper = try {
|
||||
ObjectWrapper.wrap(latLng?.toHms()?.let {
|
||||
if (withoutTiltOrBearing && farLeft != null && farRight != null && nearLeft != null) {
|
||||
if (isInvalid()) {
|
||||
Log.w(TAG, "Invalid projection layout, fallback to SDK")
|
||||
projection.toScreenLocation(it).let { p -> Point(p.x, p.y) }
|
||||
} else {
|
||||
val xPercent = (it.longitude - farLeftLng) / (farRightLng - farLeftLng)
|
||||
val yPercent = (it.latitude - farLeftLat) / (nearLeftLat - farLeftLat)
|
||||
|
||||
val x = farLeftX + xPercent * (farRightX - farLeftX)
|
||||
val y = farLeftY + yPercent * (nearLeftY - farLeftY)
|
||||
|
||||
Log.d(TAG, "toScreenLocation: $latLng -> x: $x y: $y")
|
||||
|
||||
Point(x.roundToInt(), y.roundToInt())
|
||||
}
|
||||
} else {
|
||||
projection.toScreenLocation(it).let { p -> Point(p.x, p.y) }
|
||||
}
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "toScreenLocation() error", e)
|
||||
ObjectWrapper.wrap(Point(0, 0))
|
||||
}
|
||||
|
||||
override fun getVisibleRegion(): VisibleRegion? {
|
||||
if (visibleRegion.farLeft.latitude.isNaN() || visibleRegion.farLeft.longitude.isNaN()) {
|
||||
return lastVisibleRegion
|
||||
}
|
||||
lastVisibleRegion = visibleRegion.toGms()
|
||||
Log.d(TAG, "getVisibleRegion: $visibleRegion")
|
||||
return lastVisibleRegion
|
||||
}
|
||||
}
|
||||
|
||||
class DummyProjection : IProjectionDelegate.Stub() {
|
||||
override fun fromScreenLocation(obj: IObjectWrapper?): LatLng {
|
||||
Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate fromScreenLocation")
|
||||
return LatLng(0.0, 0.0)
|
||||
}
|
||||
|
||||
override fun toScreenLocation(latLng: LatLng?): IObjectWrapper {
|
||||
Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate toScreenLocation")
|
||||
return ObjectWrapper.wrap(Point(0, 0))
|
||||
}
|
||||
|
||||
override fun getVisibleRegion(): VisibleRegion {
|
||||
Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate getVisibleRegion")
|
||||
return VisibleRegion(LatLngBounds(LatLng(0.0, 0.0), LatLng(0.0, 0.0)))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.widget.TextView
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.maps.StreetViewPanoramaOptions
|
||||
import com.google.android.gms.maps.internal.IOnStreetViewPanoramaReadyCallback
|
||||
import com.google.android.gms.maps.internal.IStreetViewPanoramaDelegate
|
||||
import com.google.android.gms.maps.internal.IStreetViewPanoramaFragmentDelegate
|
||||
|
||||
class StreetViewPanoramaFragmentImpl(private val activity: Activity) : IStreetViewPanoramaFragmentDelegate.Stub() {
|
||||
|
||||
override fun getStreetViewPanorama(): IStreetViewPanoramaDelegate? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onInflate(activity: IObjectWrapper?, options: StreetViewPanoramaOptions?, savedInstanceState: Bundle?) {
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
}
|
||||
|
||||
override fun onCreateView(layoutInflater: IObjectWrapper?, container: IObjectWrapper?, savedInstanceState: Bundle?): IObjectWrapper {
|
||||
return ObjectWrapper.wrap(TextView(activity))
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
}
|
||||
|
||||
override fun isReady(): Boolean = true
|
||||
|
||||
override fun getStreetViewPanoramaAsync(callback: IOnStreetViewPanoramaReadyCallback?) {
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.widget.TextView
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.maps.internal.IOnStreetViewPanoramaReadyCallback
|
||||
import com.google.android.gms.maps.internal.IStreetViewPanoramaDelegate
|
||||
import com.google.android.gms.maps.internal.IStreetViewPanoramaViewDelegate
|
||||
|
||||
class StreetViewPanoramaViewImpl(private val context: Context) : IStreetViewPanoramaViewDelegate.Stub() {
|
||||
|
||||
override fun getStreetViewPanorama(): IStreetViewPanoramaDelegate? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
}
|
||||
|
||||
override fun getView(): IObjectWrapper? {
|
||||
return ObjectWrapper.wrap(TextView(context))
|
||||
}
|
||||
|
||||
override fun getStreetViewPanoramaAsync(callback: IOnStreetViewPanoramaReadyCallback?) {
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms
|
||||
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import android.view.ViewGroup
|
||||
import com.google.android.gms.maps.internal.IUiSettingsDelegate
|
||||
import com.huawei.hms.maps.OnMapReadyCallback
|
||||
import com.huawei.hms.maps.UiSettings
|
||||
import org.microg.gms.maps.hms.utils.MapUiController
|
||||
import org.microg.gms.maps.hms.utils.MapUiElement
|
||||
|
||||
private const val TAG = "GmsMapsUiSettings"
|
||||
|
||||
/**
|
||||
* This class "implements" unimplemented methods to avoid duplication in subclasses
|
||||
*/
|
||||
abstract class AbstractUiSettings : IUiSettingsDelegate.Stub() {
|
||||
override fun setZoomControlsEnabled(zoom: Boolean) {
|
||||
Log.d(TAG, "unimplemented Method: setZoomControlsEnabled")
|
||||
}
|
||||
|
||||
override fun setMyLocationButtonEnabled(locationButton: Boolean) {
|
||||
Log.d(TAG, "unimplemented Method: setMyLocationButtonEnabled")
|
||||
}
|
||||
|
||||
override fun isZoomControlsEnabled(): Boolean {
|
||||
Log.d(TAG, "unimplemented Method: isZoomControlsEnabled")
|
||||
return false
|
||||
}
|
||||
|
||||
override fun isMyLocationButtonEnabled(): Boolean {
|
||||
Log.d(TAG, "unimplemented Method: isMyLocationButtonEnabled")
|
||||
return false
|
||||
}
|
||||
|
||||
override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) {
|
||||
Log.d(TAG, "unimplemented Method: setIndoorLevelPickerEnabled")
|
||||
}
|
||||
|
||||
override fun isIndoorLevelPickerEnabled(): Boolean {
|
||||
Log.d(TAG, "unimplemented Method: isIndoorLevelPickerEnabled")
|
||||
return false
|
||||
}
|
||||
|
||||
override fun setMapToolbarEnabled(mapToolbar: Boolean) {
|
||||
Log.d(TAG, "unimplemented Method: setMapToolbarEnabled")
|
||||
}
|
||||
|
||||
override fun isMapToolbarEnabled(): Boolean {
|
||||
Log.d(TAG, "unimplemented Method: isMapToolbarEnabled")
|
||||
return false
|
||||
}
|
||||
|
||||
override fun setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringZoom: Boolean) {
|
||||
Log.d(TAG, "unimplemented Method: setScrollGesturesEnabledDuringRotateOrZoom")
|
||||
}
|
||||
|
||||
override fun isScrollGesturesEnabledDuringRotateOrZoom(): Boolean {
|
||||
Log.d(TAG, "unimplemented Method: isScrollGesturesEnabledDuringRotateOrZoom")
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class UiSettingsImpl(private val uiSettings: UiSettings, rootView: ViewGroup) : IUiSettingsDelegate.Stub() {
|
||||
|
||||
private val mapUiController = MapUiController(rootView)
|
||||
|
||||
init {
|
||||
uiSettings.isZoomControlsEnabled = false
|
||||
uiSettings.isCompassEnabled = false
|
||||
uiSettings.isMapToolbarEnabled = false
|
||||
uiSettings.isMyLocationButtonEnabled = false
|
||||
mapUiController.initUiStates(
|
||||
mapOf(
|
||||
MapUiElement.MyLocationButton to false,
|
||||
MapUiElement.ZoomView to false,
|
||||
MapUiElement.CompassView to false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun setZoomControlsEnabled(zoom: Boolean) {
|
||||
Log.d(TAG, "setZoomControlsEnabled: $zoom")
|
||||
uiSettings.isZoomControlsEnabled = zoom
|
||||
mapUiController.setUiEnabled(MapUiElement.ZoomView, zoom)
|
||||
}
|
||||
|
||||
override fun setCompassEnabled(compass: Boolean) {
|
||||
Log.d(TAG, "setCompassEnabled: $compass")
|
||||
uiSettings.isCompassEnabled = compass
|
||||
mapUiController.setUiEnabled(MapUiElement.CompassView, compass)
|
||||
}
|
||||
|
||||
override fun setMyLocationButtonEnabled(locationButton: Boolean) {
|
||||
Log.d(TAG, "setMyLocationButtonEnabled: $locationButton")
|
||||
uiSettings.isMyLocationButtonEnabled = locationButton
|
||||
mapUiController.setUiEnabled(MapUiElement.MyLocationButton, locationButton)
|
||||
}
|
||||
|
||||
override fun setScrollGesturesEnabled(scrollGestures: Boolean) {
|
||||
uiSettings.isScrollGesturesEnabled = scrollGestures
|
||||
}
|
||||
|
||||
override fun setZoomGesturesEnabled(zoomGestures: Boolean) {
|
||||
uiSettings.isZoomGesturesEnabled = zoomGestures
|
||||
}
|
||||
|
||||
override fun setTiltGesturesEnabled(tiltGestures: Boolean) {
|
||||
uiSettings.isTiltGesturesEnabled = tiltGestures
|
||||
}
|
||||
|
||||
override fun setRotateGesturesEnabled(rotateGestures: Boolean) {
|
||||
uiSettings.isRotateGesturesEnabled = rotateGestures
|
||||
}
|
||||
|
||||
override fun setAllGesturesEnabled(gestures: Boolean) {
|
||||
uiSettings.setAllGesturesEnabled(gestures)
|
||||
}
|
||||
|
||||
override fun isZoomControlsEnabled(): Boolean {
|
||||
Log.d(TAG, "isZoomControlsEnabled")
|
||||
return uiSettings.isZoomControlsEnabled
|
||||
}
|
||||
|
||||
override fun isCompassEnabled(): Boolean = uiSettings.isCompassEnabled
|
||||
|
||||
override fun isMyLocationButtonEnabled(): Boolean {
|
||||
Log.d(TAG, "isMyLocationButtonEnabled")
|
||||
return uiSettings.isMyLocationButtonEnabled
|
||||
}
|
||||
|
||||
override fun isScrollGesturesEnabled(): Boolean = uiSettings.isScrollGesturesEnabled
|
||||
|
||||
override fun isZoomGesturesEnabled(): Boolean = uiSettings.isZoomGesturesEnabled
|
||||
|
||||
override fun isTiltGesturesEnabled(): Boolean = uiSettings.isTiltGesturesEnabled
|
||||
|
||||
override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled
|
||||
|
||||
override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) {
|
||||
Log.d(TAG, "setIndoorLevelPickerEnabled: $indoorLevelPicker")
|
||||
uiSettings.isIndoorLevelPickerEnabled = indoorLevelPicker
|
||||
}
|
||||
|
||||
override fun isIndoorLevelPickerEnabled(): Boolean {
|
||||
Log.d(TAG, "isIndoorLevelPickerEnabled")
|
||||
return uiSettings.isIndoorLevelPickerEnabled
|
||||
}
|
||||
|
||||
override fun setMapToolbarEnabled(mapToolbar: Boolean) {
|
||||
Log.d(TAG, "setMapToolbarEnabled: $mapToolbar")
|
||||
uiSettings.isMapToolbarEnabled = mapToolbar
|
||||
}
|
||||
|
||||
override fun isMapToolbarEnabled(): Boolean {
|
||||
Log.d(TAG, "isMapToolbarEnabled")
|
||||
return uiSettings.isMapToolbarEnabled
|
||||
}
|
||||
|
||||
override fun setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringZoom: Boolean) {
|
||||
Log.d(TAG, "setScrollGesturesEnabledDuringRotateOrZoom: $scrollDuringZoom")
|
||||
uiSettings.isScrollGesturesEnabledDuringRotateOrZoom = scrollDuringZoom
|
||||
}
|
||||
|
||||
override fun isScrollGesturesEnabledDuringRotateOrZoom(): Boolean {
|
||||
Log.d(TAG, "isScrollGesturesEnabledDuringRotateOrZoom")
|
||||
return uiSettings.isScrollGesturesEnabledDuringRotateOrZoom
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
}
|
||||
|
||||
class UiSettingsCache : AbstractUiSettings() {
|
||||
|
||||
private var compass: Boolean? = null
|
||||
private var scrollGestures: Boolean? = null
|
||||
private var zoomGestures: Boolean? = null
|
||||
private var tiltGestures: Boolean? = null
|
||||
private var rotateGestures: Boolean? = null
|
||||
private var otherGestures: Boolean? = null
|
||||
|
||||
private var isZoomControlsEnabled: Boolean? = null
|
||||
private var isMyLocationButtonEnabled: Boolean? = null
|
||||
private var isAllGesturesEnabled: Boolean? = null
|
||||
private var isIndoorLevelPickerEnabled: Boolean? = null
|
||||
private var isMapToolbarEnabled: Boolean? = null
|
||||
private var isScrollGesturesEnabledDuringRotateOrZoom: Boolean? = null
|
||||
|
||||
override fun setMapToolbarEnabled(mapToolbar: Boolean) {
|
||||
Log.d(TAG, "setMapToolbarEnabled: $mapToolbar")
|
||||
this.isMapToolbarEnabled = mapToolbar
|
||||
}
|
||||
|
||||
override fun isMapToolbarEnabled(): Boolean {
|
||||
Log.d(TAG, "isMapToolbarEnabled")
|
||||
return isMapToolbarEnabled ?: true
|
||||
}
|
||||
|
||||
override fun setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringZoom: Boolean) {
|
||||
Log.d(TAG, "setScrollGesturesEnabledDuringRotateOrZoom: $scrollDuringZoom")
|
||||
this.isScrollGesturesEnabledDuringRotateOrZoom = scrollDuringZoom
|
||||
}
|
||||
|
||||
override fun isScrollGesturesEnabledDuringRotateOrZoom(): Boolean {
|
||||
Log.d(TAG, "isScrollGesturesEnabledDuringRotateOrZoom")
|
||||
return isScrollGesturesEnabledDuringRotateOrZoom ?: true
|
||||
}
|
||||
|
||||
override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) {
|
||||
Log.d(TAG, "setIndoorLevelPickerEnabled: $indoorLevelPicker")
|
||||
this.isIndoorLevelPickerEnabled = indoorLevelPicker
|
||||
}
|
||||
|
||||
override fun isIndoorLevelPickerEnabled(): Boolean {
|
||||
Log.d(TAG, "isIndoorLevelPickerEnabled")
|
||||
return isIndoorLevelPickerEnabled ?: true
|
||||
}
|
||||
|
||||
override fun setMyLocationButtonEnabled(locationButton: Boolean) {
|
||||
Log.d(TAG, "setMyLocationButtonEnabled: $locationButton")
|
||||
this.isMyLocationButtonEnabled = locationButton
|
||||
}
|
||||
|
||||
override fun isMyLocationButtonEnabled(): Boolean {
|
||||
Log.d(TAG, "isMyLocationButtonEnabled")
|
||||
return isMyLocationButtonEnabled ?: true
|
||||
}
|
||||
|
||||
override fun setZoomControlsEnabled(zoom: Boolean) {
|
||||
Log.d(TAG, "setZoomControlsEnabled: $zoom")
|
||||
this.isZoomControlsEnabled = zoom
|
||||
}
|
||||
|
||||
override fun isZoomControlsEnabled(): Boolean {
|
||||
Log.d(TAG, "isZoomControlsEnabled")
|
||||
return isZoomControlsEnabled ?: true
|
||||
}
|
||||
|
||||
override fun setCompassEnabled(compass: Boolean) {
|
||||
this.compass = compass
|
||||
}
|
||||
|
||||
override fun setScrollGesturesEnabled(scrollGestures: Boolean) {
|
||||
this.scrollGestures = scrollGestures
|
||||
}
|
||||
|
||||
override fun setZoomGesturesEnabled(zoomGestures: Boolean) {
|
||||
this.zoomGestures = zoomGestures
|
||||
}
|
||||
|
||||
override fun setTiltGesturesEnabled(tiltGestures: Boolean) {
|
||||
this.tiltGestures = tiltGestures
|
||||
}
|
||||
|
||||
override fun setRotateGesturesEnabled(rotateGestures: Boolean) {
|
||||
this.rotateGestures = rotateGestures
|
||||
}
|
||||
|
||||
override fun setAllGesturesEnabled(gestures: Boolean) {
|
||||
isAllGesturesEnabled = gestures
|
||||
// Simulate MapLibre's UiSettings behavior
|
||||
isScrollGesturesEnabled = gestures
|
||||
isRotateGesturesEnabled = gestures
|
||||
isTiltGesturesEnabled = gestures
|
||||
isZoomGesturesEnabled = gestures
|
||||
|
||||
// Other gestures toggles double tap and quick zoom gestures
|
||||
otherGestures = gestures
|
||||
}
|
||||
|
||||
override fun isCompassEnabled(): Boolean {
|
||||
return compass ?: true
|
||||
}
|
||||
|
||||
override fun isScrollGesturesEnabled(): Boolean {
|
||||
return scrollGestures ?: true
|
||||
}
|
||||
|
||||
override fun isZoomGesturesEnabled(): Boolean {
|
||||
return zoomGestures ?: true
|
||||
}
|
||||
|
||||
override fun isTiltGesturesEnabled(): Boolean {
|
||||
return tiltGestures ?: true
|
||||
}
|
||||
|
||||
override fun isRotateGesturesEnabled(): Boolean {
|
||||
return rotateGestures ?: true
|
||||
}
|
||||
|
||||
fun getMapReadyCallback(): OnMapReadyCallback = OnMapReadyCallback { map ->
|
||||
val uiSettings = map.uiSettings
|
||||
compass?.let { uiSettings.isCompassEnabled = it }
|
||||
scrollGestures?.let { uiSettings.isScrollGesturesEnabled = it }
|
||||
zoomGestures?.let { uiSettings.isZoomGesturesEnabled = it }
|
||||
tiltGestures?.let { uiSettings.isTiltGesturesEnabled = it }
|
||||
rotateGestures?.let { uiSettings.isRotateGesturesEnabled = it }
|
||||
isAllGesturesEnabled?.let { uiSettings.setAllGesturesEnabled(it) }
|
||||
|
||||
isZoomControlsEnabled?.let { uiSettings.isZoomControlsEnabled = it }
|
||||
isMyLocationButtonEnabled?.let { uiSettings.isMyLocationButtonEnabled = it }
|
||||
isIndoorLevelPickerEnabled?.let { uiSettings.isIndoorLevelPickerEnabled = it }
|
||||
isMapToolbarEnabled?.let { uiSettings.isMapToolbarEnabled = it }
|
||||
isScrollGesturesEnabledDuringRotateOrZoom?.let { uiSettings.isScrollGesturesEnabledDuringRotateOrZoom = it }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.model
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.graphics.*
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate
|
||||
import com.huawei.hms.maps.HuaweiMap
|
||||
import com.huawei.hms.maps.model.BitmapDescriptorFactory
|
||||
|
||||
|
||||
object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
|
||||
private val TAG = "GmsMapBitmap"
|
||||
private var resources: Resources? = null
|
||||
|
||||
fun initialize(resources: Resources?) {
|
||||
BitmapDescriptorFactoryImpl.resources = resources ?: BitmapDescriptorFactoryImpl.resources
|
||||
}
|
||||
|
||||
override fun fromResource(resourceId: Int): IObjectWrapper? {
|
||||
return BitmapFactory.decodeResource(resources, resourceId)?.let {
|
||||
ObjectWrapper.wrap(BitmapDescriptorFactory.fromBitmap(it))
|
||||
}
|
||||
}
|
||||
|
||||
override fun fromAsset(assetName: String): IObjectWrapper? {
|
||||
return resources?.assets?.open(assetName)?.let {
|
||||
BitmapFactory.decodeStream(it)
|
||||
?.let { ObjectWrapper.wrap(BitmapDescriptorFactory.fromBitmap(it)) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun fromFile(fileName: String): IObjectWrapper? {
|
||||
return BitmapFactory.decodeFile(fileName)
|
||||
?.let { ObjectWrapper.wrap(BitmapDescriptorFactory.fromBitmap(it)) }
|
||||
}
|
||||
|
||||
override fun defaultMarker(): IObjectWrapper? {
|
||||
return ObjectWrapper.wrap(BitmapDescriptorFactory.defaultMarker())
|
||||
}
|
||||
|
||||
override fun defaultMarkerWithHue(hue: Float): IObjectWrapper? {
|
||||
return ObjectWrapper.wrap(BitmapDescriptorFactory.defaultMarker(hue))
|
||||
}
|
||||
|
||||
override fun fromBitmap(bitmap: Bitmap): IObjectWrapper? {
|
||||
return ObjectWrapper.wrap(BitmapDescriptorFactory.fromBitmap(bitmap))
|
||||
}
|
||||
|
||||
override fun fromPath(absolutePath: String): IObjectWrapper? {
|
||||
return BitmapFactory.decodeFile(absolutePath)
|
||||
?.let { ObjectWrapper.wrap(BitmapDescriptorFactory.fromBitmap(it)) }
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.model
|
||||
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.dynamic.unwrap
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.PatternItem
|
||||
import com.google.android.gms.maps.model.internal.ICircleDelegate
|
||||
import com.huawei.hms.maps.model.Circle
|
||||
import org.microg.gms.maps.hms.utils.toGms
|
||||
import org.microg.gms.maps.hms.utils.toHms
|
||||
|
||||
class CircleImpl(private val circle: Circle) : ICircleDelegate.Stub() {
|
||||
private var tag: Any? = null
|
||||
|
||||
override fun remove() {
|
||||
circle.remove()
|
||||
}
|
||||
|
||||
override fun getId(): String = circle.id
|
||||
|
||||
override fun setCenter(center: LatLng) {
|
||||
circle.center = center.toHms()
|
||||
}
|
||||
|
||||
override fun getCenter(): LatLng = circle.center.toGms()
|
||||
|
||||
override fun setRadius(radius: Double) {
|
||||
circle.radius = radius
|
||||
}
|
||||
|
||||
override fun getRadius(): Double = circle.radius
|
||||
|
||||
override fun setStrokeWidth(width: Float) {
|
||||
circle.strokeWidth = width
|
||||
}
|
||||
|
||||
override fun getStrokeWidth(): Float = circle.strokeWidth
|
||||
|
||||
override fun setStrokeColor(color: Int) {
|
||||
circle.strokeColor = color
|
||||
}
|
||||
|
||||
override fun getStrokeColor(): Int = circle.strokeColor
|
||||
|
||||
override fun setTag(tag: IObjectWrapper) {
|
||||
this.tag = tag.unwrap()
|
||||
}
|
||||
|
||||
override fun getTag(): IObjectWrapper? {
|
||||
return ObjectWrapper.wrap(this.tag)
|
||||
}
|
||||
|
||||
override fun setStrokePattern(pattern: List<PatternItem>?) {
|
||||
circle.strokePattern = pattern?.map { it.toHms() }
|
||||
}
|
||||
|
||||
override fun getStrokePattern(): List<PatternItem>? {
|
||||
return circle.strokePattern?.map { it.toGms() }
|
||||
}
|
||||
|
||||
override fun setFillColor(color: Int) {
|
||||
circle.fillColor = color
|
||||
}
|
||||
|
||||
override fun getFillColor(): Int = circle.fillColor
|
||||
|
||||
override fun setZIndex(zIndex: Float) {
|
||||
circle.zIndex = zIndex
|
||||
}
|
||||
|
||||
override fun getZIndex(): Float = circle.zIndex
|
||||
|
||||
override fun setVisible(visible: Boolean) {
|
||||
circle.isVisible = visible
|
||||
}
|
||||
|
||||
override fun isVisible(): Boolean = circle.isVisible
|
||||
|
||||
override fun setClickable(clickable: Boolean) {
|
||||
circle.isClickable = clickable
|
||||
}
|
||||
|
||||
override fun isClickable(): Boolean {
|
||||
return circle.isClickable
|
||||
}
|
||||
|
||||
override fun equalsRemote(other: ICircleDelegate?): Boolean = equals(other)
|
||||
|
||||
override fun hashCodeRemote(): Int = hashCode()
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is CircleImpl) {
|
||||
return other.id == id
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG = "GmsMapCircle"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.model
|
||||
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.dynamic.unwrap
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.LatLngBounds
|
||||
import com.google.android.gms.maps.model.internal.IGroundOverlayDelegate
|
||||
import com.huawei.hms.maps.model.GroundOverlay
|
||||
import org.microg.gms.maps.hms.utils.toGms
|
||||
import org.microg.gms.maps.hms.utils.toHms
|
||||
|
||||
class GroundOverlayImpl(private val groundOverlay: GroundOverlay) : IGroundOverlayDelegate.Stub() {
|
||||
private var tag: Any? = null
|
||||
|
||||
override fun getId(): String {
|
||||
return groundOverlay.id
|
||||
}
|
||||
|
||||
override fun getPosition(): LatLng? {
|
||||
return groundOverlay.position?.toGms()
|
||||
}
|
||||
|
||||
override fun setPosition(pos: LatLng?) {
|
||||
pos?.let { groundOverlay.position = it.toHms() }
|
||||
}
|
||||
|
||||
override fun getWidth(): Float {
|
||||
return groundOverlay.width
|
||||
}
|
||||
|
||||
override fun getHeight(): Float {
|
||||
return groundOverlay.height
|
||||
}
|
||||
|
||||
override fun setDimensions(width: Float, height: Float) {
|
||||
groundOverlay.setDimensions(width, height)
|
||||
}
|
||||
|
||||
override fun getBounds(): LatLngBounds? {
|
||||
return groundOverlay.bounds?.toGms()
|
||||
}
|
||||
|
||||
override fun getBearing(): Float {
|
||||
return groundOverlay.bearing
|
||||
}
|
||||
|
||||
override fun setBearing(bearing: Float) {
|
||||
groundOverlay.bearing = bearing
|
||||
}
|
||||
|
||||
override fun setZIndex(zIndex: Float) {
|
||||
groundOverlay.zIndex = zIndex
|
||||
}
|
||||
|
||||
override fun getZIndex(): Float {
|
||||
return groundOverlay.zIndex
|
||||
}
|
||||
|
||||
override fun isVisible(): Boolean {
|
||||
return groundOverlay.isVisible
|
||||
}
|
||||
|
||||
override fun setVisible(visible: Boolean) {
|
||||
groundOverlay.isVisible = visible
|
||||
}
|
||||
|
||||
override fun getTransparency(): Float {
|
||||
return groundOverlay.transparency
|
||||
}
|
||||
|
||||
override fun setTransparency(transparency: Float) {
|
||||
groundOverlay.transparency = transparency
|
||||
}
|
||||
|
||||
override fun setDimension(dimension: Float) {
|
||||
groundOverlay.setDimensions(dimension)
|
||||
}
|
||||
|
||||
override fun setPositionFromBounds(bounds: LatLngBounds?) {
|
||||
bounds?.let { groundOverlay.setPositionFromBounds(it.toHms()) }
|
||||
}
|
||||
|
||||
override fun getTag(): IObjectWrapper? {
|
||||
return ObjectWrapper.wrap(this.tag)
|
||||
}
|
||||
|
||||
override fun isClickable(): Boolean = groundOverlay.isClickable
|
||||
|
||||
override fun setClickable(clickable: Boolean) {
|
||||
groundOverlay.isClickable = clickable
|
||||
}
|
||||
|
||||
override fun setImage(obj: IObjectWrapper?) {
|
||||
groundOverlay.setImage(obj.unwrap())
|
||||
}
|
||||
|
||||
override fun setTag(tag: IObjectWrapper) {
|
||||
this.tag = tag.unwrap()
|
||||
}
|
||||
|
||||
override fun equalsRemote(other: IGroundOverlayDelegate?): Boolean {
|
||||
return this == other
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return groundOverlay.hashCode()
|
||||
}
|
||||
|
||||
override fun hashCodeRemote(): Int {
|
||||
return hashCode()
|
||||
}
|
||||
|
||||
// override fun todo(obj: IObjectWrapper?) {
|
||||
// Log.d(TAG, "Not yet implemented")
|
||||
// }
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return groundOverlay == other
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
Log.d(TAG, "Method: remove")
|
||||
groundOverlay.remove()
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsMapGroundOverlay"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.model
|
||||
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.dynamic.unwrap
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.MarkerOptions
|
||||
import com.google.android.gms.maps.model.internal.IMarkerDelegate
|
||||
import com.huawei.hms.maps.model.Marker
|
||||
import org.microg.gms.maps.hms.GoogleMapImpl
|
||||
import org.microg.gms.maps.hms.utils.toGms
|
||||
import org.microg.gms.maps.hms.utils.toHms
|
||||
|
||||
class MarkerImpl(private val mapImpl: GoogleMapImpl, private val id: String, private val options: MarkerOptions) : IMarkerDelegate.Stub() {
|
||||
private var marker: Marker? = null
|
||||
private var tag: Any? = null
|
||||
|
||||
@Synchronized
|
||||
fun update() {
|
||||
marker = mapImpl.map?.addMarker(options.toHms())?.also {
|
||||
mapImpl.markers[it.id] = this
|
||||
}
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
marker?.remove()
|
||||
}
|
||||
|
||||
override fun getId(): String = marker?.id ?: id
|
||||
|
||||
override fun setPosition(position: LatLng?) {
|
||||
marker?.position = position?.toHms()
|
||||
}
|
||||
|
||||
override fun getPosition(): LatLng? {
|
||||
return marker?.position?.toGms()
|
||||
}
|
||||
|
||||
override fun setTitle(title: String?) {
|
||||
marker?.title = title
|
||||
}
|
||||
|
||||
override fun getTitle(): String? = marker?.title
|
||||
|
||||
override fun setSnippet(snippet: String?) {
|
||||
marker?.snippet = snippet
|
||||
}
|
||||
|
||||
override fun getSnippet(): String? = marker?.snippet
|
||||
|
||||
override fun setDraggable(draggable: Boolean) {
|
||||
marker?.isDraggable = draggable
|
||||
}
|
||||
|
||||
override fun isDraggable(): Boolean = marker?.isDraggable ?: false
|
||||
|
||||
override fun showInfoWindow() {
|
||||
marker?.showInfoWindow()
|
||||
}
|
||||
|
||||
override fun hideInfoWindow() {
|
||||
marker?.hideInfoWindow()
|
||||
}
|
||||
|
||||
override fun isInfoWindowShown(): Boolean {
|
||||
return marker?.isInfoWindowShown ?: false
|
||||
}
|
||||
|
||||
override fun setVisible(visible: Boolean) {
|
||||
marker?.isVisible = visible
|
||||
}
|
||||
|
||||
override fun isVisible(): Boolean = marker?.isVisible ?: false
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other is IMarkerDelegate) return other.id == id
|
||||
return false
|
||||
}
|
||||
|
||||
override fun equalsRemote(other: IMarkerDelegate?): Boolean = equals(other)
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "$id ($title)"
|
||||
}
|
||||
|
||||
override fun hashCodeRemote(): Int = hashCode()
|
||||
|
||||
override fun setIcon(obj: IObjectWrapper?) {
|
||||
marker?.setIcon(obj.unwrap())
|
||||
}
|
||||
|
||||
override fun setAnchor(x: Float, y: Float) {
|
||||
marker?.setMarkerAnchor(x, y)
|
||||
}
|
||||
|
||||
override fun setFlat(flat: Boolean) {
|
||||
marker?.isFlat = flat
|
||||
}
|
||||
|
||||
override fun isFlat(): Boolean {
|
||||
return marker?.isFlat ?: false
|
||||
}
|
||||
|
||||
override fun setRotation(rotation: Float) {
|
||||
marker?.rotation = rotation
|
||||
}
|
||||
|
||||
override fun getRotation(): Float = marker?.rotation ?: 0f
|
||||
|
||||
override fun setInfoWindowAnchor(x: Float, y: Float) {
|
||||
marker?.setInfoWindowAnchor(x, y)
|
||||
}
|
||||
|
||||
override fun setAlpha(alpha: Float) {
|
||||
marker?.alpha = alpha
|
||||
}
|
||||
|
||||
override fun getAlpha(): Float = marker?.alpha ?: 0f
|
||||
|
||||
override fun setZIndex(zIndex: Float) {
|
||||
marker?.zIndex = zIndex
|
||||
}
|
||||
|
||||
override fun getZIndex(): Float = marker?.zIndex ?: 0f
|
||||
|
||||
override fun setTag(obj: IObjectWrapper?) {
|
||||
this.tag = obj.unwrap()
|
||||
}
|
||||
|
||||
override fun getTag(): IObjectWrapper = ObjectWrapper.wrap(this.tag)
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsMapMarker"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.model
|
||||
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.dynamic.unwrap
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.PatternItem
|
||||
import com.google.android.gms.maps.model.internal.IPolygonDelegate
|
||||
import com.huawei.hms.maps.model.Polygon
|
||||
import org.microg.gms.maps.hms.utils.toGms
|
||||
import org.microg.gms.maps.hms.utils.toHms
|
||||
import org.microg.gms.utils.warnOnTransactionIssues
|
||||
|
||||
class PolygonImpl(private val polygon: Polygon) : IPolygonDelegate.Stub() {
|
||||
private var tag: Any? = null
|
||||
|
||||
override fun remove() {
|
||||
polygon.remove()
|
||||
}
|
||||
|
||||
override fun getId(): String = polygon.id
|
||||
|
||||
override fun setPoints(points: List<LatLng>) {
|
||||
polygon.points = points.map { it.toHms() }
|
||||
}
|
||||
|
||||
override fun getPoints(): List<LatLng> = polygon.points.map { it.toGms() }
|
||||
|
||||
override fun setHoles(holes: List<Any?>?) {
|
||||
if (holes == null) {
|
||||
polygon.holes = emptyList()
|
||||
} else {
|
||||
val outHmsHoles: MutableList<MutableList<com.huawei.hms.maps.model.LatLng>> =
|
||||
ArrayList()
|
||||
for (out in holes) {
|
||||
if (out is List<*>) {
|
||||
val inHmsHoles: MutableList<com.huawei.hms.maps.model.LatLng> = ArrayList()
|
||||
for (inn in out) {
|
||||
if (inn is LatLng) {
|
||||
inHmsHoles.add(inn.toHms())
|
||||
}
|
||||
}
|
||||
outHmsHoles.add(inHmsHoles)
|
||||
}
|
||||
}
|
||||
polygon.holes = outHmsHoles
|
||||
}
|
||||
}
|
||||
|
||||
override fun getHoles(): List<Any?> {
|
||||
val outHoles = polygon.holes ?: return emptyList()
|
||||
val outGmsHoles: MutableList<MutableList<LatLng>> = ArrayList()
|
||||
for (inHoles in outHoles) {
|
||||
if (inHoles != null) {
|
||||
val inGmsHoles: MutableList<LatLng> = ArrayList()
|
||||
for (inHole in inHoles) {
|
||||
inGmsHoles.add(inHole.toGms())
|
||||
}
|
||||
outGmsHoles.add(inGmsHoles)
|
||||
}
|
||||
}
|
||||
return outGmsHoles
|
||||
}
|
||||
|
||||
override fun setStrokeWidth(width: Float) {
|
||||
polygon.strokeWidth = width
|
||||
}
|
||||
|
||||
override fun getStrokeWidth(): Float = polygon.strokeWidth
|
||||
|
||||
override fun setStrokeColor(color: Int) {
|
||||
polygon.strokeColor = color
|
||||
}
|
||||
|
||||
override fun getStrokeColor(): Int = polygon.strokeColor
|
||||
|
||||
override fun setFillColor(color: Int) {
|
||||
polygon.fillColor = color
|
||||
}
|
||||
|
||||
override fun getFillColor(): Int {
|
||||
return polygon.fillColor
|
||||
}
|
||||
|
||||
override fun setZIndex(zIndex: Float) {
|
||||
polygon.zIndex = zIndex
|
||||
}
|
||||
|
||||
override fun getZIndex(): Float {
|
||||
return polygon.zIndex
|
||||
}
|
||||
|
||||
override fun setVisible(visible: Boolean) {
|
||||
polygon.isVisible = visible
|
||||
}
|
||||
|
||||
override fun isVisible(): Boolean {
|
||||
return polygon.isVisible
|
||||
}
|
||||
|
||||
override fun setGeodesic(geod: Boolean) {
|
||||
polygon.isGeodesic = geod
|
||||
}
|
||||
|
||||
override fun isGeodesic(): Boolean {
|
||||
return polygon.isGeodesic
|
||||
}
|
||||
|
||||
override fun getStrokeJointType(): Int {
|
||||
return polygon.strokeJointType
|
||||
}
|
||||
|
||||
override fun getStrokePattern(): List<PatternItem>? {
|
||||
return polygon.strokePattern?.map { it.toGms() }
|
||||
}
|
||||
|
||||
override fun getTag(): IObjectWrapper {
|
||||
return ObjectWrapper.wrap(this.tag)
|
||||
}
|
||||
|
||||
override fun isClickable(): Boolean {
|
||||
return polygon.isClickable
|
||||
}
|
||||
|
||||
override fun setClickable(clickable: Boolean) {
|
||||
polygon.isClickable = clickable
|
||||
}
|
||||
|
||||
override fun setStrokeJointType(jointType: Int) {
|
||||
polygon.strokeJointType = jointType
|
||||
}
|
||||
|
||||
override fun setStrokePattern(pattern: List<PatternItem>?) {
|
||||
polygon.strokePattern = pattern?.map { it.toHms() }
|
||||
}
|
||||
|
||||
override fun setTag(tag: IObjectWrapper?) {
|
||||
this.tag = tag.unwrap()
|
||||
}
|
||||
|
||||
override fun equalsRemote(other: IPolygonDelegate?): Boolean = equals(other)
|
||||
|
||||
override fun hashCodeRemote(): Int = hashCode()
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is PolygonImpl) {
|
||||
return other.id == id
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags) { super.onTransact(code, data, reply, flags) }
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsMapPolygon"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.model
|
||||
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.dynamic.unwrap
|
||||
import com.google.android.gms.maps.model.*
|
||||
import com.google.android.gms.maps.model.BitmapDescriptor
|
||||
import com.google.android.gms.maps.model.CustomCap
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.PatternItem
|
||||
import com.google.android.gms.maps.model.PolylineOptions
|
||||
import com.google.android.gms.maps.model.internal.IPolylineDelegate
|
||||
import com.huawei.hms.maps.model.*
|
||||
import com.huawei.hms.maps.model.ButtCap as HmsButtCap
|
||||
import com.huawei.hms.maps.model.Cap as HmsCap
|
||||
import com.huawei.hms.maps.model.CustomCap as HmsCustomCap
|
||||
import com.huawei.hms.maps.model.RoundCap as HmsRoundCap
|
||||
import com.huawei.hms.maps.model.SquareCap as HmsSquareCap
|
||||
import com.huawei.hms.maps.model.LatLng as HmsLatLng
|
||||
import org.microg.gms.maps.hms.utils.toGms
|
||||
import org.microg.gms.maps.hms.utils.toGmsPolylineWidth
|
||||
import org.microg.gms.maps.hms.utils.toHms
|
||||
import org.microg.gms.maps.hms.utils.toHmsPolylineWidth
|
||||
|
||||
class PolylineImpl(private val polyline: Polyline, polylineOptions: PolylineOptions) : IPolylineDelegate.Stub() {
|
||||
private var tag: Any? = null
|
||||
private val linePoints = arrayListOf<LatLng>()
|
||||
private var lastPointsHash: Int = 0
|
||||
|
||||
private val toHmsCache = mutableMapOf<LatLng, HmsLatLng>()
|
||||
private fun List<LatLng>.toHmsList(): List<HmsLatLng> {
|
||||
return this.map { latLng ->
|
||||
toHmsCache.getOrPut(latLng) { latLng.toHms() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
linePoints.clear()
|
||||
toHmsCache.clear()
|
||||
polyline.remove()
|
||||
}
|
||||
|
||||
override fun getId(): String = polyline.id
|
||||
|
||||
override fun setPoints(points: List<LatLng>) {
|
||||
if (linePoints.size == points.size && linePoints == points) {
|
||||
Log.d(TAG, "setPoints skipped: identical points")
|
||||
return
|
||||
}
|
||||
|
||||
val newHash = points.hashCode()
|
||||
if (newHash == lastPointsHash) {
|
||||
Log.d(TAG, "setPoints skipped: hash unchanged")
|
||||
return
|
||||
}
|
||||
lastPointsHash = newHash
|
||||
|
||||
linePoints.clear()
|
||||
linePoints.addAll(points)
|
||||
polyline.points = linePoints.toHmsList()
|
||||
Log.d(TAG, "setPoints updated, size=${linePoints.size}")
|
||||
}
|
||||
|
||||
override fun getPoints(): List<LatLng> {
|
||||
return linePoints
|
||||
}
|
||||
|
||||
override fun setWidth(width: Float) {
|
||||
polyline.width = toHmsPolylineWidth(width)
|
||||
}
|
||||
|
||||
override fun getWidth(): Float {
|
||||
return toGmsPolylineWidth(polyline.width)
|
||||
}
|
||||
|
||||
override fun setColor(color: Int) {
|
||||
polyline.color = color
|
||||
}
|
||||
|
||||
override fun getColor(): Int {
|
||||
return polyline.color
|
||||
}
|
||||
|
||||
override fun setZIndex(zIndex: Float) {
|
||||
Log.d(TAG, "setZIndex: $zIndex")
|
||||
polyline.zIndex = zIndex
|
||||
}
|
||||
|
||||
override fun getZIndex(): Float {
|
||||
Log.d(TAG, "getZIndex")
|
||||
return polyline.zIndex
|
||||
}
|
||||
|
||||
override fun setVisible(visible: Boolean) {
|
||||
polyline.isVisible = visible
|
||||
}
|
||||
|
||||
override fun isVisible(): Boolean {
|
||||
return polyline.isVisible
|
||||
}
|
||||
|
||||
override fun setGeodesic(geod: Boolean) {
|
||||
Log.d(TAG, "setGeodesic: $geod")
|
||||
polyline.isGeodesic = geod
|
||||
}
|
||||
|
||||
override fun isGeodesic(): Boolean {
|
||||
Log.d(TAG, "isGeodesic")
|
||||
return polyline.isGeodesic
|
||||
}
|
||||
|
||||
override fun setClickable(clickable: Boolean) {
|
||||
Log.d(TAG, "setClickable: $clickable")
|
||||
polyline.isClickable = clickable
|
||||
}
|
||||
|
||||
override fun isClickable(): Boolean {
|
||||
Log.d(TAG, "isClickable")
|
||||
return polyline.isClickable
|
||||
}
|
||||
|
||||
override fun equalsRemote(other: IPolylineDelegate?): Boolean = equals(other)
|
||||
|
||||
override fun hashCodeRemote(): Int = hashCode()
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is PolylineImpl) {
|
||||
return other.id == id
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getPattern(): List<PatternItem>? {
|
||||
Log.d(TAG, "Method: getStrokePattern")
|
||||
return polyline.pattern?.map { it.toGms() }
|
||||
}
|
||||
|
||||
override fun getTag(): IObjectWrapper {
|
||||
return ObjectWrapper.wrap(this.tag)
|
||||
}
|
||||
|
||||
override fun setJointType(jointType: Int) {
|
||||
polyline.jointType = jointType
|
||||
}
|
||||
|
||||
override fun getJointType(): Int {
|
||||
return polyline.jointType
|
||||
}
|
||||
|
||||
override fun setPattern(pattern: List<PatternItem>?) {
|
||||
Log.d(TAG, "Method: setStrokePattern")
|
||||
polyline.pattern = pattern?.map { it.toHms() }
|
||||
}
|
||||
|
||||
override fun setTag(tag: IObjectWrapper?) {
|
||||
this.tag = tag.unwrap()
|
||||
}
|
||||
|
||||
override fun setEndCap(endCap: Cap) {
|
||||
polyline.endCap = endCap.toHms()
|
||||
}
|
||||
|
||||
override fun getEndCap(): Cap {
|
||||
return polyline.endCap.toGms()
|
||||
}
|
||||
|
||||
override fun setStartCap(startCap: Cap) {
|
||||
polyline.startCap = startCap.toHms()
|
||||
}
|
||||
|
||||
override fun getStartCap(): Cap {
|
||||
return polyline.startCap.toGms()
|
||||
}
|
||||
|
||||
private fun Cap.toHms(): HmsCap {
|
||||
return when (this) {
|
||||
is ButtCap -> HmsButtCap()
|
||||
is SquareCap -> HmsSquareCap()
|
||||
is RoundCap -> HmsRoundCap()
|
||||
is CustomCap -> HmsCustomCap(bitmapDescriptor.remoteObject.unwrap(), refWidth)
|
||||
else -> HmsButtCap()
|
||||
}
|
||||
}
|
||||
|
||||
private fun com.huawei.hms.maps.model.Cap.toGms(): Cap {
|
||||
return when (this) {
|
||||
is HmsButtCap -> ButtCap()
|
||||
is HmsSquareCap -> SquareCap()
|
||||
is HmsRoundCap -> RoundCap()
|
||||
is HmsCustomCap -> CustomCap(BitmapDescriptor(ObjectWrapper.wrap(bitmapDescriptor)), refWidth)
|
||||
else -> ButtCap()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsMapPolyline"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.model
|
||||
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.maps.model.internal.ITileOverlayDelegate
|
||||
import com.huawei.hms.maps.model.TileOverlay
|
||||
|
||||
class TileOverlayImpl(private val tileOverlay: TileOverlay) : ITileOverlayDelegate.Stub() {
|
||||
|
||||
override fun clearTileCache() {
|
||||
tileOverlay.clearTileCache()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return tileOverlay == other
|
||||
}
|
||||
|
||||
override fun getFadeIn(): Boolean {
|
||||
return tileOverlay.fadeIn
|
||||
}
|
||||
|
||||
override fun getId(): String {
|
||||
return tileOverlay.id
|
||||
}
|
||||
|
||||
override fun getTransparency(): Float {
|
||||
return tileOverlay.transparency
|
||||
}
|
||||
|
||||
override fun getZIndex(): Float {
|
||||
return tileOverlay.zIndex
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return tileOverlay.hashCode()
|
||||
}
|
||||
|
||||
override fun isVisible(): Boolean {
|
||||
return tileOverlay.isVisible
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
return tileOverlay.remove()
|
||||
}
|
||||
|
||||
override fun setFadeIn(fadeIn: Boolean) {
|
||||
tileOverlay.fadeIn = fadeIn
|
||||
}
|
||||
|
||||
override fun setTransparency(transparency: Float) {
|
||||
tileOverlay.transparency = transparency
|
||||
}
|
||||
|
||||
override fun setVisible(visible: Boolean) {
|
||||
tileOverlay.isVisible = visible
|
||||
}
|
||||
|
||||
override fun setZIndex(zIndex: Float) {
|
||||
tileOverlay.zIndex = zIndex
|
||||
}
|
||||
|
||||
override fun equalsRemote(other: ITileOverlayDelegate): Boolean = tileOverlay == (other as? TileOverlayImpl)?.tileOverlay
|
||||
override fun hashCodeRemote(): Int = tileOverlay.hashCode()
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
Log.e(TAG, "onTransact [known]: $code, $data, $flags")
|
||||
true
|
||||
} else {
|
||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsMapTileOverlay"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.view.LayoutInflater
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.huawei.hms.maps.MapClientIdentify
|
||||
import com.huawei.hms.maps.utils.MapClientUtil
|
||||
import org.microg.gms.common.Constants
|
||||
import java.io.File
|
||||
|
||||
class MapContext(private val context: Context) : ContextWrapper(context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY)) {
|
||||
private var layoutInflater: LayoutInflater? = null
|
||||
private val appContext: Context
|
||||
get() = context.applicationContext ?: context
|
||||
|
||||
override fun getApplicationContext(): Context {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun getCacheDir(): File {
|
||||
val cacheDir = File(appContext.cacheDir, "com.google.android.gms")
|
||||
cacheDir.mkdirs()
|
||||
return cacheDir
|
||||
}
|
||||
|
||||
override fun getFilesDir(): File {
|
||||
val filesDir = File(appContext.filesDir, "com.google.android.gms")
|
||||
filesDir.mkdirs()
|
||||
return filesDir
|
||||
}
|
||||
|
||||
override fun getClassLoader(): ClassLoader {
|
||||
return MapContext::class.java.classLoader!!
|
||||
}
|
||||
|
||||
override fun getPackageName(): String {
|
||||
// Use original package name for requests not from HMS MapClientIdentify
|
||||
val stackTrace = Thread.currentThread().stackTrace
|
||||
if (stackTrace.any { it.className == MapClientUtil::class.java.name || it.className == MapClientIdentify::class.java.name }) return Constants.GMS_PACKAGE_NAME
|
||||
return appContext.packageName
|
||||
}
|
||||
|
||||
override fun getSharedPreferences(name: String?, mode: Int): SharedPreferences {
|
||||
return appContext.getSharedPreferences("com.google.android.gms_$name", mode)
|
||||
}
|
||||
|
||||
override fun getSystemService(name: String): Any? {
|
||||
if (name == Context.LAYOUT_INFLATER_SERVICE) {
|
||||
if (layoutInflater == null) {
|
||||
layoutInflater = super.getSystemService(name) as LayoutInflater
|
||||
layoutInflater?.cloneInContext(this)?.let { layoutInflater = it }
|
||||
}
|
||||
if (layoutInflater != null) {
|
||||
return layoutInflater
|
||||
}
|
||||
}
|
||||
return context.getSystemService(name)
|
||||
}
|
||||
|
||||
override fun startActivity(intent: Intent?) {
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
@RequiresApi(24)
|
||||
override fun createDeviceProtectedStorageContext(): Context {
|
||||
return appContext.createDeviceProtectedStorageContext()
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG = "GmsMapContext"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.utils
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
enum class MapUiElement(val classType: String) {
|
||||
MyLocationButton("MyLocationButton"),
|
||||
ZoomView("ZoomView"),
|
||||
CompassView("CompassView")
|
||||
}
|
||||
|
||||
class MapUiController(private val rootView: ViewGroup) {
|
||||
|
||||
private val uiViews = mutableMapOf<MapUiElement, View>()
|
||||
private val uiStates = mutableMapOf<MapUiElement, Boolean>()
|
||||
|
||||
init {
|
||||
MapUiElement.entries.forEach { element ->
|
||||
rootView.waitForChild(element.classType) { view ->
|
||||
uiViews[element] = view
|
||||
val uiEnabled = isUiEnabled(element)
|
||||
view.isEnabled = uiEnabled
|
||||
view.alpha = if (uiEnabled) 1f else 0f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setUiEnabled(element: MapUiElement, enabled: Boolean) {
|
||||
uiStates[element] = enabled
|
||||
uiViews[element]?.alpha = if (enabled) 1f else 0f
|
||||
uiViews[element]?.isEnabled = enabled
|
||||
}
|
||||
|
||||
fun isUiEnabled(element: MapUiElement): Boolean {
|
||||
return uiStates[element] ?: true
|
||||
}
|
||||
|
||||
fun initUiStates(states: Map<MapUiElement, Boolean>) {
|
||||
states.forEach { (element, enabled) ->
|
||||
setUiEnabled(element, enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ViewGroup.waitForChild(classType: String, onReady: (View) -> Unit) {
|
||||
for (i in 0 until childCount) {
|
||||
val child = getChildAt(i)
|
||||
if (child.javaClass.name.contains(classType)) {
|
||||
onReady(child)
|
||||
return
|
||||
}
|
||||
if (child is ViewGroup) {
|
||||
child.waitForChild(classType, onReady)
|
||||
}
|
||||
}
|
||||
|
||||
setOnHierarchyChangeListener(object : ViewGroup.OnHierarchyChangeListener {
|
||||
override fun onChildViewAdded(parent: View?, child: View?) {
|
||||
if (child?.javaClass?.name?.contains(classType) == true) {
|
||||
onReady(child)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChildViewRemoved(parent: View?, child: View?) {}
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.maps.hms.utils
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import com.google.android.gms.dynamic.unwrap
|
||||
import com.google.android.gms.maps.GoogleMapOptions
|
||||
import com.google.android.gms.maps.internal.ICancelableCallback
|
||||
import com.huawei.hms.maps.HuaweiMap
|
||||
import com.huawei.hms.maps.HuaweiMapOptions
|
||||
import com.huawei.hms.maps.model.*
|
||||
import org.microg.gms.maps.hms.R
|
||||
import com.google.android.gms.maps.model.CameraPosition as GmsCameraPosition
|
||||
import com.google.android.gms.maps.model.CircleOptions as GmsCircleOptions
|
||||
import com.google.android.gms.maps.model.Dash as GmsDash
|
||||
import com.google.android.gms.maps.model.Dot as GmsDot
|
||||
import com.google.android.gms.maps.model.Gap as GmsGap
|
||||
import com.google.android.gms.maps.model.GroundOverlayOptions as GmsGroundOverlayOptions
|
||||
import com.google.android.gms.maps.model.LatLng as GmsLatLng
|
||||
import com.google.android.gms.maps.model.LatLngBounds as GmsLatLngBounds
|
||||
import com.google.android.gms.maps.model.MapStyleOptions as GmsMapStyleOptions
|
||||
import com.google.android.gms.maps.model.MarkerOptions as GmsMarkerOptions
|
||||
import com.google.android.gms.maps.model.PatternItem as GmsPatternItem
|
||||
import com.google.android.gms.maps.model.PolygonOptions as GmsPolygonOptions
|
||||
import com.google.android.gms.maps.model.PolylineOptions as GmsPolylineOptions
|
||||
import com.google.android.gms.maps.model.Tile as GmsTile
|
||||
import com.google.android.gms.maps.model.TileOverlayOptions as GmsTileOverlayOptions
|
||||
import com.google.android.gms.maps.model.VisibleRegion as GmsVisibleRegion
|
||||
|
||||
fun GmsCameraPosition.toHms(): CameraPosition {
|
||||
return CameraPosition.Builder().target(target.toHms()).zoom(toHmsZoom(zoom)).tilt(tilt)
|
||||
.bearing(toHmsBearing(bearing)).build()
|
||||
}
|
||||
|
||||
fun GmsCircleOptions.toHms(): CircleOptions =
|
||||
CircleOptions().center(center.toHms()).clickable(isClickable).fillColor(fillColor)
|
||||
.radius(radius).strokeColor(strokeColor).strokeWidth(strokeWidth).visible(isVisible)
|
||||
.zIndex(zIndex)
|
||||
|
||||
fun GmsPatternItem.toHms(): PatternItem {
|
||||
return when (this) {
|
||||
is GmsDash -> Dash(length)
|
||||
is GmsDot -> Dot()
|
||||
is GmsGap -> Gap(length)
|
||||
else -> PatternItem(0,0f)
|
||||
}
|
||||
}
|
||||
|
||||
fun GoogleMapOptions.toHms(): HuaweiMapOptions {
|
||||
val huaweiMapOptions = HuaweiMapOptions()
|
||||
camera?.let { huaweiMapOptions.camera(camera?.toHms()) }
|
||||
if (maxZoomPreference != 0f) {
|
||||
huaweiMapOptions.maxZoomPreference(toHmsZoom(maxZoomPreference))
|
||||
}
|
||||
if (minZoomPreference != 0f) {
|
||||
huaweiMapOptions.minZoomPreference(toHmsZoom(minZoomPreference))
|
||||
}
|
||||
latLngBoundsForCameraTarget?.let {
|
||||
huaweiMapOptions.latLngBoundsForCameraTarget(
|
||||
latLngBoundsForCameraTarget?.toHms()
|
||||
)
|
||||
}
|
||||
|
||||
return huaweiMapOptions
|
||||
.compassEnabled(isCompassEnabled)
|
||||
.liteMode(liteMode)
|
||||
// .mapType(mapType)
|
||||
.rotateGesturesEnabled(rotateGesturesEnabled == true)
|
||||
.scrollGesturesEnabled(scrollGesturesEnabled == true)
|
||||
.tiltGesturesEnabled(tiltGesturesEnabled == true)
|
||||
.useViewLifecycleInFragment(useViewLifecycleInFragment == true)
|
||||
.zOrderOnTop(zOrderOnTop == true)
|
||||
.zoomControlsEnabled(zoomControlsEnabled == true)
|
||||
.zoomGesturesEnabled(zoomGesturesEnabled == true)
|
||||
}
|
||||
|
||||
fun GmsLatLng.toHms(): LatLng =
|
||||
LatLng(latitude, longitude)
|
||||
|
||||
fun GmsLatLngBounds.toHms(): LatLngBounds =
|
||||
LatLngBounds(
|
||||
LatLng(if(southwest.latitude.isNaN()) 0.0 else southwest.latitude, if(southwest.longitude.isNaN()) 0.0 else southwest.longitude),
|
||||
LatLng(if(northeast.latitude.isNaN()) 0.0 else northeast.latitude, if(northeast.longitude.isNaN()) 0.0 else northeast.longitude)
|
||||
)
|
||||
|
||||
fun ICancelableCallback.toHms(): HuaweiMap.CancelableCallback =
|
||||
object : HuaweiMap.CancelableCallback {
|
||||
override fun onFinish() = this@toHms.onFinish()
|
||||
override fun onCancel() = this@toHms.onCancel()
|
||||
}
|
||||
|
||||
fun GmsMarkerOptions.toHms(): MarkerOptions {
|
||||
val markerOptions = MarkerOptions()
|
||||
icon?.let { markerOptions.icon(it.remoteObject.unwrap()) }
|
||||
return markerOptions.alpha(alpha).anchorMarker(anchorU, anchorV).draggable(isDraggable)
|
||||
.flat(isFlat).infoWindowAnchor(infoWindowAnchorU, infoWindowAnchorV)
|
||||
.position(position.toHms()).rotation(rotation).snippet(snippet).title(title)
|
||||
.visible(isVisible).zIndex(zIndex)
|
||||
}
|
||||
|
||||
fun GmsGroundOverlayOptions.toHms(): GroundOverlayOptions {
|
||||
val groundOverlayOptions = GroundOverlayOptions()
|
||||
groundOverlayOptions.anchor(anchorU, anchorV).bearing(bearing)
|
||||
.clickable(isClickable)
|
||||
.image(image.remoteObject.unwrap())
|
||||
.visible(isVisible)
|
||||
.zIndex(zIndex)
|
||||
location?.let {
|
||||
if (height > 0) {
|
||||
groundOverlayOptions.position(it.toHms(), width, height)
|
||||
} else {
|
||||
groundOverlayOptions.position(it.toHms(), width)
|
||||
}
|
||||
}
|
||||
bounds?.let { groundOverlayOptions.positionFromBounds(it.toHms()) }
|
||||
return groundOverlayOptions
|
||||
}
|
||||
|
||||
fun GmsTileOverlayOptions.toHms(): TileOverlayOptions {
|
||||
return TileOverlayOptions().tileProvider(tileProvider?.let { TileProvider { x, y, zoom -> it.getTile(x, y, zoom)?.toHms() } })
|
||||
.fadeIn(fadeIn)
|
||||
.visible(isVisible)
|
||||
.transparency(transparency)
|
||||
.zIndex(zIndex)
|
||||
}
|
||||
|
||||
fun GmsTile.toHms(): Tile = Tile(width, height, data)
|
||||
|
||||
fun GmsPolygonOptions.toHms(): PolygonOptions {
|
||||
val polygonOptions = PolygonOptions()
|
||||
holes?.map {
|
||||
val hole = it?.map { it?.toHms() }
|
||||
polygonOptions.addHole(hole)
|
||||
}
|
||||
return polygonOptions.addAll(points.map { it.toHms() })
|
||||
.clickable(isClickable)
|
||||
.fillColor(fillColor)
|
||||
.geodesic(isGeodesic)
|
||||
.strokeColor(strokeColor).strokeJointType(strokeJointType).strokeWidth(strokeWidth)
|
||||
.visible(isVisible)
|
||||
.zIndex(zIndex)
|
||||
}
|
||||
|
||||
fun GmsPolylineOptions.toHms(): PolylineOptions {
|
||||
val polylineOptions = PolylineOptions()
|
||||
polylineOptions.addAll(points.map { it.toHms() })
|
||||
return polylineOptions.clickable(isClickable).color(color).geodesic(isGeodesic)
|
||||
.jointType(jointType).visible(isVisible).width(toHmsPolylineWidth(width)).zIndex(zIndex)
|
||||
}
|
||||
|
||||
fun toHmsPolylineWidth(gmsWidth: Float): Float = gmsWidth / 3
|
||||
|
||||
fun toHmsZoom(gmsZoom: Float?): Float {
|
||||
if (gmsZoom == null) {
|
||||
return 3f
|
||||
}
|
||||
if (gmsZoom < 3) {
|
||||
return 3f
|
||||
} else if (gmsZoom > 18) {
|
||||
return 18f
|
||||
}
|
||||
return gmsZoom
|
||||
}
|
||||
|
||||
fun toHmsBearing(gmsBearing: Float): Float {
|
||||
return 360 - gmsBearing
|
||||
}
|
||||
|
||||
fun Bundle.toHms(): Bundle {
|
||||
val newBundle = Bundle(this)
|
||||
val oldLoader = newBundle.classLoader
|
||||
newBundle.classLoader = GmsLatLng::class.java.classLoader
|
||||
for (key in newBundle.keySet()) {
|
||||
when (val value = newBundle.get(key)) {
|
||||
is GmsCameraPosition -> newBundle.putParcelable(key, value.toHms())
|
||||
is GmsLatLng -> newBundle.putParcelable(key, value.toHms())
|
||||
is GmsLatLngBounds -> newBundle.putParcelable(key, value.toHms())
|
||||
is Bundle -> newBundle.putBundle(key, value.toHms())
|
||||
}
|
||||
}
|
||||
newBundle.classLoader = oldLoader
|
||||
return newBundle
|
||||
}
|
||||
|
||||
fun CameraPosition.toGms(): GmsCameraPosition =
|
||||
GmsCameraPosition(target.toGms(), zoom, tilt, bearing)
|
||||
|
||||
fun PatternItem.toGms(): GmsPatternItem = when (this) {
|
||||
is Dot -> GmsDot()
|
||||
is Dash -> GmsDash(length)
|
||||
is Gap -> GmsGap(length)
|
||||
else -> GmsGap(0f)
|
||||
}
|
||||
|
||||
fun LatLng.toGms(): GmsLatLng = GmsLatLng(latitude, longitude)
|
||||
|
||||
fun LatLngBounds.toGms(): GmsLatLngBounds = GmsLatLngBounds(
|
||||
GmsLatLng(southwest.latitude, southwest.longitude),
|
||||
GmsLatLng(northeast.latitude, northeast.longitude)
|
||||
)
|
||||
|
||||
fun VisibleRegion.toGms(): GmsVisibleRegion =
|
||||
GmsVisibleRegion(
|
||||
nearLeft.toGms(),
|
||||
nearRight.toGms(),
|
||||
farLeft.toGms(),
|
||||
farRight.toGms(),
|
||||
latLngBounds.toGms()
|
||||
)
|
||||
|
||||
fun toGmsPolylineWidth(hmsWidth: Float): Float = hmsWidth * 3
|
||||
|
||||
fun Bundle.toGms(): Bundle {
|
||||
val newBundle = Bundle(this)
|
||||
val oldLoader = newBundle.classLoader
|
||||
newBundle.classLoader = LatLng::class.java.classLoader
|
||||
for (key in newBundle.keySet()) {
|
||||
when (val value = newBundle.get(key)) {
|
||||
is CameraPosition -> newBundle.putParcelable(key, value.toGms())
|
||||
is LatLng -> newBundle.putParcelable(key, value.toGms())
|
||||
is LatLngBounds -> newBundle.putParcelable(key, value.toGms())
|
||||
is Bundle -> newBundle.putBundle(key, value.toGms())
|
||||
}
|
||||
}
|
||||
newBundle.classLoader = oldLoader
|
||||
return newBundle
|
||||
}
|
||||
|
||||
fun GmsMapStyleOptions.toHms(context: MapContext): MapStyleOptions {
|
||||
val nightMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
|
||||
if (nightMode == Configuration.UI_MODE_NIGHT_YES) {
|
||||
return MapStyleOptions.loadRawResourceStyle(context, R.raw.mapstyle_night_hms)
|
||||
}
|
||||
return MapStyleOptions.loadRawResourceStyle(context, R.raw.mapstyle_grayscale_hms)
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 946 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
|
|
@ -0,0 +1,101 @@
|
|||
[
|
||||
{
|
||||
"featureType": "all",
|
||||
"elementType": "geometry",
|
||||
"stylers": [
|
||||
{
|
||||
"color": "#f5f5f5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "all",
|
||||
"elementType": "labels.icon",
|
||||
"stylers": [
|
||||
{
|
||||
"saturation": -100
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "all",
|
||||
"elementType": "labels.text",
|
||||
"stylers": [
|
||||
{
|
||||
"saturation": -100
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "poi",
|
||||
"elementType": "geometry",
|
||||
"stylers": [
|
||||
{
|
||||
"color": "#eeeeee"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "poi.park",
|
||||
"elementType": "geometry",
|
||||
"stylers": [
|
||||
{
|
||||
"color": "#e5e5e5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "road",
|
||||
"elementType": "geometry",
|
||||
"stylers": [
|
||||
{
|
||||
"color": "#ffffff"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "road.highway",
|
||||
"elementType": "geometry",
|
||||
"stylers": [
|
||||
{
|
||||
"color": "#dadada"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "road.highway",
|
||||
"elementType": "labels.icon",
|
||||
"stylers": [
|
||||
{
|
||||
"lightness": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "transit.line",
|
||||
"elementType": "geometry",
|
||||
"stylers": [
|
||||
{
|
||||
"color": "#e5e5e5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "transit.station",
|
||||
"elementType": "geometry",
|
||||
"stylers": [
|
||||
{
|
||||
"color": "#eeeeee"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "water",
|
||||
"elementType": "geometry",
|
||||
"stylers": [
|
||||
{
|
||||
"color": "#c9c9c9"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,376 @@
|
|||
[
|
||||
{
|
||||
"mapFeature": "all",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#25292B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "all",
|
||||
"options": "labels.text.stroke",
|
||||
"paint": {
|
||||
"color": "#25292B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "all",
|
||||
"options": "labels.icon",
|
||||
"paint": {
|
||||
"icon-type": "night"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "administrative",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#E0D5C7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "administrative.country",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#787272"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "administrative.province",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#666262"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "administrative.province",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#928C82"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "administrative.district",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#AAA59E"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "administrative.locality",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#928C82"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "landcover.parkland.natural",
|
||||
"visibility": false,
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#25292B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "landcover.parkland.public-garden",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#283631"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "landcover.parkland.human-made",
|
||||
"visibility": false,
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#25292B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "landcover.parkland.public-garden",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#8BAA7F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "landcover.hospital",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#382B2B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "landcover",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#928C82"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.shopping",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#9C8C5F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "landcover.human-made.building",
|
||||
"visibility": false,
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#000000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.tourism",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#578C8C"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.beauty",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#9E7885"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.leisure",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#916A91"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.eating&drinking",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#996E50"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.lodging",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#A3678F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.health-care",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#B07373"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.public-service",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#5F7299"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.business",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#6B6B9D"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.automotive",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#6B6B9D"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.sports.outdoor",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#597A52"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.sports.other",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#3E90AB"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.natural",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#597A52"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "poi.miscellaneous",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#A7ADB0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.highway",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#E3CAA2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.national",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#A7ADB0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.province",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#A7ADB0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.city-arterial",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#808689"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.minor-road",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#808689"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.sidewalk",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#808689"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.highway.country",
|
||||
"options": "geometry.fill",
|
||||
"paint": {
|
||||
"color": "#8C7248"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.highway.city",
|
||||
"options": "geometry.fill",
|
||||
"paint": {
|
||||
"color": "#706148"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.national",
|
||||
"options": "geometry.fill",
|
||||
"paint": {
|
||||
"color": "#444A4D"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.province",
|
||||
"options": "geometry.fill",
|
||||
"paint": {
|
||||
"color": "#444A4D"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.city-arterial",
|
||||
"options": "geometry.fill",
|
||||
"paint": {
|
||||
"color": "#434B4F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.minor-road",
|
||||
"options": "geometry.fill",
|
||||
"paint": {
|
||||
"color": "#434B4F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "road.sidewalk",
|
||||
"options": "geometry.fill",
|
||||
"paint": {
|
||||
"color": "#434B4F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "transit",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#4F81B3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "transit.railway",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#5B2E57"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "transit.ferry-line",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#364D67"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "transit.airport",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#2C3235"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "water",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#243850"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "water",
|
||||
"options": "labels.text.fill",
|
||||
"paint": {
|
||||
"color": "#4C6481"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "trafficInfo.smooth",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#348734"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "trafficInfo.amble",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#947000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "trafficInfo.congestion",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#A4281E"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mapFeature": "trafficInfo.extremelycongestion",
|
||||
"options": "geometry",
|
||||
"paint": {
|
||||
"color": "#7A120B"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1 @@
|
|||
<resources></resources>
|
||||
84
play-services-maps/core/mapbox/build.gradle
Normal file
84
play-services-maps/core/mapbox/build.gradle
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2013-2019 microG Project Team
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
dependencies {
|
||||
implementation project(':play-services-maps')
|
||||
implementation project(':play-services-base-core')
|
||||
implementation project(':play-services-location')
|
||||
implementation("org.maplibre.gl:android-sdk:10.2.0")
|
||||
implementation("org.maplibre.gl:android-plugin-annotation-v9:2.0.1") {
|
||||
exclude group: 'com.google.android.gms'
|
||||
}
|
||||
implementation 'org.maplibre.gl:android-sdk-turf:5.9.0'
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
|
||||
}
|
||||
|
||||
def execResult(...args) {
|
||||
def stdout = new ByteArrayOutputStream()
|
||||
exec {
|
||||
commandLine args
|
||||
standardOutput = stdout
|
||||
}
|
||||
return stdout.toString().trim()
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "org.microg.gms.maps.mapbox"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
versionName version
|
||||
minSdkVersion androidMinSdk
|
||||
targetSdkVersion androidTargetSdk
|
||||
buildConfigField "String", "MAPBOX_KEY", "\"${localProperties.getProperty("mapbox.key", System.getenv('MAPBOX_VECTOR_TILES_KEY') ?: "")}\""
|
||||
buildConfigField "String", "STADIA_KEY", "\"${localProperties.getProperty("stadia.key", System.getenv('STADIA_API_KEY') ?: "")}\""
|
||||
|
||||
ndk {
|
||||
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'GradleCompatible'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = 1.8
|
||||
}
|
||||
}
|
||||
|
||||
if (file('user.gradle').exists()) {
|
||||
apply from: 'user.gradle'
|
||||
}
|
||||
35
play-services-maps/core/mapbox/src/main/AndroidManifest.xml
Normal file
35
play-services-maps/core/mapbox/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2013-2019 microG Project Team
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
<uses-sdk tools:overrideLibrary="com.mapbox.mapboxsdk, com.mapbox.mapboxsdk.plugins.annotation" />
|
||||
|
||||
<application />
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1 @@
|
|||
Roboto Regular/
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold10240-10495
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold10496-10751
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold10752-11007
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold11008-11263
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold11264-11519
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold11520-11775
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold11776-12031
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold12032-12287
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold12288-12543
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold12544-12799
|
||||
Binary file not shown.
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold12800-13055
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold13056-13311
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold13312-13567
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold13568-13823
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold13824-14079
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold14080-14335
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold14336-14591
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold14592-14847
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold14848-15103
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold15104-15359
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold 1536-1791
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold15360-15615
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold15616-15871
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold15872-16127
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold16128-16383
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold16384-16639
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold16640-16895
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold16896-17151
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold17152-17407
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold17408-17663
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold17664-17919
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold 1792-2047
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold17920-18175
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold18176-18431
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold18432-18687
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold18688-18943
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold18944-19199
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold19200-19455
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold19456-19711
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold19712-19967
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold19968-20223
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold20224-20479
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold 2048-2303
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold20480-20735
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold20736-20991
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold20992-21247
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold21248-21503
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold21504-21759
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold21760-22015
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold22016-22271
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold22272-22527
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold22528-22783
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold22784-23039
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold 2304-2559
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold23040-23295
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold23296-23551
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold23552-23807
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold23808-24063
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold24064-24319
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
Roboto Bold24320-24575
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue