Various changes:

- Do vtm-jni loading ourself to load correct architecture, fixes #95, related to #97
- Do not falsely announce unsupported mips architecture
- Cleanup ContextWrapping
- Add dummies for GeoData and PlaceDetection APIs
- Restart GCM when package is restarted, related to #100
This commit is contained in:
Marvin W 2016-02-28 13:24:41 +01:00
parent 91cba6cd68
commit 43198173ee
14 changed files with 237 additions and 737 deletions

2
extern/GmsApi vendored

@ -1 +1 @@
Subproject commit 2aec42fb759a426f4ff6d05ff7761a9527622776
Subproject commit c9d08fbe0e02fb7edb837552021c0751df4ddbad

1
gradle.properties Normal file
View File

@ -0,0 +1 @@
android.useDeprecatedNdk=true

Binary file not shown.

View File

@ -80,6 +80,10 @@ android {
versionName getMyVersionName()
// Update commit id to current when increasing gms version code
versionCode(8489238 + getMyVersionCode('249c935f'))
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86"
}
}
sourceSets {

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2013-2015 microG Project Team
~ Copyright 2013-2016 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.
@ -91,9 +91,7 @@
<!-- Location -->
<service
android:name="org.microg.gms.location.GoogleLocationManagerService"
android:exported="true">
<service android:name="org.microg.gms.location.GoogleLocationManagerService">
<intent-filter>
<action android:name="com.google.android.location.internal.GoogleLocationManagerService.START"/>
</intent-filter>
@ -119,6 +117,19 @@
</intent-filter>
</activity>
<service android:name="org.microg.gms.places.GeoDataService">
<intent-filter>
<action android:name="com.google.android.gms.location.places.GeoDataApi"/>
<action android:name="com.google.android.gms.location.places.PlacesApi"/>
</intent-filter>
</service>
<service android:name="org.microg.gms.places.PlaceDetectionService">
<intent-filter>
<action android:name="com.google.android.gms.location.places.PlaceDetectionApi"/>
</intent-filter>
</service>
<!-- Services Framework -->
<provider
@ -169,7 +180,6 @@
<!-- Cloud Messaging -->
<service
android:name="org.microg.gms.gcm.PushRegisterService"
android:exported="true"
android:permission="com.google.android.c2dm.permission.RECEIVE">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTER"/>
@ -189,12 +199,9 @@
<receiver android:name="org.microg.gms.gcm.TriggerReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
<intent-filter>
<action android:name="org.microg.gms.gcm.RECONNECT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_RESTARTED"/>
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.SECRET_CODE"/>
@ -214,9 +221,7 @@
<!-- DroidGuard -->
<service
android:name="org.microg.gms.droidguard.DroidGuardService"
android:exported="true">
<service android:name="org.microg.gms.droidguard.DroidGuardService">
<intent-filter>
<action android:name="com.google.android.gms.droidguard.service.START"/>
@ -226,9 +231,7 @@
<!-- Car -->
<service
android:name="org.microg.gms.car.CarService"
android:exported="true">
<service android:name="org.microg.gms.car.CarService">
<intent-filter>
<action android:name="com.google.android.gms.car.service.START"/>
@ -238,9 +241,7 @@
<!-- People -->
<service
android:name="org.microg.gms.people.PeopleService"
android:exported="true">
<service android:name="org.microg.gms.people.PeopleService">
<intent-filter>
<action android:name="com.google.android.gms.people.service.START"/>
@ -250,9 +251,7 @@
<!-- Wearable -->
<service
android:name="org.microg.gms.wearable.WearableService"
android:exported="true">
<service android:name="org.microg.gms.wearable.WearableService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND"/>
</intent-filter>
@ -260,9 +259,7 @@
<!-- Auth -->
<service
android:name="org.microg.gms.auth.loginservice.GoogleLoginService"
android:exported="true">
<service android:name="org.microg.gms.auth.loginservice.GoogleLoginService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>
@ -322,9 +319,7 @@
<!-- Games -->
<service
android:name="org.microg.gms.games.GamesStubService"
android:exported="true">
<service android:name="org.microg.gms.games.GamesStubService">
<intent-filter>
<action android:name="com.google.android.gms.games.service.START"/>
<category android:name="android.intent.category.DEFAULT"/>
@ -363,25 +358,19 @@
<!-- Other -->
<service
android:name="org.microg.gms.mdm.NetworkQualityService"
android:exported="true">
<service android:name="org.microg.gms.mdm.NetworkQualityService">
<intent-filter>
<action android:name="com.google.android.gms.mdm.services.START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.icing.LightweightIndexService"
android:exported="true">
<service android:name="org.microg.gms.icing.LightweightIndexService">
<intent-filter>
<action android:name="com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.icing.IndexService"
android:exported="true">
<service android:name="org.microg.gms.icing.IndexService">
<intent-filter>
<action android:name="com.google.android.gms.icing.INDEX_SERVICE"/>
</intent-filter>
@ -393,9 +382,7 @@
<action android:name="com.google.android.gms.analytics.service.START"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.playlog.PlayLogService"
android:exported="true">
<service android:name="org.microg.gms.playlog.PlayLogService">
<intent-filter>
<action android:name="com.google.android.gms.playlog.service.START"/>
</intent-filter>
@ -404,39 +391,29 @@
android:name=".gcm.http.GoogleHttpService"
android:exported="true"/>
<service
android:name="org.microg.gms.ads.GService"
android:exported="true">
<service android:name="org.microg.gms.ads.GService">
<intent-filter>
<action android:name="com.google.android.gms.ads.gservice.START"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.feedback.FeedbackService"
android:exported="true">
<service android:name="org.microg.gms.feedback.FeedbackService">
<intent-filter>
<action android:name="com.google.android.gms.feedback.internal.IFeedbackService"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.ads.AdvertisingIdService"
android:exported="true">
<service android:name="org.microg.gms.ads.AdvertisingIdService">
<intent-filter>
<action android:name="com.google.android.gms.ads.identifier.service.START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.clearcut.ClearcutLoggerService"
android:exported="true">
<service android:name="org.microg.gms.clearcut.ClearcutLoggerService">
<intent-filter>
<action android:name="com.google.android.gms.clearcut.service.START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.drive.api.DriveApiService"
android:exported="true">
<service android:name="org.microg.gms.drive.api.DriveApiService">
<intent-filter>
<action android:name="com.google.android.gms.drive.ApiService.START"/>
<action android:name="com.google.android.gms.drive.ApiService.STOP"/>
@ -445,18 +422,14 @@
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.auth.SignInService"
android:exported="true">
<service android:name="org.microg.gms.auth.SignInService">
<intent-filter>
<action android:name="com.google.android.gms.signin.service.START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
<service
android:name="org.microg.gms.DummyService"
android:exported="true">
<service android:name="org.microg.gms.DummyService">
<intent-filter>
<action android:name="com.google.android.gms.plus.service.START"/>
<action android:name="com.google.android.gms.plus.service.internal.START"/>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 microG Project Team
* Copyright 2013-2016 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.
@ -57,7 +57,7 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
public BackendMap(Context context, final CameraUpdateListener cameraUpdateListener) {
this.context = context;
this.cameraUpdateListener = cameraUpdateListener;
mapView = new BackendMapView(new ContextContainer(context));
mapView = new BackendMapView(context);
mapView.items().setOnItemGestureListener(this);
mapView.map().input.bind(this);
mapView.map().events.bind(this);

View File

@ -38,7 +38,6 @@ import org.oscim.tiling.ITileCache;
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
public class BackendMapView extends MapView {
private static final String TAG = BackendMapView.class.getSimpleName();
private LabelLayer labels;
private BuildingLayer buildings;
private ItemizedLayer<MarkerItem> items;

View File

@ -1,662 +0,0 @@
/*
* Copyright 2013-2015 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;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.view.Display;
import android.view.ViewDebug;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* A hacked Context that allows access to gms resources but feels like the remote context for everything else.
*/
public class ContextContainer extends Context {
private Context original;
public ContextContainer(Context original) {
this.original = original;
}
@Override
public AssetManager getAssets() {
return ResourcesContainer.get().getAssets();
}
@Override
public Resources getResources() {
return ResourcesContainer.get();
}
@Override
public PackageManager getPackageManager() {
return original.getPackageManager();
}
@Override
public ContentResolver getContentResolver() {
return original.getContentResolver();
}
@Override
public Looper getMainLooper() {
return original.getMainLooper();
}
@Override
public Context getApplicationContext() {
return original.getApplicationContext();
}
@Override
public void setTheme(int i) {
original.setTheme(i);
}
@Override
@ViewDebug.ExportedProperty(
deepExport = true
)
public Resources.Theme getTheme() {
return original.getTheme();
}
@Override
public ClassLoader getClassLoader() {
return original.getClassLoader();
}
@Override
public String getPackageName() {
return original.getPackageName();
}
@Override
public ApplicationInfo getApplicationInfo() {
return original.getApplicationInfo();
}
@Override
public String getPackageResourcePath() {
return original.getPackageResourcePath();
}
@Override
public String getPackageCodePath() {
return original.getPackageCodePath();
}
@Override
public SharedPreferences getSharedPreferences(String s, int i) {
return original.getSharedPreferences(s, i);
}
@Override
public FileInputStream openFileInput(String s) throws FileNotFoundException {
return original.openFileInput(s);
}
@Override
public FileOutputStream openFileOutput(String s, int i) throws FileNotFoundException {
return original.openFileOutput(s, i);
}
@Override
public boolean deleteFile(String s) {
return original.deleteFile(s);
}
@Override
public File getFileStreamPath(String s) {
return original.getFileStreamPath(s);
}
@Override
public File getFilesDir() {
return original.getFilesDir();
}
@Override
@TargetApi(21)
public File getNoBackupFilesDir() {
return original.getNoBackupFilesDir();
}
@Override
public File getExternalFilesDir(String s) {
return original.getExternalFilesDir(s);
}
@Override
@TargetApi(19)
public File[] getExternalFilesDirs(String s) {
return original.getExternalFilesDirs(s);
}
@Override
public File getObbDir() {
return original.getObbDir();
}
@Override
@TargetApi(19)
public File[] getObbDirs() {
return original.getObbDirs();
}
@Override
public File getCacheDir() {
return original.getCacheDir();
}
@Override
@TargetApi(21)
public File getCodeCacheDir() {
return original.getCodeCacheDir();
}
@Override
public File getExternalCacheDir() {
return original.getExternalCacheDir();
}
@Override
@TargetApi(19)
public File[] getExternalCacheDirs() {
return original.getExternalCacheDirs();
}
@Override
@TargetApi(21)
public File[] getExternalMediaDirs() {
return original.getExternalMediaDirs();
}
@Override
public String[] fileList() {
return original.fileList();
}
@Override
public File getDir(String s, int i) {
return original.getDir(s, i);
}
@Override
public SQLiteDatabase openOrCreateDatabase(String s, int i,
SQLiteDatabase.CursorFactory cursorFactory) {
return original.openOrCreateDatabase(s, i, cursorFactory);
}
@Override
public SQLiteDatabase openOrCreateDatabase(String s, int i,
SQLiteDatabase.CursorFactory cursorFactory,
DatabaseErrorHandler databaseErrorHandler) {
return original.openOrCreateDatabase(s, i, cursorFactory, databaseErrorHandler);
}
@Override
public boolean deleteDatabase(String s) {
return original.deleteDatabase(s);
}
@Override
public File getDatabasePath(String s) {
return original.getDatabasePath(s);
}
@Override
public String[] databaseList() {
return original.databaseList();
}
@Override
@Deprecated
public Drawable getWallpaper() {
return original.getWallpaper();
}
@Override
@Deprecated
public Drawable peekWallpaper() {
return original.peekWallpaper();
}
@Override
@Deprecated
public int getWallpaperDesiredMinimumWidth() {
return original.getWallpaperDesiredMinimumWidth();
}
@Override
@Deprecated
public int getWallpaperDesiredMinimumHeight() {
return original.getWallpaperDesiredMinimumHeight();
}
@Override
@Deprecated
public void setWallpaper(Bitmap bitmap) throws IOException {
original.setWallpaper(bitmap);
}
@Override
@Deprecated
public void setWallpaper(InputStream inputStream) throws IOException {
original.setWallpaper(inputStream);
}
@Override
@Deprecated
public void clearWallpaper() throws IOException {
original.clearWallpaper();
}
@Override
public void startActivity(Intent intent) {
original.startActivity(intent);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void startActivity(Intent intent, Bundle bundle) {
original.startActivity(intent, bundle);
}
@Override
public void startActivities(Intent[] intents) {
original.startActivities(intents);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void startActivities(Intent[] intents, Bundle bundle) {
original.startActivities(intents, bundle);
}
@Override
public void startIntentSender(IntentSender intentSender, Intent intent, int i, int i1, int i2)
throws IntentSender.SendIntentException {
original.startIntentSender(intentSender, intent, i, i1, i2);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void startIntentSender(IntentSender intentSender, Intent intent, int i, int i1, int i2,
Bundle bundle) throws IntentSender.SendIntentException {
original.startIntentSender(intentSender, intent, i, i1, i2, bundle);
}
@Override
public void sendBroadcast(Intent intent) {
original.sendBroadcast(intent);
}
@Override
public void sendBroadcast(Intent intent, String s) {
original.sendBroadcast(intent, s);
}
@Override
public void sendOrderedBroadcast(Intent intent, String s) {
original.sendOrderedBroadcast(intent, s);
}
@Override
public void sendOrderedBroadcast(Intent intent, String s,
BroadcastReceiver broadcastReceiver, Handler handler, int i, String s1,
Bundle bundle) {
original.sendOrderedBroadcast(intent, s, broadcastReceiver, handler, i, s1, bundle);
}
@Override
@TargetApi(17)
public void sendBroadcastAsUser(Intent intent, UserHandle userHandle) {
original.sendBroadcastAsUser(intent, userHandle);
}
@Override
@TargetApi(17)
public void sendBroadcastAsUser(Intent intent, UserHandle userHandle, String s) {
original.sendBroadcastAsUser(intent, userHandle, s);
}
@Override
@TargetApi(17)
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle userHandle, String s,
BroadcastReceiver broadcastReceiver, Handler handler, int i, String s1,
Bundle bundle) {
original.sendOrderedBroadcastAsUser(intent, userHandle, s, broadcastReceiver, handler, i,
s1,
bundle);
}
@Override
@Deprecated
public void sendStickyBroadcast(Intent intent) {
original.sendStickyBroadcast(intent);
}
@Override
@Deprecated
public void sendStickyOrderedBroadcast(Intent intent,
BroadcastReceiver broadcastReceiver, Handler handler, int i, String s,
Bundle bundle) {
original.sendStickyOrderedBroadcast(intent, broadcastReceiver, handler, i, s, bundle);
}
@Override
@Deprecated
public void removeStickyBroadcast(Intent intent) {
original.removeStickyBroadcast(intent);
}
@Override
@Deprecated
@TargetApi(17)
public void sendStickyBroadcastAsUser(Intent intent, UserHandle userHandle) {
original.sendStickyBroadcastAsUser(intent, userHandle);
}
@Override
@Deprecated
@TargetApi(17)
public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle userHandle,
BroadcastReceiver broadcastReceiver, Handler handler, int i, String s,
Bundle bundle) {
original.sendStickyOrderedBroadcastAsUser(intent, userHandle, broadcastReceiver, handler, i,
s,
bundle);
}
@Override
@Deprecated
@TargetApi(17)
public void removeStickyBroadcastAsUser(Intent intent, UserHandle userHandle) {
original.removeStickyBroadcastAsUser(intent, userHandle);
}
@Override
public Intent registerReceiver(BroadcastReceiver broadcastReceiver,
IntentFilter intentFilter) {
return original.registerReceiver(broadcastReceiver, intentFilter);
}
@Override
public Intent registerReceiver(BroadcastReceiver broadcastReceiver,
IntentFilter intentFilter, String s, Handler handler) {
return original.registerReceiver(broadcastReceiver, intentFilter, s, handler);
}
@Override
public void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
original.unregisterReceiver(broadcastReceiver);
}
@Override
public ComponentName startService(Intent intent) {
return original.startService(intent);
}
@Override
public boolean stopService(Intent intent) {
return original.stopService(intent);
}
@Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
return original.bindService(intent, serviceConnection, i);
}
@Override
public void unbindService(ServiceConnection serviceConnection) {
original.unbindService(serviceConnection);
}
@Override
public boolean startInstrumentation(ComponentName componentName, String s, Bundle bundle) {
return original.startInstrumentation(componentName, s, bundle);
}
@Override
public Object getSystemService(String s) {
return original.getSystemService(s);
}
@TargetApi(23)
@Override
public String getSystemServiceName(Class<?> serviceClass) {
return original.getSystemServiceName(serviceClass);
}
@Override
public int checkPermission(String s, int i, int i1) {
return original.checkPermission(s, i, i1);
}
@Override
public int checkCallingPermission(String s) {
return original.checkCallingPermission(s);
}
@Override
public int checkCallingOrSelfPermission(String s) {
return original.checkCallingOrSelfPermission(s);
}
@TargetApi(23)
@Override
public int checkSelfPermission(String permission) {
return original.checkSelfPermission(permission);
}
@Override
public void enforcePermission(String s, int i, int i1, String s1) {
original.enforcePermission(s, i, i1, s1);
}
@Override
public void enforceCallingPermission(String s, String s1) {
original.enforceCallingPermission(s, s1);
}
@Override
public void enforceCallingOrSelfPermission(String s, String s1) {
original.enforceCallingOrSelfPermission(s, s1);
}
@Override
public void grantUriPermission(String s, Uri uri, int i) {
original.grantUriPermission(s, uri, i);
}
@Override
public void revokeUriPermission(Uri uri, int i) {
original.revokeUriPermission(uri, i);
}
@Override
public int checkUriPermission(Uri uri, int i, int i1, int i2) {
return original.checkUriPermission(uri, i, i1, i2);
}
@Override
public int checkCallingUriPermission(Uri uri, int i) {
return original.checkCallingUriPermission(uri, i);
}
@Override
public int checkCallingOrSelfUriPermission(Uri uri, int i) {
return original.checkCallingOrSelfUriPermission(uri, i);
}
@Override
public int checkUriPermission(Uri uri, String s, String s1, int i, int i1, int i2) {
return original.checkUriPermission(uri, s, s1, i, i1, i2);
}
@Override
public void enforceUriPermission(Uri uri, int i, int i1, int i2, String s) {
original.enforceUriPermission(uri, i, i1, i2, s);
}
@Override
public void enforceCallingUriPermission(Uri uri, int i, String s) {
original.enforceCallingUriPermission(uri, i, s);
}
@Override
public void enforceCallingOrSelfUriPermission(Uri uri, int i, String s) {
original.enforceCallingOrSelfUriPermission(uri, i, s);
}
@Override
public void enforceUriPermission(Uri uri, String s, String s1, int i, int i1, int i2,
String s2) {
original.enforceUriPermission(uri, s, s1, i, i1, i2, s2);
}
@Override
public Context createPackageContext(String s, int i)
throws PackageManager.NameNotFoundException {
return original.createPackageContext(s, i);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public Context createConfigurationContext(Configuration configuration) {
return original.createConfigurationContext(configuration);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public Context createDisplayContext(Display display) {
return original.createDisplayContext(display);
}
/* HIDDEN */
public String getBasePackageName() {
return (String) safeInvoke("getBasePackageName");
}
public String getOpPackageName() {
return (String) safeInvoke("getOpPackageName");
}
public File getSharedPrefsFile(String name) {
return (File) safeInvoke("getBasePackageName", String.class, name);
}
@TargetApi(17)
public void startActivityAsUser(Intent intent, UserHandle user) {
safeInvoke("startActivityAsUser", Intent.class, UserHandle.class, intent, user);
}
@TargetApi(17)
public void startActivityAsUser(Intent intent, Bundle options, UserHandle userId) {
safeInvoke("startActivityAsUser", Intent.class, Bundle.class, UserHandle.class, intent, options, userId);
}
public void startActivityForResult(String who, Intent intent, int requestCode, Bundle options) {
safeInvoke("startActivityForResult", String.class, Intent.class, int.class, Bundle.class, who, intent, requestCode, options);
}
public boolean canStartActivityForResult() {
return (Boolean) safeInvoke("canStartActivityForResult");
}
@TargetApi(17)
public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
safeInvoke("startActivitiesAsUser", new Class[]{Intent[].class, Bundle.class, UserHandle.class}, intents, options, userHandle);
}
public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
safeInvoke("sendBroadcastMultiplePermissions", Intent.class, String[].class, intent, receiverPermissions);
}
public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
safeInvoke("sendBroadcast", Intent.class, String.class, int.class, intent, receiverPermission, appOp);
}
private Object safeInvoke(String name) {
return safeInvoke(name, new Class[0]);
}
private <T1> Object safeInvoke(String name, Class<T1> t1Class, T1 t1Value) {
return safeInvoke(name, new Class[]{t1Class}, t1Value);
}
private <T1, T2> Object safeInvoke(String name, Class<T1> t1Class, Class<T2> t2Class, T1 t1Value, T2 t2Value) {
return safeInvoke(name, new Class[]{t1Class, t2Class}, t1Value, t2Value);
}
private <T1, T2, T3> Object safeInvoke(String name, Class<T1> t1Class, Class<T2> t2Class, Class<T3> t3Class, T1 t1Value, T2 t2Value, T3 t3Value) {
return safeInvoke(name, new Class[]{t1Class, t2Class, t3Class}, t1Value, t2Value, t3Value);
}
private <T1, T2, T3, T4> Object safeInvoke(String name, Class<T1> t1Class, Class<T2> t2Class, Class<T3> t3Class, Class<T4> t4Class, T1 t1Value, T2 t2Value, T3 t3Value, T4 t4Value) {
return safeInvoke(name, new Class[]{t1Class, t2Class, t3Class, t4Class}, t1Value, t2Value, t3Value, t4Value);
}
private Object safeInvoke(String name, Class[] classes, Object... values) {
try {
Method method = Context.class.getDeclaredMethod(name, classes);
return method.invoke(original, values);
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof RuntimeException) {
throw (RuntimeException) e.getTargetException();
} else {
throw new RuntimeException(e.getTargetException());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -18,6 +18,7 @@ package org.microg.gms.maps;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
@ -29,7 +30,6 @@ import android.os.RemoteException;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import com.google.android.gms.dynamic.IObjectWrapper;
@ -75,6 +75,15 @@ import org.microg.gms.maps.markup.PolygonImpl;
import org.microg.gms.maps.markup.PolylineImpl;
import org.microg.gms.maps.markup.TileOverlayImpl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@ -82,6 +91,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class GoogleMapImpl extends IGoogleMapDelegate.Stub
implements UiSettingsImpl.UiSettingsListener, Markup.MarkupListener, BackendMap.CameraUpdateListener {
private static final String TAG = "GoogleMapImpl";
private static boolean nativeLibLoaded = false;
private final GoogleMapOptions options;
private final Context context;
@ -126,9 +136,13 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
}
};
public GoogleMapImpl(LayoutInflater inflater, GoogleMapOptions options) {
context = inflater.getContext();
backendMap = new BackendMap(context, this);
public GoogleMapImpl(Context context, GoogleMapOptions options) {
this.context = context;
Context appContext = context;
if (appContext.getApplicationContext() != null) appContext = appContext.getApplicationContext();
Context wrappedContext = RemoteContextWrapper.fromApplicationContext(appContext);
loadNativeLib(wrappedContext);
backendMap = new BackendMap(wrappedContext, this);
uiSettings = new UiSettingsImpl(this);
projection = new ProjectionImpl(backendMap.getViewport());
this.options = options;
@ -140,6 +154,53 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
if (options != null) initFromOptions();
}
private static final void copyInputStream(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) >= 0)
out.write(buffer, 0, len);
in.close();
out.close();
}
private static synchronized void loadNativeLib(Context context) {
try {
if (nativeLibLoaded) return;
ApplicationInfo otherAppInfo = context.getPackageManager().getApplicationInfo(context.getApplicationContext().getPackageName(), 0);
String primaryCpuAbi = (String) ApplicationInfo.class.getField("primaryCpuAbi").get(otherAppInfo);
if (primaryCpuAbi != null) {
String path = "lib/" + primaryCpuAbi + "/libvtm-jni.so";
File cacheFile = new File(context.getApplicationContext().getCacheDir().getAbsolutePath() + "/.gmscore/" + path);
cacheFile.getParentFile().mkdirs();
File apkFile = new File(context.getPackageCodePath());
if (!cacheFile.exists() || cacheFile.lastModified() < apkFile.lastModified()) {
ZipFile zipFile = new ZipFile(apkFile);
ZipEntry entry = zipFile.getEntry(path);
if (entry != null) {
copyInputStream(zipFile.getInputStream(entry), new FileOutputStream(cacheFile));
} else {
Log.d(TAG, "Can't load native library: " + path + " does not exist in " + apkFile);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
Log.d(TAG, "but: " + entries.nextElement());
}
}
}
Log.d(TAG, "Loading vtm-jni from " + cacheFile.getPath());
System.load(cacheFile.getAbsolutePath());
} else {
Log.d(TAG, "Loading native vtm-jni");
System.loadLibrary("vtm-jni");
}
nativeLibLoaded = true;
} catch (Exception e) {
Log.w(TAG, e);
}
}
private void initFromOptions() {
try {
uiSettings.setCompassEnabled(options.isCompassEnabled());

View File

@ -42,9 +42,8 @@ public class MapFragmentImpl extends IMapFragmentDelegate.Stub {
private GoogleMapImpl myMap() {
if (map == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = new GoogleMapImpl(inflater, options);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = new GoogleMapImpl(inflater.getContext(), options);
}
return map;
}
@ -71,7 +70,7 @@ public class MapFragmentImpl extends IMapFragmentDelegate.Stub {
Bundle savedInstanceState) throws RemoteException {
if (map == null) {
LayoutInflater inflater = (LayoutInflater) ObjectWrapper.unwrap(layoutInflater);
map = new GoogleMapImpl(inflater, options);
map = new GoogleMapImpl(inflater.getContext(), options);
//map.onCreate(savedInstanceState);
} else {
View view = map.getView();

View File

@ -45,9 +45,8 @@ public class MapViewImpl extends IMapViewDelegate.Stub {
private GoogleMapImpl myMap() {
if (map == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = new GoogleMapImpl(inflater, options);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = new GoogleMapImpl(inflater.getContext(), options);
}
return map;
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2013-2016 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;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import org.microg.gms.common.Constants;
import dalvik.system.PathClassLoader;
import static org.microg.gms.common.Constants.GMS_PACKAGE_NAME;
public class RemoteContextWrapper extends ContextWrapper {
private Context applicationContext;
public RemoteContextWrapper(Context base, Context applicationContext) {
super(base);
this.applicationContext = applicationContext;
}
public static RemoteContextWrapper fromApplicationContext(Context applicationContext) {
try {
Context context = applicationContext.createPackageContext(Constants.GMS_PACKAGE_NAME, CONTEXT_INCLUDE_CODE & CONTEXT_IGNORE_SECURITY);
return new RemoteContextWrapper(context, applicationContext);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}
}
@Override
public Context getApplicationContext() {
return applicationContext;
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2013-2016 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.places;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.common.internal.GetServiceRequest;
import com.google.android.gms.common.internal.IGmsCallbacks;
import org.microg.gms.BaseService;
import org.microg.gms.common.Services;
public class GeoDataService extends BaseService {
public GeoDataService() {
super("GmsPlcGeoSvc", Services.GEODATA.SERVICE_ID);
}
@Override
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request) throws RemoteException {
Log.d(TAG, "unimplemented Method: handleServiceRequest");
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2013-2016 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.places;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.common.internal.GetServiceRequest;
import com.google.android.gms.common.internal.IGmsCallbacks;
import org.microg.gms.BaseService;
import org.microg.gms.common.Services;
public class PlaceDetectionService extends BaseService {
public PlaceDetectionService() {
super("GmsPlcDtctSvc", Services.PLACE_DETECTION.SERVICE_ID);
}
@Override
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request) throws RemoteException {
Log.d(TAG, "unimplemented Method: handleServiceRequest");
}
}