Commit c0817e8e authored by Romain Hunault's avatar Romain Hunault

Merge branch 'v0.2.8.17785' into merge-upstream

parents 1c80f6f2 f2de773b
Subproject commit 7197b8320b4e6d55d15b76d4faf05adaba36bf72
Subproject commit 51509859ae51097ad5789ba4ca2e9ffb9658f80e
......@@ -65,7 +65,7 @@ def execResult(...args) {
return stdout.toString().trim()
}
def gmsVersion = "17.4.55"
def gmsVersion = "17.7.85"
def gmsVersionCode = Integer.parseInt(gmsVersion.replaceAll('\\.', ''))
def gitVersionBase = execResult('git', 'describe', '--tags', '--abbrev=0', '--match=v[0-9]*').substring(1)
def gitCommitCount = Integer.parseInt(execResult('git', 'rev-list', '--count', "v$gitVersionBase..HEAD"))
......
......@@ -664,6 +664,7 @@
<action android:name="com.google.android.gms.herrevad.services.LightweightNetworkQualityAndroidService.START"/>
<action android:name="com.google.android.gms.phenotype.service.START"/>
<action android:name="com.google.android.gms.auth.api.credentials.service.START"/>
<action android:name="com.google.android.gms.gass.START"/>
</intent-filter>
</service>
</application>
......
......@@ -59,6 +59,9 @@ public class DynamiteLoaderImpl extends IDynamiteLoader.Stub {
Log.d(TAG, "returning temp fix module version for " + moduleId + ". Firebase Database will not be functional!");
return com.google.android.gms.dynamite.descriptors.com.google.android.gms.firebase_database.ModuleDescriptor.MODULE_VERSION;
}
if (moduleId.equals("com.google.android.gms.googlecertificates")) {
return com.google.android.gms.dynamite.descriptors.com.google.android.gms.googlecertificates.ModuleDescriptor.MODULE_VERSION;
}
if (moduleId.equals("com.google.android.gms.cast.framework.dynamite")) {
Log.d(TAG, "returning temp fix module version for " + moduleId + ". Cast API wil not be functional!");
return 1;
......
/*
* Copyright (C) 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.
*/
package com.google.android.gms.common;
import android.os.RemoteException;
import android.support.annotation.Keep;
import android.util.Log;
import com.google.android.gms.common.internal.GoogleCertificatesQuery;
import com.google.android.gms.common.internal.IGoogleCertificatesApi;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import org.microg.gms.common.PackageUtils;
@Keep
public class GoogleCertificatesImpl extends IGoogleCertificatesApi.Stub {
private static final String TAG = "GmsCertImpl";
@Override
public IObjectWrapper getGoogleCertficates() throws RemoteException {
Log.d(TAG, "unimplemented Method: getGoogleCertficates");
return null;
}
@Override
public IObjectWrapper getGoogleReleaseCertificates() throws RemoteException {
Log.d(TAG, "unimplemented Method: getGoogleReleaseCertificates");
return null;
}
@Override
public boolean isGoogleReleaseSigned(String packageName, IObjectWrapper certData) throws RemoteException {
return PackageUtils.isGooglePackage(packageName, ObjectWrapper.unwrapTyped(certData, byte[].class));
}
@Override
public boolean isGoogleSigned(String packageName, IObjectWrapper certData) throws RemoteException {
return PackageUtils.isGooglePackage(packageName, ObjectWrapper.unwrapTyped(certData, byte[].class));
}
@Override
public boolean isGoogleOrPlatformSigned(GoogleCertificatesQuery query, IObjectWrapper packageManager) throws RemoteException {
return PackageUtils.isGooglePackage(query.getPackageName(), query.getCertData().getBytes());
}
}
......@@ -17,15 +17,28 @@
package com.google.android.gms.common.security;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Process;
import android.util.Log;
import org.conscrypt.NativeCrypto;
import org.conscrypt.OpenSSLProvider;
import org.microg.gms.common.PackageUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Security;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
......@@ -35,12 +48,69 @@ public class ProviderInstallerImpl {
private static final List<String> DISABLED = Collections.singletonList("com.discord");
public static void insertProvider(Context context) {
String packageName = PackageUtils.packageFromProcessId(context, Process.myPid());
Log.d(TAG, "Provider installer invoked for " + packageName);
try {
String packageName = PackageUtils.packageFromProcessId(context, Process.myPid());
Log.d(TAG, "Provider installer invoked for " + packageName);
if (DISABLED.contains(packageName)) {
Log.d(TAG, "Package is excluded from usage of provider installer");
} else if (Security.insertProviderAt(new OpenSSLProvider("GmsCore_OpenSSL"), 1) == 1) {
return;
}
OpenSSLProvider provider = null;
try {
provider = new OpenSSLProvider("GmsCore_OpenSSL");
} catch (UnsatisfiedLinkError e) {
Log.w(TAG, "Could not link conscrypt via default loader, trying manual loading");
// TODO: Move manual loading into helper function (as it is also used in both maps implementations)
try {
ApplicationInfo otherAppInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
String primaryCpuAbi = (String) ApplicationInfo.class.getField("primaryCpuAbi").get(otherAppInfo);
if (primaryCpuAbi != null) {
String path = "lib/" + primaryCpuAbi + "/libconscrypt_jni.so";
File cacheFile = new File(context.createPackageContext(packageName, 0).getCacheDir().getAbsolutePath() + "/.gmscore/" + path);
cacheFile.getParentFile().mkdirs();
File apkFile = new File(context.getPackageCodePath());
if (!cacheFile.exists() || cacheFile.lastModified() < apkFile.lastModified()) {
ZipFile zipFile = new ZipFile(apkFile);
ZipEntry entry = zipFile.getEntry(path);
if (entry != null) {
copyInputStream(zipFile.getInputStream(entry), new FileOutputStream(cacheFile));
} else {
Log.d(TAG, "Can't load native library: " + path + " does not exist in " + apkFile);
}
}
Log.d(TAG, "Loading conscrypt_jni from " + cacheFile.getPath());
System.load(cacheFile.getAbsolutePath());
Class<NativeCrypto> clazz = NativeCrypto.class;
Field loadError = clazz.getDeclaredField("loadError");
loadError.setAccessible(true);
loadError.set(null, null);
Method clinit =clazz.getDeclaredMethod("clinit");
clinit.setAccessible(true);
try {
clinit.invoke(null);
provider = new OpenSSLProvider("GmsCore_OpenSSL");
} catch (InvocationTargetException inner) {
if (inner.getTargetException() instanceof UnsatisfiedLinkError) {
loadError.set(null, inner.getTargetException());
}
}
}
} catch (Exception e2) {
Log.w(TAG, e2);
}
}
if (provider == null) {
Log.w(TAG, "Failed to initialize conscrypt provider");
return;
}
if (Security.insertProviderAt(provider, 1) == 1) {
Security.setProperty("ssl.SocketFactory.provider", "org.conscrypt.OpenSSLSocketFactoryImpl");
Security.setProperty("ssl.ServerSocketFactory.provider", "org.conscrypt.OpenSSLServerSocketFactoryImpl");
......@@ -50,8 +120,20 @@ public class ProviderInstallerImpl {
} else {
Log.w(TAG, "Did not insert the new SSL provider");
}
} catch (Exception e) {
} catch (Throwable e) {
Log.w(TAG, e);
}
}
private static final void copyInputStream(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) >= 0)
out.write(buffer, 0, len);
in.close();
out.close();
}
}
/*
* Copyright (C) 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.
*/
package com.google.android.gms.dynamite.descriptors.com.google.android.gms.googlecertificates;
public class ModuleDescriptor {
public static final String MODULE_ID = "com.google.android.gms.googlecertificates";
public static final int MODULE_VERSION = 1;
}
......@@ -60,10 +60,20 @@ public class PackageUtils {
KNOWN_GOOGLE_PACKAGES.put("com.google.vr.cyclops", "188c5ca3863fa121216157a5baa80755ceda70ab");
KNOWN_GOOGLE_PACKAGES.put("com.waze", "35b438fe1bc69d975dc8702dc16ab69ebf65f26f");
KNOWN_GOOGLE_PACKAGES.put("com.google.android.apps.wellbeing", "4ebdd02380f1fa0b6741491f0af35625dba76e9f");
KNOWN_GOOGLE_PACKAGES.put("com.google.android.apps.village.boond", "48e7985b8f901df335b5d5223579c81618431c7b");
KNOWN_GOOGLE_PACKAGES.put("com.google.android.apps.subscriptions.red", "de8304ace744ae4c4e05887a27a790815e610ff0");
}
public static boolean isGooglePackage(Context context, String packageName) {
String signatureDigest = firstSignatureDigest(context, packageName);
return isGooglePackage(packageName, signatureDigest);
}
public static boolean isGooglePackage(String packageName, byte[] bytes) {
return isGooglePackage(packageName, sha1sum(bytes));
}
public static boolean isGooglePackage(String packageName, String signatureDigest) {
if (signatureDigest == null) return false;
if (Arrays.asList(GOOGLE_PRIMARY_KEYS).contains(signatureDigest)) return true;
if (!KNOWN_GOOGLE_PACKAGES.containsKey(packageName)) return false;
......@@ -162,13 +172,13 @@ public class PackageUtils {
packageName = packagesForUid[0];
} else if (Arrays.asList(packagesForUid).contains(suggestedPackageName)) {
packageName = suggestedPackageName;
} else if (suggestedPackageName == null) {
} else {
packageName = packagesForUid[0];
}
}
}
if (packageName != null && suggestedPackageName != null && !packageName.equals(suggestedPackageName)) {
throw new SecurityException("UID [" + callingUid + "] is not related to packageName [" + packageName + "]");
throw new SecurityException("UID [" + callingUid + "] is not related to packageName [" + suggestedPackageName + "] (seems to be " + packageName + ")");
}
return packageName;
}
......
......@@ -306,7 +306,7 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
@Override
public void requestLocationSettingsDialog(LocationSettingsRequest settingsRequest, ISettingsCallbacks callback, String packageName) throws RemoteException {
Log.d(TAG, "requestLocationSettingsDialog: " + settingsRequest);
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
PackageUtils.getAndCheckCallingPackage(context, packageName);
callback.onLocationSettingsResult(new LocationSettingsResult(new LocationSettingsStates(true, true, false, true, true, false), Status.CANCELED));
}
......
......@@ -16,15 +16,28 @@
package org.microg.gms.people;
import android.accounts.Account;
import android.app.Service;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.Intent;
import android.content.SyncResult;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
public class ContactSyncService extends Service {
private static final String TAG = "GmsContactSync";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
return (new AbstractThreadedSyncAdapter(this, true) {
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.d(TAG, "unimplemented Method: onPerformSync");
}
}).getSyncAdapterBinder();
}
}
......@@ -20,6 +20,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
......@@ -32,7 +33,9 @@ import org.microg.gms.gcm.GcmPrefs;
import org.microg.tools.ui.Condition;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.GET_ACCOUNTS;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.READ_PHONE_STATE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
......@@ -61,7 +64,7 @@ public class Conditions {
}
}).build();
private static final String[] REQUIRED_PERMISSIONS = new String[]{ACCESS_COARSE_LOCATION, WRITE_EXTERNAL_STORAGE, GET_ACCOUNTS, READ_PHONE_STATE};
private static final String[] REQUIRED_PERMISSIONS = new String[]{ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE, GET_ACCOUNTS, READ_PHONE_STATE};
public static final Condition PERMISSIONS = new Condition.Builder()
.title(R.string.cond_perm_title)
.summaryPlurals(R.plurals.cond_perm_summary)
......@@ -70,9 +73,11 @@ public class Conditions {
@Override
public boolean isActive(Context context) {
count = 0;
for (String permission : REQUIRED_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(context, permission) != PERMISSION_GRANTED)
count++;
if (SDK_INT >= Build.VERSION_CODES.M) {
for (String permission : REQUIRED_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(context, permission) != PERMISSION_GRANTED)
count++;
}
}
return count > 0;
}
......
......@@ -21,6 +21,8 @@ import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Base64;
......@@ -87,6 +89,7 @@ public class WearableImpl {
private ConnectionConfiguration[] configurations;
private boolean configurationsUpdated = false;
private ClockworkNodePreferences clockworkNodePreferences;
public Handler networkHandler;
public WearableImpl(Context context, NodeDatabaseHelper nodeDatabase, ConfigurationDatabaseHelper configDatabase) {
this.context = context;
......@@ -94,6 +97,11 @@ public class WearableImpl {
this.configDatabase = configDatabase;
this.clockworkNodePreferences = new ClockworkNodePreferences(context);
this.rpcHelper = new RpcHelper(context);
new Thread(() -> {
Looper.prepare();
networkHandler = new Handler(Looper.myLooper());
Looper.loop();
}).start();
}
public String getLocalNodeId() {
......@@ -619,4 +627,8 @@ public class WearableImpl {
Log.d(TAG, targetNodeId + " seems not reachable");
return -1;
}
public void stop() {
this.networkHandler.getLooper().quit();
}
}
......@@ -16,10 +16,6 @@
package org.microg.gms.wearable;
import android.content.Context;
import android.os.Binder;
import android.os.Handler;
import android.os.Messenger;
import android.os.RemoteException;
import com.google.android.gms.common.internal.GetServiceRequest;
......@@ -31,24 +27,29 @@ import org.microg.gms.common.PackageUtils;
public class WearableService extends BaseService {
private static WearableImpl wearable;
private WearableImpl wearable;
public WearableService() {
super("GmsWearSvc", GmsService.WEARABLE);
}
private synchronized static WearableImpl getWearable(Context appCtx) {
if (wearable == null) {
ConfigurationDatabaseHelper configurationDatabaseHelper = new ConfigurationDatabaseHelper(appCtx);
NodeDatabaseHelper nodeDatabaseHelper = new NodeDatabaseHelper(appCtx);
wearable = new WearableImpl(appCtx, nodeDatabaseHelper, configurationDatabaseHelper);
}
return wearable;
@Override
public void onCreate() {
super.onCreate();
ConfigurationDatabaseHelper configurationDatabaseHelper = new ConfigurationDatabaseHelper(getApplicationContext());
NodeDatabaseHelper nodeDatabaseHelper = new NodeDatabaseHelper(getApplicationContext());
wearable = new WearableImpl(getApplicationContext(), nodeDatabaseHelper, configurationDatabaseHelper);
}
@Override
public void onDestroy() {
super.onDestroy();
wearable.stop();
}
@Override
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException {
PackageUtils.checkPackageUid(this, request.packageName, Binder.getCallingUid());
callback.onPostInitComplete(0, new WearableServiceImpl(this, getWearable(getApplicationContext()), request.packageName), null);
PackageUtils.getAndCheckCallingPackage(this, request.packageName);
callback.onPostInitComplete(0, new WearableServiceImpl(this, wearable, request.packageName), null);
}
}
......@@ -19,7 +19,9 @@ package org.microg.gms.maps.mapbox
import android.app.Activity
import android.os.Bundle
import android.os.Parcel
import android.util.Base64
import android.util.Log
import android.view.View
import android.view.ViewGroup
import com.google.android.gms.dynamic.IObjectWrapper
import com.google.android.gms.dynamic.ObjectWrapper
......@@ -34,32 +36,42 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu
private var options: GoogleMapOptions? = null
override fun onInflate(activity: IObjectWrapper, options: GoogleMapOptions, savedInstanceState: Bundle) {
Log.d(TAG, "onInflate: ${options.camera.target}")
this.options = options
map?.options = options
}
override fun onCreate(savedInstanceState: Bundle) {
override fun onCreate(savedInstanceState: Bundle?) {
if (options == null) {
options = savedInstanceState.getParcelable("MapOptions")
options = savedInstanceState?.getParcelable("MapOptions")
}
if (options == null) {
options = GoogleMapOptions()
}
Log.d(TAG, "onCreate: ${options?.camera?.target}")
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())
map!!.onCreate(savedInstanceState)
return ObjectWrapper.wrap(map!!.view)
} else {
val view = map!!.view
val parent = view.parent as ViewGroup
parent.removeView(view)
return ObjectWrapper.wrap(view)
}
map!!.onCreate(savedInstanceState)
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
......@@ -84,12 +96,14 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu
map?.onSaveInstanceState(outState)
}
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
}
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"
......
......@@ -28,25 +28,28 @@ 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 val options: GoogleMapOptions
private var map: GoogleMapImpl? = null
init {
this.options = options ?: GoogleMapOptions()
}
private val options: GoogleMapOptions = options ?: GoogleMapOptions()
private var map: GoogleMapImpl? = null
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "onCreate: ${options?.camera?.target}")
map = GoogleMapImpl(context, options)
map?.onCreate(savedInstanceState)
map!!.onCreate(savedInstanceState)
}
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)
......
......@@ -30,16 +30,21 @@ import org.microg.gms.maps.mapbox.utils.toGms
import org.microg.gms.maps.mapbox.utils.toMapbox
class ProjectionImpl(private val projection: Projection) : IProjectionDelegate.Stub() {
private val visibleRegion = projection.visibleRegion
private val farLeft = projection.toScreenLocation(visibleRegion.farLeft)
private val farRight = projection.toScreenLocation(visibleRegion.farRight)
private val nearLeft = projection.toScreenLocation(visibleRegion.nearLeft)
private val nearRight = projection.toScreenLocation(visibleRegion.nearRight)
override fun fromScreenLocation(obj: IObjectWrapper?): LatLng? =
obj.unwrap<Point>()?.let { projection.fromScreenLocation(PointF(it)) }?.toGms()
override fun toScreenLocation(latLng: LatLng?): IObjectWrapper =
ObjectWrapper.wrap(latLng?.toMapbox()?.let { projection.toScreenLocation(it) }?.let { Point(it.x.toInt(), it.y.toInt()) })
override fun getVisibleRegion(): VisibleRegion = try {
projection.visibleRegion.toGms()
override fun toScreenLocation(latLng: LatLng?): IObjectWrapper = try {
ObjectWrapper.wrap(latLng?.toMapbox()?.let { projection.toScreenLocation(it) }?.let { Point(it.x.toInt(), it.y.toInt()) })
} catch (e: Exception) {
VisibleRegion(LatLngBounds(LatLng(0.0, 0.0), LatLng(0.0, 0.0)))
ObjectWrapper.wrap(Point(0, 0))
}
override fun getVisibleRegion(): VisibleRegion = visibleRegion.toGms()
}
\ No newline at end of file
......@@ -78,6 +78,33 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S
override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled
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
}
override fun onTransact(code: Int, data: Parcel?, reply: Parcel?, flags: Int): Boolean =
if (super.onTransact(code, data, reply, flags)) {
true
......
......@@ -37,10 +37,13 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
}
fun registerMap(map: MapboxMap) {
Log.d(TAG, "registerMap")
map.getStyle {
it.addImages(bitmaps)
maps.add(map)
synchronized(bitmaps) {
it.addImages(bitmaps)
}
}
maps.add(map)
}
fun unregisterMap(map: MapboxMap?) {
......@@ -53,9 +56,12 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
?: floatArrayOf(0f, 0f)