Merge branch 'master' into armills-cast-mvp

This commit is contained in:
Marvin W 2019-05-27 12:58:57 +02:00
commit c0a5051941
No known key found for this signature in database
GPG Key ID: 072E9235DB996F2A
100 changed files with 2452 additions and 245 deletions

3
.gitmodules vendored
View File

@ -10,9 +10,6 @@
[submodule "extern/GmsLib"]
path = extern/GmsLib
url = https://github.com/microg/android_external_GmsLib.git
[submodule "extern/vtm"]
path = extern/vtm
url = https://github.com/microg/android_external_vtm.git
[submodule "extern/RemoteDroidGuard"]
path = extern/RemoteDroidGuard
url = https://github.com/microg/android_packages_apps_RemoteDroidGuard.git

View File

@ -10,8 +10,7 @@ android:
components:
- tools
- platform-tools
- build-tools-27.0.3
- build-tools-28.0.3
- android-27
- android-28
- extra-android-m2repository
before_install:
- yes | sdkmanager "platforms;android-27"

View File

@ -9,7 +9,7 @@ microG GmsCore is a FLOSS (Free/Libre Open Source Software) framework to allow a
License
-------
Copyright 2014-2016 microG Project Team
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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 microG Project Team
* 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.
@ -15,29 +15,31 @@
*/
buildscript {
ext.kotlin_version = '1.3.21'
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
apply plugin: 'idea'
ext.androidBuildVersionTools = "27.0.3"
ext.supportLibraryVersion = "27.1.0"
ext.androidBuildVersionTools = "28.0.3"
ext.supportLibraryVersion = "28.0.0"
ext.isReleaseVersion = false
ext.slf4jVersion = "1.7.25"
}
def androidCompileSdk() { return 27 }
def androidCompileSdk() { return 28 }
def androidTargetSdk() { return 27 }
def androidTargetSdk() { return 28 }
def androidMinSdk() { return 9 }
def androidMinSdk() { return 14 }
def versionCode() {
def stdout = new ByteArrayOutputStream()

2
extern/GmsApi vendored

@ -1 +1 @@
Subproject commit feeff75ab10072c89cd17832bf53e859b946cfae
Subproject commit 7197b8320b4e6d55d15b76d4faf05adaba36bf72

1
extern/vtm vendored

@ -1 +0,0 @@
Subproject commit a47215d9848d5f0ebd1be7e281b48e531026a47f

View File

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 microG Project Team
* 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.
@ -16,13 +16,20 @@
apply plugin: 'com.android.application'
def useMapbox() {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
return properties.getProperty("mapbox.enabled", "false") == "true"
}
dependencies {
implementation "com.android.support:support-v4:$supportLibraryVersion"
implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
implementation "com.android.support:mediarouter-v7:$supportLibraryVersion"
implementation "com.squareup.wire:wire-runtime:1.6.1"
implementation "com.takisoft.fix:preference-v7:$supportLibraryVersion.0"
implementation "de.hdodenhof:circleimageview:1.3.0"
implementation "com.squareup.wire:wire-runtime:1.6.1"
implementation "org.conscrypt:conscrypt-android:2.0.0"
// TODO: Switch to upstream once raw requests are merged
// https://github.com/vitalidze/chromecast-java-api-v2/pull/99
// implementation "su.litvak.chromecast:api-v2:0.10.4"
@ -41,11 +48,11 @@ dependencies {
implementation project(':wearable-lib')
implementation project(':remote-droid-guard-lib')
implementation project(':vtm-android')
implementation project(':vtm-extras')
implementation project(':vtm-jts')
implementation project(':vtm-microg-theme')
if (useMapbox()) {
implementation project(':play-services-maps-core-mapbox')
} else {
implementation project(':play-services-maps-core-vtm')
}
}
def execResult(...args) {
@ -57,16 +64,16 @@ def execResult(...args) {
return stdout.toString().trim()
}
def gmsVersion = "13.2.80"
def gmsVersion = "17.4.55"
def gmsVersionCode = Integer.parseInt(gmsVersion.replaceAll('\\.', ''))
def gitVersionBase = execResult('git', 'describe', '--tags', '--abbrev=0').substring(1)
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"))
def gitCommitId = execResult('git', 'show-ref', '--abbrev=7', '--head', 'HEAD').split(' ')[0]
def gitDirty = execResult('git', 'status', '--porcelain').size() > 0
def ourVersionBase = gitVersionBase.substring(0, gitVersionBase.lastIndexOf('.'))
def ourVersionMinor = Integer.parseInt(ourVersionBase.substring(ourVersionBase.lastIndexOf('.') + 1))
def ourVersionCode = gmsVersionCode * 1000 + ourVersionMinor * 2 + (gitCommitCount > 0 || gitDirty ? 1 : 0)
def ourVersionName = "$ourVersionBase.$gmsVersionCode" + (gitCommitCount > 0 && !gitDirty ? "-$gitCommitCount" : "") + (gitDirty ? "-dirty" : "") + (gitCommitCount > 0 && !gitDirty ? " ($gitCommitId)" : "")
def ourVersionName = "$ourVersionBase.$gmsVersionCode" + (gitCommitCount > 0 && !gitDirty ? "-$gitCommitCount" : "") + (gitDirty ? "-dirty" : "") + (useMapbox() ? "-mapbox" : "") + (gitCommitCount > 0 && !gitDirty ? " ($gitCommitId)" : "")
logger.lifecycle('Starting build for version {} ({})...', ourVersionName, ourVersionCode)
android {
@ -88,14 +95,11 @@ android {
sourceSets {
main {
java.srcDirs += 'src/main/protos-java'
file("${rootDir}/vtm-android/natives").eachDir() { dir ->
jniLibs.srcDirs += "${dir.path}/lib"
}
}
}
lintOptions {
disable 'MissingTranslation', 'InvalidPackage', 'BatteryLife', 'ImpliedQuantity', 'MissingQuantity'
disable 'MissingTranslation', 'InvalidPackage', 'BatteryLife', 'ImpliedQuantity', 'MissingQuantity', 'InvalidWakeLockTag'
}
buildTypes {

View File

@ -90,6 +90,7 @@
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST" tools:ignore="ProtectedPermissions"/>
<uses-sdk tools:overrideLibrary="
com.takisoft.fix.support.v7.preference,
@ -258,20 +259,14 @@
<receiver android:name="org.microg.gms.gcm.UnregisterReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/>
<action android:name="android.intent.action.PACKAGE_FULLY_REMOVED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
<!-- Map -->
<provider
android:name="org.microg.gms.maps.data.SharedTileProvider"
android:authorities="org.microg.gms.map.tile"
android:enabled="true"
android:exported="true"/>
<!-- DroidGuard -->
<service android:name="org.microg.gms.droidguard.DroidGuardService">

View File

@ -17,10 +17,41 @@
package com.google.android.gms.common.security;
import android.content.Context;
import android.os.Process;
import android.util.Log;
import org.conscrypt.OpenSSLProvider;
import org.microg.gms.common.PackageUtils;
import java.security.Security;
import java.util.Collections;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
public class ProviderInstallerImpl {
private static final String TAG = "GmsProviderInstaller";
private static final List<String> DISABLED = Collections.singletonList("com.discord");
public static void insertProvider(Context context) {
Log.d("ProviderInstallerImpl", "yep, i should do something with Security here...");
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) {
Security.setProperty("ssl.SocketFactory.provider", "org.conscrypt.OpenSSLSocketFactoryImpl");
Security.setProperty("ssl.ServerSocketFactory.provider", "org.conscrypt.OpenSSLServerSocketFactoryImpl");
SSLContext.setDefault(SSLContext.getInstance("Default"));
HttpsURLConnection.setDefaultSSLSocketFactory(SSLContext.getDefault().getSocketFactory());
Log.d(TAG, "SSL provider installed");
} else {
Log.w(TAG, "Did not insert the new SSL provider");
}
} catch (Exception e) {
Log.w(TAG, e);
}
}
}

View File

@ -197,6 +197,7 @@ public class AuthManager {
}
}
AuthRequest request = new AuthRequest().fromContext(context)
.source("android")
.app(packageName, getPackageSignature())
.email(accountName)
.token(getAccountManager().getPassword(account))

View File

@ -30,8 +30,8 @@ import static org.microg.gms.common.HttpFormClient.RequestContent;
import static org.microg.gms.common.HttpFormClient.RequestHeader;
public class AuthRequest extends HttpFormClient.Request {
private static final String SERVICE_URL = "https://android.clients.google.com/auth";
private static final String USER_AGENT = "GoogleAuth/1.4 (%s %s)";
private static final String SERVICE_URL = "https://android.googleapis.com/auth";
private static final String USER_AGENT = "GoogleAuth/1.4 (%s %s); gzip";
@RequestHeader("User-Agent")
private String userAgent;
@ -59,13 +59,13 @@ public class AuthRequest extends HttpFormClient.Request {
@RequestContent("google_play_services_version")
public int gmsVersion = Constants.MAX_REFERENCE_VERSION;
@RequestContent("accountType")
public String accountType = "HOSTED_OR_GOOGLE";
public String accountType;
@RequestContent("Email")
public String email;
@RequestContent("service")
public String service;
@RequestContent("source")
public String source = "android";
public String source;
@RequestContent({"is_called_from_account_manager", "_opt_is_called_from_account_manager"})
public boolean isCalledFromAccountManager;
@RequestContent("Token")
@ -97,10 +97,15 @@ public class AuthRequest extends HttpFormClient.Request {
return this;
}
public AuthRequest source(String source) {
this.source = source;
return this;
}
public AuthRequest locale(Locale locale) {
this.locale = locale.toString();
this.countryCode = locale.getCountry();
this.operatorCountryCode = locale.getCountry();
this.countryCode = locale.getCountry().toLowerCase();
this.operatorCountryCode = locale.getCountry().toLowerCase();
return this;
}

View File

@ -21,19 +21,17 @@ import android.accounts.AccountManager;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.StringRes;
import android.support.v4.view.LayoutInflaterCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
@ -73,7 +71,6 @@ import static android.view.View.VISIBLE;
import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT;
import static org.microg.gms.common.Constants.GMS_PACKAGE_NAME;
import static org.microg.gms.common.Constants.MAX_REFERENCE_VERSION;
import android.os.Build;
public class LoginActivity extends AssistantActivity {
public static final String TMPL_NEW_ACCOUNT = "new_account";
@ -85,6 +82,7 @@ public class LoginActivity extends AssistantActivity {
private static final String TAG = "GmsAuthLoginBrowser";
private static final String EMBEDDED_SETUP_URL = "https://accounts.google.com/EmbeddedSetup";
private static final String PROGRAMMATIC_AUTH_URL = "https://accounts.google.com/o/oauth2/programmatic_auth";
private static final String GOOGLE_SUITE_URL = "https://accounts.google.com/signin/continue";
private static final String MAGIC_USER_AGENT = " MinuteMaid";
private static final String COOKIE_OAUTH_TOKEN = "oauth_token";
@ -109,16 +107,23 @@ public class LoginActivity extends AssistantActivity {
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
Log.d(TAG, "pageFinished: " + url);
if ("identifier".equals(Uri.parse(url).getFragment()))
runOnUiThread(new Runnable() {
@Override
public void run() {
webView.setVisibility(VISIBLE);
}
});
if ("close".equals(Uri.parse(url).getFragment()))
Log.d(TAG, "pageFinished: " + view.getUrl());
Uri uri = Uri.parse(view.getUrl());
// Begin login.
// Only required if client code does not invoke showView() via JSBridge
if ("identifier".equals(uri.getFragment()) || uri.getPath().endsWith("/identifier"))
runOnUiThread(() -> webView.setVisibility(VISIBLE));
// Normal login.
if ("close".equals(uri.getFragment()))
closeWeb(false);
// Google Suite login.
if (url.startsWith(GOOGLE_SUITE_URL))
closeWeb(false);
// IDK when this is called.
if (url.startsWith(PROGRAMMATIC_AUTH_URL))
closeWeb(true);
}
@ -172,12 +177,7 @@ public class LoginActivity extends AssistantActivity {
setMessage(R.string.auth_connecting);
CookieManager.getInstance().setAcceptCookie(true);
if (SDK_INT >= LOLLIPOP) {
CookieManager.getInstance().removeAllCookies(new ValueCallback<Boolean>() {
@Override
public void onReceiveValue(Boolean value) {
start();
}
});
CookieManager.getInstance().removeAllCookies(value -> start());
} else {
//noinspection deprecation
CookieManager.getInstance().removeAllCookie();
@ -218,23 +218,10 @@ public class LoginActivity extends AssistantActivity {
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
if (LastCheckinInfo.read(this).androidId == 0) {
new Thread(new Runnable() {
@Override
public void run() {
Runnable next;
next = checkin(false) ? new Runnable() {
@Override
public void run() {
loadLoginPage();
}
} : new Runnable() {
@Override
public void run() {
showError(R.string.auth_general_error_desc);
}
};
LoginActivity.this.runOnUiThread(next);
}
new Thread(() -> {
Runnable next;
next = checkin(false) ? this::loadLoginPage : () -> showError(R.string.auth_general_error_desc);
LoginActivity.this.runOnUiThread(next);
}).start();
} else {
loadLoginPage();
@ -250,7 +237,7 @@ public class LoginActivity extends AssistantActivity {
setMessage(errorRes);
}
private void setMessage(@StringRes int res) {
private void setMessage(@StringRes int res) {
setMessage(getText(res));
}
@ -265,12 +252,7 @@ public class LoginActivity extends AssistantActivity {
private void closeWeb(boolean programmaticAuth) {
setMessage(R.string.auth_finalize);
runOnUiThread(new Runnable() {
@Override
public void run() {
webView.setVisibility(INVISIBLE);
}
});
runOnUiThread(() -> webView.setVisibility(INVISIBLE));
String cookies = CookieManager.getInstance().getCookie(programmaticAuth ? PROGRAMMATIC_AUTH_URL : EMBEDDED_SETUP_URL);
String[] temp = cookies.split(";");
for (String ar1 : temp) {
@ -286,12 +268,11 @@ public class LoginActivity extends AssistantActivity {
private void retrieveRtToken(String oAuthToken) {
new AuthRequest().fromContext(this)
.appIsGms()
.callerIsGms()
.service("ac2dm")
.token(oAuthToken).isAccessToken()
.addAccount()
.getAccountId()
.systemPartition()
.hasPermission()
.droidguardResults(null /*TODO*/)
.getResponseAsync(new HttpFormClient.Callback<AuthResponse>() {
@Override
@ -312,12 +293,9 @@ public class LoginActivity extends AssistantActivity {
setResult(RESULT_OK);
} else {
Log.w(TAG, "Account NOT created!");
runOnUiThread(new Runnable() {
@Override
public void run() {
showError(R.string.auth_general_error_desc);
setNextButtonText(android.R.string.ok);
}
runOnUiThread(() -> {
showError(R.string.auth_general_error_desc);
setNextButtonText(android.R.string.ok);
});
state = -2;
}
@ -335,6 +313,7 @@ public class LoginActivity extends AssistantActivity {
authManager.setPermitted(true);
new AuthRequest().fromContext(this)
.appIsGms()
.callerIsGms()
.service(authManager.getService())
.email(account.name)
.token(AccountManager.get(this).getPassword(account))
@ -392,9 +371,28 @@ public class LoginActivity extends AssistantActivity {
}
private class JsBridge {
@JavascriptInterface
public final void addAccount(String json) {
Log.d(TAG, "JSBridge: addAccount " + json);
}
@JavascriptInterface
public final void closeView() {
Log.d(TAG, "JSBridge: closeView");
closeWeb(false);
}
@JavascriptInterface
public final String fetchVerifiedPhoneNumber() {
Log.d(TAG, "JSBridge: fetchVerifiedPhoneNumber");
return null;
}
@SuppressWarnings("MissingPermission")
@JavascriptInterface
public final String getAccounts() {
Log.d(TAG, "JSBridge: getAccounts");
Account[] accountsByType = accountManager.getAccountsByType(accountType);
JSONArray json = new JSONArray();
for (Account account : accountsByType) {
@ -405,16 +403,23 @@ public class LoginActivity extends AssistantActivity {
@JavascriptInterface
public final String getAllowedDomains() {
Log.d(TAG, "JSBridge: getAllowedDomains");
return new JSONArray().toString();
}
@JavascriptInterface
public final String getAndroidId() {
long androidId = LastCheckinInfo.read(LoginActivity.this).androidId;
Log.d(TAG, "JSBridge: getAndroidId " + androidId);
if (androidId == 0 || androidId == -1) return null;
return Long.toHexString(androidId);
}
@JavascriptInterface
public final int getAuthModuleVersionCode() {
return 1;
}
@JavascriptInterface
public final int getBuildVersionSdk() {
return SDK_INT;
@ -425,6 +430,11 @@ public class LoginActivity extends AssistantActivity {
Log.d(TAG, "JSBridge: getDroidGuardResult: " + s);
}
@JavascriptInterface
public final int getDeviceDataVersionInfo() {
return 1;
}
@JavascriptInterface
public final String getFactoryResetChallenges() {
return new JSONArray().toString();
@ -471,14 +481,29 @@ public class LoginActivity extends AssistantActivity {
inputMethodManager.hideSoftInputFromWindow(webView.getWindowToken(), 0);
}
@JavascriptInterface
public final boolean isUserOwner() {
return true;
}
@JavascriptInterface
public final void launchEmergencyDialer() {
Log.d(TAG, "JSBridge: launchEmergencyDialer");
}
@JavascriptInterface
public final void log(String s) {
Log.d(TAG, "JSBridge: log " + s);
}
@JavascriptInterface
public final void notifyOnTermsOfServiceAccepted() {
Log.d(TAG, "Terms of service accepted. (who cares?)");
Log.d(TAG, "JSBridge: notifyOnTermsOfServiceAccepted");
}
@JavascriptInterface
public final void setAccountIdentifier(String accountIdentifier) {
Log.d(TAG, "JSBridge: setAccountIdentifier " + accountIdentifier);
}
@TargetApi(HONEYCOMB)
@ -497,7 +522,7 @@ public class LoginActivity extends AssistantActivity {
@JavascriptInterface
public final void setNewAccountCreated() {
Log.d(TAG, "New account created. (who cares?)");
Log.d(TAG, "JSBridge: setNewAccountCreated");
}
@JavascriptInterface
@ -509,12 +534,7 @@ public class LoginActivity extends AssistantActivity {
@JavascriptInterface
public final void showView() {
Log.d(TAG, "JSBridge: showView");
runOnUiThread(new Runnable() {
@Override
public void run() {
webView.setVisibility(VISIBLE);
}
});
runOnUiThread(() -> webView.setVisibility(VISIBLE));
}
@JavascriptInterface

View File

@ -16,6 +16,7 @@
package org.microg.gms.common;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.PackageInfo;
@ -119,6 +120,16 @@ public class PackageUtils {
return null;
}
@Nullable
public static String packageFromProcessId(Context context, int pid) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (manager == null) return null;
for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
if (processInfo.pid == pid) return processInfo.processName;
}
return null;
}
@SuppressWarnings("deprecation")
public static String packageFromPendingIntent(PendingIntent pi) {
if (pi == null) return null;

View File

@ -18,6 +18,7 @@ package org.microg.gms.common;
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.R;
@ -53,8 +54,12 @@ public class Utils {
}
public static boolean hasSelfPermissionOrNotify(Context context, String permission) {
if (ContextCompat.checkSelfPermission(context, permission) != PERMISSION_GRANTED) {
Toast.makeText(context, context.getString(R.string.lacking_permission_toast, permission), Toast.LENGTH_SHORT).show();
if (context.checkCallingOrSelfPermission(permission) != PERMISSION_GRANTED) {
try {
Toast.makeText(context, context.getString(R.string.lacking_permission_toast, permission), Toast.LENGTH_SHORT).show();
} catch (RuntimeException e) {
Log.w("GmsUtils", "Lacking permission to " + permission + " for pid:" + android.os.Process.myPid() + " uid:" + android.os.Process.myUid());
}
return false;
}
return true;

View File

@ -35,6 +35,7 @@ import android.os.Messenger;
import android.os.Parcelable;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
@ -52,6 +53,8 @@ import org.microg.gms.gcm.mcs.LoginResponse;
import org.microg.gms.gcm.mcs.Setting;
import java.io.Closeable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
@ -132,6 +135,10 @@ public class McsService extends Service implements Handler.Callback {
private static int maxTtl = 24 * 60 * 60;
private Object deviceIdleController;
private Method getUserIdMethod;
private Method addPowerSaveTempWhitelistAppMethod;
private class HandlerThread extends Thread {
public HandlerThread() {
@ -166,6 +173,22 @@ public class McsService extends Service implements Handler.Callback {
heartbeatIntent = PendingIntent.getService(this, 0, new Intent(ACTION_HEARTBEAT, null, this, McsService.class), 0);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
try {
Field field = Context.class.getField("DEVICE_IDLE_CONTROLLER");
IBinder binder = (IBinder) Class.forName("android.os.ServiceManager")
.getMethod("getService", String.class).invoke(null, field.get(null));
if (binder != null) {
deviceIdleController = Class.forName("android.os.IDeviceIdleController$Stub")
.getMethod("asInterface", IBinder.class).invoke(null, binder);
getUserIdMethod = UserHandle.class.getMethod("getUserId", int.class);
addPowerSaveTempWhitelistAppMethod = deviceIdleController.getClass()
.getMethod("addPowerSaveTempWhitelistApp", String.class, long.class, int.class, String.class);
}
} catch (Exception e) {
Log.w(TAG, e);
}
}
synchronized (McsService.class) {
if (handlerThread == null) {
handlerThread = new HandlerThread();
@ -452,13 +475,15 @@ public class McsService extends Service implements Handler.Callback {
}
private void handleAppMessage(DataMessageStanza msg) {
database.noteAppMessage(msg.category, msg.getSerializedSize());
GcmDatabase.App app = database.getApp(msg.category);
String packageName = msg.category;
database.noteAppMessage(packageName, msg.getSerializedSize());
GcmDatabase.App app = database.getApp(packageName);
Intent intent = new Intent();
intent.setAction(ACTION_C2DM_RECEIVE);
intent.setPackage(msg.category);
intent.setPackage(packageName);
intent.putExtra(EXTRA_FROM, msg.from);
intent.putExtra(EXTRA_MESSAGE_ID, msg.id);
if (app.wakeForDelivery) {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
} else {
@ -471,7 +496,7 @@ public class McsService extends Service implements Handler.Callback {
String receiverPermission;
try {
String name = msg.category + ".permission.C2D_MESSAGE";
String name = packageName + ".permission.C2D_MESSAGE";
getPackageManager().getPermissionInfo(name, 0);
receiverPermission = name;
} catch (PackageManager.NameNotFoundException e) {
@ -485,6 +510,17 @@ public class McsService extends Service implements Handler.Callback {
for (ResolveInfo resolveInfo : infos) {
logd("Target: " + resolveInfo);
Intent targetIntent = new Intent(intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && app.wakeForDelivery) {
try {
if (getUserIdMethod != null && addPowerSaveTempWhitelistAppMethod != null && deviceIdleController != null) {
int userId = (int) getUserIdMethod.invoke(null, getPackageManager().getApplicationInfo(packageName, 0).uid);
logd("Adding app " + packageName + " for userId " + userId + " to the temp whitelist");
addPowerSaveTempWhitelistAppMethod.invoke(deviceIdleController, packageName, 10000, userId, "GCM Push");
}
} catch (Exception e) {
Log.w(TAG, e);
}
}
targetIntent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name));
sendOrderedBroadcast(targetIntent, receiverPermission);
}

View File

@ -8,7 +8,10 @@ import android.util.Log;
import java.util.List;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.Intent.ACTION_PACKAGE_DATA_CLEARED;
import static android.content.Intent.ACTION_PACKAGE_FULLY_REMOVED;
import static android.content.Intent.EXTRA_DATA_REMOVED;
import static android.content.Intent.EXTRA_REPLACING;
public class UnregisterReceiver extends BroadcastReceiver {
private static final String TAG = "GmsGcmUnregisterRcvr";
@ -16,10 +19,13 @@ public class UnregisterReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
Log.d(TAG, "Package changed: " + intent);
if (ACTION_PACKAGE_REMOVED.contains(intent.getAction()) && intent.getBooleanExtra(EXTRA_DATA_REMOVED, false)) {
if ((ACTION_PACKAGE_REMOVED.contains(intent.getAction()) && intent.getBooleanExtra(EXTRA_DATA_REMOVED, false) &&
!intent.getBooleanExtra(EXTRA_REPLACING, false)) ||
ACTION_PACKAGE_FULLY_REMOVED.contains(intent.getAction()) ||
ACTION_PACKAGE_DATA_CLEARED.contains(intent.getAction())) {
final GcmDatabase database = new GcmDatabase(context);
final String packageName = intent.getData().getSchemeSpecificPart();
Log.d(TAG, "Package removed: " + packageName);
Log.d(TAG, "Package removed or data cleared: " + packageName);
final GcmDatabase.App app = database.getApp(packageName);
if (app != null) {
new Thread(new Runnable() {

View File

@ -28,6 +28,7 @@ import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.internal.FusedLocationProviderResult;
import com.google.android.gms.location.internal.LocationRequestUpdateData;
import org.microg.gms.common.PackageUtils;
import org.microg.gms.common.Utils;
import java.util.ArrayList;
@ -42,6 +43,7 @@ import static com.google.android.gms.location.LocationRequest.PRIORITY_HIGH_ACCU
import static com.google.android.gms.location.LocationRequest.PRIORITY_NO_POWER;
public class GoogleLocationManager implements LocationChangeListener {
private static final String TAG = "GmsLocManager";
private static final String MOCK_PROVIDER = "mock";
private static final long SWITCH_ON_FRESHNESS_CLIFF_MS = 30000; // 30 seconds
private static final String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
@ -155,8 +157,11 @@ public class GoogleLocationManager implements LocationChangeListener {
}
public void updateLocationRequest(LocationRequestUpdateData data) {
String packageName = null;
if (data.pendingIntent != null)
packageName = PackageUtils.packageFromPendingIntent(data.pendingIntent);
if (data.opCode == LocationRequestUpdateData.REQUEST_UPDATES) {
requestLocationUpdates(new LocationRequestHelper(context, hasFineLocationPermission(), hasCoarseLocationPermission(), null, data));
requestLocationUpdates(new LocationRequestHelper(context, hasFineLocationPermission(), hasCoarseLocationPermission(), packageName, data));
if (data.fusedLocationProviderCallback != null) {
try {
data.fusedLocationProviderCallback.onFusedLocationProviderResult(FusedLocationProviderResult.SUCCESS);

View File

@ -19,6 +19,7 @@ package org.microg.gms.location;
import android.app.PendingIntent;
import android.content.Context;
import android.location.Location;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
@ -52,6 +53,8 @@ import com.google.android.gms.location.places.internal.PlacesParams;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import org.microg.gms.common.PackageUtils;
import java.util.Arrays;
import java.util.List;
@ -75,23 +78,27 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
public void addGeofencesList(List<ParcelableGeofence> geofences, PendingIntent pendingIntent,
IGeofencerCallbacks callbacks, String packageName) throws RemoteException {
Log.d(TAG, "addGeofencesList: " + geofences);
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
}
@Override
public void removeGeofencesByIntent(PendingIntent pendingIntent, IGeofencerCallbacks callbacks,
String packageName) throws RemoteException {
Log.d(TAG, "removeGeofencesByIntent: " + pendingIntent);
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
}
@Override
public void removeGeofencesById(String[] geofenceRequestIds, IGeofencerCallbacks callbacks,
String packageName) throws RemoteException {
Log.d(TAG, "removeGeofencesById: " + Arrays.toString(geofenceRequestIds));
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
}
@Override
public void removeAllGeofences(IGeofencerCallbacks callbacks, String packageName) throws RemoteException {
Log.d(TAG, "removeAllGeofences");
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
}
@Override
@ -108,6 +115,7 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
@Override
public ActivityRecognitionResult getLastActivity(String packageName) throws RemoteException {
Log.d(TAG, "getLastActivity");
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
return null;
}
@ -138,35 +146,35 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
@Override
public Location getLastLocation() throws RemoteException {
Log.d(TAG, "getLastLocation");
return getLocationManager().getLastLocation(null);
return getLocationManager().getLastLocation(PackageUtils.packageFromProcessId(context, Binder.getCallingPid()));
}
@Override
public void requestLocationUpdatesWithListener(LocationRequest request,
final ILocationListener listener) throws RemoteException {
Log.d(TAG, "requestLocationUpdatesWithListener: " + request);
getLocationManager().requestLocationUpdates(request, listener, null);
getLocationManager().requestLocationUpdates(request, listener, PackageUtils.packageFromProcessId(context, Binder.getCallingPid()));
}
@Override
public void requestLocationUpdatesWithIntent(LocationRequest request,
PendingIntent callbackIntent) throws RemoteException {
Log.d(TAG, "requestLocationUpdatesWithIntent: " + request);
getLocationManager().requestLocationUpdates(request, callbackIntent, null);
getLocationManager().requestLocationUpdates(request, callbackIntent, PackageUtils.packageFromPendingIntent(callbackIntent));
}
@Override
public void removeLocationUpdatesWithListener(ILocationListener listener)
throws RemoteException {
Log.d(TAG, "removeLocationUpdatesWithListener: " + listener);
getLocationManager().removeLocationUpdates(listener, null);
getLocationManager().removeLocationUpdates(listener, PackageUtils.packageFromProcessId(context, Binder.getCallingPid()));
}
@Override
public void removeLocationUpdatesWithIntent(PendingIntent callbackIntent)
throws RemoteException {
Log.d(TAG, "removeLocationUpdatesWithIntent: " + callbackIntent);
getLocationManager().removeLocationUpdates(callbackIntent, null);
getLocationManager().removeLocationUpdates(callbackIntent, PackageUtils.packageFromPendingIntent(callbackIntent));
}
@Override
@ -226,12 +234,14 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
public void requestLocationUpdatesWithPackage(LocationRequest request, ILocationListener listener,
String packageName) throws RemoteException {
Log.d(TAG, "requestLocationUpdatesWithPackage: " + request);
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
getLocationManager().requestLocationUpdates(request, listener, packageName);
}
@Override
public Location getLastLocationWithPackage(String packageName) throws RemoteException {
Log.d(TAG, "getLastLocationWithPackage: " + packageName);
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
return getLocationManager().getLastLocation(packageName);
}
@ -248,6 +258,7 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
@Override
public LocationAvailability getLocationAvailabilityWithPackage(String packageName) throws RemoteException {
Log.d(TAG, "getLocationAvailabilityWithPackage: " + packageName);
PackageUtils.checkPackageUid(context, packageName, Binder.getCallingUid());
return new LocationAvailability();
}
@ -295,6 +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());
callback.onLocationSettingsResult(new LocationSettingsResult(new LocationSettingsStates(true, true, false, true, true, false), Status.CANCELED));
}
@ -302,14 +314,14 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
public void requestLocationUpdatesInternalWithListener(LocationRequestInternal request,
ILocationListener listener) throws RemoteException {
Log.d(TAG, "requestLocationUpdatesInternalWithListener: " + request);
getLocationManager().requestLocationUpdates(request.request, listener, null);
getLocationManager().requestLocationUpdates(request.request, listener, PackageUtils.packageFromProcessId(context, Binder.getCallingPid()));
}
@Override
public void requestLocationUpdatesInternalWithIntent(LocationRequestInternal request,
PendingIntent callbackIntent) throws RemoteException {
Log.d(TAG, "requestLocationUpdatesInternalWithIntent: " + request);
getLocationManager().requestLocationUpdates(request.request, callbackIntent, null);
getLocationManager().requestLocationUpdates(request.request, callbackIntent, PackageUtils.packageFromPendingIntent(callbackIntent));
}
@Override

View File

@ -99,6 +99,10 @@ public class GcmAppFragment extends ResourceSettingsFragment {
private void updateAppDetails() {
GcmDatabase.App app = database.getApp(packageName);
if (app == null) {
getActivity().finish();
return;
}
PreferenceScreen root = getPreferenceScreen();
SwitchPreference wakeForDelivery = (SwitchPreference) root.findPreference(PREF_WAKE_FOR_DELIVERY);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -46,12 +46,12 @@ import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import org.microg.gms.location.LocationConstants;
import org.microg.gms.maps.BackendMapView;
import org.microg.gms.maps.GmsMapsTypeHelper;
//import org.microg.gms.maps.vtm.BackendMapView;
//import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.microg.safeparcel.SafeParcelUtil;
import org.oscim.core.MapPosition;
import org.oscim.event.Event;
import org.oscim.map.Map;
//import org.oscim.core.MapPosition;
//import org.oscim.event.Event;
//import org.oscim.map.Map;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@ -61,13 +61,16 @@ import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static org.microg.gms.location.LocationConstants.EXTRA_PRIMARY_COLOR;
import static org.microg.gms.location.LocationConstants.EXTRA_PRIMARY_COLOR_DARK;
import static org.microg.gms.maps.GmsMapsTypeHelper.fromLatLngBounds;
//import static org.microg.gms.maps.vtm.GmsMapsTypeHelper.fromLatLngBounds;
public class PlacePickerActivity extends AppCompatActivity implements Map.UpdateListener {
public class
PlacePickerActivity extends AppCompatActivity /*implements Map.UpdateListener*/ {
private static final String TAG = "GmsPlacePicker";
private PlaceImpl place;
private BackendMapView mapView;
// private BackendMapView mapView;
private Intent resultIntent;
private AtomicBoolean geocoderInProgress = new AtomicBoolean(false);
@ -91,17 +94,17 @@ public class PlacePickerActivity extends AppCompatActivity implements Map.Update
((TextView) findViewById(R.id.place_picker_title)).setTextColor(getIntent().getIntExtra(EXTRA_PRIMARY_COLOR_DARK, 0));
}
mapView = (BackendMapView) findViewById(R.id.map);
mapView.map().getEventLayer().enableRotation(false);
mapView.map().getEventLayer().enableTilt(false);
mapView.map().events.bind(this);
// mapView = (BackendMapView) findViewById(R.id.map);
// mapView.map().getEventLayer().enableRotation(false);
// mapView.map().getEventLayer().enableTilt(false);
// mapView.map().events.bind(this);
LatLngBounds latLngBounds = getIntent().getParcelableExtra(LocationConstants.EXTRA_BOUNDS);
if (latLngBounds != null) {
place.viewport = latLngBounds;
MapPosition mp = new MapPosition();
mp.setByBoundingBox(fromLatLngBounds(latLngBounds), mapView.map().getWidth(), mapView.map().getHeight());
mapView.map().getMapPosition(mp);
// MapPosition mp = new MapPosition();
// mp.setByBoundingBox(fromLatLngBounds(latLngBounds), mapView.map().getWidth(), mapView.map().getHeight());
// mapView.map().getMapPosition(mp);
} else {
if (ActivityCompat.checkSelfPermission(PlacePickerActivity.this, ACCESS_FINE_LOCATION) != PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(PlacePickerActivity.this, new String[]{ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}, 0);
@ -136,7 +139,7 @@ public class PlacePickerActivity extends AppCompatActivity implements Map.Update
}
Log.d(TAG, "Set location to " + last);
if (last != null) {
mapView.map().setMapPosition(new MapPosition(last.getLatitude(), last.getLongitude(), 4096));
// mapView.map().setMapPosition(new MapPosition(last.getLatitude(), last.getLongitude(), 4096));
}
}
@ -163,12 +166,12 @@ public class PlacePickerActivity extends AppCompatActivity implements Map.Update
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
// mapView.onResume();
}
@Override
protected void onPause() {
mapView.onPause();
// mapView.onPause();
super.onPause();
}
@ -186,11 +189,12 @@ public class PlacePickerActivity extends AppCompatActivity implements Map.Update
super.onDestroy();
}
/*
@Override
public void onMapEvent(Event event, MapPosition position) {
place.viewport = GmsMapsTypeHelper.toLatLngBounds(mapView.map().viewport().getBBox(null, 0));
resultIntent.putExtra(LocationConstants.EXTRA_FINAL_BOUNDS, place.viewport);
place.latLng = GmsMapsTypeHelper.toLatLng(position.getGeoPoint());
// place.viewport = GmsMapsTypeHelper.toLatLngBounds(mapView.map().viewport().getBBox(null, 0));
// resultIntent.putExtra(LocationConstants.EXTRA_FINAL_BOUNDS, place.viewport);
// place.latLng = GmsMapsTypeHelper.toLatLng(position.getGeoPoint());
place.name = "";
place.address = "";
updateInfoText();
@ -235,7 +239,7 @@ public class PlacePickerActivity extends AppCompatActivity implements Map.Update
}
}).start();
}
}
}*/
private void updateInfoText() {
if (TextUtils.isEmpty(place.address)) {

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M0,0 L24,0 L24,24 L0,24 Z" />
<path
android:fillColor="#ff000000"
android:pathData="M15,12 C17.21,12,19,10.21,19,8 S17.21,4,15,4 S11,5.79,11,8 S12.79,12,15,12 Z M6,10 L6,7 L4,7 L4,10 L1,10 L1,12 L4,12 L4,15 L6,15 L6,12 L9,12 L9,10 L6,10 Z M15,14 C12.33,14,7,15.34,7,18 L7,20 L23,20 L23,18 C23,15.34,17.67,14,15,14 Z" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

View File

@ -37,7 +37,7 @@
android:layout_marginLeft="15dip"
android:layout_marginRight="6dip">
<TextView android:id="@+android:id/title"
<TextView android:id="@android:id/title"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -27,7 +27,7 @@
android:layout_height="0dip"
android:layout_weight="1">
<org.microg.gms.maps.BackendMapView
<!-- <org.microg.gms.maps.vtm.BackendMapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
@ -37,7 +37,7 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingBottom="41dip"
android:src="@drawable/maps_default_marker"/>
android:src="@drawable/maps_default_marker"/>-->
</RelativeLayout>
<LinearLayout
@ -130,4 +130,4 @@
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -125,6 +125,8 @@ Dies kann einige Minuten dauern."</string>
<string name="pref_more_settings">Mehr</string>
<string name="pref_add_account_title">Konto</string>
<string name="pref_add_account_summary">Google Konto hinzufügen</string>
<string name="pref_gcm_enable_mcs_summary">Google Cloud Messaging ist ein Push-Nachrichten-Dienst, der von vielen Apps genutzt wird. Zur Benutzung muss Geräte Check-In aktiviert werden.</string>
<string name="pref_gcm_apps_title">Apps die Cloud Messaging benutzen</string>
<string name="pref_gcm_confirm_new_apps_title">Neue Apps bestätigen</string>

View File

@ -133,6 +133,8 @@
<string name="pref_more_settings">Ещё</string>
<string name="pref_add_account_title">Аккаунт</string>
<string name="pref_add_account_summary">Добавить аккаунт Google</string>
<string name="pref_gcm_enable_mcs_summary">Google Cloud Messaging предоставляет push-уведомления, которые используются во многих в сторонних приложениях. Чтобы использовать их, вы должны включить регистрацию устройства.</string>
<string name="pref_gcm_heartbeat_title">Интервал соединения Cloud Messaging</string>
<string name="pref_gcm_heartbeat_summary">"Интервал в секундах, для использования серверов Google. Увеличение этого числа сократит потребление батареи, но может привести к задержкам push-сообщений.\nУстарело, будет изменено в следующем релизе."</string>

View File

@ -133,6 +133,8 @@ This can take a couple of minutes."</string>
<string name="pref_more_settings">More</string>
<string name="pref_add_account_title">Account</string>
<string name="pref_add_account_summary">Add Google account</string>
<string name="pref_gcm_enable_mcs_summary">Google Cloud Messaging is a push notification provider used by many third-party applications. To use it you must enable device registration.</string>
<string name="pref_gcm_heartbeat_title">Cloud Messaging heartbeat interval</string>
<string name="pref_gcm_heartbeat_summary">The interval in seconds for the system to heartbeat the Google servers. Increasing this number will reduce battery consumption, but might cause delays on push messages.\nDeprecated, will be replaced in future release.</string>

View File

@ -26,6 +26,14 @@
</org.microg.tools.ui.TintIconPreference>
</PreferenceCategory>
<PreferenceCategory android:title="@string/prefcat_google_services">
<org.microg.tools.ui.TintIconPreference
android:icon="@drawable/add_account"
android:summary="@string/pref_add_account_summary"
android:title="@string/pref_add_account_title">
<intent
android:targetClass="org.microg.gms.auth.login.LoginActivity"
android:targetPackage="com.google.android.gms"/>
</org.microg.tools.ui.TintIconPreference>
<org.microg.tools.ui.TintIconPreference
android:icon="@drawable/device_login"
android:key="pref_checkin"

View File

@ -0,0 +1,83 @@
/*
* 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-extensions'
apply plugin: 'kotlin-android'
dependencies {
implementation project(':play-services-api')
implementation "com.mapbox.mapboxsdk:mapbox-android-sdk:7.3.0"
implementation "com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v7:0.6.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
def execResult(...args) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine args
standardOutput = stdout
}
return stdout.toString().trim()
}
def mapboxKey() {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
return properties.getProperty("mapbox.key", "invalid")
}
android {
compileSdkVersion androidCompileSdk()
buildToolsVersion "$androidBuildVersionTools"
defaultConfig {
versionName "temp"
versionCode 1
minSdkVersion androidMinSdk()
targetSdkVersion androidTargetSdk()
buildConfigField "String", "MAPBOX_KEY", "\"${mapboxKey()}\""
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
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
}
}
if (file('user.gradle').exists()) {
apply from: 'user.gradle'
}

View File

@ -0,0 +1,34 @@
<?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 package="org.microg.gms.maps.mapbox"
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"/>
<application />
</manifest>

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2013-2017 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.maps.internal;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.RemoteException;
import android.support.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.model.internal.IBitmapDescriptorFactoryDelegate;
import org.microg.gms.maps.mapbox.CameraUpdateFactoryImpl;
import org.microg.gms.maps.mapbox.MapFragmentImpl;
import org.microg.gms.maps.mapbox.MapViewImpl;
import org.microg.gms.maps.mapbox.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");
}
@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;
}
}

View File

@ -0,0 +1,83 @@
/*
* 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 org.microg.gms.maps.mapbox
import com.mapbox.mapboxsdk.camera.CameraPosition
import com.mapbox.mapboxsdk.camera.CameraUpdate
import com.mapbox.mapboxsdk.geometry.LatLngBounds
import com.mapbox.mapboxsdk.maps.MapboxMap
import java.util.*
internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: Int, val height: Int, val padding: IntArray) : CameraUpdate {
constructor(bounds: LatLngBounds, width: Int, height: Int, paddingLeft: Int, paddingTop: Int = paddingLeft, paddingRight: Int = paddingLeft, paddingBottom: Int = paddingTop) : this(bounds, width, height, intArrayOf(paddingLeft, paddingTop, paddingRight, paddingBottom)) {}
override fun getCameraPosition(map: MapboxMap): CameraPosition? {
val padding = this.padding.clone()
val widthPad = (map.padding[0] + map.padding[2])/2
val heightPad = (map.padding[1] + map.padding[3])/2
padding[0] += widthPad
padding[1] += heightPad
padding[2] += widthPad
padding[3] += heightPad
return map.getCameraForLatLngBounds(bounds, padding)
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || other !is CameraBoundsWithSizeUpdate?) {
return false
}
val that = other as CameraBoundsWithSizeUpdate? ?: return false
if (bounds != that.bounds) {
return false
}
if (Arrays.equals(padding, that.padding)) {
return false
}
if (height != that.height || width != that.width) {
return false
}
return true
}
override fun hashCode(): Int {
var result = bounds.hashCode()
result = 31 * result + Arrays.hashCode(padding)
result = 31 * result + height.hashCode()
result = 31 * result + width.hashCode()
return result
}
override fun toString(): String {
return ("CameraBoundsWithSizeUpdate{"
+ "bounds=" + bounds
+ ", padding=" + Arrays.toString(padding)
+ '}'.toString())
}
companion object {
val TAG = "GmsCameraBounds"
}
}

View File

@ -0,0 +1,87 @@
/*
* 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 org.microg.gms.maps.mapbox
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.mapbox.mapboxsdk.camera.CameraUpdate
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
import com.mapbox.mapboxsdk.maps.MapboxMap
import org.microg.gms.maps.mapbox.utils.toMapbox
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(zoom.toDouble() - 1.0))
override fun zoomBy(zoomDelta: Float): IObjectWrapper =
ObjectWrapper.wrap(CameraUpdateFactory.zoomBy(zoomDelta.toDouble()))
override fun zoomByWithFocus(zoomDelta: Float, x: Int, y: Int): IObjectWrapper =
ObjectWrapper.wrap(CameraUpdateFactory.zoomBy(zoomDelta.toDouble(), Point(x, y)))
override fun newCameraPosition(cameraPosition: CameraPosition): IObjectWrapper =
ObjectWrapper.wrap(CameraUpdateFactory.newCameraPosition(cameraPosition.toMapbox()))
override fun newLatLng(latLng: LatLng): IObjectWrapper =
ObjectWrapper.wrap(CameraUpdateFactory.newLatLng(latLng.toMapbox()))
override fun newLatLngZoom(latLng: LatLng, zoom: Float): IObjectWrapper =
ObjectWrapper.wrap(CameraUpdateFactory.newLatLngZoom(latLng.toMapbox(), zoom.toDouble() - 1.0))
override fun newLatLngBounds(bounds: LatLngBounds, padding: Int): IObjectWrapper =
ObjectWrapper.wrap(CameraUpdateFactory.newLatLngBounds(bounds.toMapbox(), padding))
override fun scrollBy(x: Float, y: Float): IObjectWrapper {
Log.d(TAG, "unimplemented Method: scrollBy")
return ObjectWrapper.wrap(NoCameraUpdate())
}
override fun newLatLngBoundsWithSize(bounds: LatLngBounds, width: Int, height: Int, padding: Int): IObjectWrapper {
Log.d(TAG, "unimplemented Method: newLatLngBoundsWithSize")
return ObjectWrapper.wrap(CameraBoundsWithSizeUpdate(bounds.toMapbox(), 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
}
private inner class NoCameraUpdate : CameraUpdate {
override fun getCameraPosition(mapboxMap: MapboxMap): com.mapbox.mapboxsdk.camera.CameraPosition? =
mapboxMap.cameraPosition
}
companion object {
private val TAG = "GmsCameraUpdate"
}
}

View File

@ -0,0 +1,479 @@
/*
* 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 org.microg.gms.maps.mapbox
import android.content.Context
import android.location.Location
import android.os.Bundle
import android.os.Parcel
import android.os.RemoteException
import android.support.annotation.IdRes
import android.support.annotation.Keep
import android.support.v4.util.LongSparseArray
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import com.google.android.gms.dynamic.IObjectWrapper
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.CircleOptions
import com.google.android.gms.maps.model.internal.*
import com.mapbox.mapboxsdk.LibraryLoader
import com.mapbox.mapboxsdk.Mapbox
import com.mapbox.mapboxsdk.R
import com.mapbox.mapboxsdk.camera.CameraUpdate
import com.mapbox.mapboxsdk.maps.MapView
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.plugins.annotation.*
import com.mapbox.mapboxsdk.plugins.annotation.Annotation
import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND
import com.mapbox.mapboxsdk.utils.ColorUtils
import org.microg.gms.kotlin.unwrap
import org.microg.gms.maps.MapsConstants.*
import org.microg.gms.maps.mapbox.model.*
import org.microg.gms.maps.mapbox.utils.MapContext
import org.microg.gms.maps.mapbox.utils.MultiArchLoader
import org.microg.gms.maps.mapbox.utils.toGms
import org.microg.gms.maps.mapbox.utils.toMapbox
fun <T : Any> LongSparseArray<T>.values() = (0..size()).map { valueAt(it) }.mapNotNull { it }
class GoogleMapImpl(private val context: Context, private val options: GoogleMapOptions) : IGoogleMapDelegate.Stub() {
val view: FrameLayout
var map: MapboxMap? = null
private set
val dpiFactor: Float
get() = context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT
private var mapView: MapView?
private var initialized = false
private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>()
private val mapLock = Object()
val markers = mutableMapOf<Long, MarkerImpl>()
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 var markerClickListener: IOnMarkerClickListener? = null
private var markerDragListener: IOnMarkerDragListener? = null
var circleManager: CircleManager? = null
var lineManager: LineManager? = null
var fillManager: FillManager? = null
var symbolManager: SymbolManager? = null
var storedMapType: Int = MAP_TYPE_NORMAL
init {
val mapContext = MapContext(context)
LibraryLoader.setLibraryLoader(MultiArchLoader(mapContext, context))
Mapbox.getInstance(mapContext, BuildConfig.MAPBOX_KEY)
this.view = object : FrameLayout(mapContext) {
@Keep
fun <T : View> findViewTraversal(@IdRes id: Int): T? {
return null
}
}
this.mapView = MapView(mapContext)
this.view.addView(this.mapView)
}
override fun getCameraPosition(): CameraPosition? = map?.cameraPosition?.toGms()
override fun getMaxZoomLevel(): Float = map?.maxZoomLevel?.toFloat() ?: 20f
override fun getMinZoomLevel(): Float = map?.minZoomLevel?.toFloat() ?: 1f
override fun moveCamera(cameraUpdate: IObjectWrapper?) =
cameraUpdate.unwrap<CameraUpdate>()?.let { map?.moveCamera(it) } ?: Unit
override fun animateCamera(cameraUpdate: IObjectWrapper?) =
cameraUpdate.unwrap<CameraUpdate>()?.let { map?.animateCamera(it) } ?: Unit
override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) =
cameraUpdate.unwrap<CameraUpdate>()?.let { map?.animateCamera(it, callback?.toMapbox()) }
?: Unit
override fun animateCameraWithDurationAndCallback(cameraUpdate: IObjectWrapper?, duration: Int, callback: ICancelableCallback?) =
cameraUpdate.unwrap<CameraUpdate>()?.let { map?.animateCamera(it, duration, callback?.toMapbox()) }
?: Unit
override fun stopAnimation() = map?.cancelTransitions() ?: Unit
override fun addPolyline(options: PolylineOptions): IPolylineDelegate? {
val lineOptions = LineOptions()
.withLatLngs(options.points.map { it.toMapbox() })
.withLineWidth(options.width / dpiFactor)
.withLineColor(ColorUtils.colorToRgbaString(options.color))
.withLineOpacity(if (options.isVisible) 1f else 0f)
return lineManager?.let { PolylineImpl(this, it.create(lineOptions)) }
}
override fun addPolygon(options: PolygonOptions): IPolygonDelegate? {
Log.d(TAG, "unimplemented Method: addPolygon")
return null
}
override fun addMarker(options: MarkerOptions): IMarkerDelegate? {
var intBits = java.lang.Float.floatToIntBits(options.zIndex)
if (intBits < 0) intBits = intBits xor 0x7fffffff
val symbolOptions = SymbolOptions()
.withIconOpacity(if (options.isVisible) options.alpha else 0f)
.withIconRotate(options.rotation)
.withZIndex(intBits)
.withDraggable(options.isDraggable)
options.position?.let { symbolOptions.withLatLng(it.toMapbox()) }
options.icon?.remoteObject.unwrap<BitmapDescriptorImpl>()?.applyTo(symbolOptions, floatArrayOf(options.anchorU, options.anchorV), dpiFactor)
val symbol = symbolManager?.create(symbolOptions) ?: return null
val marker = MarkerImpl(this, symbol, floatArrayOf(options.anchorU, options.anchorV), options.icon?.remoteObject.unwrap<BitmapDescriptorImpl>(), options.alpha, options.title, options.snippet)
markers.put(symbol.id, marker)
return marker
}
override fun addGroundOverlay(options: GroundOverlayOptions): IGroundOverlayDelegate? {
Log.d(TAG, "unimplemented Method: addGroundOverlay")
return null
}
override fun addTileOverlay(options: TileOverlayOptions): ITileOverlayDelegate? {
Log.d(TAG, "unimplemented Method: addTileOverlay")
return null
}
override fun addCircle(options: CircleOptions): ICircleDelegate? {
val circleOptions = com.mapbox.mapboxsdk.plugins.annotation.CircleOptions()
.withLatLng(options.center.toMapbox())
.withCircleColor(ColorUtils.colorToRgbaString(options.fillColor))
.withCircleRadius(options.radius.toFloat())
.withCircleStrokeColor(ColorUtils.colorToRgbaString(options.strokeColor))
.withCircleStrokeWidth(options.strokeWidth / dpiFactor)
.withCircleOpacity(if (options.isVisible) 1f else 0f)
.withCircleStrokeOpacity(if (options.isVisible) 1f else 0f)
return circleManager?.let { CircleImpl(this, it.create(circleOptions)) }
}
override fun clear() {
circleManager?.let { clear(it) }
lineManager?.let { clear(it) }
fillManager?.let { clear(it) }
symbolManager?.let { clear(it) }
}
fun <T : Annotation<*>> clear(manager: AnnotationManager<*, T, *, *, *, *>) {
val annotations = manager.getAnnotations()
for (i in 0..annotations.size()) {
val key = annotations.keyAt(i)
val value = annotations[key];
if (value is T) manager.delete(value)
}
}
override fun getMapType(): Int {
return storedMapType
}
override fun setMapType(type: Int) {
storedMapType = type
applyMapType()
}
fun applyMapType() {
val circles = circleManager?.annotations?.values()
val lines = lineManager?.annotations?.values()
val fills = fillManager?.annotations?.values()
val symbols = symbolManager?.annotations?.values()
val update: (Style) -> Unit = {
circles?.let { circleManager?.update(it) }
lines?.let { lineManager?.update(it) }
fills?.let { fillManager?.update(it) }
symbols?.let { symbolManager?.update(it) }
}
when (storedMapType) {
MAP_TYPE_NORMAL -> map?.setStyle(Style.Builder().fromUrl("mapbox://styles/microg/cjui4020201oo1fmca7yuwbor"), update)
MAP_TYPE_SATELLITE -> map?.setStyle(Style.SATELLITE, update)
MAP_TYPE_TERRAIN -> map?.setStyle(Style.OUTDOORS, update)
MAP_TYPE_HYBRID -> map?.setStyle(Style.SATELLITE_STREETS, update)
else -> map?.setStyle(Style.LIGHT, update)
}
}
override fun isTrafficEnabled(): Boolean {
Log.d(TAG, "unimplemented Method: isTrafficEnabled")
return false
}
override fun setTrafficEnabled(traffic: Boolean) {
Log.d(TAG, "unimplemented Method: setTrafficEnabled")
}
override fun isIndoorEnabled(): Boolean {
Log.d(TAG, "unimplemented Method: isIndoorEnabled")
return false
}
override fun setIndoorEnabled(indoor: Boolean) {
Log.d(TAG, "unimplemented Method: setIndoorEnabled")
}
override fun isMyLocationEnabled(): Boolean {
Log.d(TAG, "unimplemented Method: isMyLocationEnabled")
return false
}
override fun setMyLocationEnabled(myLocation: Boolean) {
Log.d(TAG, "unimplemented Method: setMyLocationEnabled")
}
override fun getMyLocation(): Location? {
Log.d(TAG, "unimplemented Method: getMyLocation")
return null
}
override fun setLocationSource(locationSource: ILocationSourceDelegate) {
Log.d(TAG, "unimplemented Method: setLocationSource")
}
override fun getUiSettings(): IUiSettingsDelegate? = map?.uiSettings?.let { UiSettingsImpl(it) }
override fun getProjection(): IProjectionDelegate? = map?.projection?.let { ProjectionImpl(it) }
override fun setOnCameraChangeListener(listener: IOnCameraChangeListener?) {
cameraChangeListener = listener
}
override fun setOnMapClickListener(listener: IOnMapClickListener?) {
mapClickListener = listener
}
override fun setOnMapLongClickListener(listener: IOnMapLongClickListener?) {
mapLongClickListener = listener
}
override fun setOnMarkerClickListener(listener: IOnMarkerClickListener?) {
markerClickListener = listener
}
override fun setOnMarkerDragListener(listener: IOnMarkerDragListener?) {
markerDragListener = listener
}
override fun setOnInfoWindowClickListener(listener: IOnInfoWindowClickListener?) {
Log.d(TAG, "unimplemented Method: setOnInfoWindowClickListener")
}
override fun setInfoWindowAdapter(adapter: IInfoWindowAdapter?) {
Log.d(TAG, "unimplemented Method: setInfoWindowAdapter")
}
override fun getTestingHelper(): IObjectWrapper? {
Log.d(TAG, "unimplemented Method: getTestingHelper")
return null
}
override fun setOnMyLocationChangeListener(listener: IOnMyLocationChangeListener?) {
Log.d(TAG, "unimplemented Method: setOnMyLocationChangeListener")
}
override fun setOnMyLocationButtonClickListener(listener: IOnMyLocationButtonClickListener?) {
Log.d(TAG, "unimplemented Method: setOnMyLocationButtonClickListener")
}
override fun snapshot(callback: ISnapshotReadyCallback, bitmap: IObjectWrapper) {
Log.d(TAG, "unimplemented Method: snapshot")
}
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
Log.d(TAG, "padding: $left, $top, $right, $bottom")
map?.setPadding(left, top, right, bottom)
val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() ?: 0
val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_ninety_two_dp)?.toInt()
?: 0
map?.uiSettings?.setLogoMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp)
map?.uiSettings?.setCompassMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp)
map?.uiSettings?.setAttributionMargins(left + ninetyTwoDp, top + fourDp, right + fourDp, bottom + fourDp)
}
override fun isBuildingsEnabled(): Boolean {
Log.d(TAG, "unimplemented Method: isBuildingsEnabled")
return false
}
override fun setBuildingsEnabled(buildings: Boolean) {
Log.d(TAG, "unimplemented Method: setBuildingsEnabled")
}
override fun setOnMapLoadedCallback(callback: IOnMapLoadedCallback?) {
Log.d(TAG, "unimplemented Method: setOnMapLoadedCallback")
}
override fun setCameraMoveStartedListener(listener: IOnCameraMoveStartedListener?) {
cameraMoveStartedListener = listener
}
override fun setCameraMoveListener(listener: IOnCameraMoveListener?) {
cameraMoveListener = listener
}
override fun setCameraMoveCanceledListener(listener: IOnCameraMoveCanceledListener?) {
cameraMoveCanceledListener = listener
}
override fun setCameraIdleListener(listener: IOnCameraIdleListener?) {
cameraIdleListener = listener
}
fun onCreate(savedInstanceState: Bundle) {
mapView?.onCreate(savedInstanceState.toMapbox())
mapView?.getMapAsync(this::initMap)
}
private fun hasSymbolAt(latlng: com.mapbox.mapboxsdk.geometry.LatLng): Boolean {
val point = map?.projection?.toScreenLocation(latlng) ?: return false
val features = map?.queryRenderedFeatures(point, SymbolManager.ID_GEOJSON_LAYER)
?: return false
return !features.isEmpty()
}
private fun initMap(map: MapboxMap) {
if (this.map != null) return
this.map = map
applyMapType()
map.getStyle {
mapView?.let { view ->
BitmapDescriptorFactoryImpl.registerMap(map)
circleManager = CircleManager(view, map, it)
lineManager = LineManager(view, map, it)
lineManager?.lineCap = LINE_CAP_ROUND
fillManager = FillManager(view, map, it)
symbolManager = SymbolManager(view, map, it)
symbolManager?.iconAllowOverlap = true
symbolManager?.addClickListener { markers[it.id]?.let { markerClickListener?.onMarkerClick(it) } }
symbolManager?.addDragListener(object : OnSymbolDragListener {
override fun onAnnotationDragStarted(annotation: Symbol?) {
markers[annotation?.id]?.let { markerDragListener?.onMarkerDragStart(it) }
}
override fun onAnnotationDrag(annotation: Symbol?) {
markers[annotation?.id]?.let { markerDragListener?.onMarkerDrag(it) }
}
override fun onAnnotationDragFinished(annotation: Symbol?) {
markers[annotation?.id]?.let { markerDragListener?.onMarkerDragEnd(it) }
}
})
map.addOnCameraIdleListener { cameraChangeListener?.onCameraChange(map.cameraPosition.toGms()) }
map.addOnCameraIdleListener { cameraIdleListener?.onCameraIdle() }
map.addOnCameraMoveListener { cameraMoveListener?.onCameraMove() }
map.addOnCameraMoveStartedListener { cameraMoveStartedListener?.onCameraMoveStarted(it) }
map.addOnCameraMoveCancelListener { cameraMoveCanceledListener?.onCameraMoveCanceled() }
map.addOnMapClickListener {
val latlng = it
mapClickListener?.let { if (!hasSymbolAt(latlng)) it.onMapClick(latlng.toGms()); }
false
}
map.addOnMapLongClickListener {
val latlng = it
mapLongClickListener?.let { if (!hasSymbolAt(latlng)) it.onMapLongClick(latlng.toGms()); }
false
}
synchronized(mapLock) {
for (callback in initializedCallbackList) {
try {
callback.onMapReady(this)
} catch (e: RemoteException) {
Log.w(TAG, e)
}
}
initialized = true
}
}
}
}
fun onResume() = mapView?.onResume()
fun onPause() = mapView?.onPause()
fun onDestroy() {
circleManager?.onDestroy()
circleManager = null
lineManager?.onDestroy()
lineManager = null
fillManager?.onDestroy()
fillManager = null
symbolManager?.onDestroy()
symbolManager = null
BitmapDescriptorFactoryImpl.unregisterMap(map)
view.removeView(mapView)
// TODO can crash?
mapView?.onDestroy()
mapView = null
}
fun onLowMemory() = mapView?.onLowMemory()
fun onSaveInstanceState(outState: Bundle) {
val newBundle = Bundle()
mapView?.onSaveInstanceState(newBundle)
outState.putAll(newBundle.toGms())
}
fun getMapAsync(callback: IOnMapReadyCallback) {
synchronized(mapLock) {
if (initialized) {
callback.onMapReady(this)
} else {
initializedCallbackList.add(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 = "GmsMap"
}
}

View File

@ -0,0 +1,97 @@
/*
* 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 org.microg.gms.maps.mapbox
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
override fun onInflate(activity: IObjectWrapper, options: GoogleMapOptions, savedInstanceState: Bundle) {
this.options = options
}
override fun onCreate(savedInstanceState: Bundle) {
if (options == null) {
options = savedInstanceState.getParcelable("MapOptions")
}
if (options == null) {
options = GoogleMapOptions()
}
}
override fun onCreateView(layoutInflater: IObjectWrapper, container: IObjectWrapper, savedInstanceState: Bundle): IObjectWrapper {
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)
}
}
override fun getMap(): IGoogleMapDelegate? = map
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) = map?.getMapAsync(callback) ?: Unit
override fun onDestroyView() {
map?.onDestroy()
map = null
}
override fun onDestroy() {
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)) {
true
} else {
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
}
companion object {
private val TAG = "GmsMapFragment"
}
}

View File

@ -0,0 +1,65 @@
/*
* 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 org.microg.gms.maps.mapbox
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 val options: GoogleMapOptions
private var map: GoogleMapImpl? = null
init {
this.options = options ?: GoogleMapOptions()
}
override fun onCreate(savedInstanceState: Bundle) {
map = GoogleMapImpl(context, options)
map?.onCreate(savedInstanceState)
}
override fun getMap(): IGoogleMapDelegate? = map
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) = map?.getMapAsync(callback) ?: Unit
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"
}
}

View File

@ -0,0 +1,45 @@
/*
* 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 org.microg.gms.maps.mapbox
import android.graphics.Point
import android.graphics.PointF
import com.google.android.gms.dynamic.IObjectWrapper
import com.google.android.gms.dynamic.ObjectWrapper
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.mapbox.mapboxsdk.maps.Projection
import org.microg.gms.kotlin.unwrap
import org.microg.gms.maps.mapbox.utils.toGms
import org.microg.gms.maps.mapbox.utils.toMapbox
class ProjectionImpl(private val projection: Projection) : IProjectionDelegate.Stub() {
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()
} catch (e: Exception) {
VisibleRegion(LatLngBounds(LatLng(0.0, 0.0), LatLng(0.0, 0.0)))
}
}

View File

@ -0,0 +1,91 @@
/*
* 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 org.microg.gms.maps.mapbox
import android.os.Parcel
import android.os.RemoteException
import android.util.Log
import com.google.android.gms.maps.internal.IUiSettingsDelegate
import com.mapbox.mapboxsdk.maps.UiSettings
class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.Stub() {
override fun setZoomControlsEnabled(zoom: Boolean) {
Log.d(TAG, "unimplemented Method: setZoomControlsEnabled")
}
override fun setCompassEnabled(compass: Boolean) {
uiSettings.isCompassEnabled = compass
}
override fun setMyLocationButtonEnabled(locationButton: Boolean) {
Log.d(TAG, "unimplemented Method: setMyLocationButtonEnabled")
}
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, "unimplemented Method: isZoomControlsEnabled")
return false
}
override fun isCompassEnabled(): Boolean = uiSettings.isCompassEnabled
override fun isMyLocationButtonEnabled(): Boolean {
Log.d(TAG, "unimplemented Method: isMyLocationButtonEnabled")
return false
}
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 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 = "GmsMapsUi"
}
}

View File

@ -0,0 +1,45 @@
/*
* 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 org.microg.gms.maps.mapbox.model
import android.graphics.Color
import android.graphics.PointF
import android.util.Log
import com.mapbox.mapboxsdk.plugins.annotation.Symbol
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions
import com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_TOP_LEFT
import com.mapbox.mapboxsdk.utils.ColorUtils
open class BitmapDescriptorImpl(private val id: String, private val size: FloatArray) {
open fun applyTo(options: SymbolOptions, anchor: FloatArray, dpiFactor: Float): SymbolOptions {
return options.withIconImage(id).withIconAnchor(ICON_ANCHOR_TOP_LEFT).withIconOffset(arrayOf(-anchor[0] * size[0] / dpiFactor, -anchor[1] * size[1] / dpiFactor))
}
open fun applyTo(symbol: Symbol, anchor: FloatArray, dpiFactor: Float) {
symbol.iconAnchor = ICON_ANCHOR_TOP_LEFT
symbol.iconOffset = PointF(-anchor[0] * size[0] / dpiFactor, -anchor[1] * size[1] / dpiFactor)
symbol.iconImage = id
}
}
class ColorBitmapDescriptorImpl(id: String, size: FloatArray, val hue: Float) : BitmapDescriptorImpl(id, size) {
override fun applyTo(options: SymbolOptions, anchor: FloatArray, dpiFactor: Float): SymbolOptions = super.applyTo(options, anchor, dpiFactor).withIconColor(ColorUtils.colorToRgbaString(Color.HSVToColor(floatArrayOf(hue, 1.0f, 0.5f))))
override fun applyTo(symbol: Symbol, anchor: FloatArray, dpiFactor: Float) {
super.applyTo(symbol, anchor, dpiFactor)
symbol.setIconColor(Color.HSVToColor(floatArrayOf(hue, 1.0f, 0.5f)))
}
}

View File

@ -0,0 +1,112 @@
/*
* 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 org.microg.gms.maps.mapbox.model
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
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.mapbox.mapboxsdk.maps.MapboxMap
object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
private val TAG = "GmsMapBitmap"
private var resources: Resources? = null
private val maps = hashSetOf<MapboxMap>()
private val bitmaps = hashMapOf<String, Bitmap>()
fun initialize(resources: Resources) {
BitmapDescriptorFactoryImpl.resources = resources
}
fun registerMap(map: MapboxMap) {
map.getStyle {
it.addImages(bitmaps)
maps.add(map)
}
}
fun unregisterMap(map: MapboxMap?) {
maps.remove(map)
// TODO: cleanup bitmaps?
}
fun bitmapSize(id: String): FloatArray =
bitmaps[id]?.let { floatArrayOf(it.width.toFloat(), it.height.toFloat()) }
?: floatArrayOf(0f, 0f)
private fun registerBitmap(id: String, bitmapCreator: () -> Bitmap?) {
if (bitmaps.contains(id)) return
val bitmap = bitmapCreator() ?: return
bitmaps[id] = bitmap
for (map in maps) {
map.getStyle { it.addImage(id, bitmap) }
}
}
override fun fromResource(resourceId: Int): IObjectWrapper? {
val id = "resource-$resourceId"
registerBitmap(id) { BitmapFactory.decodeResource(resources, resourceId) }
return ObjectWrapper.wrap(BitmapDescriptorImpl(id, bitmapSize(id)))
}
override fun fromAsset(assetName: String): IObjectWrapper? {
val id = "asset-$assetName"
registerBitmap(id) { resources?.assets?.open(assetName)?.let { BitmapFactory.decodeStream(it) } }
return ObjectWrapper.wrap(BitmapDescriptorImpl(id, bitmapSize(id)))
}
override fun fromFile(fileName: String): IObjectWrapper? {
val id = "file-$fileName"
registerBitmap(id) { BitmapFactory.decodeFile(fileName) }
return ObjectWrapper.wrap(BitmapDescriptorImpl(id, bitmapSize(id)))
}
override fun defaultMarker(): IObjectWrapper? {
Log.d(TAG, "unimplemented Method: defaultMarker")
val id = "marker"
return ObjectWrapper.wrap(BitmapDescriptorImpl("marker", bitmapSize(id)))
}
override fun defaultMarkerWithHue(hue: Float): IObjectWrapper? {
val id = "marker"
Log.d(TAG, "unimplemented Method: defaultMarkerWithHue")
return ObjectWrapper.wrap(ColorBitmapDescriptorImpl("marker", bitmapSize(id), hue))
}
override fun fromBitmap(bitmap: Bitmap): IObjectWrapper? {
val id = "bitmap-${bitmap.hashCode()}"
registerBitmap(id) { bitmap }
return ObjectWrapper.wrap(BitmapDescriptorImpl(id, bitmapSize(id)))
}
override fun fromPath(absolutePath: String): IObjectWrapper? {
val id = "path-$absolutePath"
registerBitmap(id) { BitmapFactory.decodeFile(absolutePath) }
return ObjectWrapper.wrap(BitmapDescriptorImpl(id, bitmapSize(id)))
}
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
}
}

View File

@ -0,0 +1,108 @@
/*
* 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 org.microg.gms.maps.mapbox.model
import android.os.Parcel
import android.util.Log
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.internal.ICircleDelegate
import com.mapbox.mapboxsdk.plugins.annotation.Circle
import org.microg.gms.maps.mapbox.GoogleMapImpl
import org.microg.gms.maps.mapbox.utils.toGms
import org.microg.gms.maps.mapbox.utils.toMapbox
class CircleImpl(private val map: GoogleMapImpl, private val circle: Circle) : ICircleDelegate.Stub() {
override fun remove() {
map.circleManager?.delete(circle)
}
override fun getId(): String = "c" + circle.id.toString()
override fun setCenter(center: LatLng) {
circle.latLng = center.toMapbox()
map.circleManager?.update(circle)
}
override fun getCenter(): LatLng = circle.latLng.toGms()
override fun setRadius(radius: Double) {
circle.circleRadius = radius.toFloat()
map.circleManager?.update(circle)
}
override fun getRadius(): Double = circle.circleRadius.toDouble()
override fun setStrokeWidth(width: Float) {
circle.circleStrokeWidth = width / map.dpiFactor
map.circleManager?.update(circle)
}
override fun getStrokeWidth(): Float = circle.circleStrokeWidth * map.dpiFactor
override fun setStrokeColor(color: Int) {
circle.setCircleStrokeColor(color)
map.circleManager?.update(circle)
}
override fun getStrokeColor(): Int = circle.circleStrokeColorAsInt
override fun setFillColor(color: Int) {
circle.setCircleColor(color)
map.circleManager?.update(circle)
}
override fun getFillColor(): Int = circle.circleColorAsInt
override fun setZIndex(zIndex: Float) {
Log.d(TAG, "unimplemented Method: setZIndex")
}
override fun getZIndex(): Float {
Log.d(TAG, "unimplemented Method: getZIndex")
return 0f
}
override fun setVisible(visible: Boolean) {
circle.circleOpacity = if (visible) 1f else 0f
circle.circleStrokeOpacity = if (visible) 1f else 0f
map.circleManager?.update(circle)
}
override fun isVisible(): Boolean = circle.circleOpacity != 0f || circle.circleStrokeOpacity != 0f
override fun equalsRemote(other: ICircleDelegate?): Boolean = equals(other)
override fun hashCodeRemote(): Int = hashCode()
override fun equals(other: Any?): Boolean {
if (other is CircleImpl) {
return other.circle == circle
}
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"
}
}

View File

@ -0,0 +1,171 @@
/*
* 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 org.microg.gms.maps.mapbox.model
import android.util.Log
import com.google.android.gms.dynamic.IObjectWrapper
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.internal.IMarkerDelegate
import com.mapbox.mapboxsdk.plugins.annotation.Symbol
import org.microg.gms.kotlin.unwrap
import org.microg.gms.maps.mapbox.GoogleMapImpl
import org.microg.gms.maps.mapbox.utils.toGms
import org.microg.gms.maps.mapbox.utils.toMapbox
class MarkerImpl(private val map: GoogleMapImpl,
private val symbol: Symbol,
private var anchor: FloatArray,
private var icon: BitmapDescriptorImpl?,
private var alpha: Float = symbol.iconOpacity,
private var title: String? = null,
private var snippet: String? = null) : IMarkerDelegate.Stub() {
private var tag: IObjectWrapper? = null
override fun remove() {
map.symbolManager?.delete(symbol)
map.markers.remove(symbol.id)
}
override fun getId(): String = "m" + symbol.id.toString()
override fun setPosition(pos: LatLng?) {
pos?.let { symbol.latLng = it.toMapbox() }
map.symbolManager?.update(symbol)
}
override fun getPosition(): LatLng = symbol.latLng.toGms()
override fun setTitle(title: String?) {
this.title = title
}
override fun getTitle(): String? = title
override fun setSnippet(snippet: String?) {
this.snippet = snippet
}
override fun getSnippet(): String? = snippet
override fun setDraggable(drag: Boolean) {
symbol.isDraggable = drag
map.symbolManager?.update(symbol)
}
override fun isDraggable(): Boolean = symbol.isDraggable
override fun showInfoWindow() {
Log.d(TAG, "unimplemented Method: showInfoWindow")
}
override fun hideInfoWindow() {
Log.d(TAG, "unimplemented Method: hideInfoWindow")
}
override fun isInfoWindowShown(): Boolean {
Log.d(TAG, "unimplemented Method: isInfoWindowShow")
return false
}
override fun setVisible(visible: Boolean) {
symbol.iconOpacity = if (visible) 0f else alpha
map.symbolManager?.update(symbol)
}
override fun isVisible(): Boolean = symbol.iconOpacity != 0f
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?) {
obj.unwrap<BitmapDescriptorImpl>()?.let { icon = it }
icon?.applyTo(symbol, anchor, map.dpiFactor)
map.symbolManager?.update(symbol)
}
override fun setAnchor(x: Float, y: Float) {
anchor = floatArrayOf(x, y)
icon?.applyTo(symbol, anchor, map.dpiFactor)
map.symbolManager?.update(symbol)
}
override fun setFlat(flat: Boolean) {
Log.d(TAG, "unimplemented Method: setFlat")
}
override fun isFlat(): Boolean {
Log.d(TAG, "unimplemented Method: isFlat")
return false
}
override fun setRotation(rotation: Float) {
symbol.iconRotate = rotation
map.symbolManager?.update(symbol)
}
override fun getRotation(): Float = symbol.iconRotate
override fun setInfoWindowAnchor(x: Float, y: Float) {
Log.d(TAG, "unimplemented Method: setInfoWindowAnchor")
}
override fun setAlpha(alpha: Float) {
this.alpha = alpha
symbol.iconOpacity = alpha
map.symbolManager?.update(symbol)
}
override fun getAlpha(): Float = alpha
override fun setZIndex(zIndex: Float) {
var intBits = java.lang.Float.floatToIntBits(zIndex)
if (intBits < 0) intBits = intBits xor 0x7fffffff
symbol.zIndex = intBits
map.symbolManager?.update(symbol)
}
override fun getZIndex(): Float {
var intBits = symbol.zIndex
if (intBits < 0) intBits = intBits xor 0x7fffffff
return java.lang.Float.intBitsToFloat(intBits)
}
override fun setTag(obj: IObjectWrapper?) {
this.tag = obj
}
override fun getTag(): IObjectWrapper? = tag
companion object {
private val TAG = "GmsMapMarker"
}
}

View File

@ -0,0 +1,102 @@
/*
* 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 org.microg.gms.maps.mapbox.model
import android.os.Parcel
import android.util.Log
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.internal.IPolylineDelegate
import com.mapbox.mapboxsdk.plugins.annotation.Line
import org.microg.gms.maps.mapbox.GoogleMapImpl
import org.microg.gms.maps.mapbox.utils.toGms
import org.microg.gms.maps.mapbox.utils.toMapbox
class PolylineImpl(private val map: GoogleMapImpl, private val line: Line) : IPolylineDelegate.Stub() {
override fun remove() {
map.lineManager?.delete(line)
}
override fun getId(): String = "l" + line.id.toString()
override fun setPoints(points: MutableList<LatLng>) {
line.latLngs = points.map { it.toMapbox() }
map.lineManager?.update(line)
}
override fun getPoints(): List<LatLng> = line.latLngs.map { it.toGms() }
override fun setWidth(width: Float) {
line.lineWidth = width / map.dpiFactor
map.lineManager?.update(line)
}
override fun getWidth(): Float = line.lineWidth * map.dpiFactor
override fun setColor(color: Int) {
line.setLineColor(color)
map.lineManager?.update(line)
}
override fun getColor(): Int = line.lineColorAsInt
override fun setZIndex(zIndex: Float) {
Log.d(TAG, "unimplemented Method: setZIndex")
}
override fun getZIndex(): Float {
Log.d(TAG, "unimplemented Method: getZIndex")
return 0f
}
override fun setVisible(visible: Boolean) {
line.lineOpacity = if (visible) 1f else 0f
map.lineManager?.update(line)
}
override fun isVisible(): Boolean = line.lineOpacity != 0f
override fun setGeodesic(geod: Boolean) {
Log.d(TAG, "unimplemented Method: setGeodesic")
}
override fun isGeodesic(): Boolean {
Log.d(TAG, "unimplemented Method: isGeodesic")
return false
}
override fun equalsRemote(other: IPolylineDelegate?): Boolean = equals(other)
override fun hashCodeRemote(): Int = hashCode()
override fun equals(other: Any?): Boolean {
if (other is PolylineImpl) {
return other.line == line
}
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 {
private val TAG = "GmsMapPolyline"
}
}

View File

@ -0,0 +1,80 @@
/*
* 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 org.microg.gms.maps.mapbox.utils
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.SharedPreferences
import android.view.LayoutInflater
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 and 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 getPackageName(): String {
return appContext.packageName
}
override fun getClassLoader(): ClassLoader {
return MapContext::class.java.classLoader
}
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)
}
companion object {
val TAG = "GmsMapContext"
}
}

View File

@ -0,0 +1,79 @@
/*
* 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 org.microg.gms.maps.mapbox.utils
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.util.Log
import com.mapbox.mapboxsdk.LibraryLoader
import java.io.*
import java.util.zip.ZipFile
class MultiArchLoader(private val mapContext: Context, private val appContext: Context) : LibraryLoader() {
@SuppressLint("UnsafeDynamicallyLoadedCode")
override fun load(name: String) {
try {
val otherAppInfo = mapContext.packageManager.getApplicationInfo(appContext.packageName, 0)
val primaryCpuAbi = ApplicationInfo::class.java.getField("primaryCpuAbi").get(otherAppInfo) as String?
if (primaryCpuAbi != null) {
val path = "lib/$primaryCpuAbi/lib$name.so"
val cacheFile = File("${appContext.cacheDir.absolutePath}/.gmscore/$path")
cacheFile.parentFile.mkdirs()
val apkFile = File(mapContext.packageCodePath)
if (!cacheFile.exists() || cacheFile.lastModified() < apkFile.lastModified()) {
val zipFile = ZipFile(apkFile)
val entry = zipFile.getEntry(path)
if (entry != null) {
copyInputStream(zipFile.getInputStream(entry), FileOutputStream(cacheFile))
} else {
Log.d(TAG, "Can't load native library: $path does not exist in $apkFile")
val entries = zipFile.entries()
while (entries.hasMoreElements()) {
Log.d(TAG, "but: ${entries.nextElement()}")
}
}
}
Log.d(TAG, "Loading $name from ${cacheFile.getPath()}")
System.load(cacheFile.absolutePath)
return
}
} catch (e: Exception) {
Log.w(TAG, e)
}
Log.d(TAG, "Loading native $name")
System.loadLibrary(name)
}
@Throws(IOException::class)
private fun copyInputStream(inp: InputStream, out: OutputStream) {
val buffer = ByteArray(1024)
var len: Int = inp.read(buffer)
while (len >= 0) {
out.write(buffer, 0, len)
len = inp.read(buffer)
}
inp.close()
out.close()
}
companion object {
private val TAG = "GmsMultiArchLoader"
}
}

View File

@ -0,0 +1,95 @@
/*
* 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 org.microg.gms.maps.mapbox.utils
import android.os.Bundle
import com.google.android.gms.maps.internal.ICancelableCallback
import com.google.android.gms.maps.model.CircleOptions
import com.google.android.gms.maps.model.MarkerOptions
import com.google.android.gms.maps.model.PolylineOptions
import com.mapbox.mapboxsdk.camera.CameraPosition
import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.geometry.LatLngBounds
import com.mapbox.mapboxsdk.geometry.VisibleRegion
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.plugins.annotation.LineOptions
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions
import com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_TOP_LEFT
import com.mapbox.mapboxsdk.utils.ColorUtils
import org.microg.gms.kotlin.unwrap
import org.microg.gms.maps.mapbox.model.BitmapDescriptorImpl
fun com.google.android.gms.maps.model.LatLng.toMapbox(): LatLng =
LatLng(latitude, longitude)
fun com.google.android.gms.maps.model.LatLngBounds.toMapbox(): LatLngBounds =
LatLngBounds.from(this.northeast.latitude, this.northeast.longitude, this.southwest.latitude, this.southwest.longitude)
fun com.google.android.gms.maps.model.CameraPosition.toMapbox(): CameraPosition =
CameraPosition.Builder()
.target(target.toMapbox())
.zoom(zoom.toDouble() - 1.0)
.tilt(tilt.toDouble())
.bearing(bearing.toDouble())
.build()
fun ICancelableCallback.toMapbox(): MapboxMap.CancelableCallback =
object : MapboxMap.CancelableCallback {
override fun onFinish() = this@toMapbox.onFinish()
override fun onCancel() = this@toMapbox.onCancel()
}
fun Bundle.toMapbox(): Bundle {
val newBundle = Bundle(this)
for (key in newBundle.keySet()) {
val value = newBundle.get(key)
when (value) {
is com.google.android.gms.maps.model.CameraPosition -> newBundle.putParcelable(key, value.toMapbox())
is com.google.android.gms.maps.model.LatLng -> newBundle.putParcelable(key, value.toMapbox())
is com.google.android.gms.maps.model.LatLngBounds -> newBundle.putParcelable(key, value.toMapbox())
is Bundle -> newBundle.putBundle(key, value.toMapbox())
}
}
return newBundle
}
fun LatLng.toGms(): com.google.android.gms.maps.model.LatLng =
com.google.android.gms.maps.model.LatLng(latitude, longitude)
fun LatLngBounds.toGms(): com.google.android.gms.maps.model.LatLngBounds =
com.google.android.gms.maps.model.LatLngBounds(southWest.toGms(), northEast.toGms())
fun CameraPosition.toGms(): com.google.android.gms.maps.model.CameraPosition =
com.google.android.gms.maps.model.CameraPosition(target.toGms(), zoom.toFloat() + 1.0f, tilt.toFloat(), bearing.toFloat())
fun Bundle.toGms(): Bundle {
val newBundle = Bundle(this)
for (key in newBundle.keySet()) {
val value = newBundle.get(key)
when (value) {
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())
}
}
return newBundle
}
fun VisibleRegion.toGms(): com.google.android.gms.maps.model.VisibleRegion =
com.google.android.gms.maps.model.VisibleRegion(nearLeft.toGms(), nearRight.toGms(), farLeft.toGms(), farRight.toGms(), latLngBounds.toGms())

View File

@ -0,0 +1,78 @@
/*
* 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"
dependencies {
implementation project(":microg-ui-tools")
implementation project(":play-services-api")
implementation "org.microg:vtm-android:0.9.1-mod"
implementation "org.microg:vtm-android:0.9.1-mod:natives-armeabi"
implementation "org.microg:vtm-android:0.9.1-mod:natives-armeabi-v7a"
implementation "org.microg:vtm-android:0.9.1-mod:natives-arm64-v8a"
implementation "org.microg:vtm-android:0.9.1-mod:natives-x86"
implementation "org.microg:vtm-android:0.9.1-mod:natives-x86_64"
implementation "org.microg:vtm-extras:0.9.1-mod"
implementation "org.microg:vtm-jts:0.9.1-mod"
implementation project(":vtm-microg-theme")
}
def execResult(...args) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine args
standardOutput = stdout
}
return stdout.toString().trim()
}
android {
compileSdkVersion androidCompileSdk()
buildToolsVersion "$androidBuildVersionTools"
defaultConfig {
versionName "temp"
versionCode 1
minSdkVersion androidMinSdk()
targetSdkVersion androidTargetSdk()
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
lintOptions {
disable "MissingTranslation", "InvalidPackage", "BatteryLife", "ImpliedQuantity", "MissingQuantity"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
if (file("user.gradle").exists()) {
apply from: "user.gradle"
}

View File

@ -0,0 +1,40 @@
<?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 package="org.microg.gms.maps.vtm"
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"/>
<application>
<provider
android:name=".data.SharedTileProvider"
android:authorities="org.microg.gms.maps.vtm.tile"
android:enabled="true"
android:exported="true"/>
</application>
</manifest>

View File

@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.RemoteException;
import android.support.annotation.Keep;
import android.util.Log;
import com.google.android.gms.dynamic.IObjectWrapper;
@ -28,12 +29,13 @@ import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate;
import org.microg.gms.maps.MapFragmentImpl;
import org.microg.gms.maps.MapViewImpl;
import org.microg.gms.maps.ResourcesContainer;
import org.microg.gms.maps.bitmap.BitmapDescriptorFactoryImpl;
import org.microg.gms.maps.camera.CameraUpdateFactoryImpl;
import org.microg.gms.maps.vtm.MapFragmentImpl;
import org.microg.gms.maps.vtm.MapViewImpl;
import org.microg.gms.maps.vtm.ResourcesContainer;
import org.microg.gms.maps.vtm.bitmap.BitmapDescriptorFactoryImpl;
import org.microg.gms.maps.vtm.camera.CameraUpdateFactoryImpl;
@Keep
public class CreatorImpl extends ICreator.Stub {
private static final String TAG = "GmsMapCreator";

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.content.ContextWrapper;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.graphics.Bitmap;
@ -27,10 +27,10 @@ import android.view.View;
import com.google.android.gms.maps.internal.ISnapshotReadyCallback;
import com.google.android.gms.maps.model.CameraPosition;
import org.microg.gms.maps.camera.CameraUpdate;
import org.microg.gms.maps.markup.DrawableMarkup;
import org.microg.gms.maps.markup.MarkerItemMarkup;
import org.microg.gms.maps.markup.Markup;
import org.microg.gms.maps.vtm.camera.CameraUpdate;
import org.microg.gms.maps.vtm.markup.DrawableMarkup;
import org.microg.gms.maps.vtm.markup.MarkerItemMarkup;
import org.microg.gms.maps.vtm.markup.Markup;
import org.oscim.backend.GL;
import org.oscim.backend.GLAdapter;
import org.oscim.core.MapPosition;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.content.ContextWrapper;
@ -23,14 +23,12 @@ import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.util.Log;
import com.google.android.gms.R;
import org.microg.gms.maps.data.SharedTileCache;
import org.microg.gms.maps.markup.ClearableVectorLayer;
import org.microg.gms.maps.vtm.data.SharedTileCache;
import org.microg.gms.maps.vtm.markup.ClearableVectorLayer;
import org.microg.gms.maps.vtm.R;
import org.oscim.android.AndroidAssets;
import org.oscim.android.MapView;
import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.backend.AssetAdapter;
import org.oscim.layers.marker.ItemizedLayer;
import org.oscim.layers.marker.MarkerItem;
import org.oscim.layers.marker.MarkerSymbol;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.widget.FrameLayout;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.graphics.Bitmap;
@ -68,15 +68,15 @@ import com.google.android.gms.maps.model.internal.IPolygonDelegate;
import com.google.android.gms.maps.model.internal.IPolylineDelegate;
import com.google.android.gms.maps.model.internal.ITileOverlayDelegate;
import org.microg.gms.maps.camera.CameraUpdate;
import org.microg.gms.maps.camera.MapPositionCameraUpdate;
import org.microg.gms.maps.markup.CircleImpl;
import org.microg.gms.maps.markup.GroundOverlayImpl;
import org.microg.gms.maps.markup.MarkerImpl;
import org.microg.gms.maps.markup.Markup;
import org.microg.gms.maps.markup.PolygonImpl;
import org.microg.gms.maps.markup.PolylineImpl;
import org.microg.gms.maps.markup.TileOverlayImpl;
import org.microg.gms.maps.vtm.camera.CameraUpdate;
import org.microg.gms.maps.vtm.camera.MapPositionCameraUpdate;
import org.microg.gms.maps.vtm.markup.CircleImpl;
import org.microg.gms.maps.vtm.markup.GroundOverlayImpl;
import org.microg.gms.maps.vtm.markup.MarkerImpl;
import org.microg.gms.maps.vtm.markup.Markup;
import org.microg.gms.maps.vtm.markup.PolygonImpl;
import org.microg.gms.maps.vtm.markup.PolylineImpl;
import org.microg.gms.maps.vtm.markup.TileOverlayImpl;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,13 +14,12 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.content.Context;
import android.os.Bundle;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.os.RemoteException;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.content.res.Resources;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2017 microG Project Team
* 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps;
package org.microg.gms.maps.vtm;
import android.os.RemoteException;
import com.google.android.gms.maps.internal.IUiSettingsDelegate;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
import android.graphics.Bitmap;
import android.os.Parcel;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
@ -25,10 +25,10 @@ import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import com.google.android.gms.R;
import com.google.android.gms.dynamic.ObjectWrapper;
import org.microg.gms.maps.ResourcesContainer;
import org.microg.gms.maps.vtm.ResourcesContainer;
import org.microg.gms.maps.vtm.R;
public class DefaultBitmapDescriptor extends AbstractBitmapDescriptor {
public static final DefaultBitmapDescriptor DEFAULT_DESCRIPTOR = new DefaultBitmapDescriptor(0);

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
public class PathBitmapDescriptor {
public PathBitmapDescriptor(String absolutePath) {

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.bitmap;
package org.microg.gms.maps.vtm.bitmap;
import android.content.Context;
import android.graphics.Bitmap;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.camera;
package org.microg.gms.maps.vtm.camera;
import org.oscim.map.Map;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.camera;
package org.microg.gms.maps.vtm.camera;
import android.os.RemoteException;
import android.util.Log;
@ -26,7 +26,7 @@ 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 org.microg.gms.maps.GmsMapsTypeHelper;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.oscim.core.MapPosition;
import org.oscim.map.Map;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.camera;
package org.microg.gms.maps.vtm.camera;
import org.oscim.core.MapPosition;
import org.oscim.map.Map;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.camera;
package org.microg.gms.maps.vtm.camera;
import org.oscim.map.Map;

View File

@ -14,12 +14,11 @@
* limitations under the License.
*/
package org.microg.gms.maps.data;
package org.microg.gms.maps.vtm.data;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import org.oscim.core.Tile;
import org.oscim.tiling.ITileCache;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.data;
package org.microg.gms.maps.vtm.data;
import android.content.ContentProvider;
import android.content.ContentValues;
@ -29,7 +29,7 @@ import android.net.Uri;
*/
public class SharedTileProvider extends ContentProvider {
private static final String DB_NAME = "tilecache.db";
public static final String PROVIDER_NAME = "org.microg.gms.map.tile";
public static final String PROVIDER_NAME = "org.microg.gms.maps.vtm.tile";
public static final Uri PROVIDER_URI = Uri.parse("content://" + PROVIDER_NAME);
private SQLiteHelper sqLiteHelper;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
@ -22,7 +22,7 @@ import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.internal.ICircleDelegate;
import org.microg.gms.maps.GmsMapsTypeHelper;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.oscim.layers.vector.geometries.CircleDrawable;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.layers.vector.geometries.Style;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import org.oscim.layers.vector.VectorLayer;
import org.oscim.map.Map;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.map.Map;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
import com.google.android.gms.dynamic.IObjectWrapper;

View File

@ -14,18 +14,17 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import android.content.Context;
import android.os.Build;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.google.android.gms.R;
import com.google.android.gms.maps.model.internal.IMarkerDelegate;
import org.microg.gms.maps.GoogleMapImpl;
import org.microg.gms.maps.ResourcesContainer;
import org.microg.gms.maps.vtm.GoogleMapImpl;
import org.microg.gms.maps.vtm.ResourcesContainer;
import org.microg.gms.maps.vtm.R;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import android.content.Context;
import android.graphics.Bitmap;
@ -27,9 +27,9 @@ 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 org.microg.gms.maps.GmsMapsTypeHelper;
import org.microg.gms.maps.bitmap.BitmapDescriptorImpl;
import org.microg.gms.maps.bitmap.DefaultBitmapDescriptor;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.microg.gms.maps.vtm.bitmap.BitmapDescriptorImpl;
import org.microg.gms.maps.vtm.bitmap.DefaultBitmapDescriptor;
import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.layers.marker.MarkerItem;
import org.oscim.layers.marker.MarkerSymbol;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import android.content.Context;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
public interface Markup {
String getId();

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
@ -22,7 +22,7 @@ import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.android.gms.maps.model.internal.IPolygonDelegate;
import org.microg.gms.maps.GmsMapsTypeHelper;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.oscim.core.GeoPoint;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.layers.vector.geometries.PolygonDrawable;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import android.os.RemoteException;
import android.util.Log;
@ -23,7 +23,7 @@ import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.maps.model.internal.IPolylineDelegate;
import org.microg.gms.maps.GmsMapsTypeHelper;
import org.microg.gms.maps.vtm.GmsMapsTypeHelper;
import org.oscim.core.GeoPoint;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.layers.vector.geometries.LineDrawable;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.microg.gms.maps.markup;
package org.microg.gms.maps.vtm.markup;
import com.google.android.gms.maps.model.internal.ITileOverlayDelegate;

View File

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 169 B

View File

@ -17,14 +17,12 @@ include ':play-services-base'
include ':play-services-tasks'
include ':play-services-wearable'
include ':play-services-maps-core-mapbox'
include ':play-services-maps-core-vtm'
include ':play-services-core'
include ':microg-ui-tools'
include ':vtm'
include ':vtm-android'
include ':vtm-extras'
include ':vtm-jts'
include ':vtm-microg-theme'
include ':remote-droid-guard-lib'

1
vtm
View File

@ -1 +0,0 @@
extern/vtm/vtm

View File

@ -1 +0,0 @@
extern/vtm/vtm-android

View File

@ -1 +0,0 @@
extern/vtm/vtm-extras

View File

@ -1 +0,0 @@
extern/vtm/vtm-jts

View File

@ -2,7 +2,7 @@ apply plugin: 'java'
apply plugin: 'maven'
dependencies {
compile project(':vtm')
compile "org.microg:vtm:0.9.1-mod"
}
sourceSets {