diff --git a/build.gradle b/build.gradle index b6dea5be..ffa3adc3 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.1.0' + classpath 'com.android.tools.build:gradle:7.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10" classpath "com.squareup.wire:wire-gradle-plugin:3.2.2" } @@ -24,8 +24,8 @@ allprojects { apply plugin: 'idea' group = 'org.microg.gms' - version = "0.2.23.220217" - ext.appVersionCode = 220217001 + version = "0.2.24.220220" + ext.appVersionCode = 220220001 ext.isReleaseVersion = false } diff --git a/play-services-api/src/main/java/com/google/android/gms/clearcut/LogEventParcelable.java b/play-services-api/src/main/java/com/google/android/gms/clearcut/LogEventParcelable.java index f275f206..cb9cb2ec 100644 --- a/play-services-api/src/main/java/com/google/android/gms/clearcut/LogEventParcelable.java +++ b/play-services-api/src/main/java/com/google/android/gms/clearcut/LogEventParcelable.java @@ -27,7 +27,6 @@ import org.microg.safeparcel.AutoSafeParcelable; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.StandardCharsets; import java.util.Arrays; diff --git a/play-services-cast-framework-api/src/main/java/com/google/android/gms/cast/framework/media/NotificationOptions.java b/play-services-cast-framework-api/src/main/java/com/google/android/gms/cast/framework/media/NotificationOptions.java index e0949265..b6960149 100644 --- a/play-services-cast-framework-api/src/main/java/com/google/android/gms/cast/framework/media/NotificationOptions.java +++ b/play-services-cast-framework-api/src/main/java/com/google/android/gms/cast/framework/media/NotificationOptions.java @@ -16,8 +16,6 @@ package com.google.android.gms.cast.framework.media; -import com.google.android.gms.cast.framework.media.INotificationActionsProvider; - import org.microg.safeparcel.AutoSafeParcelable; import java.util.List; diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index 16d32fcd..a5a44232 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -22,6 +22,7 @@ dependencies { implementation 'com.squareup.wire:wire-runtime:3.6.1' implementation 'de.hdodenhof:circleimageview:3.1.0' implementation "info.armills.chromecast-java-api-v2:api-v2-raw-request:0.10.4-raw-request-1" + implementation 'androidx.webkit:webkit:1.4.0' implementation project(':play-services-cronet-core') implementation project(':play-services-core-proto') diff --git a/play-services-core/src/main/java/org/microg/gms/auth/login/LoginActivity.java b/play-services-core/src/main/java/org/microg/gms/auth/login/LoginActivity.java index 7e090360..5b6aaca7 100644 --- a/play-services-core/src/main/java/org/microg/gms/auth/login/LoginActivity.java +++ b/play-services-core/src/main/java/org/microg/gms/auth/login/LoginActivity.java @@ -19,9 +19,6 @@ package org.microg.gms.auth.login; import static android.accounts.AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE; import static android.accounts.AccountManager.VISIBILITY_USER_MANAGED_VISIBLE; import static android.os.Build.VERSION.SDK_INT; -import static android.os.Build.VERSION_CODES.GINGERBREAD_MR1; -import static android.os.Build.VERSION_CODES.HONEYCOMB; -import static android.os.Build.VERSION_CODES.LOLLIPOP; import static android.telephony.TelephonyManager.SIM_STATE_UNKNOWN; import static android.view.KeyEvent.KEYCODE_BACK; import static android.view.View.INVISIBLE; @@ -37,13 +34,11 @@ import static org.microg.gms.common.Constants.GMS_VERSION_CODE; import android.accounts.Account; import android.accounts.AccountManager; import android.annotation.SuppressLint; -import android.annotation.TargetApi; import android.content.Context; 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.text.TextUtils; import android.util.Log; @@ -55,11 +50,11 @@ import android.webkit.CookieManager; import android.webkit.JavascriptInterface; import android.webkit.WebSettings; import android.webkit.WebView; -import android.webkit.WebViewClient; import android.widget.RelativeLayout; import android.widget.TextView; import androidx.annotation.StringRes; +import androidx.webkit.WebViewClientCompat; import com.mgoogle.android.gms.R; @@ -73,6 +68,8 @@ import org.microg.gms.checkin.LastCheckinInfo; import org.microg.gms.common.HttpFormClient; import org.microg.gms.common.Utils; import org.microg.gms.people.PeopleManager; +import org.microg.gms.profile.Build; +import org.microg.gms.profile.ProfileManager; import org.microg.gms.ui.UtilsKt; import java.io.IOException; @@ -113,7 +110,7 @@ public class LoginActivity extends AssistantActivity { webView.addJavascriptInterface(new JsBridge(), "mm"); authContent = (ViewGroup) findViewById(R.id.auth_content); ((ViewGroup) findViewById(R.id.auth_root)).addView(webView); - webView.setWebViewClient(new WebViewClient() { + webView.setWebViewClient(new WebViewClientCompat() { @Override public void onPageFinished(WebView view, String url) { Log.d(TAG, "pageFinished: " + view.getUrl()); @@ -142,7 +139,7 @@ public class LoginActivity extends AssistantActivity { AccountManager accountManager = AccountManager.get(this); Account account = new Account(getIntent().getStringExtra(EXTRA_EMAIL), accountType); accountManager.addAccountExplicitly(account, getIntent().getStringExtra(EXTRA_TOKEN), null); - if (isAuthVisible(this) && SDK_INT >= Build.VERSION_CODES.O) { + if (isAuthVisible(this) && SDK_INT >= 26) { accountManager.setAccountVisibility(account, PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, VISIBILITY_USER_MANAGED_VISIBLE); } retrieveGmsToken(account); @@ -162,7 +159,7 @@ public class LoginActivity extends AssistantActivity { super.onHuaweiButtonClicked(); state++; if (state == 1) { - if (SDK_INT >= Build.VERSION_CODES.M) { + if (SDK_INT >= 23) { hideLauncherIcon(this, false); UtilsKt.hideIcon(this, false); } @@ -212,7 +209,7 @@ public class LoginActivity extends AssistantActivity { authContent.addView(loading); setMessage(R.string.auth_connecting); CookieManager.getInstance().setAcceptCookie(true); - if (SDK_INT >= LOLLIPOP) { + if (SDK_INT >= 21) { CookieManager.getInstance().removeAllCookies(value -> start()); } else { //noinspection deprecation @@ -223,7 +220,7 @@ public class LoginActivity extends AssistantActivity { private static WebView createWebView(Context context) { WebView webView = new WebView(context); - if (SDK_INT < LOLLIPOP) { + if (SDK_INT < 21) { webView.setVisibility(VISIBLE); } else { webView.setVisibility(INVISIBLE); @@ -231,13 +228,14 @@ public class LoginActivity extends AssistantActivity { webView.setLayoutParams(new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); webView.setBackgroundColor(Color.TRANSPARENT); - prepareWebViewSettings(webView.getSettings()); + prepareWebViewSettings(context, webView.getSettings()); return webView; } @SuppressLint("SetJavaScriptEnabled") - private static void prepareWebViewSettings(WebSettings settings) { - settings.setUserAgentString(settings.getUserAgentString() + MAGIC_USER_AGENT); + private static void prepareWebViewSettings(Context context, WebSettings settings) { + ProfileManager.ensureInitialized(context); + settings.setUserAgentString(Build.INSTANCE.generateWebViewUserAgentString(settings.getUserAgentString()) + MAGIC_USER_AGENT); settings.setJavaScriptEnabled(true); settings.setSupportMultipleWindows(false); settings.setSaveFormData(false); @@ -544,10 +542,8 @@ public class LoginActivity extends AssistantActivity { Log.d(TAG, "JSBridge: setAccountIdentifier"); } - @TargetApi(HONEYCOMB) @JavascriptInterface public final void setBackButtonEnabled(boolean backButtonEnabled) { - if (SDK_INT <= GINGERBREAD_MR1) return; int visibility = getWindow().getDecorView().getSystemUiVisibility(); if (backButtonEnabled) visibility &= -STATUS_BAR_DISABLE_BACK; 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 8a67b886..cd6472a3 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 @@ -120,7 +120,11 @@ public class McsService extends Service implements Handler.Callback { public static final String FROM_FIELD = "gcm@android.com"; public static final String SERVICE_HOST = "mtalk.google.com"; + // A few ports are available: 443, 5228-5230 but also 5222-5223 + // See https://github.com/microg/GmsCore/issues/408 public static final int SERVICE_PORT = 5228; + // Likely if the main port 5228 is blocked by a firewall, the other 52xx are blocked as well + public static final int SERVICE_PORT_FALLBACK = 443; private static final int WAKELOCK_TIMEOUT = 5000; // On bad mobile network a ping can take >60s, so we wait for an ACK for 90s @@ -440,24 +444,15 @@ public class McsService extends Service implements Handler.Callback { } } - private synchronized void connect() { + private boolean connect(int port) { try { - closeAll(); - ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo(); - activeNetworkPref = GcmPrefs.get(this).getNetworkPrefForInfo(activeNetworkInfo); - if (!GcmPrefs.get(this).isEnabledFor(activeNetworkInfo)) { - logd(this, "Don't connect, because disabled for " + activeNetworkInfo.getTypeName()); - scheduleReconnect(this); - return; - } wasTornDown = false; - logd(this, "Starting MCS connection..."); - Socket socket = new Socket(SERVICE_HOST, SERVICE_PORT); - logd(this, "Connected to " + SERVICE_HOST + ":" + SERVICE_PORT); - sslSocket = SSLContext.getDefault().getSocketFactory().createSocket(socket, SERVICE_HOST, SERVICE_PORT, true); - logd(this, "Activated SSL with " + SERVICE_HOST + ":" + SERVICE_PORT); + logd(this, "Starting MCS connection to port " + port + "..."); + Socket socket = new Socket(SERVICE_HOST, port); + logd(this, "Connected to " + SERVICE_HOST + ":" + port); + sslSocket = SSLContext.getDefault().getSocketFactory().createSocket(socket, SERVICE_HOST, port, true); + logd(this, "Activated SSL with " + SERVICE_HOST + ":" + port); inputStream = new McsInputStream(sslSocket.getInputStream(), rootHandler); outputStream = new McsOutputStream(sslSocket.getOutputStream(), rootHandler); inputStream.start(); @@ -469,9 +464,29 @@ public class McsService extends Service implements Handler.Callback { lastIncomingNetworkRealtime = SystemClock.elapsedRealtime(); scheduleHeartbeat(this); } catch (Exception e) { - Log.w(TAG, "Exception while connecting!", e); + Log.w(TAG, "Exception while connecting to " + SERVICE_HOST + ":" + port, e); rootHandler.sendMessage(rootHandler.obtainMessage(MSG_TEARDOWN, e)); + closeAll(); + return false; } + + return true; + } + + private synchronized void connect() { + closeAll(); + + ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo(); + activeNetworkPref = GcmPrefs.get(this).getNetworkPrefForInfo(activeNetworkInfo); + if (!GcmPrefs.get(this).isEnabledFor(activeNetworkInfo)) { + logd(this, "Don't connect, because disabled for " + activeNetworkInfo.getTypeName()); + scheduleReconnect(this); + return; + } + + if (!connect(SERVICE_PORT)) + connect(SERVICE_PORT_FALLBACK); } private void handleClose(Close close) { diff --git a/play-services-core/src/main/kotlin/org/microg/gms/profile/Build.kt b/play-services-core/src/main/kotlin/org/microg/gms/profile/Build.kt index ffaeda10..a52059a9 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/profile/Build.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/profile/Build.kt @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021, microG Project Team + * SPDX-FileCopyrightText: 2021 microG Project Team * SPDX-License-Identifier: Apache-2.0 */ @@ -91,4 +91,11 @@ object Build { @JvmField var SECURITY_PATCH: String? = null } + + fun generateWebViewUserAgentString(original: String): String { + if (!original.startsWith("Mozilla/5.0 (")) return original + val closeParen: Int = original.indexOf(')') + + return "Mozilla/5.0 (Linux; Android ${VERSION.RELEASE}; $MODEL Build/$ID; wv)${original.substring(closeParen + 1)}" + } } diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/internal/LocationRequestUpdateData.java b/play-services-location-api/src/main/java/com/google/android/gms/location/internal/LocationRequestUpdateData.java index 6da81cc3..41c1edb8 100644 --- a/play-services-location-api/src/main/java/com/google/android/gms/location/internal/LocationRequestUpdateData.java +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/internal/LocationRequestUpdateData.java @@ -20,7 +20,6 @@ import android.app.PendingIntent; import com.google.android.gms.location.ILocationCallback; import com.google.android.gms.location.ILocationListener; -import com.google.android.gms.location.internal.IFusedLocationProviderCallback; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled;