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(); + } +}