diff --git a/.travis.yml b/.travis.yml
index fb817f5d..5e7b24c4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ script:
- echo sdk.dir $ANDROID_HOME > local.properties
- export TERM=dumb
- export JAVA_OPTS="-XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError -Xmx2048m"
- - ./gradlew assemble
+ - ./gradlew --stacktrace assemble
android:
components:
- tools
diff --git a/Android.mk b/Android.mk
index 59599968..5416ad10 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,7 +23,7 @@ gmscore_root := $(LOCAL_PATH)
gmscore_dir := play-services-core
gmscore_out := $(TARGET_COMMON_OUT_ROOT)/obj/APPS/$(LOCAL_MODULE)_intermediates
gmscore_build := $(gmscore_root)/$(gmscore_dir)/build
-gmscore_apk := build/outputs/apk/play-services-core-release-unsigned.apk
+gmscore_apk := build/outputs/apk/release/play-services-core-release-unsigned.apk
$(gmscore_root)/$(gmscore_dir)/$(gmscore_apk):
rm -Rf $(gmscore_build)
diff --git a/build.gradle b/build.gradle
index eb2ee5dc..c2e1817c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,7 +20,7 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.0'
+ classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
}
}
diff --git a/extern/GmsApi b/extern/GmsApi
index d1c0bcb9..b7402671 160000
--- a/extern/GmsApi
+++ b/extern/GmsApi
@@ -1 +1 @@
-Subproject commit d1c0bcb9f818eb4a9efdc5a498dd26f178f8fe3f
+Subproject commit b74026712f45392c0f9ac3c0b083896ab15fc927
diff --git a/extern/GmsLib b/extern/GmsLib
index a3b7236b..d3a6dfcb 160000
--- a/extern/GmsLib
+++ b/extern/GmsLib
@@ -1 +1 @@
-Subproject commit a3b7236b5efa09bcd2bcb65c4946b41c63e3e98f
+Subproject commit d3a6dfcb054dd3464b1663057af8be13167a9241
diff --git a/extern/UnifiedNlp b/extern/UnifiedNlp
index b331309c..82479b79 160000
--- a/extern/UnifiedNlp
+++ b/extern/UnifiedNlp
@@ -1 +1 @@
-Subproject commit b331309c66d399918f7b293ceb6c3533ad24af88
+Subproject commit 82479b79c76353f532e0c6edd0d1dee8d49c48f4
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index f5c485b8..9ec837b2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Tue Feb 7 18:49:43 UTC 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle
index dad757df..892a5e19 100644
--- a/play-services-core/build.gradle
+++ b/play-services-core/build.gradle
@@ -49,35 +49,33 @@ dependencies {
implementation project(':vtm-microg-theme')
}
-String getMyVersionName() {
- def stdout = new ByteArrayOutputStream()
- if (rootProject.file("gradlew").exists())
- exec {
- commandLine 'git', 'describe', '--tags', '--always', '--dirty'; standardOutput = stdout
- }
- else // automatic build system, don't tag dirty
- exec { commandLine 'git', 'describe', '--tags', '--always'; standardOutput = stdout }
- return stdout.toString().trim().substring(1)
-}
-
-int getMyVersionCode() {
+def execResult(...args) {
def stdout = new ByteArrayOutputStream()
exec {
- commandLine 'git', 'rev-list', '--count', "HEAD"
+ commandLine args
standardOutput = stdout
}
- return Integer.parseInt(stdout.toString().trim())
+ return stdout.toString().trim()
}
+def gmsVersion = "12.8.79"
+def gmsVersionCode = Integer.parseInt(gmsVersion.replaceAll('\\.', ''))
+def gitVersionBase = execResult('git', 'describe', '--tags', '--abbrev=0').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 ourVersionCode = gmsVersionCode * 1000 + gitCommitCount + (gitDirty ? 1 : 0)
+def ourVersionName = "$ourVersionBase.$gmsVersionCode" + (gitCommitCount > 0 ? "-$gitCommitCount-$gitCommitId" : "") + (gitDirty ? "-dirty" : "")
+logger.lifecycle('Starting build for version {} ({})...', ourVersionName, ourVersionCode)
+
android {
compileSdkVersion androidCompileSdk()
buildToolsVersion "$androidBuildVersionTools"
defaultConfig {
- versionName getMyVersionName()
- def x = getMyVersionCode() - 367
- // We are not allowed to freely choose the hundreds column as it defines the device type
- versionCode(12221400 + x % 100 + ((int) (x / 100)) * 1000)
+ versionName ourVersionName
+ versionCode ourVersionCode
minSdkVersion androidMinSdk()
targetSdkVersion androidTargetSdk()
diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml
index 042e4c33..11f052aa 100644
--- a/play-services-core/src/main/AndroidManifest.xml
+++ b/play-services-core/src/main/AndroidManifest.xml
@@ -507,6 +507,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/play-services-core/src/main/java/com/google/android/gms/cast/framework/internal/CastDynamiteModuleImpl.java b/play-services-core/src/main/java/com/google/android/gms/cast/framework/internal/CastDynamiteModuleImpl.java
index 3bc3bd81..71bd3345 100644
--- a/play-services-core/src/main/java/com/google/android/gms/cast/framework/internal/CastDynamiteModuleImpl.java
+++ b/play-services-core/src/main/java/com/google/android/gms/cast/framework/internal/CastDynamiteModuleImpl.java
@@ -17,8 +17,6 @@
package com.google.android.gms.cast.framework.internal;
import android.content.Context;
-import android.os.Bundle;
-import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.media.MediaRouter;
import android.util.Log;
@@ -63,21 +61,18 @@ public class CastDynamiteModuleImpl extends ICastDynamiteModule.Stub {
@Override
public IMediaNotificationService newMediaNotificationServiceImpl(IObjectWrapper service, IObjectWrapper castContext, IObjectWrapper resources, CastMediaOptions options) throws RemoteException {
Log.d(TAG, "unimplemented Method: newMediaNotificationServiceImpl");
- return new IMediaNotificationService.Stub() {
- };
+ return null;
}
@Override
public IReconnectionService newReconnectionServiceImpl(IObjectWrapper service, IObjectWrapper sessionManager, IObjectWrapper discoveryManager) throws RemoteException {
Log.d(TAG, "unimplemented Method: newReconnectionServiceImpl");
- return new IReconnectionService.Stub() {
- };
+ return null;
}
@Override
public IFetchBitmapTask newFetchBitmapTaskImpl(IObjectWrapper asyncTask, IFetchBitmapTaskProgressPublisher progressPublisher, int i1, int i2, boolean b1, long l1, int i3, int i4, int i5) throws RemoteException {
Log.d(TAG, "unimplemented Method: newFetchBitmapTaskImpl");
- return new IFetchBitmapTask.Stub() {
- };
+ return null;
}
}
diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java b/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java
index 5a3084f0..d0cc000f 100644
--- a/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java
+++ b/play-services-core/src/main/java/org/microg/gms/gcm/GcmPrefs.java
@@ -100,6 +100,7 @@ public class GcmPrefs implements SharedPreferences.OnSharedPreferenceChangeListe
}
public String getNetworkPrefForInfo(NetworkInfo info) {
+ if (info == null) return PREF_NETWORK_OTHER;
if (info.isRoaming()) return PREF_NETWORK_ROAMING;
switch (info.getType()) {
case ConnectivityManager.TYPE_MOBILE:
@@ -190,7 +191,7 @@ public class GcmPrefs implements SharedPreferences.OnSharedPreferenceChangeListe
}
public boolean isEnabledFor(NetworkInfo info) {
- return isEnabled() && getHeartbeatMsFor(info) >= 0;
+ return isEnabled() && info != null && getHeartbeatMsFor(info) >= 0;
}
public boolean isGcmLogEnabled() {
diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/McsService.java b/play-services-core/src/main/java/org/microg/gms/gcm/McsService.java
index 6d64ec89..1884bcce 100644
--- a/play-services-core/src/main/java/org/microg/gms/gcm/McsService.java
+++ b/play-services-core/src/main/java/org/microg/gms/gcm/McsService.java
@@ -23,6 +23,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.net.ConnectivityManager;
import android.os.Build;
@@ -468,6 +469,15 @@ public class McsService extends Service implements Handler.Callback {
intent.putExtra(appData.key, appData.value);
}
+ String receiverPermission;
+ try {
+ String name = msg.category + ".permission.C2D_MESSAGE";
+ getPackageManager().getPermissionInfo(name, 0);
+ receiverPermission = name;
+ } catch (PackageManager.NameNotFoundException e) {
+ receiverPermission = null;
+ }
+
List infos = getPackageManager().queryBroadcastReceivers(intent, PackageManager.GET_RESOLVED_FILTER);
if (infos == null || infos.isEmpty()) {
logd("No target for message, wut?");
@@ -476,7 +486,7 @@ public class McsService extends Service implements Handler.Callback {
logd("Target: " + resolveInfo);
Intent targetIntent = new Intent(intent);
targetIntent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name));
- sendOrderedBroadcast(targetIntent, msg.category + ".permission.C2D_MESSAGE");
+ sendOrderedBroadcast(targetIntent, receiverPermission);
}
}
}
diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterService.java b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterService.java
index 5e971914..91ccdb32 100644
--- a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterService.java
+++ b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterService.java
@@ -22,8 +22,15 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
+import android.os.RemoteException;
+import android.support.annotation.Nullable;
import android.util.Log;
import org.microg.gms.checkin.CheckinService;
@@ -177,24 +184,28 @@ public class PushRegisterService extends IntentService {
}
public static void registerAndReply(Context context, Intent intent, String packageName, String requestId) {
- Intent outIntent = new Intent(ACTION_C2DM_REGISTRATION);
String sender = intent.getStringExtra(EXTRA_SENDER);
String appSignature = PackageUtils.firstSignatureDigest(context, packageName);
String regId = register(context, packageName, appSignature, sender, null).token;
- if (regId != null) {
- outIntent.putExtra(EXTRA_REGISTRATION_ID, attachRequestId(regId, requestId));
- } else {
- outIntent.putExtra(EXTRA_ERROR, attachRequestId(ERROR_SERVICE_NOT_AVAILABLE, requestId));
- }
+ Intent outIntent = createRegistrationReply(regId, requestId);
Log.d(TAG, "register[res]: " + outIntent + " extras=" + outIntent.getExtras());
sendReply(context, intent, packageName, outIntent);
}
- private static void sendReply(Context context, Intent intent, String packageName, Intent outIntent) {
+ private static Intent createRegistrationReply(String regId, String requestId) {
+ Intent outIntent = new Intent(ACTION_C2DM_REGISTRATION);
+ if (regId != null) {
+ outIntent.putExtra(EXTRA_REGISTRATION_ID, attachRequestId(regId, requestId));
+ } else {
+ outIntent.putExtra(EXTRA_ERROR, attachRequestId(ERROR_SERVICE_NOT_AVAILABLE, requestId));
+ }
+ return outIntent;
+ }
+ private static void sendReply(Context context, Intent intent, String packageName, Intent outIntent) {
try {
- if (intent.hasExtra(EXTRA_MESSENGER)) {
+ if (intent != null && intent.hasExtra(EXTRA_MESSENGER)) {
Messenger messenger = intent.getParcelableExtra(EXTRA_MESSENGER);
Message message = Message.obtain();
message.obj = outIntent;
@@ -259,4 +270,133 @@ public class PushRegisterService extends IntentService {
if (requestId == null) return msg;
return "|ID|" + requestId + "|" + msg;
}
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.d(TAG, "onBind: " + intent.toString());
+ if (ACTION_C2DM_REGISTER.equals(intent.getAction())) {
+ Messenger messenger = new Messenger(new FcmHandler(this));
+ return messenger.getBinder();
+ }
+ return super.onBind(intent);
+ }
+
+ private static class FcmRegisterTask extends AsyncTask {
+ private Context context;
+ private String packageName;
+ private String sender;
+ private Callback callback;
+
+ public FcmRegisterTask(Context context, String packageName, String sender, Callback callback) {
+ this.context = context;
+ this.packageName = packageName;
+ this.sender = sender;
+ this.callback = callback;
+ }
+
+ public interface Callback {
+ void onResult(RegisterResponse registerResponse);
+ }
+
+ @Override
+ protected RegisterResponse doInBackground(Void... voids) {
+ return register(context, packageName, PackageUtils.firstSignatureDigest(context, packageName), sender, null, false);
+ }
+
+ @Override
+ protected void onPostExecute(RegisterResponse registerResponse) {
+ callback.onResult(registerResponse);
+ }
+ }
+
+ private static class FcmHandler extends Handler {
+ private Context context;
+ private int callingUid;
+
+ public FcmHandler(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+ this.callingUid = Binder.getCallingUid();
+ return super.sendMessageAtTime(msg, uptimeMillis);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == 0) {
+ if (msg.obj instanceof Intent) {
+ Message nuMsg = Message.obtain();
+ nuMsg.what = msg.what;
+ nuMsg.arg1 = 0;
+ nuMsg.replyTo = null;
+ PendingIntent pendingIntent = ((Intent) msg.obj).getParcelableExtra(EXTRA_APP);
+ String packageName = PackageUtils.packageFromPendingIntent(pendingIntent);
+ Bundle data = new Bundle();
+ data.putBoolean("oneWay", false);
+ data.putString("pkg", packageName);
+ data.putBundle("data", msg.getData());
+ nuMsg.setData(data);
+ msg = nuMsg;
+ } else {
+ return;
+ }
+ }
+ int what = msg.what;
+ int id = msg.arg1;
+ Messenger replyTo = msg.replyTo;
+ if (replyTo == null) {
+ Log.w(TAG, "replyTo is null");
+ return;
+ }
+ Bundle data = msg.getData();
+ if (data.getBoolean("oneWay", false)) {
+ Log.w(TAG, "oneWay requested");
+ return;
+ }
+ String packageName = data.getString("pkg");
+ Bundle subdata = data.getBundle("data");
+ String sender = subdata.getString("sender");
+ try {
+ PackageUtils.checkPackageUid(context, packageName, callingUid);
+ } catch (SecurityException e) {
+ Log.w(TAG, e);
+ return;
+ }
+ new FcmRegisterTask(context, packageName, sender, registerResponse -> {
+ Bundle data1 = new Bundle();
+ if (registerResponse != null) {
+ data1.putString(EXTRA_REGISTRATION_ID, registerResponse.token);
+ } else {
+ data1.putString(EXTRA_ERROR, ERROR_SERVICE_NOT_AVAILABLE);
+ }
+
+ if (what == 0) {
+ Intent outIntent = new Intent(ACTION_C2DM_REGISTRATION);
+ outIntent.putExtras(data1);
+ Message message = Message.obtain();
+ message.obj = outIntent;
+ try {
+ replyTo.send(message);
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ }
+ } else {
+ Bundle messageData = new Bundle();
+ messageData.putBundle("data", data1);
+ Message response = Message.obtain();
+ response.what = what;
+ response.arg1 = id;
+ response.setData(messageData);
+ try {
+ replyTo.send(response);
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ }
+ }
+ }).execute();
+ }
+ }
}
diff --git a/play-services-core/src/main/java/org/microg/gms/measurement/MeasurementBrokerService.java b/play-services-core/src/main/java/org/microg/gms/measurement/MeasurementBrokerService.java
new file mode 100644
index 00000000..4cd9a0f8
--- /dev/null
+++ b/play-services-core/src/main/java/org/microg/gms/measurement/MeasurementBrokerService.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 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.measurement;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.google.android.gms.common.api.CommonStatusCodes;
+import com.google.android.gms.common.api.Status;
+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.GmsService;
+
+public class MeasurementBrokerService extends BaseService {
+ public MeasurementBrokerService() {
+ super("GmsMeasureBrokerSvc", GmsService.MEASUREMENT);
+ }
+
+ @Override
+ public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException {
+ callback.onPostInitComplete(CommonStatusCodes.SUCCESS, new MeasurementServiceImpl().asBinder(), null);
+ }
+}
diff --git a/play-services-core/src/main/java/org/microg/gms/measurement/MeasurementServiceImpl.java b/play-services-core/src/main/java/org/microg/gms/measurement/MeasurementServiceImpl.java
new file mode 100644
index 00000000..c78851b0
--- /dev/null
+++ b/play-services-core/src/main/java/org/microg/gms/measurement/MeasurementServiceImpl.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 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.measurement;
+
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.google.android.gms.measurement.internal.IMeasurementService;
+
+public class MeasurementServiceImpl extends IMeasurementService.Stub {
+ private static final String TAG = "GmsMeasureSvcImpl";
+
+ @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;
+ }
+}
diff --git a/play-services-core/src/main/java/org/microg/gms/phenotype/ConfigurationProvider.java b/play-services-core/src/main/java/org/microg/gms/phenotype/ConfigurationProvider.java
new file mode 100644
index 00000000..131be99b
--- /dev/null
+++ b/play-services-core/src/main/java/org/microg/gms/phenotype/ConfigurationProvider.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 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.phenotype;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+public class ConfigurationProvider extends ContentProvider {
+ private static final String TAG = "GmsPhenotypeCfgProvider";
+ @Override
+ public boolean onCreate() {
+ Log.d(TAG, "unimplemented Method: onCreate");
+ return false;
+ }
+
+ @Nullable
+ @Override
+ public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
+ selection = Uri.decode(uri.getLastPathSegment());
+ if (selection == null) return null;
+ return new MatrixCursor(new String[]{"key", "value"});
+ }
+
+ @Nullable
+ @Override
+ public String getType(@NonNull Uri uri) {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
+ throw new UnsupportedOperationException();
+ }
+}