diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml new file mode 100644 index 00000000..1913b6f2 --- /dev/null +++ b/.github/workflows/debug.yml @@ -0,0 +1,37 @@ +name: Debug APK Builder + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: JDK 8 Setup + uses: actions/setup-java@v1 + with: + java-version: 11.0.8 + + - name: Install NDK + run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;21.0.6113669" + + - name: Grant rights + run: chmod +x ./gradlew + + - name: Build project + run: ./gradlew build + + - name: Build APK + run: ./gradlew assembleDebug + + - name: Upload to Artifacts + uses: actions/upload-artifact@v2 + with: + name: 'MicroG' + path: play-services-core/build/outputs/apk/debug/play-services-core-debug.apk \ No newline at end of file diff --git a/README.md b/README.md index 29f47891..84099ba1 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,18 @@ # Vanced+ MicroG -This fork tweaks MicroG to be usable by applications that require Google authentication such as [YouTube Vanced+](https://gitlab.com/cuynu/vancedx). +[![Github All Releases](https://img.shields.io/github/downloads/cuynu/VancedxMicroG/total.svg)](https://github.com/cuynu/VancedxMicroG/releases/latest/download/microg.apk) [![Github All Releases](https://img.shields.io/github/release/cuynu/VancedxMicroG.svg)](https://github.com/cuynu/VancedxMicroG/releases) + +microG GmsCore is a FLOSS (Free/Libre Open Source Software) framework to allow applications designed for Google Play Services to run on systems, where Play Services is not available. + +This fork tweaks MicroG to be usable by applications that require Google authentication such as YouTube Vanced. ## Warning! -Vanced+ microG are currently **DOES NOT WORK** with ReVanced/RVX as they now uses their own ReVanced microG with specific package name! However, there are workaround : [Issues #15](https://gitlab.com/cuynu/VancedxMicroG/-/issues/15#note_1837372638) +Vanced+ microG probably not work in ReVanced/RVX in future as recent changes from ReVanced/RVX to use with they specific MicroG called ReVanced MicroG ## Notable changes - No longer a system app -- Package name changed from `com.google.android.gms` to `com.mgoogle.android.gms` to support installation alongside the official MicroG or device with Google Play Services pre-installed +- Package name changed from `com.google.android.gms` to `com.mgoogle.android.gms` to support installation alongside the official MicroG - Removed unnecessary features: - Ads - Analytics @@ -33,3 +37,4 @@ Vanced+ microG are currently **DOES NOT WORK** with ReVanced/RVX as they now use - Source Code for MicroG 0.2.25.224113 was provided by [@OxrxL](https://github.com/OxrxL) - [@shadow578](https://github.com/shadow578)'s commit used to apply `SPOOFED_PACKAGE_SIGNATURE` + diff --git a/build.gradle b/build.gradle index bcf0bcbe..c3e82a7a 100644 --- a/build.gradle +++ b/build.gradle @@ -4,31 +4,26 @@ */ buildscript { - ext.applicationNamespace = "com.google.android.gms" - ext.basePackageName = "com.mgoogle" - - ext.safeParcelVersion = '1.7.1' - - ext.kotlinVersion = '1.7.21' + ext.kotlinVersion = '1.8.20' ext.coroutineVersion = '1.6.4' - ext.annotationVersion = '1.5.0' + ext.annotationVersion = '1.6.0' ext.appcompatVersion = '1.6.1' ext.coreVersion = '1.9.0' ext.collectionVersion = '1.3.0-dev01' ext.fragmentVersion = '1.5.5' ext.lifecycleVersion = '2.5.1' - ext.materialVersion = '1.7.0' + ext.materialVersion = '1.8.0' ext.navigationVersion = '2.5.3' ext.preferenceVersion = '1.2.0' - ext.webkitVersion = '1.5.0' + ext.webkitVersion = '1.6.0' ext.circleimageviewVersion = '3.1.0' ext.volleyVersion = '1.2.1' - ext.wireVersion = '4.8.0' + ext.wireVersion = '4.5.5' - ext.androidBuildGradleVersion = '8.0.2' + ext.androidBuildGradleVersion = '8.0.0' ext.androidBuildVersionTools = '33.0.2' ext.androidMinSdk = 23 @@ -41,19 +36,20 @@ buildscript { } dependencies { - classpath "com.android.tools.build:gradle:$androidBuildGradleVersion" + classpath 'com.android.tools.build:gradle:8.0.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "com.squareup.wire:wire-gradle-plugin:$wireVersion" } } -def gmsVersion = "25.09.34" +def gmsVersion = "23.25.16" def gmsVersionCode = Integer.parseInt(gmsVersion.replaceAll('\\.', '')) -def ourVersionBase = "0.3.0" +def ourVersionBase = "0.2.28" +def ourVersionMinor = 73 -def ourVersionCode = gmsVersionCode * 1000 +def ourVersionCode = gmsVersionCode * 1000 + ourVersionMinor def ourVersionName = "$ourVersionBase.$gmsVersionCode" allprojects { @@ -70,13 +66,4 @@ subprojects { mavenCentral() google() } - afterEvaluate { - // Temporary hack for Android Studio - if (project.plugins.hasPlugin('com.android.base')) { - dependencies { - compileOnly "org.microg:safe-parcel:$safeParcelVersion" - testCompileOnly "org.microg:safe-parcel:$safeParcelVersion" - } - } - } -} \ No newline at end of file +} diff --git a/fake-signature/build.gradle b/fake-signature/build.gradle deleted file mode 100644 index e04d9893..00000000 --- a/fake-signature/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -apply plugin: 'com.android.library' - -android { - namespace "org.microg.signature.fake" - - compileSdkVersion androidCompileSdk - buildToolsVersion androidBuildVersionTools - - defaultConfig { - minSdkVersion androidMinSdk - targetSdkVersion androidTargetSdk - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 - } -} - -dependencies { -} diff --git a/fake-signature/src/main/AndroidManifest.xml b/fake-signature/src/main/AndroidManifest.xml deleted file mode 100644 index 1b3ae15d..00000000 --- a/fake-signature/src/main/AndroidManifest.xml +++ /dev/null @@ -1,1159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/fake-signature/src/main/res/values/arrays.xml b/fake-signature/src/main/res/values/arrays.xml deleted file mode 100644 index 315cce58..00000000 --- a/fake-signature/src/main/res/values/arrays.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - com.google.android.gms - com.android.vending - com.spotify.music - - - com.truecaller - - \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 126b7d28..86630672 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ android.useAndroidX=true -org.gradle.jvmargs=-Xmx2048m -XX:+UseParallelGC +org.gradle.jvmargs=-Xmx4096m -XX:+UseParallelGC android.defaults.buildfeatures.buildconfig=true android.nonTransitiveRClass=false -android.nonFinalResIds=false +android.nonFinalResIds=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd491..62d4c053 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0e1ae8ce..e736c04d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ +#Thu Jun 29 16:45:22 ICT 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-rc-3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1aa94a42..60cf9e8c 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,6 @@ #!/bin/sh +# SPDX-License-Identifier: Apache-2.0 # # Copyright © 2015-2021 the original authors. # @@ -55,7 +56,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,11 +81,13 @@ do esac done -# This is normally unused -# shellcheck disable=SC2034 +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -125,35 +128,26 @@ if [ -n "$JAVA_HOME" ] ; then fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." - fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,15 +192,11 @@ if "$cygwin" || "$msys" ; then done fi - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -214,12 +204,6 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. @@ -246,4 +230,4 @@ eval "set -- $( tr '\n' ' ' )" '"$@"' -exec "$JAVACMD" "$@" +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f..5093609d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%"=="" @echo off +@if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,8 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused +if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -41,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute +if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -55,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto execute +if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -65,6 +64,21 @@ echo location of your Java installation. goto fail +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + :execute @rem Setup the command line @@ -72,19 +86,17 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd +if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/play-services-api/build.gradle b/play-services-api/build.gradle index 20d8bea5..f78981e9 100644 --- a/play-services-api/build.gradle +++ b/play-services-api/build.gradle @@ -17,8 +17,8 @@ apply plugin: 'com.android.library' android { - compileSdkVersion androidCompileSdk - buildToolsVersion androidBuildVersionTools + compileSdk androidCompileSdk + buildToolsVersion '33.0.2' defaultConfig { minSdkVersion androidMinSdk @@ -26,13 +26,13 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = "1.8" } + namespace 'org.microg.gms.api' buildFeatures { aidl true } - namespace 'org.microg.gms.api' } dependencies { diff --git a/play-services-api/src/main/AndroidManifest.xml b/play-services-api/src/main/AndroidManifest.xml deleted file mode 100644 index 359a9b71..00000000 --- a/play-services-api/src/main/AndroidManifest.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - diff --git a/play-services-api/src/main/aidl/com/google/android/auth/IAuthManagerService.aidl b/play-services-api/src/main/aidl/com/google/android/auth/IAuthManagerService.aidl index d6afdf80..ae33a334 100644 --- a/play-services-api/src/main/aidl/com/google/android/auth/IAuthManagerService.aidl +++ b/play-services-api/src/main/aidl/com/google/android/auth/IAuthManagerService.aidl @@ -7,7 +7,7 @@ import com.google.android.gms.auth.AccountChangeEventsResponse; import com.google.android.gms.auth.AccountChangeEventsRequest; import com.google.android.gms.auth.GetHubTokenRequest; import com.google.android.gms.auth.GetHubTokenInternalResponse; -import com.google.android.gms.auth.HasCapabilitiesRequest; +import com.google.android.gms.auth.HasCababilitiesRequest; interface IAuthManagerService { Bundle getToken(String accountName, String scope, in Bundle extras) = 0; @@ -18,6 +18,6 @@ interface IAuthManagerService { Bundle getAccounts(in Bundle extras) = 5; Bundle removeAccount(in Account account) = 6; Bundle requestGoogleAccountsAccess(String packageName) = 7; - int hasCapabilities(in HasCapabilitiesRequest request) = 8; + int hasCapabilities(in HasCababilitiesRequest request) = 8; GetHubTokenInternalResponse getHubToken(in GetHubTokenRequest request, in Bundle extras) = 9; } diff --git a/play-services-api/src/main/aidl/com/google/android/gms/auth/HasCapabilitiesRequest.aidl b/play-services-api/src/main/aidl/com/google/android/gms/auth/HasCababilitiesRequest.aidl similarity index 52% rename from play-services-api/src/main/aidl/com/google/android/gms/auth/HasCapabilitiesRequest.aidl rename to play-services-api/src/main/aidl/com/google/android/gms/auth/HasCababilitiesRequest.aidl index b6cb6b9d..c0c080cd 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/auth/HasCapabilitiesRequest.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/auth/HasCababilitiesRequest.aidl @@ -1,3 +1,3 @@ package com.google.android.gms.auth; -parcelable HasCapabilitiesRequest; +parcelable HasCababilitiesRequest; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/common/internal/GoogleCertificatesQuery.aidl b/play-services-api/src/main/aidl/com/google/android/gms/common/internal/GoogleCertificatesQuery.aidl new file mode 100644 index 00000000..ae02e068 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/common/internal/GoogleCertificatesQuery.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.common.internal; + +parcelable GoogleCertificatesQuery; \ No newline at end of file diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ICertData.aidl b/play-services-api/src/main/aidl/com/google/android/gms/common/internal/ICertData.aidl similarity index 100% rename from play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ICertData.aidl rename to play-services-api/src/main/aidl/com/google/android/gms/common/internal/ICertData.aidl diff --git a/play-services-api/src/main/aidl/com/google/android/gms/common/internal/IGoogleCertificatesApi.aidl b/play-services-api/src/main/aidl/com/google/android/gms/common/internal/IGoogleCertificatesApi.aidl new file mode 100644 index 00000000..da539f32 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/common/internal/IGoogleCertificatesApi.aidl @@ -0,0 +1,12 @@ +package com.google.android.gms.common.internal; + +import com.google.android.gms.common.internal.GoogleCertificatesQuery; +import com.google.android.gms.dynamic.IObjectWrapper; + +interface IGoogleCertificatesApi { + IObjectWrapper getGoogleCertficates(); + IObjectWrapper getGoogleReleaseCertificates(); + boolean isGoogleReleaseSigned(String packageName, IObjectWrapper certData); + boolean isGoogleSigned(String packageName, IObjectWrapper certData); + boolean isGoogleOrPlatformSigned(in GoogleCertificatesQuery query, IObjectWrapper packageManager); +} \ No newline at end of file diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl b/play-services-api/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl similarity index 100% rename from play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl rename to play-services-api/src/main/aidl/com/google/android/gms/common/internal/ISignInButtonCreator.aidl diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEvent.java b/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEvent.java index 0485f3a2..d9a19568 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEvent.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEvent.java @@ -19,5 +19,5 @@ package com.google.android.gms.auth; import org.microg.safeparcel.AutoSafeParcelable; public class AccountChangeEvent extends AutoSafeParcelable { - public static Creator CREATOR = new AutoCreator(AccountChangeEvent.class); + public static Creator CREATOR = new AutoCreator<>(AccountChangeEvent.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEventsRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEventsRequest.java index 1d404288..cf8561df 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEventsRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEventsRequest.java @@ -21,18 +21,18 @@ import static org.microg.gms.auth.AuthConstants.DEFAULT_ACCOUNT_TYPE; import android.accounts.Account; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; public class AccountChangeEventsRequest extends AutoSafeParcelable { - @Field(1) - private final int versionCode = 1; - @Field(2) - private int since; @Field(3) @Deprecated - private String accountName; + private final String accountName; @Field(4) - private Account account; + private final Account account; + + public AccountChangeEventsRequest(String accountName, Account account) { + this.accountName = accountName; + this.account = account; + } public Account getAccount() { if (account != null) return account; @@ -40,6 +40,6 @@ public class AccountChangeEventsRequest extends AutoSafeParcelable { return null; } - public static Creator CREATOR = new AutoCreator(AccountChangeEventsRequest.class); + public static Creator CREATOR = new AutoCreator<>(AccountChangeEventsRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEventsResponse.java b/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEventsResponse.java index 763e5d42..10491379 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEventsResponse.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/AccountChangeEventsResponse.java @@ -17,20 +17,11 @@ package com.google.android.gms.auth; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; - -import java.util.ArrayList; -import java.util.List; public class AccountChangeEventsResponse extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 1; - @SafeParceled(value = 2, subClass = AccountChangeEvent.class) - private final List events; public AccountChangeEventsResponse() { - events = new ArrayList(); } - public static Creator CREATOR = new AutoCreator(AccountChangeEventsResponse.class); + public static Creator CREATOR = new AutoCreator<>(AccountChangeEventsResponse.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/GetHubTokenInternalResponse.java b/play-services-api/src/main/java/com/google/android/gms/auth/GetHubTokenInternalResponse.java index ccecf291..4845ed41 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/GetHubTokenInternalResponse.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/GetHubTokenInternalResponse.java @@ -5,17 +5,10 @@ package com.google.android.gms.auth; -import android.accounts.Account; -import android.content.Intent; - import org.microg.safeparcel.AutoSafeParcelable; public class GetHubTokenInternalResponse extends AutoSafeParcelable { - @Field(1) - public TokenData tokenData; @Field(2) public String status; - @Field(3) - public Intent recoveryIntent; public static final Creator CREATOR = new AutoCreator<>(GetHubTokenInternalResponse.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/GetHubTokenRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/GetHubTokenRequest.java index cdaffb51..2c4e973c 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/GetHubTokenRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/GetHubTokenRequest.java @@ -14,7 +14,5 @@ public class GetHubTokenRequest extends AutoSafeParcelable { public String service; @Field(3) public String packageName; - @Field(4) - public int callerUid; public static final Creator CREATOR = new AutoCreator<>(GetHubTokenRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/HasCapabilitiesRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/HasCababilitiesRequest.java similarity index 53% rename from play-services-api/src/main/java/com/google/android/gms/auth/HasCapabilitiesRequest.java rename to play-services-api/src/main/java/com/google/android/gms/auth/HasCababilitiesRequest.java index e35ca6d7..c9907fa8 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/HasCapabilitiesRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/HasCababilitiesRequest.java @@ -9,10 +9,8 @@ import android.accounts.Account; import org.microg.safeparcel.AutoSafeParcelable; -public class HasCapabilitiesRequest extends AutoSafeParcelable { +public class HasCababilitiesRequest extends AutoSafeParcelable { @Field(1) public Account account; - @Field(2) - public String[] capabilities; - public static final Creator CREATOR = new AutoCreator<>(HasCapabilitiesRequest.class); + public static final Creator CREATOR = new AutoCreator<>(HasCababilitiesRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/TokenData.java b/play-services-api/src/main/java/com/google/android/gms/auth/TokenData.java index c6fbe9e5..df3768c8 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/TokenData.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/TokenData.java @@ -24,8 +24,6 @@ import org.microg.safeparcel.SafeParceled; import java.util.List; public class TokenData extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 1; @SafeParceled(2) public final String token; @@ -60,5 +58,5 @@ public class TokenData extends AutoSafeParcelable { this.scopes = null; } - public static final Creator CREATOR = new AutoCreator(TokenData.class); + public static final Creator CREATOR = new AutoCreator<>(TokenData.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/Credential.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/Credential.java index 5a92ddc5..9ade5cc0 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/Credential.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/Credential.java @@ -9,21 +9,17 @@ package com.google.android.gms.auth.api.credentials; import android.net.Uri; -import android.text.TextUtils; import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import java.util.Arrays; import java.util.List; -import java.util.Locale; +import java.util.Objects; @PublicApi public class Credential extends AutoSafeParcelable { - @Field(1000) - private final int versionCode = 1; - @Field(1) private String id; @Field(2) @@ -55,13 +51,6 @@ public class Credential extends AutoSafeParcelable { return accountType; } - /** - * Returns the generated password for an account hint. - */ - public String getGeneratedPassword() { - return generatedPassword; - } - /** * Returns the credential identifier, typically an email address or user name, though it may * also be some encoded unique identifier for a federated identity account. @@ -70,23 +59,6 @@ public class Credential extends AutoSafeParcelable { return id; } - /** - * Returns the ID tokens that assert the identity of the user, if available. ID tokens provide - * a secure mechanism to verify that the user owns the identity asserted by the credential. - *

- * This is useful for account hints, where the ID token can replace the need to separately - * verify that the user owns their claimed email address - with a valid ID token, it is not - * necessary to send an account activation link to the address, simplifying the account - * creation process for the user. - *

- * A signed ID token is returned automatically for credential hints when the credential ID is a - * Google account that is authenticated on the device. This ID token can be sent along with - * your application's account creation operation, where the signature can be verified. - */ - public List getIdTokens() { - return tokens; - } - /** * Returns the display name of the credential, if available. Typically, the display name will * be the name of the user, or some other string which the user can easily recognize and @@ -96,47 +68,22 @@ public class Credential extends AutoSafeParcelable { return name; } - /** - * Returns the password used to sign in the user. - */ - public String getPassword() { - return password; - } - - /** - * Returns the URL to an image of the user, if available. - */ - public Uri getProfilePictureUri() { - return profilePictureUri; - } - - @PublicApi(exclude = true) - public String getAsString() { - if (TextUtils.isEmpty(accountType)) { - return id.toLowerCase(Locale.US) + "|"; - } else { - Uri uri = Uri.parse(accountType); - return id.toLowerCase(Locale.US) + "|" + (TextUtils.isEmpty(uri.getScheme()) ? "" : uri.getScheme().toLowerCase(Locale.US)) + "://" + - (TextUtils.isEmpty(uri.getHost()) ? "unknown" : uri.getHost().toLowerCase(Locale.US)) + ":" + uri.getPort(); - } - } - @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || !(o instanceof Credential)) return false; + if (!(o instanceof Credential)) return false; Credential that = (Credential) o; - if (id != null ? !id.equals(that.id) : that.id != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; - if (profilePictureUri != null ? !profilePictureUri.equals(that.profilePictureUri) : that.profilePictureUri != null) + if (!Objects.equals(id, that.id)) return false; + if (!Objects.equals(name, that.name)) return false; + if (!Objects.equals(profilePictureUri, that.profilePictureUri)) return false; - if (password != null ? !password.equals(that.password) : that.password != null) + if (!Objects.equals(password, that.password)) return false; - if (accountType != null ? !accountType.equals(that.accountType) : that.accountType != null) + if (!Objects.equals(accountType, that.accountType)) return false; - return generatedPassword != null ? generatedPassword.equals(that.generatedPassword) : that.generatedPassword == null; + return Objects.equals(generatedPassword, that.generatedPassword); } @@ -148,18 +95,14 @@ public class Credential extends AutoSafeParcelable { public static class Builder { private final String id; private String name; - private Uri profilePictureUri; - private String password; + private final Uri profilePictureUri; + private final String password; private String accountType; @PublicApi(exclude = true) public List tokens; @PublicApi(exclude = true) - private String generatedPassword; - - public Builder(String id) { - this.id = id; - } + private final String generatedPassword; /** * Copies the information stored in an existing credential, in order to allow that information to be modified. @@ -211,24 +154,7 @@ public class Credential extends AutoSafeParcelable { return this; } - /** - * Sets the password for the credential. Either the password or the account type must be - * set for a credential, but not both. - */ - public Builder setPassword(String password) { - this.password = password; - return this; - } - - /** - * Sets a profile picture associated with the credential, typically a picture the user has - * selected to represent the account. - */ - public Builder setProfilePictureUri(Uri profilePictureUri) { - this.profilePictureUri = profilePictureUri; - return this; - } } - public static final Creator CREATOR = new AutoCreator(Credential.class); + public static final Creator CREATOR = new AutoCreator<>(Credential.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialPickerConfig.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialPickerConfig.java index 4cb1bbc9..41ca2191 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialPickerConfig.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialPickerConfig.java @@ -8,24 +8,20 @@ package com.google.android.gms.auth.api.credentials; +import androidx.annotation.NonNull; + import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; @PublicApi public class CredentialPickerConfig extends AutoSafeParcelable { - @Field(1000) - private final int versionCode = 1; - @Field(1) - private boolean showAddAccountButton; + private final boolean showAddAccountButton; @Field(2) - private boolean showCancelButton; + private final boolean showCancelButton; @Field(3) - private boolean forNewAccount; - - private CredentialPickerConfig() { - } + private final boolean forNewAccount; public CredentialPickerConfig(boolean showAddAccountButton, boolean showCancelButton, boolean forNewAccount) { this.showAddAccountButton = showAddAccountButton; @@ -41,14 +37,7 @@ public class CredentialPickerConfig extends AutoSafeParcelable { return forNewAccount; } - public boolean shouldShowAddAccountButton() { - return showAddAccountButton; - } - - public boolean shouldShowCancelButton() { - return showCancelButton; - } - + @NonNull @Override public String toString() { return "CredentialPickerConfig{" + @@ -57,39 +46,22 @@ public class CredentialPickerConfig extends AutoSafeParcelable { '}'; } - public class Builder { - private boolean showAddAccountButton; - private boolean showCancelButton; - private boolean forNewAccount; + public static class Builder { + private final boolean showAddAccountButton; + private final boolean showCancelButton; + private final boolean forNewAccount; + + public Builder(boolean showAddAccountButton, boolean showCancelButton, boolean forNewAccount) { + this.showAddAccountButton = showAddAccountButton; + this.showCancelButton = showCancelButton; + this.forNewAccount = forNewAccount; + } public CredentialPickerConfig build() { return new CredentialPickerConfig(showAddAccountButton, showCancelButton, forNewAccount); } - /** - * Sets whether the hint request is for a new account sign-up flow. - */ - public Builder setForNewAccount(boolean forNewAccount) { - this.forNewAccount = forNewAccount; - return this; - } - - /** - * Sets whether the add account button should be shown in credential picker dialog. - */ - public Builder setShowAddAccountButton(boolean showAddAccountButton) { - this.showAddAccountButton = showAddAccountButton; - return this; - } - - /** - * Sets whether the cancel button should be shown in credential picker dialog. - */ - public Builder setShowCancelButton(boolean showCancelButton) { - this.showCancelButton = showCancelButton; - return this; - } } - public static final Creator CREATOR = new AutoCreator(CredentialPickerConfig.class); + public static final Creator CREATOR = new AutoCreator<>(CredentialPickerConfig.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialRequest.java index 6255fbf9..c4961d14 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/CredentialRequest.java @@ -10,43 +10,13 @@ package com.google.android.gms.auth.api.credentials; import org.microg.safeparcel.AutoSafeParcelable; -/** - * Parameters for requesting a Credential, via Auth.CredentialsApi.request(). Instances can be - * created using CredentialRequest.Builder. - */ public class CredentialRequest extends AutoSafeParcelable { - @Field(1000) - private final int versionCode = 1; - @Field(1) - private boolean passwordLoginSupported; - @Field(2) - private String[] accountTypes; - @Field(3) - private CredentialPickerConfig credentialPickerConfig; - @Field(4) - private CredentialPickerConfig credentialHintPickerConfig; + private final boolean passwordLoginSupported; - private CredentialRequest() { } - - public CredentialRequest(boolean passwordLoginSupported, String[] accountTypes, CredentialPickerConfig credentialPickerConfig, CredentialPickerConfig credentialHintPickerConfig) { + public CredentialRequest(boolean passwordLoginSupported) { this.passwordLoginSupported = passwordLoginSupported; - this.accountTypes = accountTypes; - this.credentialPickerConfig = credentialPickerConfig; - this.credentialHintPickerConfig = credentialHintPickerConfig; - } - - public String[] getAccountTypes() { - return accountTypes; - } - - public CredentialPickerConfig getCredentialHintPickerConfig() { - return credentialHintPickerConfig; - } - - public CredentialPickerConfig getCredentialPickerConfig() { - return credentialPickerConfig; } /** @@ -64,13 +34,12 @@ public class CredentialRequest extends AutoSafeParcelable { public static final Creator CREATOR = new AutoCreator(CredentialRequest.class); public static class Builder { - private boolean passwordLoginSupported; - private String[] accountTypes; - private CredentialPickerConfig credentialPickerConfig; - private CredentialPickerConfig credentialHintPickerConfig; + + public Builder() { + } public void setAccountTypes(String... accountTypes) { - this.accountTypes = accountTypes.clone(); + accountTypes.clone(); } } } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/HintRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/HintRequest.java index 1f1cae80..3f9336f4 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/HintRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/HintRequest.java @@ -8,6 +8,8 @@ package com.google.android.gms.auth.api.credentials; +import androidx.annotation.NonNull; + import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; @@ -19,26 +21,21 @@ import java.util.Arrays; */ @PublicApi public class HintRequest extends AutoSafeParcelable { - @Field(1000) - private final int versionCode = 2; @Field(1) - private CredentialPickerConfig hintPickerConfig; + private final CredentialPickerConfig hintPickerConfig; @Field(2) - private boolean emailAddressIdentifierSupported; + private final boolean emailAddressIdentifierSupported; @Field(3) - private boolean phoneNumberIdentifierSupported; + private final boolean phoneNumberIdentifierSupported; @Field(4) - private String[] accountTypes; + private final String[] accountTypes; @Field(5) - private boolean idTokenRequested = true; + private final boolean idTokenRequested; @Field(6) - private String serverClientId; + private final String serverClientId; @Field(7) - private String idTokenNonce; - - private HintRequest() { - } + private final String idTokenNonce; public HintRequest(CredentialPickerConfig hintPickerConfig, boolean emailAddressIdentifierSupported, boolean phoneNumberIdentifierSupported, String[] accountTypes, boolean idTokenRequested, String serverClientId, String idTokenNonce) { this.hintPickerConfig = hintPickerConfig; @@ -50,36 +47,9 @@ public class HintRequest extends AutoSafeParcelable { this.idTokenNonce = idTokenNonce; } - public String[] getAccountTypes() { - return accountTypes; - } - - public CredentialPickerConfig getHintPickerConfig() { - return hintPickerConfig; - } - - public String getIdTokenNonce() { - return idTokenNonce; - } - - public String getServerClientId() { - return serverClientId; - } - - public boolean isEmailAddressIdentifierSupported() { - return emailAddressIdentifierSupported; - } - - public boolean isPhoneNumberIdentifierSupported() { - return phoneNumberIdentifierSupported; - } - - public boolean isIdTokenRequested() { - return idTokenRequested; - } - public static final Creator CREATOR = new AutoCreator<>(HintRequest.class); + @NonNull @Override public String toString() { return "HintRequest{" + @@ -94,77 +64,29 @@ public class HintRequest extends AutoSafeParcelable { } public static class Builder { - private CredentialPickerConfig hintPickerConfig; - private boolean emailAddressIdentifierSupported; - private boolean phoneNumberIdentifierSupported; - private String[] accountTypes; - private boolean idTokenRequested = true; - private String serverClientId; - private String idTokenNonce; + private final CredentialPickerConfig hintPickerConfig; + private final boolean emailAddressIdentifierSupported; + private final boolean phoneNumberIdentifierSupported; + private final String[] accountTypes; + private final String serverClientId; + private final String idTokenNonce; + + public Builder(CredentialPickerConfig hintPickerConfig, boolean emailAddressIdentifierSupported, boolean phoneNumberIdentifierSupported, String[] accountTypes, String serverClientId, String idTokenNonce) { + this.hintPickerConfig = hintPickerConfig; + this.emailAddressIdentifierSupported = emailAddressIdentifierSupported; + this.phoneNumberIdentifierSupported = phoneNumberIdentifierSupported; + this.accountTypes = accountTypes; + this.serverClientId = serverClientId; + this.idTokenNonce = idTokenNonce; + } /** * Builds a {@link HintRequest}. */ public HintRequest build() { + boolean idTokenRequested = true; return new HintRequest(hintPickerConfig, emailAddressIdentifierSupported, phoneNumberIdentifierSupported, accountTypes, idTokenRequested, serverClientId, idTokenNonce); } - /** - * Sets the account types (identity providers) that are accepted by this application. - * It is strongly recommended that the strings listed in {@link IdentityProviders} be used for the most common - * identity providers, and strings representing the login domain of the identity provider be used for any - * others which are not listed. - * - * @param accountTypes The list of account types (identity providers) supported by the app. - * typically in the form of the associated login domain for each identity provider. - */ - public void setAccountTypes(String... accountTypes) { - this.accountTypes = accountTypes.clone(); - } - - /** - * Enables returning {@link Credential} hints where the identifier is an email address, intended for use with a password chosen by the user. - */ - public void setEmailAddressIdentifierSupported(boolean emailAddressIdentifierSupported) { - this.emailAddressIdentifierSupported = emailAddressIdentifierSupported; - } - - /** - * Sets the configuration for the hint picker dialog. - */ - public void setHintPickerConfig(CredentialPickerConfig hintPickerConfig) { - this.hintPickerConfig = hintPickerConfig; - } - - /** - * Specify a nonce value that should be included in any generated ID token for this request. - */ - public void setIdTokenNonce(String idTokenNonce) { - this.idTokenNonce = idTokenNonce; - } - - /** - * Specify whether an ID token should be acquired for hints, if available for the selected credential identifier. - * This is enabled by default; disable this if your app does not use ID tokens as part of authentication to decrease latency in retrieving credentials and credential hints. - */ - public void setIdTokenRequested(boolean idTokenRequested) { - this.idTokenRequested = idTokenRequested; - } - - /** - * Enables returning {@link Credential} hints where the identifier is a phone number, intended for use with a password chosen by the user or SMS verification. - */ - public void setPhoneNumberIdentifierSupported(boolean phoneNumberIdentifierSupported) { - this.phoneNumberIdentifierSupported = phoneNumberIdentifierSupported; - } - - /** - * Specify the server client ID for the backend associated with this app. - * If a Google ID token can be generated for a retrieved credential or hint, and the specified server client ID is correctly configured to be associated with the app, then it will be used as the audience of the generated token. - * If a null value is specified, the default audience will be used for the generated ID token. - */ - public void setServerClientId(String serverClientId) { - this.serverClientId = serverClientId; - } } } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdToken.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdToken.java index aa6d19d4..5d84423e 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdToken.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdToken.java @@ -14,17 +14,11 @@ import org.microg.safeparcel.AutoSafeParcelable; @PublicApi public class IdToken extends AutoSafeParcelable { - @Field(1000) - private final int versionCode = 1; - @Field(1) - private String accountType; + private final String accountType; @Field(2) - private String id; - - private IdToken() { - } + private final String id; public IdToken(String accountType, String id) { this.accountType = accountType; @@ -38,12 +32,5 @@ public class IdToken extends AutoSafeParcelable { return accountType; } - /** - * Returns the ID token, formatted according to the rules defined by the account type. - */ - public String getIdToken() { - return id; - } - - public static final Creator CREATOR = new AutoCreator(IdToken.class); + public static final Creator CREATOR = new AutoCreator<>(IdToken.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdentityProviders.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdentityProviders.java index 8cd24eed..1d974993 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdentityProviders.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/IdentityProviders.java @@ -8,27 +8,8 @@ package com.google.android.gms.auth.api.credentials; -import android.accounts.Account; - /** * Identity provider constants for use with {@link CredentialRequest.Builder#setAccountTypes(String...)} */ public final class IdentityProviders { - public static final String FACEBOOK = "//www.facebook.com"; - public static final String GOOGLE = "//accounts.google.com"; - public static final String LINKEDIN = "//www.linkedin.com"; - public static final String MICROSOFT = "//login.live.com"; - public static final String PAYPAL = "//www.paypal.com"; - public static final String TWITTER = "//twitter.com"; - public static final String YAHOO = "//login.yahoo.com"; - - /** - * Attempts to translate the account type in the provided account into the string that should be used in the credentials API. - * - * @param account an account on the device. - * @return The identity provider string for use with the Credentials API, or {@code null} if the account type is unknown. - */ - public static String getIdentityProviderForAccount(Account account) { - return null; - } } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/DeleteRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/DeleteRequest.java index bd7ae6f2..e560ddc5 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/DeleteRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/DeleteRequest.java @@ -19,5 +19,5 @@ package com.google.android.gms.auth.api.credentials.internal; import org.microg.safeparcel.AutoSafeParcelable; public class DeleteRequest extends AutoSafeParcelable { - public static final Creator CREATOR = new AutoCreator(DeleteRequest.class); + public static final Creator CREATOR = new AutoCreator<>(DeleteRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/GeneratePasswordRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/GeneratePasswordRequest.java index 3da7a72a..5fd6fcb7 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/GeneratePasswordRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/GeneratePasswordRequest.java @@ -19,5 +19,5 @@ package com.google.android.gms.auth.api.credentials.internal; import org.microg.safeparcel.AutoSafeParcelable; public class GeneratePasswordRequest extends AutoSafeParcelable { - public static final Creator CREATOR = new AutoCreator(GeneratePasswordRequest.class); + public static final Creator CREATOR = new AutoCreator<>(GeneratePasswordRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/SaveRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/SaveRequest.java index 5ec25998..24a9d92f 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/SaveRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/credentials/internal/SaveRequest.java @@ -19,5 +19,5 @@ package com.google.android.gms.auth.api.credentials.internal; import org.microg.safeparcel.AutoSafeParcelable; public class SaveRequest extends AutoSafeParcelable { - public static final Creator CREATOR = new AutoCreator(SaveRequest.class); + public static final Creator CREATOR = new AutoCreator<>(SaveRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/proxy/ProxyRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/proxy/ProxyRequest.java index acca03a4..dc1fbd39 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/proxy/ProxyRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/proxy/ProxyRequest.java @@ -5,33 +5,16 @@ package com.google.android.gms.auth.api.proxy; -import android.os.Bundle; +import androidx.annotation.NonNull; import org.microg.safeparcel.AutoSafeParcelable; public class ProxyRequest extends AutoSafeParcelable { - public static final int HTTP_METHOD_GET = 0; - public static final int HTTP_METHOD_POST = 1; - public static final int HTTP_METHOD_PUT = 2; - public static final int HTTP_METHOD_DELETE = 3; - public static final int HTTP_METHOD_HEAD = 4; - public static final int HTTP_METHOD_OPTIONS = 5; - public static final int HTTP_METHOD_TRACE = 6; - public static final int HTTP_METHOD_PATCH = 7; - @Field(1000) - private final int versionCode = 2; @Field(1) public String url; - @Field(2) - public int httpMethod; - @Field(3) - public long timeoutMillis; - @Field(4) - public byte[] body; - @Field(5) - public Bundle headers; + @NonNull @Override public String toString() { return url; diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/api/proxy/ProxyResponse.java b/play-services-api/src/main/java/com/google/android/gms/auth/api/proxy/ProxyResponse.java index b18d21be..263d2e20 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/api/proxy/ProxyResponse.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/api/proxy/ProxyResponse.java @@ -5,26 +5,11 @@ package com.google.android.gms.auth.api.proxy; -import android.app.PendingIntent; -import android.os.Bundle; - import org.microg.safeparcel.AutoSafeParcelable; public class ProxyResponse extends AutoSafeParcelable { - public static final int STATUS_CODE_NO_CONNECTION = -1; - - @Field(1000) - private final int versionCode = 1; @Field(1) public int gmsStatusCode; - @Field(2) - public PendingIntent recoveryAction; - @Field(3) - public int httpStatusCode; - @Field(4) - public Bundle headers; - @Field(5) - public byte[] body; public static final Creator CREATOR = new AutoCreator<>(ProxyResponse.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/AccountRecoveryGuidanceRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/AccountRecoveryGuidanceRequest.java index d5f1d054..1c267ed1 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/AccountRecoveryGuidanceRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/AccountRecoveryGuidanceRequest.java @@ -24,8 +24,6 @@ import org.microg.safeparcel.SafeParceled; public class AccountRecoveryGuidanceRequest extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 1; @SafeParceled(2) @Deprecated public final String accountName; @@ -42,5 +40,5 @@ public class AccountRecoveryGuidanceRequest extends AutoSafeParcelable { this.account = account; } - public static final Creator CREATOR = new AutoCreator(AccountRecoveryGuidanceRequest.class); + public static final Creator CREATOR = new AutoCreator<>(AccountRecoveryGuidanceRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/AccountRemovalRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/AccountRemovalRequest.java index 439825c2..dc90a7d0 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/AccountRemovalRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/AccountRemovalRequest.java @@ -24,8 +24,6 @@ import org.microg.safeparcel.SafeParceled; public class AccountRemovalRequest extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 1; @SafeParceled(2) @Deprecated public final String accountName; diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/ConfirmCredentialsRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/ConfirmCredentialsRequest.java index 16142d6a..9edad8b2 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/ConfirmCredentialsRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/ConfirmCredentialsRequest.java @@ -16,19 +16,9 @@ package com.google.android.gms.auth.firstparty.dataservice; -import com.google.android.gms.auth.firstparty.shared.AccountCredentials; -import com.google.android.gms.auth.firstparty.shared.CaptchaSolution; - import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; public class ConfirmCredentialsRequest extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 1; - @SafeParceled(2) - public AccountCredentials accountCredentials; - @SafeParceled(3) - public CaptchaSolution captchaSolution; - public static final Creator CREATOR = new AutoCreator(ConfirmCredentialsRequest.class); + public static final Creator CREATOR = new AutoCreator<>(ConfirmCredentialsRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/TokenRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/TokenRequest.java index 099e56f4..73062668 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/TokenRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/TokenRequest.java @@ -25,8 +25,6 @@ import org.microg.safeparcel.SafeParceled; // TODO public class TokenRequest extends AutoSafeParcelable{ - @SafeParceled(1) - private final int versionCode = 4; @SafeParceled(3) public String accountName; @SafeParceled(4) @@ -40,5 +38,5 @@ public class TokenRequest extends AutoSafeParcelable{ return new Account(accountName, accountType); } - public static final Creator CREATOR = new AutoCreator(TokenRequest.class); + public static final Creator CREATOR = new AutoCreator<>(TokenRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/TokenResponse.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/TokenResponse.java deleted file mode 100644 index 999e9a96..00000000 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/dataservice/TokenResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.gms.auth.firstparty.dataservice; - -public class TokenResponse { -} diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/delegate/ConfirmCredentialsWorkflowRequest.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/delegate/ConfirmCredentialsWorkflowRequest.java index d4308ef7..b8e5ed63 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/delegate/ConfirmCredentialsWorkflowRequest.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/delegate/ConfirmCredentialsWorkflowRequest.java @@ -17,27 +17,18 @@ package com.google.android.gms.auth.firstparty.delegate; import android.accounts.Account; -import android.accounts.AccountAuthenticatorResponse; import android.os.Bundle; -import com.google.android.gms.auth.firstparty.shared.AppDescription; - import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; public class ConfirmCredentialsWorkflowRequest extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 3; @SafeParceled(2) public String accountName; - @SafeParceled(3) - public AppDescription appDescription; @SafeParceled(4) public Bundle extras; @SafeParceled(5) public Account account; - @SafeParceled(6) - public AccountAuthenticatorResponse accountAuthenticatorResponse; - public static final Creator CREATOR = new AutoCreator(ConfirmCredentialsWorkflowRequest.class); + public static final Creator CREATOR = new AutoCreator<>(ConfirmCredentialsWorkflowRequest.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/proximity/data/Permit.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/proximity/data/Permit.java deleted file mode 100644 index 139bf29b..00000000 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/proximity/data/Permit.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.gms.auth.firstparty.proximity.data; - -public class Permit { -} diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/AccountCredentials.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/AccountCredentials.java index 33995a9a..67e7c7db 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/AccountCredentials.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/AccountCredentials.java @@ -23,8 +23,6 @@ import org.microg.safeparcel.SafeParceled; // TODO public class AccountCredentials extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 2; @SafeParceled(3) public String accountName; @SafeParceled(9) @@ -34,5 +32,5 @@ public class AccountCredentials extends AutoSafeParcelable { return new Account(accountName, accountType); } - public static final Creator CREATOR = new AutoCreator(AccountCredentials.class); + public static final Creator CREATOR = new AutoCreator<>(AccountCredentials.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/AppDescription.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/AppDescription.java index efa4b2bc..1ccdf4f6 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/AppDescription.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/AppDescription.java @@ -17,19 +17,8 @@ package com.google.android.gms.auth.firstparty.shared; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; public class AppDescription extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 1; - @SafeParceled(2) - public int callingUid; - @SafeParceled(3) - public String sessiondId; - @SafeParceled(4) - public String sessiondSig; - @SafeParceled(5) - public String callingPkg; - public static final Creator CREATOR = new AutoCreator(AppDescription.class); + public static final Creator CREATOR = new AutoCreator<>(AppDescription.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/CaptchaSolution.java b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/CaptchaSolution.java index c0cb9326..ce1d3f61 100644 --- a/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/CaptchaSolution.java +++ b/play-services-api/src/main/java/com/google/android/gms/auth/firstparty/shared/CaptchaSolution.java @@ -17,13 +17,9 @@ package com.google.android.gms.auth.firstparty.shared; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; // TODO public class CaptchaSolution extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 1; - - public static final Creator CREATOR = new AutoCreator(CaptchaSolution.class); + public static final Creator CREATOR = new AutoCreator<>(CaptchaSolution.class); } diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/CertData.java b/play-services-api/src/main/java/com/google/android/gms/common/internal/CertData.java similarity index 93% rename from play-services-basement/src/main/java/com/google/android/gms/common/internal/CertData.java rename to play-services-api/src/main/java/com/google/android/gms/common/internal/CertData.java index 826d1c37..62b1abfd 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/CertData.java +++ b/play-services-api/src/main/java/com/google/android/gms/common/internal/CertData.java @@ -55,12 +55,12 @@ public class CertData extends ICertData.Stub { } @Override - public IObjectWrapper getWrappedBytes() throws RemoteException { + public IObjectWrapper getWrappedBytes() { return ObjectWrapper.wrap(getBytes()); } @Override - public int remoteHashCode() throws RemoteException { + public int remoteHashCode() { return hashCode(); } } diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesQuery.java b/play-services-api/src/main/java/com/google/android/gms/common/internal/GoogleCertificatesQuery.java similarity index 53% rename from play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesQuery.java rename to play-services-api/src/main/java/com/google/android/gms/common/internal/GoogleCertificatesQuery.java index dce40a90..02dcc3e9 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesQuery.java +++ b/play-services-api/src/main/java/com/google/android/gms/common/internal/GoogleCertificatesQuery.java @@ -1,38 +1,47 @@ /* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2019 microG Project Team + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ -package com.google.android.gms.common; +package com.google.android.gms.common.internal; import android.os.IBinder; -import android.os.Parcel; import android.os.RemoteException; -import androidx.annotation.NonNull; -import com.google.android.gms.common.internal.CertData; -import com.google.android.gms.common.internal.ICertData; -import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter; + import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.dynamic.ObjectWrapper; -import org.microg.gms.common.Hide; -@Hide -@SafeParcelable.Class -public class GoogleCertificatesQuery extends AbstractSafeParcelable { - @Field(value = 1, getterName = "getCallingPackage") - String callingPackage; - @Field(2) - IBinder certDataBinder; +import org.microg.safeparcel.AutoSafeParcelable; +import org.microg.safeparcel.SafeParceled; + +public class GoogleCertificatesQuery extends AutoSafeParcelable { + @SafeParceled(1) + private final String packageName; + @SafeParceled(2) + private final IBinder certDataBinder; private CertData certData; - @Field(3) - boolean allowTestKeys; - @Field(4) - boolean ignoreTestKeysOverride; + @SafeParceled(3) + private final boolean allowNonRelease; - public String getCallingPackage() { - return callingPackage; + public GoogleCertificatesQuery(String packageName, IBinder certDataBinder, boolean allowNonRelease) { + this.packageName = packageName; + this.certDataBinder = certDataBinder; + this.allowNonRelease = allowNonRelease; + } + + public String getPackageName() { + return packageName; } public CertData getCertData() { @@ -68,10 +77,5 @@ public class GoogleCertificatesQuery extends AbstractSafeParcelable { return certData; } - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - CREATOR.writeToParcel(this, dest, flags); - } - - public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(GoogleCertificatesQuery.class); + public static final Creator CREATOR = new AutoCreator(GoogleCertificatesQuery.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java b/play-services-api/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java index 6f10959a..d32e668b 100644 --- a/play-services-api/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java +++ b/play-services-api/src/main/java/com/google/android/gms/common/server/FavaDiagnosticsEntity.java @@ -20,5 +20,5 @@ import org.microg.safeparcel.AutoSafeParcelable; public class FavaDiagnosticsEntity extends AutoSafeParcelable { - public static final Creator CREATOR = new AutoCreator(FavaDiagnosticsEntity.class); + public static final Creator CREATOR = new AutoCreator<>(FavaDiagnosticsEntity.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/identity/intents/model/CountrySpecification.java b/play-services-api/src/main/java/com/google/android/gms/identity/intents/model/CountrySpecification.java deleted file mode 100644 index b9770e36..00000000 --- a/play-services-api/src/main/java/com/google/android/gms/identity/intents/model/CountrySpecification.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.gms.identity.intents.model; - -public class CountrySpecification { -} diff --git a/play-services-api/src/main/java/com/google/android/gms/identity/intents/model/UserAddress.java b/play-services-api/src/main/java/com/google/android/gms/identity/intents/model/UserAddress.java deleted file mode 100644 index aa3959f2..00000000 --- a/play-services-api/src/main/java/com/google/android/gms/identity/intents/model/UserAddress.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.gms.identity.intents.model; - -public class UserAddress { -} diff --git a/play-services-api/src/main/java/com/google/android/gms/people/internal/ParcelableLoadImageOptions.java b/play-services-api/src/main/java/com/google/android/gms/people/internal/ParcelableLoadImageOptions.java index d0a7a742..64322959 100644 --- a/play-services-api/src/main/java/com/google/android/gms/people/internal/ParcelableLoadImageOptions.java +++ b/play-services-api/src/main/java/com/google/android/gms/people/internal/ParcelableLoadImageOptions.java @@ -17,20 +17,8 @@ package com.google.android.gms.people.internal; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; public class ParcelableLoadImageOptions extends AutoSafeParcelable { - @SafeParceled(1000) - private final int versionCode = 1; - @SafeParceled(1) - public int imageSize; - - @SafeParceled(2) - public int avatarOptions; - - @SafeParceled(3) - public boolean useLargePictureForCp2Images; - - public static final Creator CREATOR = new AutoCreator(ParcelableLoadImageOptions.class); + public static final Creator CREATOR = new AutoCreator<>(ParcelableLoadImageOptions.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/people/model/AccountMetadata.java b/play-services-api/src/main/java/com/google/android/gms/people/model/AccountMetadata.java index 53038bbc..dfb64544 100644 --- a/play-services-api/src/main/java/com/google/android/gms/people/model/AccountMetadata.java +++ b/play-services-api/src/main/java/com/google/android/gms/people/model/AccountMetadata.java @@ -17,24 +17,8 @@ package com.google.android.gms.people.model; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; public class AccountMetadata extends AutoSafeParcelable { - @SafeParceled(1) - private final int versionCode = 2; - - @SafeParceled(2) - public boolean hasGooglePlus = true; - - @SafeParceled(3) - public boolean hasFeature2 = true; - - @SafeParceled(4) - public boolean hasFeature3 = true; - - @SafeParceled(5) - public boolean hasFeature4 = true; - - public static Creator CREATOR = new AutoCreator(AccountMetadata.class); + public static Creator CREATOR = new AutoCreator<>(AccountMetadata.class); } diff --git a/play-services-api/src/main/java/com/google/android/gms/people/model/AvatarReference.java b/play-services-api/src/main/java/com/google/android/gms/people/model/AvatarReference.java index b03af386..6e3da8e2 100644 --- a/play-services-api/src/main/java/com/google/android/gms/people/model/AvatarReference.java +++ b/play-services-api/src/main/java/com/google/android/gms/people/model/AvatarReference.java @@ -17,18 +17,11 @@ package com.google.android.gms.people.model; import org.microg.safeparcel.AutoSafeParcelable; -import org.microg.safeparcel.SafeParceled; public class AvatarReference extends AutoSafeParcelable { - @SafeParceled(1000) - private int versionCode; + public static final Creator CREATOR = new AutoCreator<>(AvatarReference.class); - @SafeParceled(1) - public int source; - - @SafeParceled(2) - public String location; - - public static final Creator CREATOR = new AutoCreator(AvatarReference.class); + public AvatarReference() { + } } diff --git a/play-services-base-api/build.gradle b/play-services-base-api/build.gradle index 23b6b07c..59dc1be7 100644 --- a/play-services-base-api/build.gradle +++ b/play-services-base-api/build.gradle @@ -34,11 +34,11 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } + namespace 'org.microg.gms.base.api' buildFeatures { aidl true } - namespace 'org.microg.gms.base.api' } \ No newline at end of file diff --git a/play-services-base-api/src/main/AndroidManifest.xml b/play-services-base-api/src/main/AndroidManifest.xml deleted file mode 100644 index 055d07d5..00000000 --- a/play-services-base-api/src/main/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/play-services-base-api/src/main/java/com/google/android/gms/common/data/DataHolder.java b/play-services-base-api/src/main/java/com/google/android/gms/common/data/DataHolder.java index 4af2bcf1..77acbb1b 100644 --- a/play-services-base-api/src/main/java/com/google/android/gms/common/data/DataHolder.java +++ b/play-services-base-api/src/main/java/com/google/android/gms/common/data/DataHolder.java @@ -17,16 +17,13 @@ package com.google.android.gms.common.data; import android.annotation.SuppressLint; -import android.content.ContentValues; -import android.database.AbstractWindowedCursor; -import android.database.CharArrayBuffer; import android.database.Cursor; import android.database.CursorWindow; -import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.os.Parcel; +import androidx.annotation.NonNull; + import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; @@ -45,9 +42,6 @@ import java.util.Map; */ @PublicApi(until = "1") public class DataHolder extends AutoSafeParcelable implements Closeable { - @SafeParceled(1000) - private final int versionCode = 1; - @SafeParceled(1) private final String[] columns; @@ -69,13 +63,6 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { protected static final int FIELD_TYPE_STRING = 3; protected static final int FIELD_TYPE_BLOB = 4; - private DataHolder() { - columns = null; - windows = null; - statusCode = 0; - metadata = null; - } - /** * Creates a data holder with the specified data. * @@ -92,17 +79,6 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { validateContents(); } - /** - * Creates a data holder wrapping the provided cursor, with provided status code and metadata. - * - * @param cursor The cursor containing the data. - * @param statusCode The status code of this {@link DataHolder}. - * @param metadata The metadata associated with this {@link DataHolder} (may be null). - */ - public DataHolder(AbstractWindowedCursor cursor, int statusCode, Bundle metadata) { - this(cursor.getColumnNames(), createCursorWindows(cursor), statusCode, metadata); - } - /** * Creates a data holder wrapping the provided cursor, with provided status code and metadata. * @@ -118,38 +94,10 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { * Get a {@link DataHolder.Builder} to create a new {@link DataHolder} manually. * * @param columns The array of column names that the object supports. - * @param uniqueColumn The non-null column name that must contain unique values. New rows added to the builder with the same value in this column will replace any older rows. - * @return {@link DataHolder.Builder} object to work with. - */ - public static Builder builder(String[] columns, String uniqueColumn) { - return new Builder(columns, uniqueColumn); - } - - /** - * Get a {@link DataHolder.Builder} to create a new {@link DataHolder} manually. - * - * @param columns The array of column names that the object supports. * @return {@link DataHolder.Builder} object to work with. */ public static Builder builder(String[] columns) { - return builder(columns, null); - } - - /** - * @param statusCode The status code of this {@link DataHolder}. - * @param metadata The metadata associated with this {@link DataHolder} (may be null). - * @return An empty {@link DataHolder} object with the given status and metadata. - */ - public static DataHolder empty(int statusCode, Bundle metadata) { - return new DataHolder(new String[0], new CursorWindow[0], statusCode, metadata); - } - - /** - * @param statusCode The status code of this {@link DataHolder}. - * @return An empty {@link DataHolder} object with the given status and null metadata. - */ - public static DataHolder empty(int statusCode) { - return empty(statusCode, null); + return new Builder(columns); } @SuppressLint({"NewApi", "ObsoleteSdkInt"}) @@ -172,20 +120,6 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { } } - /** - * Copies the String content in the given column at the provided position into a {@link CharArrayBuffer}. - * This will throw an {@link IllegalArgumentException} if the column does not exist, the - * position is invalid, or the data holder has been closed. - * - * @param column The column to retrieve. - * @param row The row to retrieve the data from. - * @param windowIndex Index of the cursor window to extract the data from. - * @param dataOut The {@link CharArrayBuffer} to copy into. - */ - public void copyToBuffer(String column, int row, int windowIndex, CharArrayBuffer dataOut) { - throw new RuntimeException("Not yet available"); - } - @SuppressWarnings("deprecation") private static CursorWindow[] createCursorWindows(Builder builder) { if (builder.columns.length == 0) return new CursorWindow[0]; @@ -278,34 +212,6 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { return windows.toArray(new CursorWindow[0]); } - /** - * Retrieves the boolean value for a given column at the provided position. - * This will throw an {@link IllegalArgumentException} if the column does not exist, the - * position is invalid, or the data holder has been closed. - * - * @param column The column to retrieve. - * @param row The row to retrieve the data from. - * @param windowIndex Index of the cursor window to extract the data from. - * @return The boolean value in that column. - */ - public boolean getBoolean(String column, int row, int windowIndex) { - return windows[windowIndex].getLong(row, columnIndices.get(column)) == 1; - } - - /** - * Retrieves the byte array value for a given column at the provided position. - * This will throw an {@link IllegalArgumentException} if the column does not exist, the - * position is invalid, or the data holder has been closed. - * - * @param column The column to retrieve. - * @param row The row to retrieve the data from. - * @param windowIndex Index of the cursor window to extract the data from. - * @return The byte array value in that column. - */ - public byte[] getByteArray(String column, int row, int windowIndex) { - return windows[windowIndex].getBlob(row, columnIndices.get(column)); - } - /** * Gets the number of rows in the data holder. * @@ -321,38 +227,6 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { return c; } - /** - * Retrieves the integer value for a given column at the provided position. - * This will throw an {@link IllegalArgumentException} if the column does not exist, the - * position is invalid, or the data holder has been closed. - * - * @param column The column to retrieve. - * @param row The row to retrieve the data from. - * @param windowIndex Index of the cursor window to extract the data from. - * @return The integer value in that column. - */ - public int getInteger(String column, int row, int windowIndex) { - return windows[windowIndex].getInt(row, columnIndices.get(column)); - } - - /** - * Retrieves the long value for a given column at the provided position. - * This will throw an {@link IllegalArgumentException} if the column does not exist, the - * position is invalid, or the data holder has been closed. - * - * @param column The column to retrieve. - * @param row The row to retrieve the data from. - * @param windowIndex Index of the cursor window to extract the data from. - * @return The long value in that column. - */ - public long getLong(String column, int row, int windowIndex) { - return windows[windowIndex].getLong(row, columnIndices.get(column)); - } - - public int getStatusCode() { - return statusCode; - } - /** * Retrieves the string value for a given column at the provided position. * This will throw an {@link IllegalArgumentException} if the column does not exist, the @@ -367,42 +241,7 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { return windows[windowIndex].getString(row, columnIndices.get(column)); } - /** - * Returns whether the given column at the provided position contains null. - * This will throw an {@link IllegalArgumentException} if the column does not exist, the - * position is invalid, or the data holder has been closed. - * - * @param column The column to retrieve. - * @param row The row to retrieve the data from. - * @param windowIndex Index of the cursor window to extract the data from. - * @return Whether the column value is null at this position. - */ - public boolean isNull(String column, int row, int windowIndex) { - return windows[windowIndex].isNull(row, columnIndices.get(column)); - } - - public boolean isClosed() { - synchronized (this) { - return closed; - } - } - - /** - * Retrieves the column data at the provided position as a URI if possible, checking for null values. - * This will throw an {@link IllegalArgumentException} if the column does not exist, the - * position is invalid, or the data holder has been closed. - * - * @param column The column to retrieve. - * @param row The row to retrieve the data from. - * @param windowIndex Index of the cursor window to extract the data from. - * @return The column data as a URI, or null if not present. - */ - public Uri parseUri(String column, int row, int windowIndex) { - String string = getString(column, row, windowIndex); - if (string != null) return Uri.parse(string); - return null; - } - + @NonNull @Override public String toString() { return "DataHolder{" + @@ -428,14 +267,10 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { public static class Builder { private final String[] columns; private final ArrayList> rows; - private final String uniqueColumn; - private final Map uniqueIndizes; - private Builder(String[] columns, String uniqueColumn) { + private Builder(String[] columns) { this.columns = columns; this.rows = new ArrayList<>(); - this.uniqueColumn = uniqueColumn; - this.uniqueIndizes = new HashMap<>(); } /** @@ -466,58 +301,6 @@ public class DataHolder extends AutoSafeParcelable implements Closeable { return rows.size(); } - /** - * Sort the rows in this builder based on the standard data type comparisons for the value in the provided column. - * Calling this multiple times with the same column will not change the sort order of the builder. - * Note that any data which is added after this call will not be sorted. - * - * @param sortColumn The column to sort the rows in this builder by. - * @return {@link DataHolder.Builder} to continue construction. - */ - public Builder sort(String sortColumn) { - throw new RuntimeException("Not yet implemented"); - } - - /** - * Add a new row of data to the {@link DataHolder} this {@link DataHolder.Builder} will create. Note that the data must contain an entry for all columns - *

- * Currently the only supported value types that are supported are String, Long, and Boolean (Integer is also accepted and will be stored as a Long). - * - * @param values {@link ContentValues} containing row data. - * @return {@link DataHolder.Builder} to continue construction. - */ - public Builder withRow(ContentValues values) { - HashMap row = new HashMap<>(); - for (Map.Entry entry : values.valueSet()) { - row.put(entry.getKey(), entry.getValue()); - } - return withRow(row); - } - - /** - * Add a new row of data to the {@link DataHolder} this {@link DataHolder.Builder} will create. Note that the data must contain an entry for all columns - *

- * Currently the only supported value types that are supported are String, Long, and Boolean (Integer is also accepted and will be stored as a Long). - * - * @param row Map containing row data. - * @return {@link DataHolder.Builder} to continue construction. - */ - public Builder withRow(HashMap row) { - if (uniqueColumn != null) { - Object val = row.get(uniqueColumn); - if (val != null) { - Integer old = uniqueIndizes.get(val); - if (old != null) { - rows.set(old, row); - return this; - } else { - uniqueIndizes.put(val, rows.size()); - } - } - } - rows.add(row); - return this; - } } public static final Creator CREATOR = new AutoCreator(DataHolder.class) { diff --git a/play-services-base-api/src/main/java/com/google/android/gms/common/data/Freezable.java b/play-services-base-api/src/main/java/com/google/android/gms/common/data/Freezable.java deleted file mode 100644 index 51f4847e..00000000 --- a/play-services-base-api/src/main/java/com/google/android/gms/common/data/Freezable.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.gms.common.data; - -public interface Freezable { - /** - * Freeze a volatile representation into an immutable representation. Objects returned from - * this call are safe to cache. - *

- * Note that the output of {@link #freeze} may not be identical to the parent object, but - * should be equal. - * - * @return A concrete implementation of the data object. - */ - T freeze(); - - /** - * Check to see if this object is valid for use. If the object is still volatile, this method - * will indicate whether or not the object can be safely used. - * The output of a call to {@link #freeze()} will always be valid. - * - * @return whether or not the object is valid for use. - */ - boolean isDataValid(); -} diff --git a/play-services-base-api/src/main/java/com/google/android/gms/common/images/WebImage.java b/play-services-base-api/src/main/java/com/google/android/gms/common/images/WebImage.java index fee75495..4b5e4ad7 100644 --- a/play-services-base-api/src/main/java/com/google/android/gms/common/images/WebImage.java +++ b/play-services-base-api/src/main/java/com/google/android/gms/common/images/WebImage.java @@ -18,6 +18,8 @@ package com.google.android.gms.common.images; import android.net.Uri; +import androidx.annotation.NonNull; + import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; @@ -58,7 +60,9 @@ public class WebImage extends AutoSafeParcelable { return height; } + @NonNull public String toString() { - return String.format(Locale.getDefault(), "Image %dx%d %s", width, height, uri.toString()); + assert uri != null; + return String.format(Locale.getDefault(), "Image %dx%d %s", width, height, uri); } } diff --git a/play-services-base-core/build.gradle b/play-services-base-core/build.gradle index 34288f21..5a5dfa30 100644 --- a/play-services-base-core/build.gradle +++ b/play-services-base-core/build.gradle @@ -23,8 +23,6 @@ android { defaultConfig { minSdkVersion androidMinSdk targetSdkVersion androidTargetSdk - - buildConfigField "String", "BASE_PACKAGE_NAME", "\"$basePackageName\"" } sourceSets { diff --git a/play-services-base-core/src/main/AndroidManifest.xml b/play-services-base-core/src/main/AndroidManifest.xml index 369707e7..6585028c 100644 --- a/play-services-base-core/src/main/AndroidManifest.xml +++ b/play-services-base-core/src/main/AndroidManifest.xml @@ -3,26 +3,11 @@ ~ SPDX-FileCopyrightText: 2020, microG Project Team ~ SPDX-License-Identifier: Apache-2.0 --> - - - - - + - - + android:exported="false" /> diff --git a/play-services-base-core/src/main/java/org/microg/gms/AbstractGmsServiceBroker.java b/play-services-base-core/src/main/java/org/microg/gms/AbstractGmsServiceBroker.java index a0ff2b99..9ff67ff8 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/AbstractGmsServiceBroker.java +++ b/play-services-base-core/src/main/java/org/microg/gms/AbstractGmsServiceBroker.java @@ -16,19 +16,16 @@ package org.microg.gms; -import android.accounts.Account; import android.os.Bundle; import android.os.Parcel; import android.os.RemoteException; import android.util.Log; -import com.google.android.gms.common.api.Scope; import com.google.android.gms.common.internal.GetServiceRequest; import com.google.android.gms.common.internal.IGmsCallbacks; import com.google.android.gms.common.internal.IGmsServiceBroker; import com.google.android.gms.common.internal.ValidateAccountRequest; -import org.microg.gms.base.core.BuildConfig; import org.microg.gms.common.GmsService; import java.util.EnumSet; @@ -59,37 +56,24 @@ public abstract class AbstractGmsServiceBroker extends IGmsServiceBroker.Stub { @Override public void getAddressService(IGmsCallbacks callback, int versionCode, String packageName) throws RemoteException { - callGetService(GmsService.ADDRESS, callback, versionCode, packageName); + callGetService(callback, versionCode, packageName); } - private void callGetService(GmsService service, IGmsCallbacks callback, int gmsVersion, + private void callGetService(IGmsCallbacks callback, int gmsVersion, String packageName) throws RemoteException { - callGetService(service, callback, gmsVersion, packageName, null); + callGetService(GmsService.ADDRESS, callback, gmsVersion, packageName, null); } - private void callGetService(GmsService service, IGmsCallbacks callback, int gmsVersion, - String packageName, Bundle extras) throws RemoteException { - callGetService(service, callback, gmsVersion, packageName, extras, null, null); - } - - private void callGetService(GmsService service, IGmsCallbacks callback, int gmsVersion, String packageName, Bundle extras, String accountName, String[] scopes) throws RemoteException { + private void callGetService(GmsService service, IGmsCallbacks callback, int gmsVersion, String packageName, Bundle extras) throws RemoteException { GetServiceRequest request = new GetServiceRequest(service.SERVICE_ID); request.gmsVersion = gmsVersion; request.packageName = packageName; request.extras = extras; - request.account = accountName == null ? null : new Account(accountName, BuildConfig.BASE_PACKAGE_NAME); - request.scopes = scopes == null ? null : scopesFromStringArray(scopes); + request.account = null; + request.scopes = null; getService(callback, request); } - private Scope[] scopesFromStringArray(String[] arr) { - Scope[] scopes = new Scope[arr.length]; - for (int i = 0; i < arr.length; i++) { - scopes[i] = new Scope(arr[i]); - } - return scopes; - } - @Override public void getService(IGmsCallbacks callback, GetServiceRequest request) throws RemoteException { GmsService gmsService = GmsService.byServiceId(request.serviceId); @@ -104,7 +88,7 @@ public abstract class AbstractGmsServiceBroker extends IGmsServiceBroker.Stub { public abstract void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException; @Override - public void validateAccount(IGmsCallbacks callback, ValidateAccountRequest request) throws RemoteException { + public void validateAccount(IGmsCallbacks callback, ValidateAccountRequest request) { throw new IllegalArgumentException("ValidateAccountRequest not supported"); } diff --git a/play-services-base-core/src/main/java/org/microg/gms/BaseService.java b/play-services-base-core/src/main/java/org/microg/gms/BaseService.java index 3941e508..38545ff0 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/BaseService.java +++ b/play-services-base-core/src/main/java/org/microg/gms/BaseService.java @@ -21,6 +21,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; +import androidx.annotation.NonNull; import androidx.lifecycle.LifecycleService; import com.google.android.gms.common.internal.GetServiceRequest; @@ -58,7 +59,7 @@ public abstract class BaseService extends LifecycleService { } @Override - public IBinder onBind(Intent intent) { + public IBinder onBind(@NonNull Intent intent) { super.onBind(intent); Log.d(TAG, "onBind: " + intent); return broker.asBinder(); diff --git a/play-services-base-core/src/main/java/org/microg/gms/common/DeviceConfiguration.java b/play-services-base-core/src/main/java/org/microg/gms/common/DeviceConfiguration.java index 55bffb3c..d4ab5940 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/common/DeviceConfiguration.java +++ b/play-services-base-core/src/main/java/org/microg/gms/common/DeviceConfiguration.java @@ -16,8 +16,6 @@ package org.microg.gms.common; -import android.annotation.SuppressLint; - import android.app.ActivityManager; import android.content.Context; import android.content.pm.ConfigurationInfo; @@ -28,8 +26,6 @@ import android.opengl.GLES10; import android.os.Build; import android.util.DisplayMetrics; -import org.microg.gms.profile.ProfileManager; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -60,7 +56,6 @@ public class DeviceConfiguration { public int widthPixels; public DeviceConfiguration(Context context) { - ProfileManager.ensureInitialized(context); ConfigurationInfo configurationInfo = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getDeviceConfigurationInfo(); touchScreen = configurationInfo.reqTouchScreen; keyboardType = configurationInfo.reqKeyboardType; @@ -83,35 +78,29 @@ public class DeviceConfiguration { } Collections.sort(sharedLibraries); availableFeatures = new ArrayList<>(); - packageManager.getSystemAvailableFeatures(); - for (FeatureInfo featureInfo : packageManager.getSystemAvailableFeatures()) { - if (featureInfo != null && featureInfo.name != null) - availableFeatures.add(featureInfo.name); + if (packageManager.getSystemAvailableFeatures() != null) { + for (FeatureInfo featureInfo : packageManager.getSystemAvailableFeatures()) { + if (featureInfo != null && featureInfo.name != null) availableFeatures.add(featureInfo.name); + } } Collections.sort(availableFeatures); this.nativePlatforms = getNativePlatforms(); widthPixels = displayMetrics.widthPixels; heightPixels = displayMetrics.heightPixels; - locales = getLocales(context); + locales = new ArrayList<>(Arrays.asList(context.getAssets().getLocales())); + for (int i = 0; i < locales.size(); i++) { + locales.set(i, locales.get(i).replace("-", "_")); + } + Collections.sort(locales); Set glExtensions = new HashSet<>(); addEglExtensions(glExtensions); this.glExtensions = new ArrayList<>(glExtensions); Collections.sort(this.glExtensions); } - @SuppressLint("GetLocales") - private static List getLocales(Context context) { - List locales = new ArrayList(); - locales.addAll(Arrays.asList(context.getAssets().getLocales())); - for (int i = 0; i < locales.size(); i++) { - locales.set(i, locales.get(i).replace("-", "_")); - } - Collections.sort(locales); - return locales; - } - - @SuppressWarnings({"InlinedApi"}) + @SuppressWarnings({"deprecation", "InlinedApi"}) private static List getNativePlatforms() { + List nativePlatforms; return Arrays.asList(Build.SUPPORTED_ABIS); } diff --git a/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java b/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java index 417ad6f7..c7a2ff52 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java +++ b/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java @@ -1,7 +1,5 @@ package org.microg.gms.common; -import static android.os.Build.VERSION.SDK_INT; - import android.annotation.SuppressLint; import android.app.Notification; import android.app.NotificationChannel; @@ -13,6 +11,7 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.net.Uri; +import android.os.Build; import android.os.PowerManager; import android.provider.Settings; import android.util.Log; @@ -34,7 +33,7 @@ public class ForegroundServiceContext extends ContextWrapper { if (!isIgnoringBatteryOptimizations()) { Log.d(TAG, "Starting in foreground mode."); service.putExtra(EXTRA_FOREGROUND, true); - if (SDK_INT >= 26) { + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { return super.startForegroundService(service); } else { return super.startService(service); @@ -76,7 +75,7 @@ public class ForegroundServiceContext extends ContextWrapper { String serviceName = getServiceName(service); Log.d(tag, "Started " + serviceName + " in foreground mode."); try { - Notification notification = buildForegroundNotification(service); + Notification notification = buildForegroundNotification(service, serviceName); service.startForeground(serviceName.hashCode(), notification); Log.d(tag, "Notification: " + notification); } catch (Exception e) { @@ -86,9 +85,9 @@ public class ForegroundServiceContext extends ContextWrapper { } @SuppressLint("BatteryLife") - private static Notification buildForegroundNotification(Context context) { + private static Notification buildForegroundNotification(Context context, String serviceName) { Intent notificationIntent = new Intent(); - if (SDK_INT >= 31) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { notificationIntent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); notificationIntent.setData(Uri.parse("package:" + context.getPackageName())); } else { @@ -98,8 +97,8 @@ public class ForegroundServiceContext extends ContextWrapper { PendingIntent notificationPendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, - PendingIntent.FLAG_IMMUTABLE); - if (SDK_INT >= 26) { + 0); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel Channel = new NotificationChannel("foreground-service", context.getResources().getString(R.string.notification_service_name), NotificationManager.IMPORTANCE_LOW); diff --git a/play-services-base-core/src/main/java/org/microg/gms/common/PackageUtils.java b/play-services-base-core/src/main/java/org/microg/gms/common/PackageUtils.java index 03fd8b93..50d112d0 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/common/PackageUtils.java +++ b/play-services-base-core/src/main/java/org/microg/gms/common/PackageUtils.java @@ -16,10 +16,6 @@ package org.microg.gms.common; -import static org.microg.gms.common.Constants.GMS_PACKAGE_NAME; -import static org.microg.gms.common.Constants.GMS_PACKAGE_SIGNATURE_SHA1; - -import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.Application; import android.app.PendingIntent; @@ -32,8 +28,6 @@ import android.util.Log; import androidx.annotation.Nullable; -import org.microg.gms.base.core.BuildConfig; - import java.lang.reflect.Method; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -41,25 +35,28 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; + +import static android.os.Build.VERSION.SDK_INT; +import static org.microg.gms.common.Constants.GMS_PACKAGE_NAME; +import static org.microg.gms.common.Constants.GMS_PACKAGE_SIGNATURE_SHA1; +import static org.microg.gms.common.Constants.GMS_SECONDARY_PACKAGE_SIGNATURE_SHA1; public class PackageUtils { private static final String GOOGLE_PLATFORM_KEY = GMS_PACKAGE_SIGNATURE_SHA1; - private static final String GOOGLE_LEGACY_KEY = "58e1c4133f7441ec3d2c270270a14802da47ba0e"; // Seems to be no longer used. - private static final String[] GOOGLE_PRIMARY_KEYS = {GOOGLE_PLATFORM_KEY, "24bb24c05e47e0aefa68a58a766179d9b613a600", "afb0fed5eeaebdd86f56a97742f4b6b33ef59875", "61226bdb57cc32c8a2a9ef71f7bc9548e95dcc0b", "3a82b5ee26bc46bf68113d920e610cd090198d4a"}; + private static final String GOOGLE_PLATFORM_KEY_2 = GMS_SECONDARY_PACKAGE_SIGNATURE_SHA1; + private static final String GOOGLE_APP_KEY = "24bb24c05e47e0aefa68a58a766179d9b613a600"; + private static final String[] GOOGLE_PRIMARY_KEYS = {GOOGLE_PLATFORM_KEY, GOOGLE_PLATFORM_KEY_2, GOOGLE_APP_KEY}; - public static final Map KNOWN_GOOGLE_PACKAGES; + private static final Map KNOWN_GOOGLE_PACKAGES; static { KNOWN_GOOGLE_PACKAGES = new HashMap<>(); - KNOWN_GOOGLE_PACKAGES.put("com.google.android.apps.youtube", "24bb24c05e47e0aefa68a58a766179d9b613a600"); KNOWN_GOOGLE_PACKAGES.put("com.google.android.apps.youtube.music", "afb0fed5eeaebdd86f56a97742f4b6b33ef59875"); } public static boolean isGooglePackage(Context context, String packageName) { String signatureDigest = firstSignatureDigest(context, packageName); - packageName = PackageSpoofUtils.spoofPackageName(context.getPackageManager(), packageName); return isGooglePackage(packageName, signatureDigest); } @@ -76,7 +73,7 @@ public class PackageUtils { if (signatureDigest == null) return false; if (Arrays.asList(GOOGLE_PRIMARY_KEYS).contains(signatureDigest)) return true; if (!KNOWN_GOOGLE_PACKAGES.containsKey(packageName)) return false; - return Objects.equals(KNOWN_GOOGLE_PACKAGES.get(packageName), signatureDigest); + return KNOWN_GOOGLE_PACKAGES.get(packageName).equals(signatureDigest); } public static void assertExtendedAccess(Context context) { @@ -86,14 +83,14 @@ public class PackageUtils { public static boolean callerHasExtendedAccess(Context context) { String[] packagesForUid = context.getPackageManager().getPackagesForUid(Binder.getCallingUid()); - if (packagesForUid != null) { + if (packagesForUid != null && packagesForUid.length != 0) { for (String packageName : packagesForUid) { packageName = PackageSpoofUtils.spoofPackageName(context.getPackageManager(), packageName); if (isGooglePackage(context, packageName) || GMS_PACKAGE_NAME.equals(packageName)) return true; } } - return context.checkCallingPermission(BuildConfig.BASE_PACKAGE_NAME + ".gms.EXTENDED_ACCESS") == PackageManager.PERMISSION_GRANTED; + return context.checkCallingPermission("org.mgoogle.gms.EXTENDED_ACCESS") == PackageManager.PERMISSION_GRANTED; } public static void checkPackageUid(Context context, String packageName, int callingUid) { @@ -123,9 +120,9 @@ public class PackageUtils { try { info = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); } catch (PackageManager.NameNotFoundException e) { - return KNOWN_GOOGLE_PACKAGES.get(packageName); + return null; } - if (info != null && info.signatures != null) { + if (info != null && info.signatures != null && info.signatures.length > 0) { for (Signature sig : info.signatures) { String digest = sha1sum(sig.toByteArray()); if (digest != null) { @@ -150,7 +147,7 @@ public class PackageUtils { } catch (PackageManager.NameNotFoundException e) { return null; } - if (info != null && info.signatures != null) { + if (info != null && info.signatures != null && info.signatures.length > 0) { for (Signature sig : info.signatures) { byte[] digest = sha1bytes(sig.toByteArray()); if (digest != null) { @@ -181,7 +178,10 @@ public class PackageUtils { } catch (final NoSuchAlgorithmException e) { return null; } - return md.digest(bytes); + if (md != null) { + return md.digest(bytes); + } + return null; } @Nullable @@ -220,7 +220,7 @@ public class PackageUtils { if (suggestedCallerPid > 0 && suggestedCallerPid != callingPid) { throw new SecurityException("suggested PID [" + suggestedCallerPid + "] and real calling PID [" + callingPid + "] mismatch!"); } - return getAndCheckPackage(context, suggestedPackageName, callingUid, callingPid); + return getAndCheckPackage(context, suggestedPackageName, callingUid, Binder.getCallingPid()); } @Nullable @@ -252,6 +252,7 @@ public class PackageUtils { } @Nullable + @Deprecated public static String packageFromProcessId(Context context, int pid) { ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); if (manager == null) return null; @@ -276,6 +277,7 @@ public class PackageUtils { return null; } + @SuppressWarnings("deprecation") public static String packageFromPendingIntent(PendingIntent pi) { if (pi == null) return null; return pi.getCreatorPackage(); @@ -285,10 +287,8 @@ public class PackageUtils { if (android.os.Build.VERSION.SDK_INT >= 28) return Application.getProcessName(); try { - @SuppressLint("PrivateApi") Class activityThread = Class.forName("android.app.ActivityThread"); String methodName = "currentProcessName"; - @SuppressLint("DiscouragedPrivateApi") Method getProcessName = activityThread.getDeclaredMethod(methodName); return (String) getProcessName.invoke(null); } catch (Exception e) { @@ -333,12 +333,17 @@ public class PackageUtils { } catch (final NoSuchAlgorithmException e) { return null; } - bytes = md.digest(bytes); - StringBuilder sb = new StringBuilder(2 * bytes.length); - for (byte b : bytes) { - sb.append(String.format("%02x", b)); + if (md != null) { + bytes = md.digest(bytes); + if (bytes != null) { + StringBuilder sb = new StringBuilder(2 * bytes.length); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } } - return sb.toString(); + return null; } public static int versionCode(Context context, String packageName) { diff --git a/play-services-base-core/src/main/kotlin/org/microg/gms/common/PackageSpoofUtils.kt b/play-services-base-core/src/main/kotlin/org/microg/gms/common/PackageSpoofUtils.kt index 7aec1077..94ec088d 100644 --- a/play-services-base-core/src/main/kotlin/org/microg/gms/common/PackageSpoofUtils.kt +++ b/play-services-base-core/src/main/kotlin/org/microg/gms/common/PackageSpoofUtils.kt @@ -4,17 +4,15 @@ import android.content.pm.PackageManager import android.os.Bundle import android.util.Log -import org.microg.gms.base.core.BuildConfig - /** * utilities to spoof package information */ internal object PackageSpoofUtils { private const val TAG = "SpoofUtils" private const val META_SPOOF_PACKAGE_NAME = - "${BuildConfig.BASE_PACKAGE_NAME}.android.gms.SPOOFED_PACKAGE_NAME" + "com.mgoogle.android.gms.SPOOFED_PACKAGE_NAME" private const val META_SPOOF_PACKAGE_SIGNATURE = - "${BuildConfig.BASE_PACKAGE_NAME}.android.gms.SPOOFED_PACKAGE_SIGNATURE" + "com.mgoogle.android.gms.SPOOFED_PACKAGE_SIGNATURE" private val spoofedPackageNameCache = HashMap() private val spoofedPackageSignatureCache = HashMap() @@ -141,7 +139,6 @@ internal object PackageSpoofUtils { * @param packageName name of the package to get metadata of * @return package metadata bundle */ - @Suppress("DEPRECATION") private fun getPackageMetadata(packageManager: PackageManager, packageName: String): Bundle? { return try { // PackageManager.getPackageInfo() has been deprecated in targetSdkVersion 30+ diff --git a/play-services-base-core/src/main/kotlin/org/microg/gms/profile/Build.kt b/play-services-base-core/src/main/kotlin/org/microg/gms/profile/Build.kt index 725e0d6a..c0398c2b 100644 --- a/play-services-base-core/src/main/kotlin/org/microg/gms/profile/Build.kt +++ b/play-services-base-core/src/main/kotlin/org/microg/gms/profile/Build.kt @@ -5,8 +5,6 @@ package org.microg.gms.profile -import android.annotation.TargetApi - object Build { @JvmField var BOARD: String? = null @@ -89,9 +87,6 @@ object Build { @JvmField var SECURITY_PATCH: String? = null - - @JvmField - var DEVICE_INITIAL_SDK_INT: Int = 0 } fun generateWebViewUserAgentString(original: String): String { diff --git a/play-services-base-core/src/main/kotlin/org/microg/gms/profile/ProfileManager.kt b/play-services-base-core/src/main/kotlin/org/microg/gms/profile/ProfileManager.kt index 76286eab..0cbc69b8 100644 --- a/play-services-base-core/src/main/kotlin/org/microg/gms/profile/ProfileManager.kt +++ b/play-services-base-core/src/main/kotlin/org/microg/gms/profile/ProfileManager.kt @@ -10,8 +10,8 @@ import android.content.Context import android.content.res.XmlResourceParser import android.util.Log import org.microg.gms.utils.FileXmlResourceParser -import org.microg.gms.settings.SettingsContract -import org.microg.gms.settings.SettingsContract.Profile +import org.microg.mgms.settings.SettingsContract +import org.microg.mgms.settings.SettingsContract.Profile import org.xmlpull.v1.XmlPullParser import java.io.File import java.util.* @@ -32,7 +32,11 @@ object ProfileManager { private fun getSystemProfileFile(): File = File("/system/etc/microg_device_profile.xml") private fun getProfileResId(context: Context, profile: String) = context.resources.getIdentifier("${context.packageName}:xml/profile_$profile".lowercase(Locale.US), null, null) - fun getConfiguredProfile(context: Context): String = SettingsContract.getSettings(context, Profile.getContentUri(context), arrayOf(Profile.PROFILE)) { it.getString(0) } ?: PROFILE_AUTO + fun getConfiguredProfile(context: Context): String = Profile.getContentUri(context)?.let { + SettingsContract.getSettings(context, + it, arrayOf(Profile.PROFILE)) { it.getString(0) } + } + ?: PROFILE_AUTO fun getAutoProfile(context: Context): String { if (hasProfile(context, PROFILE_SYSTEM) && isAutoProfile(context, PROFILE_SYSTEM)) return PROFILE_SYSTEM @@ -68,60 +72,43 @@ object ProfileManager { PROFILE_AUTO -> false PROFILE_REAL -> false PROFILE_NATIVE -> true - else -> { - val parser = getProfileXml(context, profile) - if (parser != null) { - try { - var next = parser.next() - while (next != XmlPullParser.END_DOCUMENT) { - when (next) { - XmlPullParser.START_TAG -> when (parser.name) { - "profile" -> { - return@runCatching parser.getAttributeBooleanValue(null, "auto", false) - } - } + else -> getProfileXml(context, profile)?.use { + var next = it.next() + while (next != XmlPullParser.END_DOCUMENT) { + when (next) { + XmlPullParser.START_TAG -> when (it.name) { + "profile" -> { + return@use it.getAttributeBooleanValue(null, "auto", false) } - next = parser.next() } - } finally { - parser.close() } - false - } else { - false + next = it.next() } - } + } == true } }.getOrDefault(false) - fun getActiveProfileData(context: Context): Map = - getProfileData(context, getProfile(context), getRealData()) - private fun getProfileData(context: Context, profile: String, realData: Map): Map { try { if (profile in listOf(PROFILE_REAL, PROFILE_NATIVE)) return realData - if (profile != PROFILE_USER && getProfileResId(context, profile) == 0) return realData + val profileResId = getProfileResId(context, profile) + if (profileResId == 0) return realData val resultData = mutableMapOf() resultData.putAll(realData) - val parser = getProfileXml(context, profile) - if (parser != null) { - try { - var next = parser.next() - while (next != XmlPullParser.END_DOCUMENT) { - when (next) { - XmlPullParser.START_TAG -> when (parser.name) { - "data" -> { - val key = parser.getAttributeValue(null, "key") - val value = parser.getAttributeValue(null, "value") - resultData[key] = value - Log.d(TAG, "Overwrite from profile: $key = $value") - } + getProfileXml(context, profile)?.use { + var next = it.next() + while (next != XmlPullParser.END_DOCUMENT) { + when (next) { + XmlPullParser.START_TAG -> when (it.name) { + "data" -> { + val key = it.getAttributeValue(null, "key") + val value = it.getAttributeValue(null, "value") + resultData[key] = value + Log.d(TAG, "Overwrite from profile: $key = $value") } } - next = parser.next() } - } finally { - parser.close() + next = it.next() } } return resultData @@ -132,8 +119,14 @@ object ProfileManager { } private fun getProfile(context: Context) = getConfiguredProfile(context).let { if (it != PROFILE_AUTO) it else getAutoProfile(context) } - private fun getSerialFromSettings(context: Context): String? = SettingsContract.getSettings(context, Profile.getContentUri(context), arrayOf(Profile.SERIAL)) { it.getString(0) } - private fun saveSerial(context: Context, serial: String) = SettingsContract.setSettings(context, Profile.getContentUri(context)) { put(Profile.SERIAL, serial) } + private fun getSerialFromSettings(context: Context): String? = + Profile.getContentUri(context)?.let { + SettingsContract.getSettings(context, + it, arrayOf(Profile.SERIAL)) { it.getString(0) } + } + private fun saveSerial(context: Context, serial: String) = + Profile.getContentUri(context) + ?.let { SettingsContract.setSettings(context, it) { put(Profile.SERIAL, serial) } } private fun randomSerial(template: String, prefixLength: Int = (template.length / 2).coerceAtMost(6)): String { val serial = StringBuilder() @@ -169,20 +162,15 @@ object ProfileManager { // From profile try { - val parser = getProfileXml(context, profile) - if (parser != null) { - try { - var next = parser.next() - while (next != XmlPullParser.END_DOCUMENT) { - when (next) { - XmlPullParser.START_TAG -> when (parser.name) { - "serial" -> return parser.getAttributeValue(null, "template") - } + getProfileXml(context, profile)?.use { + var next = it.next() + while (next != XmlPullParser.END_DOCUMENT) { + when (next) { + XmlPullParser.START_TAG -> when (it.name) { + "serial" -> return it.getAttributeValue(null, "template") } - next = parser.next() } - } finally { - parser.close() + next = it.next() } } } catch (e: Exception) { @@ -205,7 +193,6 @@ object ProfileManager { return serial } - @SuppressLint("BlockedPrivateApi") private fun getRealData(): Map = mutableMapOf( "Build.BOARD" to android.os.Build.BOARD, "Build.BOOTLOADER" to android.os.Build.BOOTLOADER, @@ -239,15 +226,9 @@ object ProfileManager { if (android.os.Build.VERSION.SDK_INT >= 23) { put("Build.VERSION.SECURITY_PATCH", android.os.Build.VERSION.SECURITY_PATCH) } - try { - val field = android.os.Build.VERSION::class.java.getDeclaredField("DEVICE_INITIAL_SDK_INT") - field.isAccessible = true - put("Build.VERSION.DEVICE_INITIAL_SDK_INT", field.getInt(null).toString()) - } catch (ignored: Exception) { - } } - fun applyProfileData(profileData: Map) { + private fun applyProfileData(profileData: Map) { fun applyStringField(key: String, valueSetter: (String) -> Unit) = profileData[key]?.let { valueSetter(it) } fun applyIntField(key: String, valueSetter: (Int) -> Unit) = profileData[key]?.toIntOrNull()?.let { valueSetter(it) } fun applyLongField(key: String, valueSetter: (Long) -> Unit) = profileData[key]?.toLongOrNull()?.let { valueSetter(it) } @@ -277,7 +258,6 @@ object ProfileManager { applyStringField("Build.VERSION.RELEASE") { Build.VERSION.RELEASE = it } applyStringField("Build.VERSION.SDK") { Build.VERSION.SDK = it } applyIntField("Build.VERSION.SDK_INT") { Build.VERSION.SDK_INT = it } - applyIntField("Build.VERSION.DEVICE_INITIAL_SDK_INT") { Build.VERSION.DEVICE_INITIAL_SDK_INT = it } if (android.os.Build.VERSION.SDK_INT >= 21) { Build.SUPPORTED_ABIS = profileData["Build.SUPPORTED_ABIS"]?.split(",")?.toTypedArray() ?: emptyArray() } else { @@ -305,35 +285,30 @@ object ProfileManager { fun getProfileName(context: Context, profile: String): String? = getProfileName { getProfileXml(context, profile) } - private fun getProfileName(parserCreator: () -> XmlResourceParser?): String? { - val parser = parserCreator() - if (parser != null) { - try { - var next = parser.next() - while (next != XmlPullParser.END_DOCUMENT) { - when (next) { - XmlPullParser.START_TAG -> when (parser.name) { - "profile" -> { - return parser.getAttributeValue(null, "name") - } - } + private fun getProfileName(parserCreator: () -> XmlResourceParser?): String? = parserCreator()?.use { + var next = it.next() + while (next != XmlPullParser.END_DOCUMENT) { + when (next) { + XmlPullParser.START_TAG -> when (it.name) { + "profile" -> { + return@use it.getAttributeValue(null, "name") } - next = parser.next() } - } finally { - parser.close() } + next = it.next() } - return null + null } fun setProfile(context: Context, profile: String?) { val changed = getProfile(context) != profile val newProfile = profile ?: PROFILE_AUTO val newSerial = if (changed) getSerial(context, newProfile, true) else getSerial(context) - SettingsContract.setSettings(context, Profile.getContentUri(context)) { - put(Profile.PROFILE, newProfile) - if (changed) put(Profile.SERIAL, newSerial) + Profile.getContentUri(context)?.let { + SettingsContract.setSettings(context, it) { + put(Profile.PROFILE, newProfile) + if (changed) put(Profile.SERIAL, newSerial) + } } if (changed && activeProfile != null) applyProfile(context, newProfile, newSerial) } @@ -342,7 +317,7 @@ object ProfileManager { val profileName = getProfileName { FileXmlResourceParser(file) } ?: return false try { Log.d(TAG, "Importing user profile '$profileName'") - file.copyTo(getUserProfileFile(context), overwrite = true) + file.copyTo(getUserProfileFile(context)) if (activeProfile == PROFILE_USER) applyProfile(context, PROFILE_USER) return true } catch (e: Exception) { diff --git a/play-services-base-core/src/main/kotlin/org/microg/gms/profile/ProfileProvider.kt b/play-services-base-core/src/main/kotlin/org/microg/gms/profile/ProfileProvider.kt deleted file mode 100644 index 53e4149f..00000000 --- a/play-services-base-core/src/main/kotlin/org/microg/gms/profile/ProfileProvider.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 e Foundation - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.profile - -import android.content.ContentProvider -import android.content.ContentValues -import android.database.Cursor -import android.database.MatrixCursor -import android.net.Uri -import org.microg.gms.settings.SettingsContract - -class ProfileProvider : ContentProvider() { - - val COLUMN_ID = "profile_id" - val COLUMN_VALUE = "profile_value" - - override fun onCreate(): Boolean { - ProfileManager.ensureInitialized(context!!) - return true - } - - override fun query( - uri: Uri, - projection: Array?, - selection: String?, - selectionArgs: Array?, - sortOrder: String? - ): Cursor = - MatrixCursor(arrayOf(COLUMN_ID, COLUMN_VALUE)).apply { - ProfileManager.getActiveProfileData(context!!).entries - .forEach { - addRow(arrayOf(it.key, it.value)) - } - } - - override fun getType(uri: Uri): String { - return "vnd.android.cursor.item/vnd.${SettingsContract.getAuthority(context!!)}.${uri.path}" - } - - override fun insert(uri: Uri, values: ContentValues?): Nothing = throw UnsupportedOperationException() - - override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Nothing = - throw UnsupportedOperationException() - - override fun update( - uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array? - ): Nothing = throw UnsupportedOperationException() - -} diff --git a/play-services-base-core/src/main/kotlin/org/microg/gms/settings/MetaDataPreferences.kt b/play-services-base-core/src/main/kotlin/org/microg/gms/settings/MetaDataPreferences.kt deleted file mode 100644 index 1e21f6d9..00000000 --- a/play-services-base-core/src/main/kotlin/org/microg/gms/settings/MetaDataPreferences.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.settings - -import android.content.Context -import android.content.SharedPreferences -import android.content.pm.PackageManager.GET_META_DATA -import android.os.Bundle - -class MetaDataPreferences(private val context: Context, private val prefix: String = "") : SharedPreferences { - private val metaData by lazy { - runCatching { context.packageManager.getApplicationInfo(context.packageName, GET_META_DATA) }.getOrNull()?.metaData ?: Bundle.EMPTY - } - - override fun getAll(): Map = metaData.keySet().filter { it.startsWith(prefix) }.associate { it.substring(prefix.length) to metaData.get(it) } - - override fun getString(key: String, defValue: String?): String? = metaData.getString(prefix + key, defValue) - - override fun getStringSet(key: String, defValues: Set?): Set? = metaData.getStringArray(prefix + key)?.toSet() ?: defValues - - override fun getInt(key: String?, defValue: Int): Int = metaData.getInt(prefix + key, defValue) - - override fun getLong(key: String?, defValue: Long): Long = metaData.getLong(prefix + key, defValue) - - override fun getFloat(key: String?, defValue: Float): Float = metaData.getFloat(prefix + key, defValue) - - override fun getBoolean(key: String?, defValue: Boolean): Boolean = metaData.getBoolean(prefix + key, defValue) - - override fun contains(key: String?): Boolean = metaData.containsKey(prefix + key) - - override fun edit(): SharedPreferences.Editor { - throw UnsupportedOperationException() - } - - override fun registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) { - throw UnsupportedOperationException() - } - - override fun unregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) { - throw UnsupportedOperationException() - } -} \ No newline at end of file diff --git a/play-services-base-core/src/main/kotlin/org/microg/gms/utils/BinderUtils.kt b/play-services-base-core/src/main/kotlin/org/microg/gms/utils/BinderUtils.kt index 226bb431..79e8ff8f 100644 --- a/play-services-base-core/src/main/kotlin/org/microg/gms/utils/BinderUtils.kt +++ b/play-services-base-core/src/main/kotlin/org/microg/gms/utils/BinderUtils.kt @@ -12,13 +12,13 @@ import android.util.Log private const val TAG = "BinderUtils" -fun IBinder.warnOnTransactionIssues(code: Int, reply: Parcel?, flags: Int, tag: String = TAG, base: () -> Boolean): Boolean { +fun IBinder.warnOnTransactionIssues(code: Int, reply: Parcel?, flags: Int, base: () -> Boolean): Boolean { if (base.invoke()) { if ((flags and Binder.FLAG_ONEWAY) > 0 && (reply?.dataSize() ?: 0) > 0) { - Log.w(tag, "Method $code in $interfaceDescriptor is oneway, but returned data") + Log.w(TAG, "Method $code in $interfaceDescriptor is oneway, but returned data") } return true } - Log.w(tag, "Unknown method $code in $interfaceDescriptor, skipping") + Log.w(TAG, "Unknown method $code in $interfaceDescriptor, skipping") return (flags and Binder.FLAG_ONEWAY) > 0 // Don't return false on oneway transaction to suppress warning } diff --git a/play-services-base-core/src/main/kotlin/org/microg/gms/settings/SettingsContract.kt b/play-services-base-core/src/main/kotlin/org/microg/mgms/settings/SettingsContract.kt similarity index 80% rename from play-services-base-core/src/main/kotlin/org/microg/gms/settings/SettingsContract.kt rename to play-services-base-core/src/main/kotlin/org/microg/mgms/settings/SettingsContract.kt index 8851d1a1..4f930962 100644 --- a/play-services-base-core/src/main/kotlin/org/microg/gms/settings/SettingsContract.kt +++ b/play-services-base-core/src/main/kotlin/org/microg/mgms/settings/SettingsContract.kt @@ -1,4 +1,4 @@ -package org.microg.gms.settings +package org.microg.mgms.settings import android.content.ContentValues import android.content.Context @@ -12,8 +12,7 @@ object SettingsContract { object CheckIn { private const val id = "check-in" - fun getContentUri(context: Context) = Uri.withAppendedPath(getAuthorityUri(context), id) - fun getContentType(context: Context) = "vnd.android.cursor.item/vnd.${getAuthority(context)}.$id" + fun getContentUri(context: Context): Uri? = Uri.withAppendedPath(getAuthorityUri(context), id) const val ENABLED = "checkin_enable_service" const val ANDROID_ID = "androidId" @@ -22,6 +21,7 @@ object SettingsContract { const val SECURITY_TOKEN = "securityToken" const val VERSION_INFO = "versionInfo" const val DEVICE_DATA_VERSION_INFO = "deviceDataVersionInfo" + const val BRAND_SPOOF = "brandSpoof" const val HIDE_LAUNCHER_ICON = "hideLauncherIcon" @@ -43,8 +43,7 @@ object SettingsContract { object Gcm { private const val id = "gcm" - fun getContentUri(context: Context) = Uri.withAppendedPath(getAuthorityUri(context), id) - fun getContentType(context: Context) = "vnd.android.cursor.item/vnd.${getAuthority(context)}.$id" + fun getContentUri(context: Context): Uri? = Uri.withAppendedPath(getAuthorityUri(context), id) const val FULL_LOG = "gcm_full_log" const val LAST_PERSISTENT_ID = "gcm_last_persistent_id" @@ -75,24 +74,20 @@ object SettingsContract { object Auth { private const val id = "auth" - fun getContentUri(context: Context) = Uri.withAppendedPath(getAuthorityUri(context), id) - fun getContentType(context: Context) = "vnd.android.cursor.item/vnd.${getAuthority(context)}.$id" + fun getContentUri(context: Context): Uri? = Uri.withAppendedPath(getAuthorityUri(context), id) const val TRUST_GOOGLE = "auth_manager_trust_google" const val VISIBLE = "auth_manager_visible" - const val INCLUDE_ANDROID_ID = "auth_include_android_id" val PROJECTION = arrayOf( TRUST_GOOGLE, VISIBLE, - INCLUDE_ANDROID_ID, ) } object Profile { private const val id = "profile" - fun getContentUri(context: Context) = Uri.withAppendedPath(getAuthorityUri(context), id) - fun getContentType(context: Context) = "vnd.android.cursor.item/vnd.${getAuthority(context)}.$id" + fun getContentUri(context: Context): Uri? = Uri.withAppendedPath(getAuthorityUri(context), id) const val PROFILE = "device_profile" const val SERIAL = "device_profile_serial" diff --git a/play-services-base-core/src/main/kotlin/org/microg/gms/settings/SettingsProvider.kt b/play-services-base-core/src/main/kotlin/org/microg/mgms/settings/SettingsProvider.kt similarity index 86% rename from play-services-base-core/src/main/kotlin/org/microg/gms/settings/SettingsProvider.kt rename to play-services-base-core/src/main/kotlin/org/microg/mgms/settings/SettingsProvider.kt index 39dc00e1..ba7e2e25 100644 --- a/play-services-base-core/src/main/kotlin/org/microg/gms/settings/SettingsProvider.kt +++ b/play-services-base-core/src/main/kotlin/org/microg/mgms/settings/SettingsProvider.kt @@ -4,8 +4,9 @@ */ @file:Suppress("DEPRECATION") -package org.microg.gms.settings +package org.microg.mgms.settings +import android.annotation.SuppressLint import android.content.ContentProvider import android.content.ContentValues import android.content.Context @@ -16,20 +17,22 @@ import android.database.MatrixCursor import android.net.Uri import android.preference.PreferenceManager import org.microg.gms.common.PackageUtils.warnIfNotMainProcess -import org.microg.gms.settings.SettingsContract.Auth -import org.microg.gms.settings.SettingsContract.CheckIn -import org.microg.gms.settings.SettingsContract.Gcm -import org.microg.gms.settings.SettingsContract.Profile -import org.microg.gms.settings.SettingsContract.getAuthority +import org.microg.mgms.settings.SettingsContract.Auth +import org.microg.mgms.settings.SettingsContract.CheckIn +import org.microg.mgms.settings.SettingsContract.Gcm +import org.microg.mgms.settings.SettingsContract.Profile +import org.microg.mgms.settings.SettingsContract.getAuthority import java.io.File -private const val SETTINGS_PREFIX = "org.microg.gms.settings." - /** * All settings access should go through this [ContentProvider], * because it provides safe access from different processes which normal [SharedPreferences] don't. */ +@SuppressLint("DiscouragedPrivateApi") class SettingsProvider : ContentProvider() { + companion object { + const val INTERVAL = 1 * 60 * 1000 // 1 minute + } private val preferences: SharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(context) @@ -49,10 +52,6 @@ class SettingsProvider : ContentProvider() { } } - private val metaDataPreferences: SharedPreferences by lazy { - MetaDataPreferences(context!!, SETTINGS_PREFIX) - } - override fun onCreate(): Boolean { return true } @@ -100,7 +99,7 @@ class SettingsProvider : ContentProvider() { CheckIn.VERSION_INFO -> checkInPrefs.getString(key, "") ?: "" CheckIn.DEVICE_DATA_VERSION_INFO -> checkInPrefs.getString(key, "") ?: "" CheckIn.BRAND_SPOOF -> getSettingsBoolean(key, false) - CheckIn.HIDE_LAUNCHER_ICON -> getSettingsBoolean(key, true) + CheckIn.HIDE_LAUNCHER_ICON -> getSettingsBoolean(key, false) else -> throw IllegalArgumentException() } } @@ -168,9 +167,9 @@ class SettingsProvider : ContentProvider() { Gcm.NETWORK_ROAMING -> Integer.parseInt(preferences.getString(key, "0") ?: "0") Gcm.NETWORK_OTHER -> Integer.parseInt(preferences.getString(key, "0") ?: "0") - Gcm.LEARNT_MOBILE -> preferences.getInt(key, 300000) - Gcm.LEARNT_WIFI -> preferences.getInt(key, 300000) - Gcm.LEARNT_OTHER -> preferences.getInt(key, 300000) + Gcm.LEARNT_MOBILE -> preferences.getInt(key, INTERVAL) + Gcm.LEARNT_WIFI -> preferences.getInt(key, INTERVAL) + Gcm.LEARNT_OTHER -> preferences.getInt(key, INTERVAL) else -> throw IllegalArgumentException("Unknown key: $key") } @@ -205,7 +204,6 @@ class SettingsProvider : ContentProvider() { when (key) { Auth.TRUST_GOOGLE -> getSettingsBoolean(key, true) Auth.VISIBLE -> getSettingsBoolean(key, false) - Auth.INCLUDE_ANDROID_ID -> getSettingsBoolean(key, true) else -> throw IllegalArgumentException("Unknown key: $key") } } @@ -217,7 +215,6 @@ class SettingsProvider : ContentProvider() { when (key) { Auth.TRUST_GOOGLE -> editor.putBoolean(key, value as Boolean) Auth.VISIBLE -> editor.putBoolean(key, value as Boolean) - Auth.INCLUDE_ANDROID_ID -> editor.putBoolean(key, value as Boolean) else -> throw IllegalArgumentException("Unknown key: $key") } } @@ -272,16 +269,12 @@ class SettingsProvider : ContentProvider() { * @return the current setting as [Int], because [ContentProvider] does not support [Boolean]. */ private fun getSettingsBoolean(key: String, def: Boolean): Int { - return listOf(preferences, systemDefaultPreferences, metaDataPreferences).getBooleanAsInt(key, def) + return listOf(preferences, systemDefaultPreferences).getBooleanAsInt(key, def) } - private fun getSettingsString(key: String, def: String? = null): String? = listOf(preferences, systemDefaultPreferences, metaDataPreferences).getString(key, def) - private fun getSettingsInt(key: String, def: Int): Int = listOf(preferences, systemDefaultPreferences, metaDataPreferences).getInt(key, def) - private fun getSettingsLong(key: String, def: Long): Long = listOf(preferences, systemDefaultPreferences, metaDataPreferences).getLong(key, def) + private fun getSettingsString(key: String, def: String? = null): String? = listOf(preferences, systemDefaultPreferences).getString(key, def) private fun List.getString(key: String, def: String?): String? = foldRight(def) { preferences, defValue -> preferences?.getString(key, defValue) ?: defValue } - private fun List.getInt(key: String, def: Int): Int = foldRight(def) { preferences, defValue -> preferences?.getInt(key, defValue) ?: defValue } - private fun List.getLong(key: String, def: Long): Long = foldRight(def) { preferences, defValue -> preferences?.getLong(key, defValue) ?: defValue } private fun List.getBoolean(key: String, def: Boolean): Boolean = foldRight(def) { preferences, defValue -> preferences?.getBoolean(key, defValue) ?: defValue } private fun List.getBooleanAsInt(key: String, def: Boolean): Int = if (getBoolean(key, def)) 1 else 0 } diff --git a/play-services-base-core/src/main/res/layout/preference_app_heading.xml b/play-services-base-core/src/main/res/layout/preference_app_heading.xml deleted file mode 100644 index cb7e4edf..00000000 --- a/play-services-base-core/src/main/res/layout/preference_app_heading.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/play-services-base-core/src/main/res/layout/preference_switch_bar.xml b/play-services-base-core/src/main/res/layout/preference_switch_bar.xml deleted file mode 100644 index 9818305b..00000000 --- a/play-services-base-core/src/main/res/layout/preference_switch_bar.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/play-services-base-core/src/main/res/values-ja/strings.xml b/play-services-base-core/src/main/res/values-ja/strings.xml index a603746e..97f279c1 100644 --- a/play-services-base-core/src/main/res/values-ja/strings.xml +++ b/play-services-base-core/src/main/res/values-ja/strings.xml @@ -4,8 +4,8 @@ ~ SPDX-License-Identifier: Apache-2.0 --> - バッテリー節約の警告 + 電池の最適化 の警告 通知を展開する - microGをバックグラウンドで保持 - こちらをタップして、microGのバッテリー最適化を無効にし、デバイスを再起動して通知を削除する + Vanced microGをバックグラウンドで保持 + ここをタップして、Vanced microGの[電池の最適化]を無効にし、デバイスを再起動して通知を削除してください。 diff --git a/play-services-base/build.gradle b/play-services-base/build.gradle index e1cff12a..7c7057d4 100644 --- a/play-services-base/build.gradle +++ b/play-services-base/build.gradle @@ -26,8 +26,8 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } namespace 'org.microg.gms.base' } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/GoogleApiAvailability.java b/play-services-base/src/main/java/com/google/android/gms/common/GoogleApiAvailability.java index 74f857a3..61ee1ec0 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/GoogleApiAvailability.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/GoogleApiAvailability.java @@ -16,65 +16,25 @@ package com.google.android.gms.common; -import static com.google.android.gms.common.ConnectionResult.INTERNAL_ERROR; -import static com.google.android.gms.common.ConnectionResult.INVALID_ACCOUNT; -import static com.google.android.gms.common.ConnectionResult.NETWORK_ERROR; -import static com.google.android.gms.common.ConnectionResult.RESOLUTION_REQUIRED; -import static com.google.android.gms.common.ConnectionResult.SERVICE_DISABLED; -import static com.google.android.gms.common.ConnectionResult.SERVICE_INVALID; -import static com.google.android.gms.common.ConnectionResult.SERVICE_MISSING; -import static com.google.android.gms.common.ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED; -import static com.google.android.gms.common.ConnectionResult.SIGN_IN_REQUIRED; -import static com.google.android.gms.common.ConnectionResult.SUCCESS; - -import android.app.Activity; import android.app.Dialog; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; -import android.util.Log; -import androidx.fragment.app.FragmentActivity; - -import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; -import com.google.android.gms.tasks.Task; -import com.google.android.gms.tasks.Tasks; - -import org.microg.gms.common.Constants; import org.microg.gms.common.PublicApi; @PublicApi public class GoogleApiAvailability { - private static final String TAG = "GmsApiAvailability"; - - /** - * Package name for Google Play services. - */ - public static final String GOOGLE_PLAY_SERVICES_PACKAGE = Constants.GMS_PACKAGE_NAME; - - /** - * Google Play services client library version (declared in library's AndroidManifest.xml android:versionCode). - */ - public static final int GOOGLE_PLAY_SERVICES_VERSION_CODE = Constants.GMS_VERSION_CODE; - - private static GoogleApiAvailability instance; private GoogleApiAvailability() { } + private static final class InstanceHolder { + static final GoogleApiAvailability instance = new GoogleApiAvailability(); + } + /** * Returns the singleton instance of GoogleApiAvailability. */ public static GoogleApiAvailability getInstance() { - if (instance == null) { - synchronized (GoogleApiAvailability.class) { - if (instance == null) { - instance = new GoogleApiAvailability(); - } - } - } - return instance; + return InstanceHolder.instance; } @@ -84,219 +44,10 @@ public class GoogleApiAvailability { * to the Play Store if Google Play services is out of date or missing, or to system settings * if Google Play services is disabled on the device. * - * @param activity parent activity for creating the dialog, also used for identifying language to display dialog in. - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param requestCode The requestCode given when calling startActivityForResult. */ - public Dialog getErrorDialog(Activity activity, int errorCode, int requestCode) { - return getErrorDialog(activity, errorCode, requestCode, null); - } - - /** - * Returns a dialog to address the provided errorCode. The returned dialog displays a localized - * message about the error and upon user confirmation (by tapping on dialog) will direct them - * to the Play Store if Google Play services is out of date or missing, or to system settings - * if Google Play services is disabled on the device. - * - * @param activity parent activity for creating the dialog, also used for identifying language to display dialog in. - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param requestCode The requestCode given when calling startActivityForResult. - * @param cancelListener The {@link DialogInterface.OnCancelListener} to invoke if the dialog is canceled. - */ - public Dialog getErrorDialog(Activity activity, int errorCode, int requestCode, DialogInterface.OnCancelListener cancelListener) { + public Dialog getErrorDialog() { // TODO return null; } - /** - * Returns a PendingIntent to address the provided connection failure. - *

- * If {@link ConnectionResult#hasResolution()} is true, then {@link ConnectionResult#getResolution()} - * will be returned. Otherwise, the returned PendingIntent will direct the user to either the - * Play Store if Google Play services is out of date or missing, or system settings if Google - * Play services is disabled on the device. - * - * @param context parent context for creating the PendingIntent. - * @param result the connection failure. If successful or the error is not resolvable by the user, null is returned. - */ - public PendingIntent getErrorResolutionPendingIntent(Context context, ConnectionResult result) { - if (result.hasResolution()) { - return result.getResolution(); - } - return getErrorResolutionPendingIntent(context, result.getErrorCode(), 0); - } - - /** - * Returns a PendingIntent to address the provided errorCode. It will direct the user to either - * the Play Store if Google Play services is out of date or missing, or system settings if - * Google Play services is disabled on the device. - * - * @param context parent context for creating the PendingIntent. - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param requestCode The requestCode given when calling startActivityForResult. - */ - public PendingIntent getErrorResolutionPendingIntent(Context context, int errorCode, int requestCode) { - // TODO - return null; - } - - /** - * Returns a human-readable string of the error code returned from {@link #isGooglePlayServicesAvailable(Context)}. - */ - public final String getErrorString(int errorCode) { - return ConnectionResult.getStatusString(errorCode); - } - - /** - * Verifies that Google Play services is installed and enabled on this device, and that the - * version installed on this device is no older than the one required by this client. - * - * @return status code indicating whether there was an error. Can be one of following in - * {@link ConnectionResult}: SUCCESS, SERVICE_MISSING, SERVICE_UPDATING, - * SERVICE_VERSION_UPDATE_REQUIRED, SERVICE_DISABLED, SERVICE_INVALID - */ - public int isGooglePlayServicesAvailable(Context context) { - Log.d(TAG, "As we can't know right now if the later desired feature is available, " + - "we just pretend it to be."); - return SUCCESS; - } - - /** - * Verifies that Google Play services is installed and enabled on this device, and that the version installed on - * this device is no older than the one required by this client or the version is not older than the one specified - * in minApkVersion. - * - * @return status code indicating whether there was an error. Can be one of following in - * {@link ConnectionResult}: SUCCESS, SERVICE_MISSING, SERVICE_UPDATING, - * SERVICE_VERSION_UPDATE_REQUIRED, SERVICE_DISABLED, SERVICE_INVALID - */ - public int isGooglePlayServicesAvailable(Context context, int minApkVersion) { - return isGooglePlayServicesAvailable(context); - } - - /** - * Determines whether an error can be resolved via user action. If true, proceed by calling - * {@link #getErrorDialog(Activity, int, int)} and showing the dialog. - * - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)}, or - * returned to your application via {@link OnConnectionFailedListener#onConnectionFailed(ConnectionResult)} - * @return true if the error is resolvable with {@link #getErrorDialog(Activity, int, int)} - */ - public final boolean isUserResolvableError(int errorCode) { - switch (errorCode) { - case SERVICE_MISSING: - case SERVICE_VERSION_UPDATE_REQUIRED: - case SERVICE_DISABLED: - case SERVICE_INVALID: - return true; - case SIGN_IN_REQUIRED: - case INVALID_ACCOUNT: - case RESOLUTION_REQUIRED: - case NETWORK_ERROR: - case INTERNAL_ERROR: - default: - return false; - } - } - - /** - * Attempts to make Google Play services available on this device. If Play Services is already - * available, the returned {@link Task} may complete immediately. - *

- * If it is necessary to display UI in order to complete this request (e.g. sending the user - * to the Google Play store) the passed {@link Activity} will be used to display this UI. - *

- * It is recommended to call this method from {@link Activity#onCreate(Bundle)}. - * If the passed {@link Activity} completes before the returned {@link Task} completes, the - * Task will fail with a {@link java.util.concurrent.CancellationException}. - *

- * This method must be called from the main thread. - * - * @return A {@link Task}. If this Task completes without throwing an exception, Play Services - * is available on this device. - */ - public Task makeGooglePlayServicesAvailable(Activity activity) { - int status = isGooglePlayServicesAvailable(activity); - if (status == SUCCESS) { - return Tasks.forResult(null); - } - // TODO - return Tasks.forResult(null); - } - - /** - * Displays a DialogFragment for an error code returned by {@link #isGooglePlayServicesAvailable(Context)}. - * - * @param activity parent activity for creating the dialog, also used for identifying language to display dialog in. - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param requestCode The requestCode given when calling startActivityForResult. - * @return true if the dialog is shown, false otherwise - * @throws RuntimeException if API level is below 11 and activity is not a {@link FragmentActivity}. - * @see ErrorDialogFragment - * @see SupportErrorDialogFragmet - */ - public boolean showErrorDialogFragment(Activity activity, int errorCode, int requestCode) { - return showErrorDialogFragment(activity, errorCode, requestCode, null); - } - - /** - * Displays a DialogFragment for an error code returned by {@link #isGooglePlayServicesAvailable(Context)}. - * - * @param activity parent activity for creating the dialog, also used for identifying language to display dialog in. - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param requestCode The requestCode given when calling startActivityForResult. - * @param cancelListener The {@link DialogInterface.OnCancelListener} to invoke if the dialog is canceled. - * @return true if the dialog is shown, false otherwise - * @throws RuntimeException if API level is below 11 and activity is not a {@link FragmentActivity}. - */ - public boolean showErrorDialogFragment(Activity activity, int errorCode, int requestCode, DialogInterface.OnCancelListener cancelListener) { - Dialog dialog = getErrorDialog(activity, errorCode, requestCode, cancelListener); - if (dialog == null) { - return false; - } else { - // TODO - return false; - } - } - - /** - * Displays a notification for an error code returned from - * {@link #isGooglePlayServicesAvailable(Context)}, if it is resolvable by the user. - *

- * This method is similar to {@link #getErrorDialog(int, android.app.Activity, int)}, but is - * provided for background tasks that cannot or should not display dialogs. - * - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param context used for identifying language to display dialog in as well as accessing the - * {@link android.app.NotificationManager}. - */ - public void showErrorNotification(Context context, int errorCode) { - if (errorCode == RESOLUTION_REQUIRED) { - Log.e(TAG, "showErrorNotification(context, errorCode) is called for RESOLUTION_REQUIRED when showErrorNotification(context, result) should be called"); - } - - if (isUserResolvableError(errorCode)) { - GooglePlayServicesUtil.showErrorNotification(errorCode, context); - } - } - - /** - * Displays a notification for a connection failure, if it is resolvable by the user. - * - * @param context The calling context used to display the notification. - * @param result The connection failure. If successful or the error is not resolvable by the - * user, no notification is shown. - */ - public void showErrorNotification(Context context, ConnectionResult result) { - PendingIntent pendingIntent = getErrorResolutionPendingIntent(context, result); - if (pendingIntent != null) { - // TODO - } - } } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/GooglePlayServicesClient.java b/play-services-base/src/main/java/com/google/android/gms/common/GooglePlayServicesClient.java index a5642fdd..0941e410 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/GooglePlayServicesClient.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/GooglePlayServicesClient.java @@ -26,20 +26,6 @@ public interface GooglePlayServicesClient { boolean isConnected(); - boolean isConnecting(); - - void registerConnectionCallbacks(ConnectionCallbacks listener); - - boolean isConnectionCallbacksRegistered(ConnectionCallbacks listener); - - void unregisterConnectionCallbacks(ConnectionCallbacks listener); - - void registerConnectionFailedListener(OnConnectionFailedListener listener); - - boolean isConnectionFailedListenerRegistered(OnConnectionFailedListener listener); - - void unregisterConnectionFailedListener(OnConnectionFailedListener listener); - @Deprecated interface OnConnectionFailedListener { diff --git a/play-services-base/src/main/java/com/google/android/gms/common/GooglePlayServicesUtil.java b/play-services-base/src/main/java/com/google/android/gms/common/GooglePlayServicesUtil.java index 4850b816..d5399280 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/GooglePlayServicesUtil.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/GooglePlayServicesUtil.java @@ -16,14 +16,8 @@ package com.google.android.gms.common; -import android.app.Activity; import android.app.Dialog; -import android.app.Fragment; import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.content.pm.PackageManager; -import android.content.res.Resources; import android.util.Log; import org.microg.gms.common.Constants; @@ -40,8 +34,6 @@ import org.microg.gms.common.PublicApi; public class GooglePlayServicesUtil { private static final String TAG = "GooglePlayServicesUtil"; - public static final String GMS_ERROR_DIALOG = "GooglePlayServicesErrorDialog"; - /** * Package name for Google Play services. */ @@ -54,45 +46,16 @@ public class GooglePlayServicesUtil { @Deprecated public static final int GOOGLE_PLAY_SERVICES_VERSION_CODE = Constants.GMS_VERSION_CODE; - /** - * Package name for Google Play Store. - */ - public static final String GOOGLE_PLAY_STORE_PACKAGE = "com.android.vending"; - /** * Returns a dialog to address the provided errorCode. The returned dialog displays a localized * message about the error and upon user confirmation (by tapping on dialog) will direct them * to the Play Store if Google Play services is out of date or missing, or to system settings * if Google Play services is disabled on the device. * - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param activity parent activity for creating the dialog, also used for identifying - * language to display dialog in. - * @param requestCode The requestCode given when calling startActivityForResult. */ @Deprecated - public static Dialog getErrorDialog(int errorCode, Activity activity, int requestCode) { - return getErrorDialog(errorCode, activity, requestCode, null); - } - - /** - * Returns a dialog to address the provided errorCode. The returned dialog displays a localized - * message about the error and upon user confirmation (by tapping on dialog) will direct them - * to the Play Store if Google Play services is out of date or missing, or to system settings - * if Google Play services is disabled on the device. - * - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param activity parent activity for creating the dialog, also used for identifying - * language to display dialog in. - * @param requestCode The requestCode given when calling startActivityForResult. - * @param cancelListener The {@link DialogInterface.OnCancelListener} to invoke if the dialog - * is canceled. - */ - @Deprecated - public static Dialog getErrorDialog(int errorCode, Activity activity, int requestCode, DialogInterface.OnCancelListener cancelListener) { - return GoogleApiAvailability.getInstance().getErrorDialog(activity, errorCode, requestCode, cancelListener); + public static Dialog getErrorDialog() { + return GoogleApiAvailability.getInstance().getErrorDialog(); } /** @@ -100,22 +63,17 @@ public class GooglePlayServicesUtil { * following places to either the Play Store if Google Play services is out of date or missing, * or system settings if Google Play services is disabled on the device. * - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param activity parent context for creating the PendingIntent. - * @param requestCode The requestCode given when calling startActivityForResult. */ @Deprecated - public static PendingIntent getErrorPendingIntent(int errorCode, Activity activity, - int requestCode) { + public static PendingIntent getErrorPendingIntent() { return null; // TODO } /** - * Returns a human-readable string of the error code returned from {@link #isGooglePlayServicesAvailable(Context)}. + * Returns a human-readable string of the error code returned from {@link #isGooglePlayServicesAvailable()}. */ @Deprecated - public static String getErrorString(int errorCode) { + public static String getErrorString() { return null; // TODO } @@ -124,27 +82,7 @@ public class GooglePlayServicesUtil { * application, or null if Google Play services is not available on this device. */ @Deprecated - public static String getOpenSourceSoftwareLicenseInfo(Context context) { - return null; // TODO - } - - /** - * This gets the Context object of the Buddy APK. This loads the Buddy APK code from the Buddy - * APK into memory. This returned context can be used to create classes and obtain resources - * defined in the Buddy APK. - * - * @return The Context object of the Buddy APK or null if the Buddy APK is not installed on the device. - */ - public static Context getRemoteContext(Context context) { - return null; // TODO - } - - /** - * This gets the Resources object of the Buddy APK. - * - * @return The Resources object of the Buddy APK or null if the Buddy APK is not installed on the device. - */ - public static Resources getRemoteResources(Context context) { + public static String getOpenSourceSoftwareLicenseInfo() { return null; // TODO } @@ -157,79 +95,41 @@ public class GooglePlayServicesUtil { * SERVICE_DISABLED, SERVICE_INVALID */ @Deprecated - public static int isGooglePlayServicesAvailable(Context context) { + public static int isGooglePlayServicesAvailable() { Log.d(TAG, "As we can't know right now if the later desired feature is available, " + "we just pretend it to be."); return ConnectionResult.SUCCESS; } @Deprecated - public static boolean isGoogleSignedUid(PackageManager packageManager, int uid) { + public static boolean isGoogleSignedUid() { return false; // TODO } /** * Determines whether an error is user-recoverable. If true, proceed by calling - * {@link #getErrorDialog(int, Activity, int)} and showing the dialog. + * {@link #getErrorDialog()} and showing the dialog. * - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)}, or - * returned to your application via {@link com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener#onConnectionFailed(ConnectionResult)} - * @return true if the error is recoverable with {@link #getErrorDialog(int, Activity, int)} + * @return true if the error is recoverable with {@link #getErrorDialog()} */ @Deprecated - public static boolean isUserRecoverableError(int errorCode) { + public static boolean isUserRecoverableError() { return false; // TODO } - /** - * Display a DialogFragment for an error code returned by {@link #isGooglePlayServicesAvailable(Context)}. - * - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param activity parent activity for creating the dialog, also used for identifying - * language to display dialog in. - * @param requestCode The requestCode given when calling startActivityForResult. - * @return true if the dialog is shown, false otherwise - * @throws RuntimeException if API level is below 11 and activity is not a {@link android.support.v4.app.FragmentActivity}. - */ @Deprecated - public static boolean showErrorDialogFragment(int errorCode, Activity activity, int requestCode) { - return showErrorDialogFragment(errorCode, activity, requestCode, null); - } - - @Deprecated - public static boolean showErrorDialogFragment(int errorCode, Activity activity, Fragment fragment, int requestCode, DialogInterface.OnCancelListener cancelListener) { + public static boolean showErrorDialogFragment() { return false; // TODO } - /** - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param activity parent activity for creating the dialog, also used for identifying - * language to display dialog in. - * @param requestCode The requestCode given when calling startActivityForResult. - * @param cancelListener The {@link DialogInterface.OnCancelListener} to invoke if the dialog - * is canceled. - * @return true if the dialog is shown, false otherwise. - * @throws RuntimeException if API level is below 11 and activity is not a {@link android.support.v4.app.FragmentActivity}. - */ - @Deprecated - public static boolean showErrorDialogFragment(int errorCode, Activity activity, int requestCode, DialogInterface.OnCancelListener cancelListener) { - return showErrorDialogFragment(errorCode, activity, null, requestCode, cancelListener); - } - /** * Displays a notification relevant to the provided error code. This method is similar to - * {@link #getErrorDialog(int, android.app.Activity, int)}, but is provided for background + * {@link #getErrorDialog()}, but is provided for background * tasks that cannot or shouldn't display dialogs. * - * @param errorCode error code returned by {@link #isGooglePlayServicesAvailable(Context)} call. - * If errorCode is {@link ConnectionResult#SUCCESS} then null is returned. - * @param context used for identifying language to display dialog in as well as accessing the - * {@link android.app.NotificationManager}. */ @Deprecated - public static void showErrorNotification(int errorCode, Context context) { + public static void showErrorNotification() { // TODO } } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/AccountInfo.java b/play-services-base/src/main/java/com/google/android/gms/common/api/AccountInfo.java index 30d6a169..fd400c45 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/AccountInfo.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/AccountInfo.java @@ -20,5 +20,5 @@ import org.microg.safeparcel.AutoSafeParcelable; @Deprecated public class AccountInfo extends AutoSafeParcelable { - public static final Creator CREATOR = new AutoCreator(AccountInfo.class); + public static final Creator CREATOR = new AutoCreator<>(AccountInfo.class); } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/Api.java b/play-services-base/src/main/java/com/google/android/gms/common/api/Api.java index fd91a375..6b7f15e3 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/Api.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/Api.java @@ -16,11 +16,6 @@ package com.google.android.gms.common.api; -import android.accounts.Account; - -import com.google.android.gms.auth.api.signin.GoogleSignInAccount; - -import org.microg.gms.common.Hide; import org.microg.gms.common.PublicApi; import org.microg.gms.common.api.ApiClientBuilder; @@ -70,45 +65,6 @@ public final class Api { interface NotRequiredOptions extends ApiOptions { } - /** - * {@link ApiOptions} implementation for {@link Api}s that do not take any options. - */ - @PublicApi - final class NoOptions implements NotRequiredOptions { - } - - /** - * Base interface for {@link ApiOptions} that are optional. - */ - @PublicApi - interface Optional extends HasOptions, NotRequiredOptions { - } - - /** - * An interface for {@link ApiOptions} that include an account. - */ - @PublicApi - interface HasAccountOptions extends HasOptions, NotRequiredOptions { - Account getAccount(); - } - - /** - * An interface for {@link ApiOptions} that includes a {@link GoogleSignInAccount} - */ - @PublicApi - interface HasGoogleSignInAccountOptions extends HasOptions { - GoogleSignInAccount getGoogleSignInAccount(); - } } - @Hide - public interface Client { - void connect(); - - void disconnect(); - - boolean isConnected(); - - boolean isConnecting(); - } } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApi.java b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApi.java index 4a33737c..f0adb967 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApi.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApi.java @@ -7,51 +7,22 @@ package com.google.android.gms.common.api; import android.content.Context; -import com.google.android.gms.common.api.internal.ApiKey; -import com.google.android.gms.tasks.Task; -import com.google.android.gms.tasks.TaskCompletionSource; - -import org.microg.gms.common.Hide; import org.microg.gms.common.PublicApi; import org.microg.gms.common.api.GoogleApiManager; -import org.microg.gms.common.api.PendingGoogleApiCall; @PublicApi -public abstract class GoogleApi implements HasApiKey { - private GoogleApiManager manager; - @Hide +public abstract class GoogleApi implements HasApiKey { + @PublicApi(exclude = true) public Api api; - @Hide - public O options; @PublicApi(exclude = true) protected GoogleApi(Context context, Api api) { this.api = api; - this.manager = GoogleApiManager.getInstance(context); - } - - @PublicApi(exclude = true) - protected GoogleApi(Context context, Api api, O options) { - this.api = api; - this.manager = GoogleApiManager.getInstance(context); - this.options = options; - } - - @PublicApi(exclude = true) - protected Task scheduleTask(PendingGoogleApiCall apiCall) { - TaskCompletionSource completionSource = new TaskCompletionSource<>(); - manager.scheduleTask(this, apiCall, completionSource); - return completionSource.getTask(); - } - - @Override - @PublicApi(exclude = true) - public ApiKey getApiKey() { - return null; + GoogleApiManager.getInstance(); } @PublicApi(exclude = true) public O getOptions() { - return options; + return null; } } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiActivity.java b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiActivity.java index b47a2d47..8a6b0690 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiActivity.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiActivity.java @@ -1,26 +1,6 @@ -/* - * SPDX-FileCopyrightText: 2020, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - * Notice: Portions of this file are reproduced from work created and shared by Google and used - * according to terms described in the Creative Commons 4.0 Attribution License. - * See https://developers.google.com/readme/policies for details. - */ - package com.google.android.gms.common.api; import android.app.Activity; -import android.content.DialogInterface; -import org.microg.gms.common.PublicApi; - -/** - * Helper activity used by Google Play services APIs to display resolutions for connection errors. - */ -@PublicApi -public class GoogleApiActivity extends Activity implements DialogInterface.OnCancelListener { - @Override - @PublicApi(exclude = true) - public void onCancel(DialogInterface dialog) { - - } +public class GoogleApiActivity extends Activity { } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiClient.java b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiClient.java index 62e52ba3..0e20b6d5 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiClient.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/GoogleApiClient.java @@ -19,15 +19,10 @@ package com.google.android.gms.common.api; import android.app.Activity; import android.content.Context; import android.os.Bundle; -import android.os.Handler; import android.os.Looper; -import android.view.View; - -import androidx.fragment.app.FragmentActivity; import com.google.android.gms.common.ConnectionResult; -import org.microg.gms.auth.AuthConstants; import org.microg.gms.common.PublicApi; import org.microg.gms.common.api.ApiClientSettings; import org.microg.gms.common.api.GoogleApiClientImpl; @@ -36,7 +31,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.concurrent.TimeUnit; /** * The main entry point for Google Play services integration. @@ -59,32 +53,6 @@ import java.util.concurrent.TimeUnit; @PublicApi @Deprecated public interface GoogleApiClient { - /** - * Connects the client to Google Play services. Blocks until the connection either succeeds or - * fails. This is not allowed on the UI thread. - * - * @return the result of the connection - */ - ConnectionResult blockingConnect(); - - /** - * Connects the client to Google Play services. Blocks until the connection is set or failed or - * has timed out. This is not allowed on the UI thread. - * - * @param timeout the maximum time to wait - * @param unit the time unit of the {@code timeout} argument - * @return the result of the connection - */ - ConnectionResult blockingConnect(long timeout, TimeUnit unit); - - /** - * Clears the account selected by the user and reconnects the client asking the user to pick an - * account again if {@link Builder#useDefaultAccount()} was set. - * - * @return the pending result is fired once the default account has been cleared, but before - * the client is reconnected - for that {@link ConnectionCallbacks} can be used. - */ - PendingResult clearDefaultAccountAndReconnect(); /** * Connects the client to Google Play services. This method returns immediately, and connects @@ -143,23 +111,7 @@ public interface GoogleApiClient { * @see #registerConnectionFailedListener(OnConnectionFailedListener) * @see #unregisterConnectionFailedListener(OnConnectionFailedListener) */ - public boolean isConnectionFailedListenerRegistered(OnConnectionFailedListener listener); - - /** - * Closes the current connection to Google Play services and creates a new connection. - *

- * This method closes the current connection then returns immediately and reconnects to the - * service in the background. - *

- * After calling this method, your application will receive - * {@link ConnectionCallbacks#onConnected(Bundle)} if the connection is successful, or - * {@link OnConnectionFailedListener#onConnectionFailed(ConnectionResult)} if the connection - * failed. - * - * @see #connect() - * @see #disconnect() - */ - void reconnect(); + boolean isConnectionFailedListenerRegistered(OnConnectionFailedListener listener); /** * Registers a listener to receive connection events from this {@link GoogleApiClient}. If the @@ -198,20 +150,7 @@ public interface GoogleApiClient { * @param listener the listener where the results of the asynchronous {@link #connect()} call * are delivered. */ - public void registerConnectionFailedListener(OnConnectionFailedListener listener); - - /** - * Disconnects the client and stops automatic lifecycle management. Use this before creating a - * new client (which might be necessary when switching accounts, changing the set of used APIs - * etc.). - *

- * This method must be called from the main thread. - * - * @param lifecycleActivity the activity managing the client's lifecycle. - * @throws IllegalStateException if called from outside of the main thread. - * @see Builder#enableAutoManage(FragmentActivity, int, OnConnectionFailedListener) - */ - void stopAutoManager(FragmentActivity lifecycleActivity) throws IllegalStateException; + void registerConnectionFailedListener(OnConnectionFailedListener listener); /** * Removes a connection listener from this {@link GoogleApiClient}. Note that removing a @@ -224,73 +163,19 @@ public interface GoogleApiClient { */ void unregisterConnectionCallbacks(ConnectionCallbacks listener); - /** - * Removes a connection failed listener from the {@link GoogleApiClient}. Note that removing a - * listener does not generate any callbacks. - *

- * If the specified listener is not currently registered to receive connection failed events, - * this method will have no effect. - * - * @param listener the listener to unregister. - */ - void unregisterConnectionFailedListener(OnConnectionFailedListener listener); - - /** - * Builder to configure a {@link GoogleApiClient}. - */ @PublicApi class Builder { private final Context context; - private final Map apis = new HashMap(); - private final Set connectionCallbacks = new HashSet(); - private final Set connectionFailedListeners = new HashSet(); - private final Set scopes = new HashSet(); - private String accountName; - private int clientId = -1; - private FragmentActivity fragmentActivity; - private Looper looper; - private int gravityForPopups; - private OnConnectionFailedListener unresolvedConnectionFailedListener; - private View viewForPopups; + private final Map apis = new HashMap<>(); + private final Set connectionCallbacks = new HashSet<>(); + private final Set connectionFailedListeners = new HashSet<>(); + private final Looper looper; - /** - * Builder to help construct the {@link GoogleApiClient} object. - * - * @param context The context to use for the connection. - */ public Builder(Context context) { this.context = context; this.looper = context.getMainLooper(); } - /** - * Builder to help construct the {@link GoogleApiClient} object. - * - * @param context The context to use for the connection. - * @param connectedListener The listener where the results of the asynchronous - * {@link #connect()} call are delivered. - * @param connectionFailedListener The listener which will be notified if the connection - * attempt fails. - */ - public Builder(Context context, ConnectionCallbacks connectedListener, - OnConnectionFailedListener connectionFailedListener) { - this(context); - addConnectionCallbacks(connectedListener); - addOnConnectionFailedListener(connectionFailedListener); - } - - /** - * Specify which Apis are requested by your app. See {@link Api} for more information. - * - * @param api The Api requested by your app. - * @param options Any additional parameters required for the specific AP - * @see Api - */ - public Builder addApi(Api api, O options) { - apis.put(api, options); - return this; - } - /** * Specify which Apis are requested by your app. See {@link Api} for more information. * @@ -302,136 +187,20 @@ public interface GoogleApiClient { return this; } - /** - * Registers a listener to receive connection events from this {@link GoogleApiClient}. - * Applications should balance calls to this method with calls to - * {@link #unregisterConnectionCallbacks(ConnectionCallbacks)} to avoid - * leaking resources. - *

- * If the specified listener is already registered to receive connection events, this - * method will not add a duplicate entry for the same listener. - *

- * Note that the order of messages received here may not be stable, so clients should not - * rely on the order that multiple listeners receive events in. - * - * @param listener the listener where the results of the asynchronous {@link #connect()} - * call are delivered. - */ - public Builder addConnectionCallbacks(ConnectionCallbacks listener) { - connectionCallbacks.add(listener); - return this; - } - - /** - * Adds a listener to register to receive connection failed events from this - * {@link GoogleApiClient}. Applications should balance calls to this method with calls to - * {@link #unregisterConnectionFailedListener(OnConnectionFailedListener)} to avoid - * leaking resources. - *

- * If the specified listener is already registered to receive connection failed events, - * this method will not add a duplicate entry for the same listener. - *

- * Note that the order of messages received here may not be stable, so clients should not - * rely on the order that multiple listeners receive events in. - * - * @param listener the listener where the results of the asynchronous {@link #connect()} - * call are delivered. - */ - public Builder addOnConnectionFailedListener(OnConnectionFailedListener listener) { - connectionFailedListeners.add(listener); - return this; - } - - /** - * Specify the OAuth 2.0 scopes requested by your app. See - * {@link com.google.android.gms.common.Scopes} for more information. - * - * @param scope The OAuth 2.0 scopes requested by your app. - * @see com.google.android.gms.common.Scopes - */ - public Builder addScope(Scope scope) { - scopes.add(scope.getScopeUri()); - return this; - } - /** * Builds a new {@link GoogleApiClient} object for communicating with the Google APIs. * * @return The {@link GoogleApiClient} object. */ public GoogleApiClient build() { - return new GoogleApiClientImpl(context, looper, getClientSettings(), apis, connectionCallbacks, connectionFailedListeners, clientId); + int clientId = -1; + return new GoogleApiClientImpl(context, looper, getClientSettings(), apis, connectionCallbacks, connectionFailedListeners); } private ApiClientSettings getClientSettings() { - ApiClientSettings clientSettings = new ApiClientSettings(); - clientSettings.accountName = accountName; - clientSettings.scopes = new HashSet<>(scopes); - clientSettings.gravityForPopups = gravityForPopups; - clientSettings.viewForPopups = viewForPopups; - return clientSettings; + return null; } - public Builder enableAutoManage(FragmentActivity fragmentActivity, int cliendId, - OnConnectionFailedListener unresolvedConnectionFailedListener) - throws NullPointerException, IllegalArgumentException, IllegalStateException { - this.fragmentActivity = fragmentActivity; - this.clientId = cliendId; - this.unresolvedConnectionFailedListener = unresolvedConnectionFailedListener; - return this; - } - - /** - * Specify an account name on the device that should be used. If this is never called, the - * client will use the current default account for Google Play services for this - * application. - * - * @param accountName The account name on the device that should be used by - * {@link GoogleApiClient}. - */ - public Builder setAccountName(String accountName) { - this.accountName = accountName; - return this; - } - - /** - * Specifies the part of the screen at which games service popups (for example, - * "welcome back" or "achievement unlocked" popups) will be displayed using gravity. - * - * @param gravityForPopups The gravity which controls the placement of games service popups. - */ - public Builder setGravityForPopups(int gravityForPopups) { - this.gravityForPopups = gravityForPopups; - return this; - } - - /** - * Sets a {@link Handler} to indicate which thread to use when invoking callbacks. Will not - * be used directly to handle callbacks. If this is not called then the application's main - * thread will be used. - */ - public Builder setHandler(Handler handler) { - this.looper = handler.getLooper(); - return this; - } - - /** - * Sets the {@link View} to use as a content view for popups. - * - * @param viewForPopups The view to use as a content view for popups. View cannot be null. - */ - public Builder setViewForPopups(View viewForPopups) { - this.viewForPopups = viewForPopups; - return this; - } - - /** - * Specify that the default account should be used when connecting to services. - */ - public Builder useDefaultAccount() { - this.accountName = AuthConstants.DEFAULT_ACCOUNT; - return this; - } } /** @@ -441,23 +210,8 @@ public interface GoogleApiClient { @PublicApi @Deprecated interface ConnectionCallbacks extends org.microg.gms.common.api.ConnectionCallbacks { - /** - * A suspension cause informing that the service has been killed. - */ - int CAUSE_SERVICE_DISCONNECTED = 1; - /** - * A suspension cause informing you that a peer device connection was lost. - */ - int CAUSE_NETWORK_LOST = 2; - - void onConnected(Bundle connectionHint); } - /** - * Provides callbacks for scenarios that result in a failed attempt to connect the client to - * the service. See {@link ConnectionResult} for a list of error codes and suggestions for - * resolution. - */ @PublicApi @Deprecated interface OnConnectionFailedListener extends org.microg.gms.common.api.OnConnectionFailedListener { diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/HasApiKey.java b/play-services-base/src/main/java/com/google/android/gms/common/api/HasApiKey.java index e208b4d8..642a636d 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/HasApiKey.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/HasApiKey.java @@ -5,8 +5,5 @@ package com.google.android.gms.common.api; -import com.google.android.gms.common.api.internal.ApiKey; - -public interface HasApiKey { - ApiKey getApiKey(); +public interface HasApiKey { } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/PendingResult.java b/play-services-base/src/main/java/com/google/android/gms/common/api/PendingResult.java index ec162920..e5f92160 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/PendingResult.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/PendingResult.java @@ -16,44 +16,5 @@ package com.google.android.gms.common.api; -import java.util.concurrent.TimeUnit; - -/** - * Represents a pending result from calling an API method in Google Play services. The final result - * object from a PendingResult is of type R, which can be retrieved in one of two ways. - *

- *

    - *
  • via blocking calls to {@link #await()}, or {@link #await(long, TimeUnit)}, or
  • - *
  • via a callback by passing in an object implementing interface {@link ResultCallback} to - * {@link #setResultCallback(ResultCallback)}.
  • - *
- * After the result has been retrieved using {@link #await()} or delivered to the result callback, - * it is an error to attempt to retrieve the result again. It is the responsibility of the caller - * or callback receiver to release any resources associated with the returned result. Some result - * types may implement {@link Releasable}, in which case {@link Releasable#release()} should be - * used to free the associated resources. - *

- * TODO: Docs - */ -public interface PendingResult { - /** - * Blocks until the task is completed. This is not allowed on the UI thread. The returned - * result object can have an additional failure mode of INTERRUPTED. - */ - public R await(); - - /** - * Blocks until the task is completed or has timed out waiting for the result. This is not - * allowed on the UI thread. The returned result object can have an additional failure mode - * of either INTERRUPTED or TIMEOUT. - */ - public R await(long time, TimeUnit unit); - - public void cancel(); - - public boolean isCanceled(); - - public void setResultCallback(ResultCallback callback, long time, TimeUnit unit); - - public void setResultCallback(ResultCallback callback); +public interface PendingResult { } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/api/internal/ApiKey.java b/play-services-base/src/main/java/com/google/android/gms/common/api/internal/ApiKey.java index 5a42d8fd..b679b2b9 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/api/internal/ApiKey.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/api/internal/ApiKey.java @@ -5,8 +5,8 @@ package com.google.android.gms.common.api.internal; -import com.google.android.gms.common.api.Api; +public class ApiKey { -public class ApiKey { - private Api api; + public ApiKey() { + } } diff --git a/play-services-base/src/main/java/com/google/android/gms/common/data/DataBuffer.java b/play-services-base/src/main/java/com/google/android/gms/common/data/DataBuffer.java index 49c13a99..907aee2d 100644 --- a/play-services-base/src/main/java/com/google/android/gms/common/data/DataBuffer.java +++ b/play-services-base/src/main/java/com/google/android/gms/common/data/DataBuffer.java @@ -16,6 +16,8 @@ package com.google.android.gms.common.data; +import androidx.annotation.NonNull; + import com.google.android.gms.common.api.Releasable; import org.microg.gms.common.PublicApi; @@ -28,11 +30,8 @@ import java.util.Iterator; @PublicApi public abstract class DataBuffer implements Releasable, Iterable { - private final DataHolder dataHolder; - @PublicApi(exclude = true) - public DataBuffer(DataHolder dataHolder) { - this.dataHolder = dataHolder; + public DataBuffer() { } /** @@ -43,20 +42,6 @@ public abstract class DataBuffer implements Releasable, Iterable { release(); } - /** - * Get the item at the specified position. Note that the objects returned from subsequent - * invocations of this method for the same position may not be identical objects, but will be - * equal in value. - * - * @param position The position of the item to retrieve. - * @return the item at {@code position} in this buffer. - */ - public abstract T get(int position); - - public int getCount() { - return dataHolder == null ? 0 : dataHolder.getCount(); - } - /** * @deprecated {@link #release()} is idempotent, and so is safe to call multiple times */ @@ -65,6 +50,7 @@ public abstract class DataBuffer implements Releasable, Iterable { return false; } + @NonNull @Override public Iterator iterator() { return null; @@ -78,12 +64,4 @@ public abstract class DataBuffer implements Releasable, Iterable { } - /** - * In order to use this one should correctly override setDataRow(int) in his DataBufferRef - * implementation. Be careful: there will be single DataBufferRef while iterating. - * If you are not sure - DO NOT USE this iterator. - */ - public Iterator singleRefIterator() { - return null; - } } diff --git a/play-services-base/src/main/java/org/microg/gms/common/DummyApiClient.java b/play-services-base/src/main/java/org/microg/gms/common/DummyApiClient.java deleted file mode 100644 index c527866f..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/DummyApiClient.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.common; - -import com.google.android.gms.common.api.Api; - -public class DummyApiClient implements Api.Client { - private boolean connected = false; - - @Override - public void connect() { - connected = true; - } - - @Override - public void disconnect() { - connected = false; - } - - @Override - public boolean isConnected() { - return connected; - } - - @Override - public boolean isConnecting() { - return false; - } -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/ForwardConnectionCallbacks.java b/play-services-base/src/main/java/org/microg/gms/common/ForwardConnectionCallbacks.java deleted file mode 100644 index fdffdac7..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/ForwardConnectionCallbacks.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.common; - -import android.os.Bundle; - -import com.google.android.gms.common.GooglePlayServicesClient; -import com.google.android.gms.common.api.GoogleApiClient; - -public final class ForwardConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks { - private final GooglePlayServicesClient.ConnectionCallbacks callbacks; - - public ForwardConnectionCallbacks(GooglePlayServicesClient.ConnectionCallbacks callbacks) { - this.callbacks = callbacks; - } - - @Override - public boolean equals(Object o) { - return o instanceof ForwardConnectionCallbacks && - callbacks.equals(((ForwardConnectionCallbacks) o).callbacks); - } - - @Override - public int hashCode() { - return callbacks.hashCode(); - } - - @Override - public void onConnected(Bundle connectionHint) { - callbacks.onConnected(connectionHint); - } - - @Override - public void onConnectionSuspended(int cause) { - callbacks.onDisconnected(); - } -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/ForwardConnectionFailedListener.java b/play-services-base/src/main/java/org/microg/gms/common/ForwardConnectionFailedListener.java deleted file mode 100644 index 1d1f4434..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/ForwardConnectionFailedListener.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.common; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GooglePlayServicesClient; -import com.google.android.gms.common.api.GoogleApiClient; - -public final class ForwardConnectionFailedListener - implements GoogleApiClient.OnConnectionFailedListener { - private final GooglePlayServicesClient.OnConnectionFailedListener listener; - - public ForwardConnectionFailedListener( - GooglePlayServicesClient.OnConnectionFailedListener listener) { - this.listener = listener; - } - - @Override - public boolean equals(Object o) { - return o instanceof ForwardConnectionFailedListener && - listener.equals(((ForwardConnectionFailedListener) o).listener); - } - - @Override - public int hashCode() { - return listener.hashCode(); - } - - @Override - public void onConnectionFailed(ConnectionResult result) { - listener.onConnectionFailed(result); - } -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/GmsClient.java b/play-services-base/src/main/java/org/microg/gms/common/GmsClient.java deleted file mode 100644 index e5b71717..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/GmsClient.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.common; - -import android.accounts.Account; -import android.content.ComponentName; -import android.content.Context; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.IBinder; -import android.os.IInterface; -import android.os.RemoteException; -import android.util.Log; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.CommonStatusCodes; -import com.google.android.gms.common.internal.ConnectionInfo; -import com.google.android.gms.common.internal.GetServiceRequest; -import com.google.android.gms.common.internal.IGmsCallbacks; -import com.google.android.gms.common.internal.IGmsServiceBroker; - -import org.microg.gms.common.api.ConnectionCallbacks; -import org.microg.gms.common.api.OnConnectionFailedListener; - -public abstract class GmsClient implements Api.Client { - private static final String TAG = "GmsClient"; - - private final Context context; - protected final ConnectionCallbacks callbacks; - protected final OnConnectionFailedListener connectionFailedListener; - protected ConnectionState state = ConnectionState.NOT_CONNECTED; - private ServiceConnection serviceConnection; - private I serviceInterface; - private final String actionString; - - protected boolean requireMicrog; - protected String packageName; - - protected int serviceId = -1; - protected Account account = null; - protected Bundle extras = new Bundle(); - - public GmsClient(Context context, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener, String actionString) { - this.context = context; - this.callbacks = callbacks; - this.connectionFailedListener = connectionFailedListener; - this.actionString = actionString; - this.requireMicrog = false; - this.packageName = context.getPackageName(); - } - - protected void onConnectedToBroker(IGmsServiceBroker broker, GmsCallbacks callbacks) throws RemoteException { - if (serviceId == -1) { - throw new IllegalStateException("Service ID not set in constructor and onConnectedToBroker not implemented"); - } - GetServiceRequest request = new GetServiceRequest(serviceId); - request.packageName = packageName; - request.account = account; - request.extras = extras; - broker.getService(callbacks, request); - } - - protected abstract I interfaceFromBinder(IBinder binder); - - @Override - public synchronized void connect() { - Log.d(TAG, "connect()"); - if (state == ConnectionState.CONNECTED || state == ConnectionState.CONNECTING) { - Log.d(TAG, "Already connected/connecting - nothing to do"); - } - state = ConnectionState.CONNECTING; - if (serviceConnection != null) { - MultiConnectionKeeper.getInstance(context).unbind(actionString, serviceConnection); - } - serviceConnection = new GmsServiceConnection(); - if (!MultiConnectionKeeper.getInstance(context).bind(actionString, serviceConnection, requireMicrog)) { - state = ConnectionState.ERROR; - handleConnectionFailed(); - } - } - - public void handleConnectionFailed() { - connectionFailedListener.onConnectionFailed(new ConnectionResult(ConnectionResult.API_UNAVAILABLE, null)); - } - - @Override - public synchronized void disconnect() { - Log.d(TAG, "disconnect()"); - if (state == ConnectionState.DISCONNECTING) return; - if (state == ConnectionState.CONNECTING) { - state = ConnectionState.DISCONNECTING; - return; - } - serviceInterface = null; - if (serviceConnection != null) { - MultiConnectionKeeper.getInstance(context).unbind(actionString, serviceConnection); - serviceConnection = null; - } - state = ConnectionState.NOT_CONNECTED; - } - - @Override - public synchronized boolean isConnected() { - return (state == ConnectionState.CONNECTED && serviceInterface != null && serviceInterface.asBinder().isBinderAlive() ) || state == ConnectionState.PSEUDO_CONNECTED; - } - - @Override - public synchronized boolean isConnecting() { - return state == ConnectionState.CONNECTING; - } - - public synchronized boolean hasError() { - return state == ConnectionState.ERROR; - } - - public Context getContext() { - return context; - } - - public synchronized I getServiceInterface() { - if (isConnecting()) { - // TODO: wait for connection to be established and return afterwards. - throw new IllegalStateException("Waiting for connection"); - } else if (!isConnected()) { - throw new IllegalStateException("interface only available once connected!"); - } - return serviceInterface; - } - - protected enum ConnectionState { - NOT_CONNECTED, CONNECTING, CONNECTED, DISCONNECTING, ERROR, PSEUDO_CONNECTED - } - - private class GmsServiceConnection implements ServiceConnection { - - @Override - public void onServiceConnected(ComponentName componentName, IBinder iBinder) { - try { - Log.d(TAG, "ServiceConnection : onServiceConnected(" + componentName + ")"); - onConnectedToBroker(IGmsServiceBroker.Stub.asInterface(iBinder), new GmsCallbacks()); - } catch (RemoteException e) { - disconnect(); - } - } - - @Override - public void onServiceDisconnected(ComponentName componentName) { - synchronized (GmsClient.this) { - state = ConnectionState.NOT_CONNECTED; - } - } - } - - public class GmsCallbacks extends IGmsCallbacks.Stub { - - @Override - public void onPostInitComplete(int statusCode, IBinder binder, Bundle params) - throws RemoteException { - if (statusCode != CommonStatusCodes.SUCCESS) { - state = ConnectionState.CONNECTED; - disconnect(); - connectionFailedListener.onConnectionFailed(new ConnectionResult(statusCode)); - } else { - synchronized (GmsClient.this) { - if (state == ConnectionState.DISCONNECTING) { - state = ConnectionState.CONNECTED; - disconnect(); - return; - } - state = ConnectionState.CONNECTED; - serviceInterface = interfaceFromBinder(binder); - } - Log.d(TAG, "GmsCallbacks : onPostInitComplete(" + serviceInterface + ")"); - callbacks.onConnected(params); - } - } - - @Override - public void onAccountValidationComplete(int statusCode, Bundle params) throws RemoteException { - Log.d(TAG, "GmsCallbacks : onAccountValidationComplete"); - } - - @Override - public void onPostInitCompleteWithConnectionInfo(int statusCode, IBinder binder, ConnectionInfo info) throws RemoteException { - onPostInitComplete(statusCode, binder, info == null ? null : info.params); - } - } - -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/GmsConnector.java b/play-services-base/src/main/java/org/microg/gms/common/GmsConnector.java deleted file mode 100644 index b77c6d2c..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/GmsConnector.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.common; - -import android.os.Looper; -import android.os.Message; -import android.os.RemoteException; -import android.util.Log; - -import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.GoogleApiClient; -import com.google.android.gms.common.api.PendingResult; -import com.google.android.gms.common.api.Result; - -import org.microg.gms.common.api.AbstractPendingResult; -import org.microg.gms.common.api.GoogleApiClientImpl; - -public class GmsConnector { - private static final String TAG = "GmsConnector"; - - private final GoogleApiClientImpl apiClient; - private final Api api; - private final Callback callback; - - public GmsConnector(GoogleApiClient apiClient, Api api, Callback callback) { - this.apiClient = (GoogleApiClientImpl) apiClient; - this.api = api; - this.callback = callback; - } - - public static PendingResult call(GoogleApiClient client, Api api, GmsConnector.Callback callback) { - return new GmsConnector(client, api, callback).connect(); - } - - public AbstractPendingResult connect() { - Log.d(TAG, "connect()"); - apiClient.incrementUsageCounter(); - apiClient.getApiConnection(api); - Looper looper = apiClient.getLooper(); - final AbstractPendingResult result = new AbstractPendingResult(looper); - Message msg = new Message(); - msg.obj = result; - new Handler(looper).sendMessage(msg); - return result; - } - - public interface Callback { - void onClientAvailable(C client, ResultProvider resultProvider) throws RemoteException; - - interface ResultProvider { - void onResultAvailable(R result); - } - } - - private class Handler extends android.os.Handler { - private Handler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - Log.d(TAG, "Handler : handleMessage"); - final AbstractPendingResult result = (AbstractPendingResult) msg.obj; - try { - C connection = (C) apiClient.getApiConnection(api); - callback.onClientAvailable(connection, new GmsConnector.Callback.ResultProvider() { - @Override - public void onResultAvailable(R realResult) { - result.deliverResult(realResult); - apiClient.decrementUsageCounter(); - } - }); - } catch (RemoteException ignored) { - - } - } - } -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/MultiConnectionKeeper.java b/play-services-base/src/main/java/org/microg/gms/common/MultiConnectionKeeper.java deleted file mode 100644 index 616224bf..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/MultiConnectionKeeper.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.common; - -import android.annotation.SuppressLint; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PermissionInfo; -import android.content.pm.ResolveInfo; -import android.os.IBinder; -import android.util.Log; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static org.microg.gms.common.Constants.GMS_PACKAGE_NAME; - -public class MultiConnectionKeeper { - private static final String TAG = "GmsMultiConKeeper"; - - private static MultiConnectionKeeper INSTANCE; - - private final Context context; - private final Map connections = new HashMap(); - - public MultiConnectionKeeper(Context context) { - this.context = context; - } - - public synchronized static MultiConnectionKeeper getInstance(Context context) { - if (INSTANCE == null) - INSTANCE = new MultiConnectionKeeper(context.getApplicationContext()); - return INSTANCE; - } - - public synchronized boolean bind(String action, ServiceConnection connection) { - return bind(action, connection, false); - } - - public synchronized boolean bind(String action, ServiceConnection connection, boolean requireMicrog) { - Connection con = connections.get(action); - Log.d(TAG, "bind(" + action + ", " + connection + ", " + requireMicrog + ") has=" + (con != null)); - if (con != null) { - if (!con.forwardsConnection(connection)) { - con.addConnectionForward(connection); - if (!con.isBound()) - con.bind(); - } - } else { - con = new Connection(action, requireMicrog); - con.addConnectionForward(connection); - con.bind(); - connections.put(action, con); - } - Log.d(TAG, "bind() : bound=" + con.isBound()); - return con.isBound(); - } - - public synchronized void unbind(String action, ServiceConnection connection) { - Log.d(TAG, "unbind(" + action + ", " + connection + ")"); - Connection con = connections.get(action); - if (con != null) { - con.removeConnectionForward(connection); - if (con.isBound()) { - if (!con.hasForwards()) { - con.unbind(); - connections.remove(action); - } else { - Log.d(TAG, "Not unbinding for " + connection + ": has pending other bindings on action " + action); - } - } - } - } - - public class Connection { - private final String actionString; - private final boolean requireMicrog; - private final Set connectionForwards = new HashSet(); - private boolean bound = false; - private boolean connected = false; - private IBinder binder; - private ComponentName component; - private ServiceConnection serviceConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName componentName, IBinder iBinder) { - Log.d(TAG, "Connection(" + actionString + ") : ServiceConnection : " + - "onServiceConnected(" + componentName + ")"); - binder = iBinder; - component = componentName; - for (ServiceConnection connection : connectionForwards) { - connection.onServiceConnected(componentName, iBinder); - } - connected = true; - } - - @Override - public void onServiceDisconnected(ComponentName componentName) { - Log.d(TAG, "Connection(" + actionString + ") : ServiceConnection : " + - "onServiceDisconnected(" + componentName + ")"); - binder = null; - component = componentName; - for (ServiceConnection connection : connectionForwards) { - connection.onServiceDisconnected(componentName); - } - connected = false; - bound = false; - } - }; - - public Connection(String actionString) { - this(actionString, false); - } - - public Connection(String actionString, boolean requireMicrog) { - this.actionString = actionString; - this.requireMicrog = requireMicrog; - } - - @SuppressLint("InlinedApi") - public void bind() { - Log.d(TAG, "Connection(" + actionString + ") : bind()"); - Intent gmsIntent = new Intent(actionString).setPackage(GMS_PACKAGE_NAME); - Intent selfIntent = new Intent(actionString).setPackage(context.getPackageName()); - Intent intent; - ResolveInfo resolveInfo; - if ((resolveInfo = context.getPackageManager().resolveService(gmsIntent, 0)) == null) { - Log.w(TAG, "No GMS service found for " + actionString); - if (context.getPackageManager().resolveService(selfIntent, 0) != null) { - Log.d(TAG, "Found service for " + actionString + " in self package, using it instead"); - intent = selfIntent; - } else { - return; - } - } else if (requireMicrog && !isMicrog(resolveInfo)) { - Log.w(TAG, "GMS service found for " + actionString + " but looks not like microG"); - if (context.getPackageManager().resolveService(selfIntent, 0) != null) { - Log.d(TAG, "Found service for " + actionString + " in self package, using it instead"); - intent = selfIntent; - } else { - intent = gmsIntent; - } - } else { - intent = gmsIntent; - } - int flags = Context.BIND_AUTO_CREATE | Context.BIND_DEBUG_UNBIND | Context.BIND_ADJUST_WITH_ACTIVITY; - bound = context.bindService(intent, serviceConnection, flags); - Log.d(TAG, "Connection(" + actionString + ") : bind() : bindService=" + bound); - if (!bound) { - context.unbindService(serviceConnection); - } - } - - public boolean isMicrog(ResolveInfo resolveInfo) { - if (resolveInfo == null || resolveInfo.serviceInfo == null) return false; - if (resolveInfo.serviceInfo.name.startsWith("org.microg.")) return true; - try { - PermissionInfo info = context.getPackageManager().getPermissionInfo("org.microg.gms.EXTENDED_ACCESS", 0); - return info.packageName.equals(resolveInfo.serviceInfo.packageName); - } catch (PackageManager.NameNotFoundException e) { - return false; - } - } - - public boolean isBound() { - return bound; - } - - public IBinder getBinder() { - return binder; - } - - public void unbind() { - Log.d(TAG, "Connection(" + actionString + ") : unbind()"); - try { - context.unbindService(serviceConnection); - } catch (IllegalArgumentException e) { // not bound (whatever reason) - Log.w(TAG, e); - } - bound = false; - } - - public void addConnectionForward(ServiceConnection connection) { - connectionForwards.add(connection); - if (connected) { - connection.onServiceConnected(component, binder); - } - } - - public void removeConnectionForward(ServiceConnection connection) { - connectionForwards.remove(connection); - if (connected) { - connection.onServiceDisconnected(component); - } - } - - public boolean forwardsConnection(ServiceConnection connection) { - return connectionForwards.contains(connection); - } - - public boolean hasForwards() { - return !connectionForwards.isEmpty(); - } - } -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/AbstractPendingResult.java b/play-services-base/src/main/java/org/microg/gms/common/api/AbstractPendingResult.java index 15aac9e3..cea4229b 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/AbstractPendingResult.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/AbstractPendingResult.java @@ -19,93 +19,11 @@ package org.microg.gms.common.api; import android.os.Looper; import com.google.android.gms.common.api.PendingResult; -import com.google.android.gms.common.api.Result; -import com.google.android.gms.common.api.ResultCallback; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class AbstractPendingResult implements PendingResult { - private final Object lock = new Object(); - private final CountDownLatch countDownLatch = new CountDownLatch(1); - private final ResultCallbackHandler handler; - private boolean canceled; - private R result; - private ResultCallback resultCallback; +public class AbstractPendingResult implements PendingResult { public AbstractPendingResult(Looper looper) { - handler = new ResultCallbackHandler(looper); + new ResultCallbackHandler<>(looper); } - private R getResult() { - synchronized (lock) { - return result; - } - } - - @Override - public R await() { - try { - countDownLatch.await(); - } catch (InterruptedException ignored) { - } - return getResult(); - } - - @Override - public R await(long time, TimeUnit unit) { - try { - countDownLatch.await(time, unit); - } catch (InterruptedException ignored) { - } - return getResult(); - } - - @Override - public void cancel() { - // TODO - } - - @Override - public boolean isCanceled() { - synchronized (lock) { - return canceled; - } - } - - public boolean isReady() { - return this.countDownLatch.getCount() == 0L; - } - - @Override - public void setResultCallback(ResultCallback callback, long time, TimeUnit unit) { - synchronized (lock) { - if (!isCanceled()) { - if (isReady()) { - handler.sendResultCallback(callback, getResult()); - } else { - handler.sendTimeoutResultCallback(this, unit.toMillis(time)); - } - } - } - } - - @Override - public void setResultCallback(ResultCallback callback) { - synchronized (lock) { - if (!isCanceled()) { - if (isReady()) { - handler.sendResultCallback(callback, getResult()); - } else { - resultCallback = callback; - } - } - } - } - - public void deliverResult(R result) { - this.result = result; - countDownLatch.countDown(); - - } } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/AbstractPlayServicesClient.java b/play-services-base/src/main/java/org/microg/gms/common/api/AbstractPlayServicesClient.java deleted file mode 100644 index eb9d66bd..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/api/AbstractPlayServicesClient.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.common.api; - -import android.util.Log; - -import com.google.android.gms.common.GooglePlayServicesClient; -import com.google.android.gms.common.api.GoogleApiClient; - -import org.microg.gms.common.ForwardConnectionCallbacks; -import org.microg.gms.common.ForwardConnectionFailedListener; - -public class AbstractPlayServicesClient implements GooglePlayServicesClient { - private static final String TAG = "GmsPlayServicesClient"; - - protected final GoogleApiClient googleApiClient; - - public AbstractPlayServicesClient(GoogleApiClient googleApiClient) { - this.googleApiClient = googleApiClient; - } - - public void assertConnected() { - if (!isConnected()) throw new IllegalStateException("Not connected!"); - } - - @Override - public void connect() { - Log.d(TAG, "connect()"); - googleApiClient.connect(); - } - - @Override - public void disconnect() { - Log.d(TAG, "disconnect()"); - //TODO googleApiClient.disconnect(); - } - - @Override - public boolean isConnected() { - return googleApiClient.isConnected(); - } - - @Override - public boolean isConnecting() { - return googleApiClient.isConnecting(); - } - - @Override - public void registerConnectionCallbacks(final ConnectionCallbacks listener) { - googleApiClient.registerConnectionCallbacks(new ForwardConnectionCallbacks(listener)); - } - - @Override - public boolean isConnectionCallbacksRegistered(ConnectionCallbacks listener) { - return googleApiClient - .isConnectionCallbacksRegistered(new ForwardConnectionCallbacks(listener)); - } - - @Override - public void unregisterConnectionCallbacks( - ConnectionCallbacks listener) { - googleApiClient.unregisterConnectionCallbacks(new ForwardConnectionCallbacks(listener)); - } - - @Override - public void registerConnectionFailedListener( - OnConnectionFailedListener listener) { - googleApiClient.registerConnectionFailedListener( - new ForwardConnectionFailedListener(listener)); - } - - @Override - public boolean isConnectionFailedListenerRegistered( - OnConnectionFailedListener listener) { - return googleApiClient.isConnectionFailedListenerRegistered( - new ForwardConnectionFailedListener(listener)); - } - - @Override - public void unregisterConnectionFailedListener( - OnConnectionFailedListener listener) { - googleApiClient.unregisterConnectionFailedListener( - new ForwardConnectionFailedListener(listener)); - } -} diff --git a/play-services-api/src/main/java/com/google/android/gms/identity/accounts/api/AccountData.java b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClient.java similarity index 78% rename from play-services-api/src/main/java/com/google/android/gms/identity/accounts/api/AccountData.java rename to play-services-base/src/main/java/org/microg/gms/common/api/ApiClient.java index d909cbf3..602e150e 100644 --- a/play-services-api/src/main/java/com/google/android/gms/identity/accounts/api/AccountData.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClient.java @@ -14,7 +14,14 @@ * limitations under the License. */ -package com.google.android.gms.identity.accounts.api; +package org.microg.gms.common.api; -public class AccountData { +public interface ApiClient { + void connect(); + + void disconnect(); + + boolean isConnected(); + + boolean isConnecting(); } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientBuilder.java b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientBuilder.java index 18336fa5..b5aa386f 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientBuilder.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientBuilder.java @@ -22,5 +22,5 @@ import android.os.Looper; import com.google.android.gms.common.api.Api; public interface ApiClientBuilder { - Api.Client build(O options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener); + ApiClient build(O options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener); } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientSettings.java b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientSettings.java index af67e799..d1e314a7 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientSettings.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/ApiClientSettings.java @@ -5,15 +5,5 @@ package org.microg.gms.common.api; -import android.view.View; - -import java.util.Set; - public class ApiClientSettings { - public String accountName; - public String packageName; - public Integer sessionId; - public Set scopes; - public int gravityForPopups; - public View viewForPopups; } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiClientImpl.java b/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiClientImpl.java index 2dffa374..371a6555 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiClientImpl.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiClientImpl.java @@ -19,117 +19,59 @@ package org.microg.gms.common.api; import android.content.Context; import android.os.Bundle; import android.os.Looper; - -import androidx.fragment.app.FragmentActivity; - import android.util.Log; -import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.Api; import com.google.android.gms.common.api.GoogleApiClient; -import com.google.android.gms.common.api.PendingResult; -import com.google.android.gms.common.api.Status; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.concurrent.TimeUnit; public class GoogleApiClientImpl implements GoogleApiClient { private static final String TAG = "GmsApiClientImpl"; - private final Context context; - private final Looper looper; - private final ApiClientSettings clientSettings; - private final Map apis = new HashMap(); - private final Map apiConnections = new HashMap(); - private final Set connectionCallbacks = new HashSet(); - private final Set connectionFailedListeners = new HashSet(); - private final int clientId; - private final ConnectionCallbacks baseConnectionCallbacks = new ConnectionCallbacks() { - @Override - public void onConnected(Bundle connectionHint) { - Log.d(TAG, "ConnectionCallbacks : onConnected()"); - for (ConnectionCallbacks callback : connectionCallbacks) { - callback.onConnected(connectionHint); - } - } - - @Override - public void onConnectionSuspended(int cause) { - Log.d(TAG, "ConnectionCallbacks : onConnectionSuspended()"); - for (ConnectionCallbacks callback : connectionCallbacks) { - callback.onConnectionSuspended(cause); - } - } - }; - private final OnConnectionFailedListener baseConnectionFailedListener = new - OnConnectionFailedListener() { - @Override - public void onConnectionFailed(ConnectionResult result) { - Log.d(TAG, "OnConnectionFailedListener : onConnectionFailed()"); - for (OnConnectionFailedListener listener : connectionFailedListeners) { - listener.onConnectionFailed(result); - } - } - }; - private int usageCounter = 0; + private final Map apiConnections = new HashMap<>(); + private final Set connectionCallbacks = new HashSet<>(); + private final Set connectionFailedListeners = new HashSet<>(); private boolean shouldDisconnect = false; public GoogleApiClientImpl(Context context, Looper looper, ApiClientSettings clientSettings, Map apis, Set connectionCallbacks, - Set connectionFailedListeners, int clientId) { - this.context = context; - this.looper = looper; - this.clientSettings = clientSettings; - this.apis.putAll(apis); + Set connectionFailedListeners) { this.connectionCallbacks.addAll(connectionCallbacks); this.connectionFailedListeners.addAll(connectionFailedListeners); - this.clientId = clientId; - - if (this.clientSettings.sessionId == null) { - this.clientSettings.sessionId = hashCode(); - } for (Api api : apis.keySet()) { + ConnectionCallbacks baseConnectionCallbacks = new ConnectionCallbacks() { + @Override + public void onConnected(Bundle connectionHint) { + Log.d(TAG, "ConnectionCallbacks : onConnected()"); + for (ConnectionCallbacks callback : connectionCallbacks) { + callback.onConnected(connectionHint); + } + } + + @Override + public void onConnectionSuspended(int cause) { + Log.d(TAG, "ConnectionCallbacks : onConnectionSuspended()"); + for (ConnectionCallbacks callback : connectionCallbacks) { + callback.onConnectionSuspended(cause); + } + } + }; + OnConnectionFailedListener baseConnectionFailedListener = result -> { + Log.d(TAG, "OnConnectionFailedListener : onConnectionFailed()"); + for (OnConnectionFailedListener listener : connectionFailedListeners) { + listener.onConnectionFailed(result); + } + }; apiConnections.put(api, api.getBuilder().build(apis.get(api), context, looper, clientSettings, baseConnectionCallbacks, baseConnectionFailedListener)); } } - public synchronized void incrementUsageCounter() { - usageCounter++; - } - - public synchronized void decrementUsageCounter() { - usageCounter--; - if (shouldDisconnect) disconnect(); - } - - public Looper getLooper() { - return looper; - } - - public Api.Client getApiConnection(Api api) { - return apiConnections.get(api); - } - - @Override - public ConnectionResult blockingConnect() { - return null; - } - - @Override - public ConnectionResult blockingConnect(long timeout, TimeUnit unit) { - return null; - } - - @Override - public PendingResult clearDefaultAccountAndReconnect() { - return null; - } - @Override public synchronized void connect() { Log.d(TAG, "connect()"); @@ -141,7 +83,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { Log.d(TAG, "Already connected/connecting, nothing to do"); return; } - for (Api.Client connection : apiConnections.values()) { + for (ApiClient connection : apiConnections.values()) { if (!connection.isConnected()) { connection.connect(); } @@ -150,21 +92,17 @@ public class GoogleApiClientImpl implements GoogleApiClient { @Override public synchronized void disconnect() { - if (usageCounter > 0) { - shouldDisconnect = true; - } else { - Log.d(TAG, "disconnect()"); - for (Api.Client connection : apiConnections.values()) { - if (connection.isConnected()) { - connection.disconnect(); - } + Log.d(TAG, "disconnect()"); + for (ApiClient connection : apiConnections.values()) { + if (connection.isConnected()) { + connection.disconnect(); } } } @Override public synchronized boolean isConnected() { - for (Api.Client connection : apiConnections.values()) { + for (ApiClient connection : apiConnections.values()) { if (!connection.isConnected()) return false; } return true; @@ -172,7 +110,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { @Override public synchronized boolean isConnecting() { - for (Api.Client connection : apiConnections.values()) { + for (ApiClient connection : apiConnections.values()) { if (connection.isConnecting()) return true; } return false; @@ -189,13 +127,6 @@ public class GoogleApiClientImpl implements GoogleApiClient { return connectionFailedListeners.contains(listener); } - @Override - public synchronized void reconnect() { - Log.d(TAG, "reconnect()"); - disconnect(); - connect(); - } - @Override public void registerConnectionCallbacks(ConnectionCallbacks listener) { connectionCallbacks.add(listener); @@ -206,18 +137,9 @@ public class GoogleApiClientImpl implements GoogleApiClient { connectionFailedListeners.add(listener); } - @Override - public void stopAutoManager(FragmentActivity lifecycleActivity) throws IllegalStateException { - - } - @Override public void unregisterConnectionCallbacks(ConnectionCallbacks listener) { connectionCallbacks.remove(listener); } - @Override - public void unregisterConnectionFailedListener(OnConnectionFailedListener listener) { - connectionFailedListeners.remove(listener); - } } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiManager.java b/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiManager.java index 5cf7933e..a5fa2545 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiManager.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/GoogleApiManager.java @@ -5,185 +5,17 @@ package org.microg.gms.common.api; -import android.content.Context; -import android.os.Bundle; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.api.Api; -import com.google.android.gms.common.api.GoogleApi; -import com.google.android.gms.tasks.Task; -import com.google.android.gms.tasks.TaskCompletionSource; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import android.annotation.SuppressLint; public class GoogleApiManager { + @SuppressLint("StaticFieldLeak") private static GoogleApiManager instance; - private Context context; - private Map clientMap = new HashMap<>(); - private Map>> waitingApiCallMap = new HashMap<>(); - private GoogleApiManager(Context context) { - this.context = context; + private GoogleApiManager() { } - public synchronized static GoogleApiManager getInstance(Context context) { - if (instance == null) instance = new GoogleApiManager(context); - return instance; + public synchronized static void getInstance() { + if (instance == null) instance = new GoogleApiManager(); } - private synchronized A clientForApi(GoogleApi api) { - ApiInstance apiInstance = new ApiInstance(api); - if (clientMap.containsKey(apiInstance)) { - return (A) clientMap.get(apiInstance); - } else { - Api.Client client = api.api.getBuilder().build(api.getOptions(), context, context.getMainLooper(), null, new ConnectionCallback(apiInstance), new ConnectionFailedListener(apiInstance)); - clientMap.put(apiInstance, client); - waitingApiCallMap.put(apiInstance, new ArrayList<>()); - return (A) client; - } - } - - public synchronized void scheduleTask(GoogleApi api, PendingGoogleApiCall apiCall, TaskCompletionSource completionSource) { - A client = clientForApi(api); - boolean connecting = client.isConnecting(); - boolean connected = client.isConnected(); - if (connected) { - try { - apiCall.execute(client, completionSource); - } catch (Exception e) { - completionSource.setException(e); - } - } else { - waitingApiCallMap.get(new ApiInstance(api)).add(new WaitingApiCall((PendingGoogleApiCall) apiCall, completionSource)); - if (!connecting) { - client.connect(); - } - } - } - - private synchronized void onInstanceConnected(ApiInstance apiInstance, Bundle connectionHint) { - List> waitingApiCalls = waitingApiCallMap.get(apiInstance); - for (WaitingApiCall waitingApiCall : waitingApiCalls) { - try { - waitingApiCall.execute(clientMap.get(apiInstance)); - } catch (Exception e) { - waitingApiCall.failed(e); - } - } - waitingApiCalls.clear(); - } - - private synchronized void onInstanceSuspended(ApiInstance apiInstance, int cause) { - - } - - private synchronized void onInstanceFailed(ApiInstance apiInstance, ConnectionResult result) { - List> waitingApiCalls = waitingApiCallMap.get(apiInstance); - for (WaitingApiCall waitingApiCall : waitingApiCalls) { - waitingApiCall.failed(new RuntimeException(result.getErrorMessage())); - } - waitingApiCalls.clear(); - } - - private class ConnectionCallback implements ConnectionCallbacks { - private ApiInstance apiInstance; - - public ConnectionCallback(ApiInstance apiInstance) { - this.apiInstance = apiInstance; - } - - @Override - public void onConnected(Bundle connectionHint) { - onInstanceConnected(apiInstance, connectionHint); - } - - @Override - public void onConnectionSuspended(int cause) { - onInstanceSuspended(apiInstance, cause); - } - } - - private class ConnectionFailedListener implements OnConnectionFailedListener { - private ApiInstance apiInstance; - - public ConnectionFailedListener(ApiInstance apiInstance) { - this.apiInstance = apiInstance; - } - - @Override - public void onConnectionFailed(ConnectionResult result) { - onInstanceFailed(apiInstance, result); - } - } - - private static class WaitingApiCall { - private PendingGoogleApiCall apiCall; - private TaskCompletionSource completionSource; - - public WaitingApiCall(PendingGoogleApiCall apiCall, TaskCompletionSource completionSource) { - this.apiCall = apiCall; - this.completionSource = completionSource; - } - - public void execute(Api.Client client) throws Exception { - apiCall.execute(client, completionSource); - } - - public void failed(Exception e) { - completionSource.setException(e); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - WaitingApiCall that = (WaitingApiCall) o; - - if (apiCall != null ? !apiCall.equals(that.apiCall) : that.apiCall != null) return false; - return completionSource != null ? completionSource.equals(that.completionSource) : that.completionSource == null; - } - - @Override - public int hashCode() { - int result = apiCall != null ? apiCall.hashCode() : 0; - result = 31 * result + (completionSource != null ? completionSource.hashCode() : 0); - return result; - } - } - - private static class ApiInstance { - private Class apiClass; - private Api.ApiOptions apiOptions; - - public ApiInstance(Class apiClass, Api.ApiOptions apiOptions) { - this.apiClass = apiClass; - this.apiOptions = apiOptions; - } - - public ApiInstance(GoogleApi api) { - this(api.getClass(), api.getOptions()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ApiInstance that = (ApiInstance) o; - - if (apiClass != null ? !apiClass.equals(that.apiClass) : that.apiClass != null) return false; - return apiOptions != null ? apiOptions.equals(that.apiOptions) : that.apiOptions == null; - } - - @Override - public int hashCode() { - int result = apiClass != null ? apiClass.hashCode() : 0; - result = 31 * result + (apiOptions != null ? apiOptions.hashCode() : 0); - return result; - } - } } diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/InstantPendingResult.java b/play-services-base/src/main/java/org/microg/gms/common/api/InstantPendingResult.java deleted file mode 100644 index ba75725c..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/api/InstantPendingResult.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.common.api; - -import com.google.android.gms.common.api.PendingResult; -import com.google.android.gms.common.api.Result; -import com.google.android.gms.common.api.ResultCallback; - -import java.util.concurrent.TimeUnit; - -public class InstantPendingResult implements PendingResult { - R value; - - public InstantPendingResult(R value) { - this.value = value; - } - - @Override - public R await() { - return value; - } - - @Override - public R await(long time, TimeUnit unit) { - return value; - } - - @Override - public void cancel() { - - } - - @Override - public boolean isCanceled() { - return false; - } - - @Override - public void setResultCallback(ResultCallback callback, long time, TimeUnit unit) { - callback.onResult(value); - } - - @Override - public void setResultCallback(ResultCallback callback) { - callback.onResult(value); - } -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/PendingGoogleApiCall.java b/play-services-base/src/main/java/org/microg/gms/common/api/PendingGoogleApiCall.java deleted file mode 100644 index 578d02b9..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/api/PendingGoogleApiCall.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.common.api; - -import com.google.android.gms.common.api.Api; -import com.google.android.gms.tasks.TaskCompletionSource; - -public interface PendingGoogleApiCall { - void execute(A client, TaskCompletionSource completionSource) throws Exception; -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/ResultCallbackHandler.java b/play-services-base/src/main/java/org/microg/gms/common/api/ResultCallbackHandler.java index c19c849c..a737a076 100644 --- a/play-services-base/src/main/java/org/microg/gms/common/api/ResultCallbackHandler.java +++ b/play-services-base/src/main/java/org/microg/gms/common/api/ResultCallbackHandler.java @@ -47,17 +47,6 @@ class ResultCallbackHandler extends Handler { } } - public void sendResultCallback(ResultCallback callback, R result) { - Message message = new Message(); - message.what = CALLBACK_ON_COMPLETE; - message.obj = new OnCompleteObject(callback, result); - sendMessage(message); - } - - public void sendTimeoutResultCallback(AbstractPendingResult pendingResult, long millis) { - - } - public static class OnCompleteObject { public ResultCallback callback; public R result; diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/ReturningGoogleApiCall.java b/play-services-base/src/main/java/org/microg/gms/common/api/ReturningGoogleApiCall.java deleted file mode 100644 index f836b9d4..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/api/ReturningGoogleApiCall.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.common.api; - -import com.google.android.gms.common.api.Api; -import com.google.android.gms.tasks.TaskCompletionSource; - -public interface ReturningGoogleApiCall extends PendingGoogleApiCall { - R execute(A client) throws Exception; - - @Override - default void execute(A client, TaskCompletionSource completionSource) { - try { - completionSource.setResult(execute(client)); - } catch (Exception e) { - completionSource.setException(e); - } - } -} diff --git a/play-services-base/src/main/java/org/microg/gms/common/api/VoidReturningGoogleApiCall.java b/play-services-base/src/main/java/org/microg/gms/common/api/VoidReturningGoogleApiCall.java deleted file mode 100644 index ee8cbf66..00000000 --- a/play-services-base/src/main/java/org/microg/gms/common/api/VoidReturningGoogleApiCall.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.common.api; - -import com.google.android.gms.common.api.Api; -import com.google.android.gms.tasks.TaskCompletionSource; - -public interface VoidReturningGoogleApiCall extends PendingGoogleApiCall{ - void execute(A client) throws Exception; - - @Override - default void execute(A client, TaskCompletionSource completionSource) { - try { - execute(client); - completionSource.setResult(null); - } catch (Exception e) { - completionSource.setException(e); - } - } -} diff --git a/play-services-basement/build.gradle b/play-services-basement/build.gradle index 9884e3c9..8971fb98 100644 --- a/play-services-basement/build.gradle +++ b/play-services-basement/build.gradle @@ -18,12 +18,12 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' dependencies { - api "org.microg:safe-parcel:$safeParcelVersion" + api "org.microg:safe-parcel:1.7.0" // Dependencies from play-services-basement:18.0.0 api "androidx.collection:collection:$collectionVersion" - api "androidx.core:core:$coreVersion" - api "androidx.fragment:fragment:$fragmentVersion" + api "androidx.core:core-ktx:$coreVersion" + api "androidx.fragment:fragment-ktx:$fragmentVersion" } android { @@ -39,7 +39,6 @@ android { minSdkVersion androidMinSdk targetSdkVersion androidTargetSdk buildConfigField "int", "VERSION_CODE", "$appVersionCode" - buildConfigField "String", "BASE_PACKAGE_NAME", "\"$basePackageName\"" } buildFeatures { diff --git a/play-services-basement/src/main/AndroidManifest.xml b/play-services-basement/src/main/AndroidManifest.xml deleted file mode 100644 index 359a9b71..00000000 --- a/play-services-basement/src/main/AndroidManifest.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/ConnectionResult.aidl b/play-services-basement/src/main/aidl/com/google/android/gms/common/ConnectionResult.aidl deleted file mode 100644 index e46e6d5d..00000000 --- a/play-services-basement/src/main/aidl/com/google/android/gms/common/ConnectionResult.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.google.android.gms.common; - -parcelable ConnectionResult; \ No newline at end of file diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesLookupQuery.aidl b/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesLookupQuery.aidl deleted file mode 100644 index fab15aa1..00000000 --- a/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesLookupQuery.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.google.android.gms.common; - -parcelable GoogleCertificatesLookupQuery; \ No newline at end of file diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesLookupResponse.aidl b/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesLookupResponse.aidl deleted file mode 100644 index e9b4bff3..00000000 --- a/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesLookupResponse.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.google.android.gms.common; - -parcelable GoogleCertificatesLookupResponse; \ No newline at end of file diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesQuery.aidl b/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesQuery.aidl deleted file mode 100644 index e6aedfef..00000000 --- a/play-services-basement/src/main/aidl/com/google/android/gms/common/GoogleCertificatesQuery.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.google.android.gms.common; - -parcelable GoogleCertificatesQuery; \ No newline at end of file diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ConnectionInfo.aidl b/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ConnectionInfo.aidl deleted file mode 100644 index b393f11d..00000000 --- a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/ConnectionInfo.aidl +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common.internal; -parcelable ConnectionInfo; diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/IGmsCallbacks.aidl b/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/IGmsCallbacks.aidl index 8fe63347..b0210281 100644 --- a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/IGmsCallbacks.aidl +++ b/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/IGmsCallbacks.aidl @@ -1,15 +1,7 @@ -/* - * SPDX-FileCopyrightText: 2020, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - package com.google.android.gms.common.internal; import android.os.Bundle; -import com.google.android.gms.common.internal.ConnectionInfo; interface IGmsCallbacks { void onPostInitComplete(int statusCode, IBinder binder, in Bundle params); - void onAccountValidationComplete(int statusCode, in Bundle params); - void onPostInitCompleteWithConnectionInfo(int statusCode, IBinder binder, in ConnectionInfo info); } diff --git a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/IGoogleCertificatesApi.aidl b/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/IGoogleCertificatesApi.aidl deleted file mode 100644 index 6d54ad26..00000000 --- a/play-services-basement/src/main/aidl/com/google/android/gms/common/internal/IGoogleCertificatesApi.aidl +++ /dev/null @@ -1,18 +0,0 @@ -package com.google.android.gms.common.internal; - -import com.google.android.gms.common.GoogleCertificatesLookupQuery; -import com.google.android.gms.common.GoogleCertificatesLookupResponse; -import com.google.android.gms.common.GoogleCertificatesQuery; -import com.google.android.gms.dynamic.IObjectWrapper; - -interface IGoogleCertificatesApi { - IObjectWrapper getGoogleCertificates() = 0; - IObjectWrapper getGoogleReleaseCertificates() = 1; - boolean isGoogleReleaseSigned(String packageName, IObjectWrapper certData) = 2; - boolean isGoogleSigned(String packageName, IObjectWrapper certData) = 3; - boolean isGoogleOrPlatformSigned(in GoogleCertificatesQuery query, IObjectWrapper packageManager) = 4; - GoogleCertificatesLookupResponse isPackageGoogleOrPlatformSigned(in GoogleCertificatesLookupQuery query) = 5; - boolean isPackageGoogleOrPlatformSignedAvailable() = 6; - GoogleCertificatesLookupResponse queryPackageSigned(in GoogleCertificatesLookupQuery query) = 7; - boolean isFineGrainedPackageVerificationAvailable() = 8; -} \ No newline at end of file diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/ConnectionResult.java b/play-services-basement/src/main/java/com/google/android/gms/common/ConnectionResult.java index f3272de8..23ebfb81 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/common/ConnectionResult.java +++ b/play-services-basement/src/main/java/com/google/android/gms/common/ConnectionResult.java @@ -18,7 +18,6 @@ package com.google.android.gms.common; import android.app.Activity; import android.app.PendingIntent; -import android.content.Intent; import android.content.IntentSender; import android.text.TextUtils; @@ -239,35 +238,6 @@ public class ConnectionResult { } } - /** - * Indicates the type of error that interrupted connection. - * - * @return the error code, or {@link #SUCCESS} if no error occurred. - */ - public int getErrorCode() { - return statusCode; - } - - /** - * Returns an error message for connection result. - * - * @return the message - */ - public String getErrorMessage() { - return message; - } - - /** - * A pending intent to resolve the connection failure. This intent can be started with - * {@link Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int)} to - * present UI to solve the issue. - * - * @return The pending intent to resolve the connection failure. - */ - public PendingIntent getResolution() { - return pendingIntent; - } - @Override public int hashCode() { return Arrays.hashCode(new Object[]{statusCode, pendingIntent, message}); @@ -283,15 +253,6 @@ public class ConnectionResult { return statusCode != 0 && pendingIntent != null; } - /** - * Returns {@code true} if the connection was successful. - * - * @return {@code true} if the connection was successful, {@code false} if there was an error. - */ - public boolean isSuccess() { - return statusCode == 0; - } - /** * Resolves an error by starting any intents requiring user interaction. See * {@link #SIGN_IN_REQUIRED}, and {@link #RESOLUTION_REQUIRED}. diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesLookupQuery.java b/play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesLookupQuery.java deleted file mode 100644 index ab8da97a..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesLookupQuery.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common; - -import android.content.Context; -import android.os.Parcel; -import androidx.annotation.NonNull; -import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter; -import com.google.android.gms.dynamic.IObjectWrapper; -import com.google.android.gms.dynamic.ObjectWrapper; - -@SafeParcelable.Class -public class GoogleCertificatesLookupQuery extends AbstractSafeParcelable { - @Field(value = 1, getterName = "getCallingPackage") - String callingPackage; - @Field(2) - boolean allowTestKeys; - @Field(3) - boolean ignoreTestKeysOverride; - @Field(4) - IObjectWrapper contextWrapper; - private Context context; - @Field(5) - boolean isChimeraPackage; - @Field(6) - boolean includeHashesInErrorMessage; - - public String getCallingPackage() { - return callingPackage; - } - - public Context getContext() { - if (context == null && contextWrapper != null) { - context = ObjectWrapper.unwrapTyped(contextWrapper, Context.class); - } - return context; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - CREATOR.writeToParcel(this, dest, flags); - } - - public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(GoogleCertificatesLookupQuery.class); -} diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesLookupResponse.java b/play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesLookupResponse.java deleted file mode 100644 index 90e0ee3a..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/GoogleCertificatesLookupResponse.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common; - -import android.os.Parcel; -import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter; - -@SafeParcelable.Class -public class GoogleCertificatesLookupResponse extends AbstractSafeParcelable { - @Field(1) - public final boolean result; - @Field(2) - public final String errorMessage; - @Field(3) - public final int statusValue; - @Field(4) - public final int firstPartyStatusValue; - - @Constructor - public GoogleCertificatesLookupResponse(@Param(1) boolean result, @Param(2) String errorMessage, @Param(3) int statusValue, @Param(4) int firstPartyStatusValue) { - this.result = result; - this.errorMessage = errorMessage; - this.statusValue = statusValue; - this.firstPartyStatusValue = firstPartyStatusValue; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - CREATOR.writeToParcel(this, out, flags); - } - - public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(GoogleCertificatesLookupResponse.class); -} diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/Scopes.java b/play-services-basement/src/main/java/com/google/android/gms/common/Scopes.java deleted file mode 100644 index 520bef02..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/Scopes.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.gms.common; - -public class Scopes { - public static final String PROFILE = "profile"; - public static final String APP_STATE = "https://www.googleapis.com/auth/appstate"; -} diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/api/CommonStatusCodes.java b/play-services-basement/src/main/java/com/google/android/gms/common/api/CommonStatusCodes.java index 6a2cbb51..984c6fce 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/common/api/CommonStatusCodes.java +++ b/play-services-basement/src/main/java/com/google/android/gms/common/api/CommonStatusCodes.java @@ -16,13 +16,10 @@ package com.google.android.gms.common.api; -import androidx.annotation.NonNull; - import org.microg.gms.common.PublicApi; @PublicApi public class CommonStatusCodes { - public static final int SUCCESS_CACHE = -1; public static final int SUCCESS = 0; @Deprecated public static final int SERVICE_MISSING = 1; @@ -31,61 +28,10 @@ public class CommonStatusCodes { @Deprecated public static final int SERVICE_DISABLED = 3; public static final int SIGN_IN_REQUIRED = 4; - public static final int INVALID_ACCOUNT = 5; public static final int RESOLUTION_REQUIRED = 6; - public static final int NETWORK_ERROR = 7; public static final int INTERNAL_ERROR = 8; - public static final int SERVICE_INVALID = 9; - public static final int DEVELOPER_ERROR = 10; - public static final int LICENSE_CHECK_FAILED = 11; public static final int ERROR = 13; public static final int INTERRUPTED = 14; - public static final int TIMEOUT = 15; public static final int CANCELED = 16; - public static final int API_NOT_CONNECTED = 17; - public static final int DEAD_CLIENT = 18; - @NonNull - public static String getStatusCodeString(int statusCode) { - switch (statusCode) { - case SUCCESS_CACHE: - return "SUCCESS_CACHE"; - case SUCCESS: - return "SUCCESS"; - case SERVICE_VERSION_UPDATE_REQUIRED: - return "SERVICE_VERSION_UPDATE_REQUIRED"; - case SERVICE_DISABLED: - return "SERVICE_DISABLED"; - case SIGN_IN_REQUIRED: - return "SIGN_IN_REQUIRED"; - case INVALID_ACCOUNT: - return "INVALID_ACCOUNT"; - case RESOLUTION_REQUIRED: - return "RESOLUTION_REQUIRED"; - case NETWORK_ERROR: - return "NETWORK_ERROR"; - case INTERNAL_ERROR: - return "INTERNAL_ERROR"; - case SERVICE_INVALID: - return "SERVICE_INVALID"; - case DEVELOPER_ERROR: - return "DEVELOPER_ERROR"; - case LICENSE_CHECK_FAILED: - return "LICENSE_CHECK_FAILED"; - case ERROR: - return "ERROR"; - case INTERRUPTED: - return "INTERRUPTED"; - case TIMEOUT: - return "TIMEOUT"; - case CANCELED: - return "CANCELED"; - case API_NOT_CONNECTED: - return "API_NOT_CONNECTED"; - case DEAD_CLIENT: - return "DEAD_CLIENT"; - default: - return "unknown status code: " + statusCode; - } - } } diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/api/Scope.java b/play-services-basement/src/main/java/com/google/android/gms/common/api/Scope.java index 60bc1fb9..a90803e7 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/common/api/Scope.java +++ b/play-services-basement/src/main/java/com/google/android/gms/common/api/Scope.java @@ -16,6 +16,8 @@ package com.google.android.gms.common.api; +import androidx.annotation.NonNull; + import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; @@ -44,20 +46,22 @@ public class Scope extends AutoSafeParcelable { @Override public boolean equals(Object o) { - return this == o || o instanceof Scope && scopeUri.equals(((Scope) o).scopeUri); - } - - public String getScopeUri() { - return scopeUri; + if (this == o) return true; + if (!(o instanceof Scope)) return false; + assert scopeUri != null; + return scopeUri.equals(((Scope) o).scopeUri); } @Override public int hashCode() { + assert scopeUri != null; return scopeUri.hashCode(); } + @NonNull @Override public String toString() { + assert scopeUri != null; return scopeUri; } diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/api/Status.java b/play-services-basement/src/main/java/com/google/android/gms/common/api/Status.java index 7b936e67..433ef043 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/common/api/Status.java +++ b/play-services-basement/src/main/java/com/google/android/gms/common/api/Status.java @@ -16,11 +16,7 @@ package com.google.android.gms.common.api; -import android.app.Activity; import android.app.PendingIntent; -import android.content.Intent; -import android.content.IntentSender; -import android.content.IntentSender.SendIntentException; import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; @@ -44,16 +40,8 @@ public final class Status extends AutoSafeParcelable implements Result { @SafeParceled(1) private final int statusCode; - @SafeParceled(2) - private final String statusMessage; - - @SafeParceled(3) - private final PendingIntent resolution; - private Status() { statusCode = 0; - statusMessage = null; - resolution = null; } /** @@ -84,19 +72,6 @@ public final class Status extends AutoSafeParcelable implements Result { */ public Status(int statusCode, String statusMessage, PendingIntent resolution) { this.statusCode = statusCode; - this.statusMessage = statusMessage; - this.resolution = resolution; - } - - /** - * A pending intent to resolve the failure. This intent can be started with - * {@link Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int)} to - * present UI to solve the issue. - * - * @return The pending intent to resolve the failure. - */ - public PendingIntent getResolution() { - return resolution; } /** @@ -111,30 +86,6 @@ public final class Status extends AutoSafeParcelable implements Result { return this; } - /** - * Indicates the status of the operation. - * - * @return Status code resulting from the operation. The value is one of the constants in - * {@link CommonStatusCodes} or specific to the APIs added to the GoogleApiClient. - */ - public int getStatusCode() { - return statusCode; - } - - public String getStatusMessage() { - return statusMessage; - } - - /** - * Returns true if calling {@link #startResolutionForResult(Activity, int)} will start any - * intents requiring user interaction. - * - * @return true if there is a resolution that can be started. - */ - public boolean hasResolution() { - return resolution != null; - } - /** * Returns true if the operation was canceled. */ @@ -142,39 +93,5 @@ public final class Status extends AutoSafeParcelable implements Result { return statusCode == CommonStatusCodes.CANCELED; } - /** - * Returns true if the operation was interrupted. - */ - public boolean isInterrupted() { - return statusCode == CommonStatusCodes.INTERRUPTED; - } - - /** - * Returns true if the operation was successful. - * - * @return true if the operation was successful, false if there was an error. - */ - public boolean isSuccess() { - return statusCode <= 0; - } - - /** - * Resolves an error by starting any intents requiring user interaction. See - * {@link CommonStatusCodes#SIGN_IN_REQUIRED}, and {@link CommonStatusCodes#RESOLUTION_REQUIRED}. - * - * @param activity An Activity context to use to resolve the issue. The activity's - * onActivityResult method will be invoked after the user is done. If the - * resultCode is {@link Activity#RESULT_OK}, the application should try to - * connect again. - * @param requestCode The request code to pass to onActivityResult. - * @throws SendIntentException If the resolution intent has been canceled or is no longer able - * to execute the request. - */ - public void startResolutionForResult(Activity activity, int requestCode) throws SendIntentException { - if (hasResolution()) { - activity.startIntentSenderForResult(resolution.getIntentSender(), requestCode, null, 0, 0, 0); - } - } - public static final Creator CREATOR = new AutoCreator<>(Status.class); } diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/ConnectionInfo.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/ConnectionInfo.java deleted file mode 100644 index 19326d08..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/ConnectionInfo.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common.internal; - -import android.os.Bundle; -import android.os.Parcel; -import androidx.annotation.NonNull; -import com.google.android.gms.common.Feature; -import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter; - -@SafeParcelable.Class -public class ConnectionInfo extends AbstractSafeParcelable { - @Field(1) - public Bundle params; - @Field(2) - public Feature[] features; - @Field(3) - public int unknown3; - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - CREATOR.writeToParcel(this, dest, flags); - } - - public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ConnectionInfo.class); -} diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/GetServiceRequest.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/GetServiceRequest.java index 9df8735c..a203a99f 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/GetServiceRequest.java +++ b/play-services-basement/src/main/java/com/google/android/gms/common/internal/GetServiceRequest.java @@ -31,7 +31,7 @@ import java.util.Arrays; public class GetServiceRequest extends AutoSafeParcelable { @Field(1) - private final int versionCode = 6; + private final int versionCode = 4; @Field(2) public final int serviceId; @Field(3) @@ -47,7 +47,6 @@ public class GetServiceRequest extends AutoSafeParcelable { @Field(8) public Account account; @Field(9) - @Deprecated private long field9; @Field(10) public Feature[] defaultFeatures; @@ -60,7 +59,7 @@ public class GetServiceRequest extends AutoSafeParcelable { @Field(14) private boolean field14; @Field(15) - private String attributionTag; + private String field15; private GetServiceRequest() { serviceId = -1; diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/ValidateAccountRequest.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/ValidateAccountRequest.java index 1cf0ecc1..75e59d95 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/ValidateAccountRequest.java +++ b/play-services-basement/src/main/java/com/google/android/gms/common/internal/ValidateAccountRequest.java @@ -16,18 +16,8 @@ package com.google.android.gms.common.internal; -import android.os.Parcel; -import androidx.annotation.NonNull; -import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelable; -import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter; +import org.microg.safeparcel.AutoSafeParcelable; -@SafeParcelable.Class -public class ValidateAccountRequest extends AbstractSafeParcelable { - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - CREATOR.writeToParcel(this, dest, flags); - } - - public static SafeParcelableCreatorAndWriter CREATOR = findCreator(ValidateAccountRequest.class); +public class ValidateAccountRequest extends AutoSafeParcelable { + public static Creator CREATOR = new AutoCreator<>(ValidateAccountRequest.class); } diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/AbstractSafeParcelable.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/AbstractSafeParcelable.java deleted file mode 100644 index ec7d84d5..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/AbstractSafeParcelable.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common.internal.safeparcel; - -public abstract class AbstractSafeParcelable implements SafeParcelable { - - @SuppressWarnings("unchecked") - public static SafeParcelableCreatorAndWriter findCreator(java.lang.Class tClass) { - String creatorClassName = tClass.getName() + "$000Creator"; - try { - return (SafeParcelableCreatorAndWriter) java.lang.Class.forName(creatorClassName).newInstance(); - } catch (Exception e) { - throw new RuntimeException("No Creator found for " + tClass.getName(), e); - } - } - - @Override - public int describeContents() { - return 0; - } -} diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelReader.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelReader.java deleted file mode 100644 index 226f50e8..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelReader.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common.internal.safeparcel; - -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.HashMap; - -@SuppressWarnings("MagicNumber") -public final class SafeParcelReader { - - private SafeParcelReader() { - } - - @Deprecated - public static int halfOf(int i) { - return i & 0xFFFF; - } - - public static int getFieldId(int header) { - return header & 0xFFFF; - } - - @Deprecated - public static int readSingleInt(Parcel parcel) { - return parcel.readInt(); - } - - public static int readHeader(Parcel parcel) { - return parcel.readInt(); - } - - private static int readSize(Parcel parcel, int header) { - if ((header & 0xFFFF0000) != 0xFFFF0000) - return header >> 16 & 0xFFFF; - return parcel.readInt(); - } - - private static void readExpectedSize(Parcel parcel, int header, int expectedSize) { - int i = readSize(parcel, header); - if (i != expectedSize) - throw new ReadException("Expected size " + expectedSize + " got " + i + " (0x" + Integer.toHexString(i) + ")", parcel); - } - - @Deprecated - public static int readStart(Parcel parcel) { - return readObjectHeader(parcel); - } - - public static int readObjectHeader(Parcel parcel) { - int header = readHeader(parcel); - int size = readSize(parcel, header); - int start = parcel.dataPosition(); - if (getFieldId(header) != SafeParcelable.SAFE_PARCEL_OBJECT_MAGIC) - throw new ReadException("Expected object header. Got 0x" + Integer.toHexString(header), parcel); - int end = start + size; - if ((end < start) || (end > parcel.dataSize())) - throw new ReadException("Size read is invalid start=" + start + " end=" + end, parcel); - return end; - } - - public static int readInt(Parcel parcel, int header) { - readExpectedSize(parcel, header, 4); - return parcel.readInt(); - } - - public static byte readByte(Parcel parcel, int header) { - readExpectedSize(parcel, header, 4); - return (byte) parcel.readInt(); - } - - public static short readShort(Parcel parcel, int header) { - readExpectedSize(parcel, header, 4); - return (short) parcel.readInt(); - } - - public static boolean readBool(Parcel parcel, int header) { - readExpectedSize(parcel, header, 4); - return parcel.readInt() != 0; - } - - public static long readLong(Parcel parcel, int header) { - readExpectedSize(parcel, header, 8); - return parcel.readLong(); - } - - public static float readFloat(Parcel parcel, int header) { - readExpectedSize(parcel, header, 4); - return parcel.readFloat(); - } - - public static double readDouble(Parcel parcel, int header) { - readExpectedSize(parcel, header, 8); - return parcel.readDouble(); - } - - public static String readString(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - String string = parcel.readString(); - parcel.setDataPosition(start + size); - return string; - } - - public static IBinder readBinder(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - IBinder binder = parcel.readStrongBinder(); - parcel.setDataPosition(start + size); - return binder; - } - - public static T readParcelable(Parcel parcel, int header, Parcelable.Creator creator) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - T t = creator.createFromParcel(parcel); - parcel.setDataPosition(start + size); - return t; - } - - public static ArrayList readList(Parcel parcel, int header, ClassLoader classLoader) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - ArrayList list = parcel.readArrayList(classLoader); - parcel.setDataPosition(start + size); - return list; - } - - public static HashMap readMap(Parcel parcel, int header, ClassLoader classLoader) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - HashMap map = parcel.readHashMap(classLoader); - parcel.setDataPosition(start + size); - return map; - } - - public static ArrayList readParcelableList(Parcel parcel, int header, Parcelable.Creator creator) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - ArrayList list = parcel.createTypedArrayList(creator); - parcel.setDataPosition(start + size); - return list; - } - - public static ArrayList readStringList(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - ArrayList list = parcel.createStringArrayList(); - parcel.setDataPosition(start + size); - return list; - } - - public static ArrayList readIntegerList(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - int length = parcel.readInt(); - ArrayList list = new ArrayList<>(length); - for (int i = 0; i < length; i++) { - list.add(parcel.readInt()); - } - parcel.setDataPosition(start + size); - return list; - } - - public static ArrayList readLongList(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - int length = parcel.readInt(); - ArrayList list = new ArrayList<>(length); - for (int i = 0; i < length; i++) { - list.add(parcel.readLong()); - } - parcel.setDataPosition(start + size); - return list; - } - - public static ArrayList readFloatList(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - int length = parcel.readInt(); - ArrayList list = new ArrayList<>(length); - for (int i = 0; i < length; i++) { - list.add(parcel.readFloat()); - } - parcel.setDataPosition(start + size); - return list; - } - - public static ArrayList readDoubleList(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - int length = parcel.readInt(); - ArrayList list = new ArrayList<>(length); - for (int i = 0; i < length; i++) { - list.add(parcel.readDouble()); - } - parcel.setDataPosition(start + size); - return list; - } - - public static ArrayList readBooleanList(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - int length = parcel.readInt(); - ArrayList list = new ArrayList<>(length); - for (int i = 0; i < length; i++) { - list.add(parcel.readInt() != 0); - } - parcel.setDataPosition(start + size); - return list; - } - - public static T[] readParcelableArray(Parcel parcel, int header, Parcelable.Creator creator) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - T[] arr = parcel.createTypedArray(creator); - parcel.setDataPosition(start + size); - return arr; - } - - public static String[] readStringArray(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - String[] arr = parcel.createStringArray(); - parcel.setDataPosition(start + size); - return arr; - } - - public static byte[] readByteArray(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - byte[] arr = parcel.createByteArray(); - parcel.setDataPosition(start + size); - return arr; - } - - public static byte[][] readByteArrayArray(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - int length = parcel.readInt(); - byte[][] arr = new byte[length][]; - for (int i = 0; i < length; i++) { - arr[i] = parcel.createByteArray(); - } - parcel.setDataPosition(start + size); - return arr; - } - - public static float[] readFloatArray(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - float[] arr = parcel.createFloatArray(); - parcel.setDataPosition(start + size); - return arr; - } - - public static int[] readIntArray(Parcel parcel, int header) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - int[] arr = parcel.createIntArray(); - parcel.setDataPosition(start + size); - return arr; - } - - public static Bundle readBundle(Parcel parcel, int header, ClassLoader classLoader) { - int size = readSize(parcel, header); - if (size == 0) - return null; - int start = parcel.dataPosition(); - Bundle bundle = parcel.readBundle(classLoader); - parcel.setDataPosition(start + size); - return bundle; - } - - public static void skip(Parcel parcel, int header) { - int size = readSize(parcel, header); - parcel.setDataPosition(parcel.dataPosition() + size); - } - - public static class ReadException extends RuntimeException { - public ReadException(String message, Parcel parcel) { - super(message); - } - } -} \ No newline at end of file diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelWriter.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelWriter.java deleted file mode 100644 index b2f96116..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelWriter.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common.internal.safeparcel; - -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.List; -import java.util.Map; - -@SuppressWarnings("MagicNumber") -public final class SafeParcelWriter { - - private SafeParcelWriter() { - } - - private static void writeHeader(Parcel parcel, int fieldId, int size) { - if (size >= 0xFFFF) { - parcel.writeInt(0xFFFF0000 | fieldId); - parcel.writeInt(size); - } else { - parcel.writeInt(size << 16 | fieldId); - } - } - - @Deprecated - public static int writeStart(Parcel parcel) { - return writeObjectHeader(parcel); - } - - public static int writeObjectHeader(Parcel parcel) { - writeHeader(parcel, SafeParcelable.SAFE_PARCEL_OBJECT_MAGIC, 0xFFFF); - return parcel.dataPosition(); - } - - private static int writeObjectHeader(Parcel parcel, int fieldId) { - writeHeader(parcel, fieldId, 0xFFFF); - return parcel.dataPosition(); - } - - @Deprecated - public static void writeEnd(Parcel parcel, int start) { - finishObjectHeader(parcel, start); - } - - public static void finishObjectHeader(Parcel parcel, int start) { - int end = parcel.dataPosition(); - int length = end - start; - parcel.setDataPosition(start - 4); - parcel.writeInt(length); - parcel.setDataPosition(end); - } - - public static void write(Parcel parcel, int fieldId, Boolean val) { - if (val == null) return; - writeHeader(parcel, fieldId, 4); - parcel.writeInt(val ? 1 : 0); - } - - public static void write(Parcel parcel, int fieldId, Byte val) { - if (val == null) return; - writeHeader(parcel, fieldId, 4); - parcel.writeInt(val); - } - - public static void write(Parcel parcel, int fieldId, Short val) { - if (val == null) return; - writeHeader(parcel, fieldId, 4); - parcel.writeInt(val); - } - - public static void write(Parcel parcel, int fieldId, Integer val) { - if (val == null) return; - writeHeader(parcel, fieldId, 4); - parcel.writeInt(val); - } - - public static void write(Parcel parcel, int fieldId, Long val) { - if (val == null) return; - writeHeader(parcel, fieldId, 8); - parcel.writeLong(val); - } - - public static void write(Parcel parcel, int fieldId, Float val) { - if (val == null) return; - writeHeader(parcel, fieldId, 4); - parcel.writeFloat(val); - } - - public static void write(Parcel parcel, int fieldId, Double val) { - if (val == null) return; - writeHeader(parcel, fieldId, 8); - parcel.writeDouble(val); - } - - public static void write(Parcel parcel, int fieldId, String val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeString(val); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, Parcelable val, int flags, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - val.writeToParcel(parcel, flags); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, Bundle val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeBundle(val); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, byte[] val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeByteArray(val); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, byte[][] val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeInt(val.length); - for (byte[] arr : val) { - parcel.writeByteArray(arr); - } - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, float[] val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeFloatArray(val); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, int[] val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeIntArray(val); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, String[] val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeStringArray(val); - finishObjectHeader(parcel, start); - } - } - - public static void writeStringList(Parcel parcel, int fieldId, List val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeStringList(val); - finishObjectHeader(parcel, start); - } - } - - public static void writeIntegerList(Parcel parcel, int fieldId, List val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeInt(val.size()); - for (Integer i : val) { - parcel.writeInt(i); - } - finishObjectHeader(parcel, start); - } - } - - public static void writeLongList(Parcel parcel, int fieldId, List val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeInt(val.size()); - for (Long l : val) { - parcel.writeLong(l); - } - finishObjectHeader(parcel, start); - } - } - - public static void writeFloatList(Parcel parcel, int fieldId, List val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeInt(val.size()); - for (Float f : val) { - parcel.writeFloat(f); - } - finishObjectHeader(parcel, start); - } - } - - public static void writeDoubleList(Parcel parcel, int fieldId, List val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeInt(val.size()); - for (Double d : val) { - parcel.writeDouble(d); - } - finishObjectHeader(parcel, start); - } - } - - public static void writeBooleanList(Parcel parcel, int fieldId, List val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeInt(val.size()); - for (Boolean b : val) { - parcel.writeInt(b ? 1 : 0); - } - finishObjectHeader(parcel, start); - } - } - - private static void writeArrayPart(Parcel parcel, T val, int flags) { - int before = parcel.dataPosition(); - parcel.writeInt(1); - int start = parcel.dataPosition(); - val.writeToParcel(parcel, flags); - int end = parcel.dataPosition(); - parcel.setDataPosition(before); - parcel.writeInt(end - start); - parcel.setDataPosition(end); - } - - public static void write(Parcel parcel, int fieldId, T[] val, int flags, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeInt(val.length); - for (T t : val) { - if (t == null) { - parcel.writeInt(0); - } else { - writeArrayPart(parcel, t, flags); - } - } - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, List val, int flags, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeInt(val.size()); - for (T t : val) { - if (t == null) { - parcel.writeInt(0); - } else { - writeArrayPart(parcel, t, flags); - } - } - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, Parcel val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.appendFrom(val, 0, val.dataSize()); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, List val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeList(val); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, Map val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeMap(val); - finishObjectHeader(parcel, start); - } - } - - public static void write(Parcel parcel, int fieldId, IBinder val, boolean mayNull) { - if (val == null) { - if (mayNull) { - writeHeader(parcel, fieldId, 0); - } - } else { - int start = writeObjectHeader(parcel, fieldId); - parcel.writeStrongBinder(val); - finishObjectHeader(parcel, start); - } - } - -} \ No newline at end of file diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelable.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelable.java deleted file mode 100644 index 0d8d1cc0..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelable.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common.internal.safeparcel; - -import android.os.Parcelable; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -public interface SafeParcelable extends Parcelable { - int SAFE_PARCEL_OBJECT_MAGIC = 0x4F45; - - @Target(ElementType.TYPE) - @interface Class { - } - - @Target(ElementType.CONSTRUCTOR) - @interface Constructor { - - } - - @Target(ElementType.PARAMETER) - @interface Param { - int value(); - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - @interface Field { - int value(); - - boolean mayNull() default false; - - java.lang.Class subClass() default SafeParcelable.class; - - boolean useValueParcel() default false; - - boolean useDirectList() default false; - - long versionCode() default -1; - - String defaultValue() default ""; - - String type() default ""; - - String getterName() default ""; - - String getter() default ""; - } -} diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelableCreatorAndWriter.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelableCreatorAndWriter.java deleted file mode 100644 index 6afaa9c6..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelableCreatorAndWriter.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common.internal.safeparcel; - -import android.os.Parcel; -import android.os.Parcelable; - -public interface SafeParcelableCreatorAndWriter extends Parcelable.Creator { - void writeToParcel(T object, Parcel parcel, int flags); -} diff --git a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelableSerializer.java b/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelableSerializer.java deleted file mode 100644 index 66b8b4d5..00000000 --- a/play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelableSerializer.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.google.android.gms.common.internal.safeparcel; - -import android.os.Parcel; -import android.os.Parcelable; - -public class SafeParcelableSerializer { - public static T deserializeFromBytes(byte[] bytes, Parcelable.Creator tCreator) { - if (bytes == null) return null; - Parcel parcel = Parcel.obtain(); - parcel.unmarshall(bytes, 0, bytes.length); - parcel.setDataPosition(0); - T parcelable = tCreator.createFromParcel(parcel); - parcel.recycle(); - return parcelable; - } - - public static byte[] serializeToBytes(T parcelable) { - if (parcelable == null) return null; - Parcel parcel = Parcel.obtain(); - parcelable.writeToParcel(parcel, 0); - byte[] bytes = parcel.marshall(); - parcel.recycle(); - return bytes; - } -} diff --git a/play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java b/play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java index 4bc96034..9158c941 100644 --- a/play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java +++ b/play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java @@ -18,7 +18,6 @@ package com.google.android.gms.dynamic; import android.os.IBinder; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.lang.reflect.Field; @@ -35,13 +34,37 @@ public class ObjectWrapper extends IObjectWrapper.Stub { if (obj == null) { return null; } - if (obj instanceof ObjectWrapper) { return ((ObjectWrapper) obj).t; } - IBinder binder = obj.asBinder(); - Field field = getField(binder); + Field[] fields = binder.getClass().getDeclaredFields(); + + if (fields.length < 1) { + throw new IllegalArgumentException("No fields were found"); + } + + // Ignore synthetic field(s) from JaCoCo or elsewhere + // https://www.jacoco.org/jacoco/trunk/doc/faq.html + + @Nullable + Field field = null; + + for (Field currentField : fields) { + if (currentField.isSynthetic()) { + continue; + } + + if (field == null) { + field = currentField; + } else { + throw new IllegalArgumentException("Too many non-synthetic fields were found"); + } + } + + if (field == null) { + throw new IllegalArgumentException("No non-synthetic fields were found"); + } if (!field.isAccessible()) { field.setAccessible(true); @@ -62,35 +85,6 @@ public class ObjectWrapper extends IObjectWrapper.Stub { } } - @NonNull - private static Field getField(IBinder binder) { - Field[] fields = binder.getClass().getDeclaredFields(); - - if (fields.length < 1) { - throw new IllegalArgumentException("No fields were found"); - } - - @Nullable - Field field = null; - - for (Field currentField : fields) { - if (currentField.isSynthetic()) { - continue; - } - - if (field == null) { - field = currentField; - } else { - throw new IllegalArgumentException("Too many non-synthetic fields were found"); - } - } - - if (field == null) { - throw new IllegalArgumentException("No non-synthetic fields were found"); - } - return field; - } - @Nullable public static T unwrapTyped(IObjectWrapper obj, Class clazz) { try { @@ -103,4 +97,4 @@ public class ObjectWrapper extends IObjectWrapper.Stub { public static ObjectWrapper wrap(T t) { return new ObjectWrapper<>(t); } -} +} \ No newline at end of file diff --git a/play-services-basement/src/main/java/org/microg/gms/auth/AuthConstants.java b/play-services-basement/src/main/java/org/microg/gms/auth/AuthConstants.java index 6cac0d45..774f5756 100644 --- a/play-services-basement/src/main/java/org/microg/gms/auth/AuthConstants.java +++ b/play-services-basement/src/main/java/org/microg/gms/auth/AuthConstants.java @@ -16,14 +16,11 @@ package org.microg.gms.auth; -import org.microg.gms.basement.BuildConfig; - public class AuthConstants { - public static final String DEFAULT_ACCOUNT = "<>"; public static final String SCOPE_GET_ACCOUNT_ID = "^^_account_id_^^"; public static final String PROVIDER_METHOD_GET_ACCOUNTS = "get_accounts"; public static final String PROVIDER_METHOD_CLEAR_PASSWORD = "clear_password"; public static final String PROVIDER_EXTRA_CLEAR_PASSWORD = "clear_password"; public static final String PROVIDER_EXTRA_ACCOUNTS = "accounts"; - public static final String DEFAULT_ACCOUNT_TYPE = BuildConfig.BASE_PACKAGE_NAME; + public static final String DEFAULT_ACCOUNT_TYPE = "com.mgoogle"; } diff --git a/play-services-basement/src/main/java/org/microg/gms/common/Constants.java b/play-services-basement/src/main/java/org/microg/gms/common/Constants.java index a905f2bc..077bdbde 100644 --- a/play-services-basement/src/main/java/org/microg/gms/common/Constants.java +++ b/play-services-basement/src/main/java/org/microg/gms/common/Constants.java @@ -21,8 +21,9 @@ import org.microg.gms.basement.BuildConfig; public class Constants { public static final int GMS_VERSION_CODE = (BuildConfig.VERSION_CODE / 1000) * 1000; public static final String GMS_PACKAGE_NAME = "com.google.android.gms"; - public static final String GSF_PACKAGE_NAME = BuildConfig.BASE_PACKAGE_NAME + ".android.gsf"; public static final String GMS_PACKAGE_SIGNATURE_SHA1 = "38918a453d07199354f8b19af05ec6562ced5788"; + public static final String GMS_SECONDARY_PACKAGE_SIGNATURE_SHA1 = "bd32424203e0fb25f36b57e5aa356f9bdd1da998"; + @Deprecated public static final int MAX_REFERENCE_VERSION = GMS_VERSION_CODE; } diff --git a/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java b/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java index efdbb1d2..739bc259 100644 --- a/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java +++ b/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java @@ -19,161 +19,20 @@ package org.microg.gms.common; public enum GmsService { UNKNOWN(-2), ANY(-1), - GAMES(1, "com.google.android.gms.games.service.START", "com.google.android.gms.games.internal.connect.service.START"), - PLUS(2, "com.google.android.gms.plus.service.START", "com.google.android.gms.plus.service.internal.START"), - PANORAMA(3, "com.google.android.gms.panorama.service.START"), - WALLET(4, "com.google.android.gms.wallet.service.BIND"), PEOPLE(5, "com.google.android.gms.people.service.START"), - LOCATION(6), - APPSTATE(7, "com.google.android.gms.appstate.service.START"), - ADREQUEST(8, "com.google.android.gms.ads.service.START"), ACCOUNT(9, "com.google.android.gms.accounts.ACCOUNT_SERVICE"), - CAST(10, "com.google.android.gms.cast.service.BIND_CAST_DEVICE_CONTROLLER_SERVICE"), - DRIVE(11, "com.google.android.gms.drive.ApiService.START"), ADDRESS(12, "com.google.android.gms.identity.service.BIND"), - CAR(13, "com.google.android.gms.car.service.START"), - WEARABLE(14, "com.google.android.gms.wearable.BIND"), AUTH_PROXY(16, "com.google.android.gms.auth.service.START"), - FITNESS(17, "com.google.android.gms.fitness.GoogleFitnessService.START"), - REMINDERS(18, "com.google.android.gms.reminders.service.START"), - LIGHTWEIGHT_INDEX(19, "com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE"), - DEVICE_CONNECTION(20, "com.google.android.gms.deviceconnection.service.START"), INDEX(21, "com.google.android.gms.icing.INDEX_SERVICE"), - LOCATION_REPORTING(22, "com.google.android.gms.location.reporting.service.START", "com.google.android.location.reporting.service.START"), - LOCATION_MANAGER(23, "com.google.android.location.internal.GoogleLocationManagerService.START"), - PLAY_LOG(24, "com.google.android.gms.playlog.service.START"), - DROIDGUARD(25, "com.google.android.gms.droidguard.service.START"), - LOCKBOX(26, "com.google.android.gms.lockbox.service.START"), - CAST_MIRRORING(27, "com.google.android.gms.cast_mirroring.service.START"), - NETWORK_QUALITY(28, "com.google.android.gms.mdm.services.START"), - FEEDBACK(29, "com.google.android.gms.feedback.internal.IFeedbackService"), - SEARCH_ADMINISTRATION(30), - PHOTO_AUTO_BACKUP(31, "com.google.android.gms.photos.autobackup.service.START"), - SEARCH_QUERIES(32), - SEARCH_GLOBAL(33), - UDC(35, "com.google.android.gms.udc.service.START"), - SEARCH_CORPORA(36), - DEVICE_MANAGER(37, "com.google.android.gms.mdm.services.DeviceManagerApiService.START"), - PSEUDONYMOUS_ID(38, "com.google.android.gms.pseudonymous.service.START"), COMMON(39, "com.google.android.gms.common.service.START"), - CLEARCUT_LOGGER(40, "com.google.android.gms.clearcut.service.START"), - USAGE_REPORTING(41, "com.google.android.gms.usagereporting.service.START"), - KIDS(42, "com.google.android.gms.kids.service.START"), - DOWNLOAD(43, "com.google.android.gms.common.download.START"), SIGN_IN(44, "com.google.android.gms.signin.service.START"), - SAFETY_NET_CLIENT(45, "com.google.android.gms.safetynet.service.START"), - GSERVICES(46, "com.google.android.gms.ads.gservice.START"), - CONTEXT_MANAGER(47, "com.google.android.contextmanager.service.ContextManagerService.START"), - AUDIO_MODEM(48, "com.google.android.gms.audiomodem.service.AudioModemService.START"), - NEARBY_SHARING(49, "com.google.android.gms.nearby.sharing.service.NearbySharingService.START"), - LIGHTWEIGHT_NETWORK_QUALITY(50, "com.google.android.gms.herrevad.services.LightweightNetworkQualityAndroidService.START"), - PHENOTYPE(51, "com.google.android.gms.phenotype.service.START"), - VOICE_UNLOCK(52, "com.google.android.gms.speech.service.START"), - NEARBY_CONNECTIONS(54, "com.google.android.gms.nearby.connection.service.START"), - FITNESS_SENSORS(55, "com.google.android.gms.fitness.SensorsApi"), - FITNESS_RECORDING(56, "com.google.android.gms.fitness.RecordingApi"), - FITNESS_HISTORY(57, "com.google.android.gms.fitness.HistoryApi"), - FITNESS_SESSIONS(58, "com.google.android.gms.fitness.SessionsApi"), - FITNESS_BLE(59, "com.google.android.gms.fitness.BleApi"), - FITNESS_CONFIG(60, "com.google.android.gms.fitness.ConfigApi"), - FITNESS_INTERNAL(61, "com.google.android.gms.fitness.InternalApi"), - NEARBY_MESSAGES(62, "com.google.android.gms.nearby.messages.service.NearbyMessagesService.START"), - HELP(63, "com.google.android.gms.googlehelp.service.GoogleHelpService.START"), - CONFIG(64, "com.google.android.gms.config.START"), - GEODATA(65, "com.google.android.gms.location.places.GeoDataApi"), - SEARCH_IME(66), - PLACE_DETECTION(67, "com.google.android.gms.location.places.PlaceDetectionApi"), CREDENTIALS(68, "com.google.android.gms.auth.api.credentials.service.START"), - NEARBY_BOOTSTRAP(69, "com.google.android.gms.nearby.bootstrap.service.NearbyBootstrapService.START"), - PLUS_INTERNAL(70), - SOURCE_DEVICE(75, "com.google.android.gms.smartdevice.d2d.SourceDeviceService.START"), - TARGET_DEVICE(76, "com.google.android.gms.smartdevice.d2d.TargetDeviceService.START"), - APP_INVITE(77, "com.google.android.gms.appinvite.service.START"), - TAP_AND_PAY(79, "com.google.android.gms.tapandpay.service.BIND"), - CHROME_SYNC(80, "com.google.android.gms.chromesync.service.START"), - ACCOUNTS(81, "com.google.android.gms.smartdevice.setup.accounts.AccountsService.START"), - CAST_REMOTE_DISPLAY(83, "com.google.android.gms.cast.remote_display.service.START"), - TRUST_AGENT(85, "com.google.android.gms.trustagent.StateApi.START"), - AUTH_SIGN_IN(91, "com.google.android.gms.auth.api.signin.service.START"), - MEASUREMENT(93, "com.google.android.gms.measurement.START"), - FREIGHTER(98, "com.google.android.gms.freighter.service.START"), - GUNS(110, "com.google.android.gms.notifications.service.START"), - BLE(111, "com.google.android.gms.beacon.internal.IBleService.START"), - FIREBASE_AUTH(112, "com.google.firebase.auth.api.gms.service.START"), - APP_INDEXING(113), - GASS(116, "com.google.android.gms.gass.START"), - WORK_ACCOUNT(120), - INSTANT_APPS(121, "com.google.android.gms.instantapps.START"), - CAST_FIRSTPATY(122, "com.google.android.gms.cast.firstparty.START"), - AD_CACHE(123, "com.google.android.gms.ads.service.CACHE"), - SMS_RETRIEVER(126, "com.google.android.gms.auth.api.phone.service.SmsRetrieverApiService.START"), - CRYPT_AUTH(129, "com.google.android.gms.auth.cryptauth.cryptauthservice.START"), - DYNAMIC_LINKS(131, "com.google.firebase.dynamiclinks.service.START"), - FONTS(132, "com.google.android.gms.fonts.service.START"), - ROMANESCO(135, "com.google.android.gms.romanesco.service.START"), - TRAINER(139, "com.google.android.gms.learning.trainer.START"), - FIDO2_REGULAR(148, "com.google.android.gms.fido.fido2.regular.START"), - FIDO2_PRIVILEGED(149, "com.google.android.gms.fido.fido2.privileged.START"), - DATA_DOWNLOAD(152, "com.google.android.mdd.service.START"), - ACCOUNT_DATA(153, "com.google.android.gms.auth.account.data.service.START"), - CONSTELLATION(155, "com.google.android.gms.constellation.service.START"), - AUDIT(154, "com.google.android.gms.audit.service.START"), - SYSTEM_UPDATE(157, "com.google.android.gms.update.START_API_SERVICE"), - MOBSTORE(160, "com.google.android.mobstore.service.START"), - USER_LOCATION(163, "com.google.android.gms.userlocation.service.START"), - AD_HTTP(166, "com.google.android.gms.ads.service.HTTP"), - LANGUAGE_PROFILE(167, "com.google.android.gms.languageprofile.service.START"), - MDNS(168, "com.google.android.gms.mdns.service.START"), - FIDO2_ZEROPARTY(180, "com.google.android.gms.fido.fido2.zeroparty.START"), - G1_RESTORE(181, "com.google.android.gms.backup.G1_RESTORE"), - G1_BACKUP(182, "com.google.android.gms.backup.G1_BACKUP"), - OSS_LICENSES(185, "com.google.android.gms.oss.licenses.service.START"), - PAYSE(188, "com.google.android.gms.payse.service.BIND"), - RCS(189, "com.google.android.gms.rcs.START"), - CARRIER_AUTH(191, "com.google.android.gms.carrierauth.service.START"), - SYSTEM_UPDATE_SINGLE_UESR(192, "com.google.android.gms.update.START_SINGLE_USER_API_SERVICE"), - APP_USAGE(193, "com.google.android.gms.appusage.service.START"), - NEARBY_SHARING_2(194, "com.google.android.gms.nearby.sharing.START_SERVICE"), - AD_CONSENT_LOOKUP(195, "com.google.android.gms.ads.service.CONSENT_LOOKUP"), - CREDENTIAL_MANAGER(196, "com.google.android.gms.credential.manager.service.firstparty.START"), - PHONE_INTERNAL(197, "com.google.android.gms.auth.api.phone.service.InternalService.START"), - PAY(198, "com.google.android.gms.pay.service.BIND"), - ASTERISM(199, "com.google.android.gms.asterism.service.START"), - MODULE_RESTORE(201, "com.google.android.gms.backup.GMS_MODULE_RESTORE"), - FACS_CACHE(202, "com.google.android.gms.facs.cache.service.START"), - RECAPTCHA(205, "com.google.android.gms.recaptcha.service.START"), - CONTACT_SYNC(208, "com.google.android.gms.people.contactssync.service.START"), IDENTITY_SIGN_IN(212, "com.google.android.gms.auth.api.identity.service.signin.START"), - CREDENTIAL_STORE(214, "com.google.android.gms.fido.credentialstore.internal_service.START"), - MDI_SYNC(215, "com.google.android.gms.mdisync.service.START"), - EVENT_ATTESTATION(216, "com.google.android.gms.ads.identifier.service.EVENT_ATTESTATION"), - SCHEDULER(218, "com.google.android.gms.scheduler.ACTION_PROXY_SCHEDULE"), - AUTHORIZATION(219, "com.google.android.gms.auth.api.identity.service.authorization.START"), - FACS_SYNC(220, "com.google.android.gms.facs.internal.service.START"), - AUTH_CONFIG_SYNC(221, "com.google.android.gms.auth.config.service.START"), - CREDENTIAL_SAVING(223, "com.google.android.gms.auth.api.identity.service.credentialsaving.START"), - GOOGLE_AUTH(224, "com.google.android.gms.auth.account.authapi.START"), - ENTERPRISE_LOADER(225, "com.google.android.gms.enterprise.loader.service.START"), - THUNDERBIRD(226, "com.google.android.gms.thunderbird.service.START"), - NEARBY_EXPOSURE(236, "com.google.android.gms.nearby.exposurenotification.START"), - GMS_COMPLIANCE(257, "com.google.android.gms.gmscompliance.service.START"), - FIDO_SOURCE_DEVICE(262, "com.google.android.gms.fido.sourcedevice.service.START"), - FAST_PAIR(265, "com.google.android.gms.nearby.fastpair.START"), - MATCHSTICK_LIGHTER(268, "com.google.android.gms.matchstick.lighter.service.START"), - FIDO_TARGET_DEVICE_INTERNAL(269, "com.google.android.gms.fido.targetdevice.internal_service.START"), - TELEMETRY(270, "com.google.android.gms.common.telemetry.service.START"), - SECOND_DEVICE_AUTH(275, "com.google.android.gms.setup.auth.SecondDeviceAuth.START"), - LOCATION_SHARING_REPORTER(277, "com.google.android.gms.locationsharingreporter.service.START"), - OCR(279, "com.google.android.gms.ocr.service.START"), - POTOKENS(285, "com.google.android.gms.potokens.service.START"), - OCR_INTERNAL(281, "com.google.android.gms.ocr.service.internal.START"), - IN_APP_REACH(315, "com.google.android.gms.inappreach.service.START"), - APP_ERRORS(334, "com.google.android.gms.apperrors.service.START_APP_ERROR"), ; - public int SERVICE_ID; - public String ACTION; - public String[] SECONDARY_ACTIONS; + public final int SERVICE_ID; + public final String ACTION; + public final String[] SECONDARY_ACTIONS; GmsService(int serviceId, String... actions) { this.SERVICE_ID = serviceId; @@ -181,11 +40,6 @@ public enum GmsService { this.SECONDARY_ACTIONS = actions; } - public interface ADVERTISING_ID { - // Has no service id - String ACTION = "com.google.android.gms.ads.identifier.service.START"; - } - public static GmsService byServiceId(int serviceId) { for (GmsService service : values()) { if (service.SERVICE_ID == serviceId) return service; @@ -193,15 +47,6 @@ public enum GmsService { return UNKNOWN; } - public static GmsService byAction(String action) { - for (GmsService service : values()) { - for (String serviceAction : service.SECONDARY_ACTIONS) { - if (serviceAction.equals(action)) return service; - } - } - return UNKNOWN; - } - public static String nameFromServiceId(int serviceId) { return byServiceId(serviceId).toString(serviceId); } @@ -210,4 +55,4 @@ public enum GmsService { if (this != UNKNOWN) return toString(); return "UNKNOWN(" + serviceId + ")"; } -} +} \ No newline at end of file diff --git a/play-services-basement/src/main/java/org/microg/gms/common/Hide.java b/play-services-basement/src/main/java/org/microg/gms/common/Hide.java deleted file mode 100644 index e15414b5..00000000 --- a/play-services-basement/src/main/java/org/microg/gms/common/Hide.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.common; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Hide the class, method or field from the public API. - */ -@Retention(RetentionPolicy.SOURCE) -@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR}) -public @interface Hide { -} diff --git a/play-services-basement/src/main/java/org/microg/gms/common/PublicApi.java b/play-services-basement/src/main/java/org/microg/gms/common/PublicApi.java index a7fb9b44..92663979 100644 --- a/play-services-basement/src/main/java/org/microg/gms/common/PublicApi.java +++ b/play-services-basement/src/main/java/org/microg/gms/common/PublicApi.java @@ -43,8 +43,6 @@ public @interface PublicApi { * marked as public api. * * @return true if the method or field is not part of the public api - * @deprecated use {@link Hide} instead */ - @Deprecated boolean exclude() default false; } diff --git a/play-services-basement/src/main/java/org/microg/gms/gcm/GcmConstants.java b/play-services-basement/src/main/java/org/microg/gms/gcm/GcmConstants.java index 00117d4e..d96fe90a 100644 --- a/play-services-basement/src/main/java/org/microg/gms/gcm/GcmConstants.java +++ b/play-services-basement/src/main/java/org/microg/gms/gcm/GcmConstants.java @@ -16,80 +16,29 @@ package org.microg.gms.gcm; -import org.microg.gms.basement.BuildConfig; - public final class GcmConstants { - public static final String ACTION_C2DM_RECEIVE = BuildConfig.BASE_PACKAGE_NAME + ".android.c2dm.intent.RECEIVE"; - public static final String ACTION_C2DM_REGISTER = BuildConfig.BASE_PACKAGE_NAME + ".android.c2dm.intent.REGISTER"; - public static final String ACTION_C2DM_REGISTRATION = BuildConfig.BASE_PACKAGE_NAME + ".android.c2dm.intent.REGISTRATION"; - public static final String ACTION_C2DM_UNREGISTER = BuildConfig.BASE_PACKAGE_NAME + ".android.c2dm.intent.UNREGISTER"; - public static final String ACTION_GCM_SEND = BuildConfig.BASE_PACKAGE_NAME + ".android.gcm.intent.SEND"; - public static final String ACTION_NOTIFICATION_OPEN = BuildConfig.BASE_PACKAGE_NAME + ".android.gms.gcm.NOTIFICATION_OPEN"; - public static final String ACTION_NOTIFICATION_DISMISS = BuildConfig.BASE_PACKAGE_NAME + ".android.gms.gcm.NOTIFICATION_DISMISS"; - public static final String ACTION_SCHEDULE = BuildConfig.BASE_PACKAGE_NAME + ".android.gms.gcm.ACTION_SCHEDULE"; - public static final String ACTION_TASK_READY = BuildConfig.BASE_PACKAGE_NAME + ".android.gms.gcm.ACTION_TASK_READY"; - public static final String ACTION_TASK_INITIALZE = BuildConfig.BASE_PACKAGE_NAME + ".android.gms.gcm.SERVICE_ACTION_INITIALIZE"; - public static final String ACTION_INSTANCE_ID = BuildConfig.BASE_PACKAGE_NAME + ".android.gms.iid.InstanceID"; + public static final String ACTION_C2DM_RECEIVE = "com.mgoogle.android.c2dm.intent.RECEIVE"; + public static final String ACTION_C2DM_REGISTER = "com.mgoogle.android.c2dm.intent.REGISTER"; + public static final String ACTION_C2DM_REGISTRATION = "com.mgoogle.android.c2dm.intent.REGISTRATION"; + public static final String ACTION_C2DM_UNREGISTER = "com.mgoogle.android.c2dm.intent.UNREGISTER"; public static final String EXTRA_APP = "app"; public static final String EXTRA_APP_OVERRIDE = "org.microg.gms.gcm.APP_OVERRIDE"; - public static final String EXTRA_APP_ID = "appid"; - public static final String EXTRA_APP_VERSION_CODE = "app_ver"; public static final String EXTRA_APP_VERSION_NAME = "app_ver_name"; - public static final String EXTRA_CLIENT_VERSION = "cliv"; - public static final String EXTRA_COMPONENT = "component"; public static final String EXTRA_COLLAPSE_KEY = "collapse_key"; - public static final String EXTRA_DELAY = "google.delay"; public static final String EXTRA_DELETE = "delete"; public static final String EXTRA_ERROR = "error"; public static final String EXTRA_FROM = "from"; - public static final String EXTRA_GSF_INTENT = "GSF"; - public static final String EXTRA_GMS_VERSION = "gmsv"; - public static final String EXTRA_IS_MESSENGER2 = "messenger2"; public static final String EXTRA_KID = "kid"; public static final String EXTRA_MESSENGER = "google.messenger"; - public static final String EXTRA_MESSAGE_TYPE = "message_type"; public static final String EXTRA_MESSAGE_ID = "google.message_id"; - public static final String EXTRA_OS_VERSION = "osv"; - public static final String EXTRA_PENDING_INTENT = BuildConfig.BASE_PACKAGE_NAME + ".android.gms.gcm.PENDING_INTENT"; - public static final String EXTRA_PUBLIC_KEY = "pub2"; - public static final String EXTRA_RAWDATA = "rawData"; - public static final String EXTRA_RAWDATA_BASE64 = "gcm.rawData64"; public static final String EXTRA_REGISTRATION_ID = "registration_id"; public static final String EXTRA_RETRY_AFTER = "Retry-After"; - public static final String EXTRA_SCHEDULER_ACTION = "scheduler_action"; - public static final String EXTRA_SCOPE = "scope"; public static final String EXTRA_SENDER = "sender"; - public static final String EXTRA_SENDER_LEGACY = "legacy.sender"; public static final String EXTRA_SEND_TO = "google.to"; public static final String EXTRA_SEND_FROM = "google.from"; - public static final String EXTRA_SIGNATURE = "sig"; - public static final String EXTRA_SUBSCIPTION = "subscription"; - public static final String EXTRA_SUBTYPE = "subtype"; - public static final String EXTRA_USE_GSF = "useGsf"; - public static final String EXTRA_TAG = "tag"; - public static final String EXTRA_TOPIC = "gcm.topic"; public static final String EXTRA_TTL = "google.ttl"; public static final String EXTRA_UNREGISTERED = "unregistered"; - public static final String MESSAGE_TYPE_GCM = "gcm"; - public static final String MESSAGE_TYPE_DELETED_MESSAGE = "deleted_message"; - public static final String MESSAGE_TYPE_SEND_ERROR = "send_error"; - public static final String MESSAGE_TYPE_SEND_EVENT = "send_event"; - - public static final String SCHEDULER_ACTION_CANCEL = "CANCEL_TASK"; - public static final String SCHEDULER_ACTION_CANCEL_ALL = "CANCEL_ALL"; - public static final String SCHEDULER_ACTION_SCHEDULE = "SCHEDULE_TASK"; - - public static final String PERMISSION_GTALK = BuildConfig.BASE_PACKAGE_NAME + ".android.gtalkservice.permission.GTALK_SERVICE"; - public static final String PERMISSION_NETWORK_TASK = BuildConfig.BASE_PACKAGE_NAME + ".android.gms.permission.BIND_NETWORK_TASK_SERVICE"; - public static final String PERMISSION_RECEIVE = BuildConfig.BASE_PACKAGE_NAME + ".android.c2dm.permission.RECEIVE"; - public static final String PERMISSION_SEND = BuildConfig.BASE_PACKAGE_NAME + ".android.c2dm.permission.SEND"; - public static final String ERROR_SERVICE_NOT_AVAILABLE = "SERVICE_NOT_AVAILABLE"; - - public static final String INSTANCE_ID_SCOPE_GCM = "GCM"; - - public static final String GCMID_INSTANCE_ID = "google.com/iid"; - public static final String GCMID_REFRESH = "gcm.googleapis.com/refresh"; } diff --git a/play-services-basement/src/main/kotlin/com/google/android/gms/dynamic/ObjectWrapper.kt b/play-services-basement/src/main/kotlin/com/google/android/gms/dynamic/ObjectWrapper.kt index 06c131ab..27996b8f 100644 --- a/play-services-basement/src/main/kotlin/com/google/android/gms/dynamic/ObjectWrapper.kt +++ b/play-services-basement/src/main/kotlin/com/google/android/gms/dynamic/ObjectWrapper.kt @@ -14,9 +14,5 @@ * limitations under the License. */ -package org.microg.gms.kotlin +package com.google.android.gms.dynamic -import com.google.android.gms.dynamic.IObjectWrapper -import com.google.android.gms.dynamic.ObjectWrapper - -inline fun IObjectWrapper?.unwrap(): T? = ObjectWrapper.unwrapTyped(this, T::class.java) diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index 22e0b42c..2449e81f 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -23,8 +23,6 @@ dependencies { implementation "de.hdodenhof:circleimageview:$circleimageviewVersion" implementation "androidx.webkit:webkit:$webkitVersion" - implementation project(':fake-signature') - implementation project(':play-services-base-core') implementation project(':play-services-core-proto') implementation project(':play-services-core:microg-ui-tools') // deprecated @@ -49,41 +47,21 @@ dependencies { } android { - namespace "${basePackageName}.android.gms" - compileSdkVersion androidCompileSdk buildToolsVersion androidBuildVersionTools defaultConfig { versionName version versionCode appVersionCode - resourceConfigurations += ['xxhdpi'] + resConfigs 'xxhdpi' minSdkVersion androidMinSdk targetSdkVersion androidTargetSdk - buildConfigField "String", "BASE_PACKAGE_NAME", "\"$basePackageName\"" - - multiDexEnabled true - multiDexKeepProguard file('multidex-keep.pro') - ndk { abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64" } - buildConfigField "String", "APPLICATION_NAMESPACE", "\"${android.namespace}\"" - buildConfigField "String", "BASE_PACKAGE_NAME", "\"$basePackageName\"" - manifestPlaceholders = [ - basePackageName: "$basePackageName" - ] - - // provide package name to xml resources - resValue "string", "var_authenticator_account_type", "$basePackageName" - resValue "string", "var_contact_syncadapter_account_type", "$basePackageName" - resValue "string", "var_pref_auth_action_security_settings", "${basePackageName}.android.gms.accountsettings.SECURITY_SETTINGS" - resValue "string", "var_pref_auth_action_privacy_settings", "${basePackageName}.android.gms.accountsettings.PRIVACY_SETTINGS" - resValue "string", "var_pref_auth_action_preferences_settings", "${basePackageName}.android.gms.accountsettings.ACCOUNT_PREFERENCES_SETTINGS" - resValue "string", "var_pref_start_gms_package", "${basePackageName}.android.gms" } buildFeatures { @@ -97,9 +75,6 @@ android { } } - lintOptions { - disable 'MissingTranslation', 'GetLocales', 'BatteryLife', 'ImpliedQuantity', 'MissingQuantity', 'InvalidWakeLockTag', 'Range' - } buildTypes { release { @@ -114,11 +89,17 @@ android { } packagingOptions { - exclude 'META-INF/ASL2.0' jniLibs { - useLegacyPackaging true + useLegacyPackaging false + } + resources { + excludes += ['META-INF/ASL2.0'] } } + lint { + disable 'MissingTranslation', 'BatteryLife', 'ImpliedQuantity', 'MissingQuantity', 'InvalidWakeLockTag', 'Range' + } + namespace 'com.mgoogle.android.gms' } if (file('user.gradle').exists()) { diff --git a/play-services-core/microg-ui-tools/build.gradle b/play-services-core/microg-ui-tools/build.gradle index 260aa6a5..d9a5c2bb 100644 --- a/play-services-core/microg-ui-tools/build.gradle +++ b/play-services-core/microg-ui-tools/build.gradle @@ -23,20 +23,17 @@ android { defaultConfig { minSdkVersion androidMinSdk targetSdkVersion androidTargetSdk - - buildConfigField "String", "GMS_APPLICATION_NAMESPACE", "\"$applicationNamespace\"" } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 11 + targetCompatibility = 11 } - - lintOptions { - // TODO: Remove MissingTranslation once we have stable strings and proper translations. - disable 'MissingTranslation', 'GetLocales' + lint { + disable 'MissingTranslation' } namespace 'org.microg.tools.ui' + } dependencies { diff --git a/play-services-core/microg-ui-tools/src/main/AndroidManifest.xml b/play-services-core/microg-ui-tools/src/main/AndroidManifest.xml deleted file mode 100644 index 359a9b71..00000000 --- a/play-services-core/microg-ui-tools/src/main/AndroidManifest.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractAboutFragment.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractAboutFragment.java index bb065aca..b77ea4ce 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractAboutFragment.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractAboutFragment.java @@ -29,6 +29,7 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -64,7 +65,7 @@ public abstract class AbstractAboutFragment extends Fragment { } protected String getAppName() { - return getAppName(getContext()); + return getAppName(requireContext()); } public static String getLibVersion(String packageName) { @@ -82,7 +83,7 @@ public abstract class AbstractAboutFragment extends Fragment { } protected String getSelfVersion() { - return getSelfVersion(getContext()); + return getSelfVersion(requireContext()); } protected String getSummary() { @@ -93,7 +94,7 @@ public abstract class AbstractAboutFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View aboutRoot = inflater.inflate(R.layout.about_root, container, false); - ((ImageView) aboutRoot.findViewById(android.R.id.icon)).setImageDrawable(getIcon(getContext())); + ((ImageView) aboutRoot.findViewById(android.R.id.icon)).setImageDrawable(getIcon(requireContext())); ((TextView) aboutRoot.findViewById(android.R.id.title)).setText(getAppName()); ((TextView) aboutRoot.findViewById(R.id.about_version)).setText(getString(R.string.about_version_str, getSelfVersion())); String summary = getSummary(); @@ -136,6 +137,7 @@ public abstract class AbstractAboutFragment extends Fragment { this.copyright = copyright; } + @NonNull @Override public String toString() { return name + ", " + copyright; diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractDashboardActivity.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractDashboardActivity.java index 30bf98c8..85bc123f 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractDashboardActivity.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractDashboardActivity.java @@ -66,22 +66,6 @@ public abstract class AbstractDashboardActivity extends AppCompatActivity { resetConditionViews(); } - protected void addAllConditions(Condition[] conditions) { - for (Condition condition : conditions) { - addCondition(condition); - } - } - - protected void addCondition(Condition condition) { - conditions.add(condition); - if (conditionContainer == null) return; - if (condition.isEvaluated()) { - addConditionToView(condition); - } else { - evaluateConditionAsync(condition); - } - } - private synchronized void addConditionToView(Condition condition) { for (int i = 0; i < conditionContainer.getChildCount(); i++) { if (conditionContainer.getChildAt(i).getTag() == condition) return; @@ -89,11 +73,6 @@ public abstract class AbstractDashboardActivity extends AppCompatActivity { conditionContainer.addView(condition.createView(this, conditionContainer)); } - protected void clearConditions() { - conditions.clear(); - resetConditionViews(); - } - protected Fragment getFragment() { if (preferencesResource == 0) { throw new IllegalStateException("Neither preferencesResource given, nor overriden getFragment()"); diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSettingsActivity.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSettingsActivity.java index 2b0542a5..db1da7b2 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSettingsActivity.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSettingsActivity.java @@ -3,15 +3,15 @@ package org.microg.tools.ui; import android.os.Bundle; import android.view.MenuItem; import android.view.ViewGroup; -import androidx.appcompat.widget.Toolbar; + import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentTransaction; + +import java.util.Objects; public abstract class AbstractSettingsActivity extends AppCompatActivity { protected boolean showHomeAsUp = false; protected int preferencesResource = 0; - private ViewGroup customBarContainer; protected int customBarLayout = 0; protected SwitchBar switchBar; @@ -19,14 +19,13 @@ public abstract class AbstractSettingsActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.settings_activity); - setSupportActionBar((Toolbar) findViewById(R.id.toolbar)); if (showHomeAsUp) { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); + Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); } switchBar = (SwitchBar) findViewById(R.id.switch_bar); - customBarContainer = (ViewGroup) findViewById(R.id.custom_bar); + ViewGroup customBarContainer = (ViewGroup) findViewById(R.id.custom_bar); if (customBarLayout != 0) { customBarContainer.addView(getLayoutInflater().inflate(customBarLayout, customBarContainer, false)); } @@ -36,26 +35,6 @@ public abstract class AbstractSettingsActivity extends AppCompatActivity { .commit(); } - public void setCustomBarLayout(int layout) { - customBarLayout = layout; - if (customBarContainer != null) { - customBarContainer.removeAllViews(); - customBarContainer.addView(getLayoutInflater().inflate(customBarLayout, customBarContainer, false)); - } - } - - public SwitchBar getSwitchBar() { - return switchBar; - } - - public void replaceFragment(Fragment fragment) { - getSupportFragmentManager().beginTransaction() - .addToBackStack("root") - .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) - .replace(R.id.content_wrapper, fragment) - .commit(); - } - @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSettingsFragment.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSettingsFragment.java index 0f1967a5..78ac70b0 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSettingsFragment.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSettingsFragment.java @@ -16,6 +16,7 @@ package org.microg.tools.ui; +import androidx.annotation.NonNull; import androidx.fragment.app.DialogFragment; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; @@ -26,10 +27,11 @@ public abstract class AbstractSettingsFragment extends PreferenceFragmentCompat private static final String DIALOG_FRAGMENT_TAG = "androidx.preference.PreferenceFragment.DIALOG"; @Override - public void onDisplayPreferenceDialog(Preference preference) { + public void onDisplayPreferenceDialog(@NonNull Preference preference) { if (preference instanceof DialogPreference) { DialogFragment f = DialogPreference.DialogPreferenceCompatDialogFragment.newInstance(preference.getKey()); f.setTargetFragment(this, 0); + assert getFragmentManager() != null; f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG); } else { super.onDisplayPreferenceDialog(preference); diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/Condition.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/Condition.java index 5adeeb88..c94b3bd6 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/Condition.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/Condition.java @@ -192,6 +192,7 @@ public class Condition { public synchronized void evaluate(Context context) { active = evaluation == null || evaluation.isActive(context); + assert evaluation != null; evaluatedPlurals = evaluation.getPluralsCount(); evaluated = true; evaluating = false; @@ -222,29 +223,40 @@ public class Condition { @StringRes private int titleRes; @PluralsRes - private int titlePluralsRes; + private final int titlePluralsRes; private CharSequence title; @StringRes private int summaryRes; @PluralsRes - private int summaryPluralsRes; + private final int summaryPluralsRes; private CharSequence summary; @StringRes - private int firstActionTextRes; + private final int firstActionTextRes; @PluralsRes - private int firstActionPluralsRes; - private CharSequence firstActionText; - private View.OnClickListener firstActionListener; + private final int firstActionPluralsRes; + private final CharSequence firstActionText; + private final View.OnClickListener firstActionListener; @StringRes - private int secondActionTextRes; + private final int secondActionTextRes; @PluralsRes - private int secondActionPluralsRes; - private CharSequence secondActionText; - private View.OnClickListener secondActionListener; - private Evaluation evaluation; + private final int secondActionPluralsRes; + private final CharSequence secondActionText; + private final View.OnClickListener secondActionListener; + private final Evaluation evaluation; - public Builder() { + public Builder(int titlePluralsRes, int summaryPluralsRes, int firstActionTextRes, int firstActionPluralsRes, CharSequence firstActionText, View.OnClickListener firstActionListener, int secondActionTextRes, int secondActionPluralsRes, CharSequence secondActionText, View.OnClickListener secondActionListener, Evaluation evaluation) { + this.titlePluralsRes = titlePluralsRes; + this.summaryPluralsRes = summaryPluralsRes; + this.firstActionTextRes = firstActionTextRes; + this.firstActionPluralsRes = firstActionPluralsRes; + this.firstActionText = firstActionText; + this.firstActionListener = firstActionListener; + this.secondActionTextRes = secondActionTextRes; + this.secondActionPluralsRes = secondActionPluralsRes; + this.secondActionText = secondActionText; + this.secondActionListener = secondActionListener; + this.evaluation = evaluation; } public Builder icon(Drawable val) { @@ -267,11 +279,6 @@ public class Condition { return this; } - public Builder titlePlurals(@PluralsRes int val) { - titlePluralsRes = val; - return this; - } - public Builder summary(CharSequence val) { summary = val; return this; @@ -282,52 +289,6 @@ public class Condition { return this; } - public Builder summaryPlurals(@PluralsRes int val) { - summaryPluralsRes = val; - return this; - } - - public Builder firstAction(CharSequence text, View.OnClickListener listener) { - firstActionText = text; - firstActionListener = listener; - return this; - } - - public Builder firstAction(@StringRes int val, View.OnClickListener listener) { - firstActionTextRes = val; - firstActionListener = listener; - return this; - } - - public Builder firstActionPlurals(@PluralsRes int val, View.OnClickListener listener) { - firstActionPluralsRes = val; - firstActionListener = listener; - return this; - } - - public Builder secondAction(CharSequence text, View.OnClickListener listener) { - secondActionText = text; - secondActionListener = listener; - return this; - } - - public Builder secondAction(@StringRes int val, View.OnClickListener listener) { - secondActionTextRes = val; - secondActionListener = listener; - return this; - } - - public Builder secondActionPlurals(@PluralsRes int val, View.OnClickListener listener) { - secondActionPluralsRes = val; - secondActionListener = listener; - return this; - } - - public Builder evaluation(Evaluation evaluation) { - this.evaluation = evaluation; - return this; - } - public Condition build() { return new Condition(this); } diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/DialogPreference.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/DialogPreference.java index af07a691..b5335089 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/DialogPreference.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/DialogPreference.java @@ -24,6 +24,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; +import androidx.annotation.NonNull; import androidx.fragment.app.DialogFragment; import androidx.preference.Preference; import androidx.preference.PreferenceDialogFragmentCompat; @@ -59,22 +60,21 @@ public class DialogPreference extends androidx.preference.DialogPreference imple * Called when the dialog is dismissed and should be used to save data to * the {@link SharedPreferences}. * - * @param positiveResult Whether the positive button was clicked (true), or - * the negative button was clicked or the dialog was canceled (false). */ - protected void onDialogClosed(boolean positiveResult) { + protected void onDialogClosed() { } @Override - public boolean onPreferenceDisplayDialog(PreferenceFragmentCompat caller, Preference pref) { + public boolean onPreferenceDisplayDialog(@NonNull PreferenceFragmentCompat caller, @NonNull Preference pref) { DialogPreferenceCompatDialogFragment fragment = new DialogPreferenceCompatDialogFragment(); fragment.setTargetFragment(caller, 0); + assert caller.getFragmentManager() != null; fragment.show(caller.getFragmentManager(), DIALOG_FRAGMENT_TAG); return true; } @Override - public void onBindViewHolder(PreferenceViewHolder view) { + public void onBindViewHolder(@NonNull PreferenceViewHolder view) { super.onBindViewHolder(view); ViewGroup.LayoutParams layoutParams = view.findViewById(R.id.icon_frame).getLayoutParams(); @@ -88,7 +88,7 @@ public class DialogPreference extends androidx.preference.DialogPreference imple public static class DialogPreferenceCompatDialogFragment extends PreferenceDialogFragmentCompat { @Override - protected View onCreateDialogView(Context context) { + protected View onCreateDialogView(@NonNull Context context) { if (getPreference() instanceof DialogPreference) { View view = ((DialogPreference) getPreference()).onCreateDialogView(); if (view != null) return view; @@ -99,7 +99,7 @@ public class DialogPreference extends androidx.preference.DialogPreference imple @Override public void onDialogClosed(boolean positiveResult) { if (getPreference() instanceof DialogPreference) { - ((DialogPreference) getPreference()).onDialogClosed(positiveResult); + ((DialogPreference) getPreference()).onDialogClosed(); } } diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/LongTextPreference.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/LongTextPreference.java deleted file mode 100644 index 4c6edb8b..00000000 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/LongTextPreference.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.tools.ui; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.TextView; - -import androidx.preference.Preference; -import androidx.preference.PreferenceViewHolder; - -public class LongTextPreference extends Preference { - - public LongTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - public LongTextPreference(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public LongTextPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public LongTextPreference(Context context) { - super(context); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - TextView view = (TextView) holder.findViewById(android.R.id.summary); - if (view != null) { - view.setMaxLines(Integer.MAX_VALUE); - } - } -} diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/RadioButtonPreference.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/RadioButtonPreference.java deleted file mode 100644 index e45d3812..00000000 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/RadioButtonPreference.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.tools.ui; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.util.AttributeSet; - -import androidx.core.content.res.TypedArrayUtils; -import androidx.preference.CheckBoxPreference; - -public class RadioButtonPreference extends CheckBoxPreference { - - public RadioButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) { - this(context, attrs, defStyleAttr, 0); - } - - public RadioButtonPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - setWidgetLayoutResource(R.layout.preference_widget_radiobutton); - } - - @SuppressLint("RestrictedApi") - public RadioButtonPreference(Context context, AttributeSet attrs) { - this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.checkBoxPreferenceStyle, - android.R.attr.checkBoxPreferenceStyle)); - } - - public RadioButtonPreference(Context context) { - this(context, null); - } -} diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBar.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBar.java index b9144222..0a30f683 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBar.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBar.java @@ -116,39 +116,12 @@ public class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedC mSwitch.setChecked(checked); } - public void setCheckedInternal(boolean checked) { - setTextViewLabel(checked); - mSwitch.setCheckedInternal(checked); - } - - public boolean isChecked() { - return mSwitch.isChecked(); - } - public void setEnabled(boolean enabled) { super.setEnabled(enabled); mTextView.setEnabled(enabled); mSwitch.setEnabled(enabled); } - public final ToggleSwitch getSwitch() { - return mSwitch; - } - - public void show() { - if (!isShowing()) { - setVisibility(View.VISIBLE); - mSwitch.setOnCheckedChangeListener(this); - } - } - - public void hide() { - if (isShowing()) { - setVisibility(View.GONE); - mSwitch.setOnCheckedChangeListener(null); - } - } - public boolean isShowing() { return (getVisibility() == View.VISIBLE); } @@ -178,13 +151,6 @@ public class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedC mSwitchChangeListeners.add(listener); } - public void removeOnSwitchChangeListener(OnSwitchChangeListener listener) { - if (!mSwitchChangeListeners.contains(listener)) { - throw new IllegalStateException("Cannot remove OnSwitchChangeListener"); - } - mSwitchChangeListeners.remove(listener); - } - static class SavedState extends BaseSavedState { boolean checked; boolean visible; diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/ToggleSwitch.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/ToggleSwitch.java index 6530319e..3a3a7bb3 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/ToggleSwitch.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/ToggleSwitch.java @@ -44,10 +44,6 @@ public class ToggleSwitch extends SwitchMaterial { super(context, attrs, defStyleAttr); } - public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) { - mOnBeforeListener = listener; - } - @Override public void setChecked(boolean checked) { if (mOnBeforeListener != null diff --git a/play-services-core/microg-ui-tools/src/main/res/layout/settings_activity.xml b/play-services-core/microg-ui-tools/src/main/res/layout/settings_activity.xml index e5f71828..a664de26 100644 --- a/play-services-core/microg-ui-tools/src/main/res/layout/settings_activity.xml +++ b/play-services-core/microg-ui-tools/src/main/res/layout/settings_activity.xml @@ -19,14 +19,6 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - diff --git a/play-services-core/multidex-keep.pro b/play-services-core/multidex-keep.pro deleted file mode 100644 index 0cd8699e..00000000 --- a/play-services-core/multidex-keep.pro +++ /dev/null @@ -1,9 +0,0 @@ -# Make sure maps is in the primary dex file --keep class com.google.android.gms.maps.** { *; } --keep class org.microg.gms.maps.** { *; } --keep class com.mapbox.** { *; } --keep class org.oscim.** { *; } - -# Keep Conscrypt in the primary dex file otherwise it will error out on legacy Android versions --keep class com.google.android.gms.common.security.ProviderInstallerImpl { *; } --keep class com.google.android.gms.org.conscrypt.** { *; } diff --git a/play-services-core/proguard-rules.pro b/play-services-core/proguard-rules.pro index 923a7661..9b421ddd 100644 --- a/play-services-core/proguard-rules.pro +++ b/play-services-core/proguard-rules.pro @@ -21,13 +21,10 @@ # Keep dynamically loaded GMS classes -keep public class com.google.android.gms.common.security.ProviderInstallerImpl { public *; } --keep public class com.google.android.gms.dynamic.IObjectWrapper { public *; } --keep public class com.google.android.gms.dynamite.descriptors.** { public *; } # Keep AutoSafeParcelables -keep public class * extends org.microg.safeparcel.AutoSafeParcelable { @org.microg.safeparcel.SafeParceled *; - (...); } # Keep form data diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml index 5a42409c..fd9bd743 100644 --- a/play-services-core/src/main/AndroidManifest.xml +++ b/play-services-core/src/main/AndroidManifest.xml @@ -18,45 +18,39 @@ xmlns:tools="http://schemas.android.com/tools"> - - - + + @@ -65,17 +59,15 @@ - - - - + + + - + @@ -94,28 +86,32 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:multiArch="true" - android:theme="@style/Theme.App" + android:theme="@style/AppTheme" android:networkSecurityConfig="@xml/network_security_config" tools:targetApi="r"> - + + + + android:exported="false" /> @@ -139,16 +135,15 @@ - + - @@ -156,11 +151,11 @@ + android:process=":persistent" + android:exported="true"> - - + + @@ -168,10 +163,10 @@ + android:process=":persistent" + android:exported="true"> - + @@ -181,8 +176,8 @@ + android:process=":persistent" + android:exported="true"> @@ -194,8 +189,8 @@ + android:process=":persistent" + android:exported="true"> @@ -218,8 +213,8 @@ + android:process=":persistent" + android:exported="true"> @@ -237,7 +232,7 @@ - + + android:process=":ui"> @@ -263,7 +257,7 @@ @@ -285,13 +279,13 @@ + android:process=":ui" + android:exported="true"> @@ -321,14 +315,14 @@ + android:theme="@style/AppTheme" + android:exported="true"> @@ -339,7 +333,7 @@ @@ -353,13 +347,13 @@ + android:theme="@style/AppTheme" + android:exported="true"> @@ -375,15 +369,6 @@ android:resource="@string/gms_settings_summary" /> - - - - - - + android:exported="true"> - + - - - - - - - - - = 29) { + if (Build.VERSION.SDK_INT >= 29) { return context.getOpPackageName(); } Context applicationContext = context.getApplicationContext(); diff --git a/play-services-core/src/main/java/org/microg/gms/auth/AccountContentProvider.java b/play-services-core/src/main/java/org/microg/gms/auth/AccountContentProvider.java index 9274f439..9c96646b 100644 --- a/play-services-core/src/main/java/org/microg/gms/auth/AccountContentProvider.java +++ b/play-services-core/src/main/java/org/microg/gms/auth/AccountContentProvider.java @@ -17,7 +17,6 @@ package org.microg.gms.auth; import static android.accounts.AccountManager.VISIBILITY_VISIBLE; -import static android.os.Build.VERSION.SDK_INT; import android.Manifest; import android.accounts.Account; @@ -28,6 +27,7 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.util.Log; @@ -36,7 +36,6 @@ import androidx.annotation.Nullable; import org.microg.gms.common.PackageUtils; import java.util.Arrays; -import java.util.Objects; import static org.microg.gms.auth.AuthConstants.DEFAULT_ACCOUNT_TYPE; import static org.microg.gms.auth.AuthConstants.PROVIDER_EXTRA_ACCOUNTS; @@ -55,10 +54,11 @@ public class AccountContentProvider extends ContentProvider { @Nullable @Override public Bundle call(String method, String arg, Bundle extras) { - String suggestedPackageName = getCallingPackage(); + String suggestedPackageName; + suggestedPackageName = getCallingPackage(); String packageName = PackageUtils.getAndCheckCallingPackage(getContext(), suggestedPackageName); Log.d(TAG, "Call " + method + " from " + packageName + " with arg " + arg); - if (!PackageUtils.callerHasExtendedAccess(Objects.requireNonNull(getContext()))) { + if (!PackageUtils.callerHasExtendedAccess(getContext())) { String[] packagesForUid = getContext().getPackageManager().getPackagesForUid(Binder.getCallingUid()); if (packagesForUid != null && packagesForUid.length != 0) Log.w(TAG, "Not granting extended access to " + Arrays.toString(packagesForUid) @@ -72,10 +72,10 @@ public class AccountContentProvider extends ContentProvider { if (arg != null && (arg.equals(DEFAULT_ACCOUNT_TYPE) || arg.startsWith(DEFAULT_ACCOUNT_TYPE + "."))) { AccountManager am = AccountManager.get(getContext()); accounts = am.getAccountsByTypeForPackage(arg, packageName); - if (accounts.length == 0) { + if (accounts == null || accounts.length == 0) { accounts = am.getAccountsByType(arg); } - if (SDK_INT >= 26 && arg.equals(DEFAULT_ACCOUNT_TYPE)) { + if (Build.VERSION.SDK_INT >= 26 && accounts != null && arg.equals(DEFAULT_ACCOUNT_TYPE)) { for (Account account : accounts) { if (am.getAccountVisibility(account, packageName) == AccountManager.VISIBILITY_UNDEFINED) { Log.d(TAG, "Make account " + account + " visible to " + packageName); diff --git a/play-services-core/src/main/java/org/microg/gms/auth/AuthManager.java b/play-services-core/src/main/java/org/microg/gms/auth/AuthManager.java index 57b6a516..73adeabf 100644 --- a/play-services-core/src/main/java/org/microg/gms/auth/AuthManager.java +++ b/play-services-core/src/main/java/org/microg/gms/auth/AuthManager.java @@ -18,25 +18,24 @@ package org.microg.gms.auth; import static android.content.pm.ApplicationInfo.FLAG_SYSTEM; import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; -import static android.os.Build.VERSION.SDK_INT; import static org.microg.gms.auth.AuthPrefs.isTrustGooglePermitted; import android.accounts.Account; import android.accounts.AccountManager; import android.content.Context; import android.content.pm.PackageManager; +import android.os.Build; import android.util.Log; -import org.microg.gms.base.core.BuildConfig; import org.microg.gms.common.PackageUtils; -import org.microg.gms.settings.SettingsContract; +import org.microg.mgms.settings.SettingsContract; import java.io.IOException; public class AuthManager { private static final String TAG = "GmsAuthManager"; - public static final String PERMISSION_TREE_BASE = BuildConfig.BASE_PACKAGE_NAME + ".android.googleapps.permission.GOOGLE_AUTH."; + public static final String PERMISSION_TREE_BASE = "com.mgoogle.android.googleapps.permission.GOOGLE_AUTH."; public static final String PREF_AUTH_VISIBLE = SettingsContract.Auth.VISIBLE; public static final int ONE_HOUR_IN_SECONDS = 60 * 60; @@ -105,7 +104,7 @@ public class AuthManager { public void setPermitted(boolean value) { setUserData(buildPermKey(), value ? "1" : "0"); - if (SDK_INT >= 26 && value && packageName != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && value && packageName != null) { // Make account persistently visible as we already granted access accountManager.setAccountVisibility(getAccount(), packageName, AccountManager.VISIBILITY_VISIBLE); } @@ -170,7 +169,7 @@ public class AuthManager { public void setAuthToken(String service, String auth) { getAccountManager().setAuthToken(getAccount(), buildTokenKey(service), auth); - if (SDK_INT >= 26 && packageName != null && auth != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && packageName != null && auth != null) { // Make account persistently visible as we already granted access accountManager.setAccountVisibility(getAccount(), packageName, AccountManager.VISIBILITY_VISIBLE); } diff --git a/play-services-core/src/main/java/org/microg/gms/auth/AuthManagerServiceImpl.java b/play-services-core/src/main/java/org/microg/gms/auth/AuthManagerServiceImpl.java index 7f57a370..5ddf9d28 100644 --- a/play-services-core/src/main/java/org/microg/gms/auth/AuthManagerServiceImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/auth/AuthManagerServiceImpl.java @@ -16,29 +16,28 @@ package org.microg.gms.auth; +import static android.accounts.AccountManager.KEY_ACCOUNTS; +import static android.accounts.AccountManager.KEY_ACCOUNT_NAME; +import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE; +import static android.accounts.AccountManager.KEY_AUTHTOKEN; +import static android.accounts.AccountManager.KEY_CALLER_PID; + import android.accounts.Account; import android.accounts.AccountManager; import android.annotation.SuppressLint; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.Context; -import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Parcel; import android.os.RemoteException; -import android.util.Base64; import android.util.Log; -import androidx.core.app.NotificationCompat; - import com.google.android.auth.IAuthManagerService; -import com.mgoogle.android.gms.R; import com.google.android.gms.auth.AccountChangeEventsRequest; import com.google.android.gms.auth.AccountChangeEventsResponse; import com.google.android.gms.auth.GetHubTokenInternalResponse; import com.google.android.gms.auth.GetHubTokenRequest; -import com.google.android.gms.auth.HasCapabilitiesRequest; +import com.google.android.gms.auth.HasCababilitiesRequest; import com.google.android.gms.auth.TokenData; import com.google.android.gms.common.api.Scope; @@ -46,13 +45,9 @@ import org.microg.gms.common.PackageUtils; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import static android.accounts.AccountManager.*; -import static android.os.Build.VERSION.SDK_INT; - public class AuthManagerServiceImpl extends IAuthManagerService.Stub { private static final String TAG = "GmsAuthManagerSvc"; @@ -67,11 +62,8 @@ public class AuthManagerServiceImpl extends IAuthManagerService.Stub { public static final String KEY_REQUEST_VISIBLE_ACTIVITIES = "request_visible_actions"; public static final String KEY_SUPPRESS_PROGRESS_SCREEN = "suppressProgressScreen"; public static final String KEY_SYNC_EXTRAS = "sync_extras"; - public static final String KEY_DELEGATION_TYPE = "delegation_type"; - public static final String KEY_DELEGATEE_USER_ID = "delegatee_user_id"; public static final String KEY_ERROR = "Error"; - public static final String KEY_USER_RECOVERY_INTENT = "userRecoveryIntent"; private final Context context; @@ -115,8 +107,7 @@ public class AuthManagerServiceImpl extends IAuthManagerService.Stub { packageName = PackageUtils.getAndCheckCallingPackage(context, packageName, extras.getInt(KEY_CALLER_UID, 0), extras.getInt(KEY_CALLER_PID, 0)); boolean notify = extras.getBoolean(KEY_HANDLE_NOTIFICATION, false); - if (!AuthConstants.SCOPE_GET_ACCOUNT_ID.equals(scope)) - Log.d(TAG, "getToken: account:" + account.name + " scope:" + scope + " extras:" + extras + ", notify: " + notify); + Log.d(TAG, "getToken: account:" + account.name + " scope:" + scope + " extras:" + extras + ", notify: " + notify); /* * TODO: This scope seems to be invalid (according to https://developers.google.com/oauthplayground/), @@ -178,29 +169,18 @@ public class AuthManagerServiceImpl extends IAuthManagerService.Stub { } @Override - public Bundle requestGoogleAccountsAccess(String packageName) throws RemoteException { - PackageUtils.assertExtendedAccess(context); - if (SDK_INT >= 26) { - for (Account account : get(context).getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE)) { - AccountManager.get(context).setAccountVisibility(account, packageName, VISIBILITY_VISIBLE); - } - Bundle res = new Bundle(); - res.putString("Error", "Ok"); - return res; - } else { - Log.w(TAG, "Not implemented: requestGoogleAccountsAccess(" + packageName + ")"); - } + public Bundle requestGoogleAccountsAccess(String packageName) { + Log.w(TAG, "Not implemented: requestGoogleAccountsAccess(" + packageName + ")"); return null; } @Override - public int hasCapabilities(HasCapabilitiesRequest request) throws RemoteException { - Log.w(TAG, "Not implemented: hasCapabilities(" + request.account + ", " + Arrays.toString(request.capabilities) + ")"); + public int hasCapabilities(HasCababilitiesRequest request) { return 1; } @Override - public GetHubTokenInternalResponse getHubToken(GetHubTokenRequest request, Bundle extras) throws RemoteException { + public GetHubTokenInternalResponse getHubToken(GetHubTokenRequest request, Bundle extras) { Log.w(TAG, "Not implemented: getHubToken()"); return null; } @@ -214,11 +194,7 @@ public class AuthManagerServiceImpl extends IAuthManagerService.Stub { Log.d(TAG, "clearToken: token:" + token + " extras:" + extras); AccountManager.get(context).invalidateAuthToken(AuthConstants.DEFAULT_ACCOUNT_TYPE, token); - - Bundle res = new Bundle(); - res.putString("Error", "Ok"); - res.putBoolean("booleanResult", true); - return res; + return null; } @Override diff --git a/play-services-core/src/main/java/org/microg/gms/auth/AuthRequest.java b/play-services-core/src/main/java/org/microg/gms/auth/AuthRequest.java index e1b4749a..55ff536b 100644 --- a/play-services-core/src/main/java/org/microg/gms/auth/AuthRequest.java +++ b/play-services-core/src/main/java/org/microg/gms/auth/AuthRequest.java @@ -113,9 +113,7 @@ public class AuthRequest extends HttpFormClient.Request { public AuthRequest fromContext(Context context) { build(context); locale(Utils.getLocale(context)); - if (AuthPrefs.shouldIncludeAndroidId(context)) { - androidIdHex = Long.toHexString(LastCheckinInfo.read(context).getAndroidId()); - } + androidIdHex = Long.toHexString(LastCheckinInfo.read(context).getAndroidId()); return this; } diff --git a/play-services-core/src/main/java/org/microg/gms/auth/login/AssistantActivity.java b/play-services-core/src/main/java/org/microg/gms/auth/login/AssistantActivity.java index de9832e8..b4bea3f8 100644 --- a/play-services-core/src/main/java/org/microg/gms/auth/login/AssistantActivity.java +++ b/play-services-core/src/main/java/org/microg/gms/auth/login/AssistantActivity.java @@ -45,7 +45,7 @@ public abstract class AssistantActivity extends Activity { @SuppressLint("WrongViewCast") private void formatTitle() { if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { - double widthPixels = (double) (getResources().getDisplayMetrics().widthPixels); + double widthPixels = getResources().getDisplayMetrics().widthPixels; findViewById(R.id.title_container).getLayoutParams().height = (int) (dpToPx(TITLE_MIN_HEIGHT) + (TITLE_WIDTH_FACTOR * widthPixels)); } else { 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 f52b93c4..96d12f57 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 @@ -25,9 +25,9 @@ import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; import static org.microg.gms.auth.AuthPrefs.isAuthVisible; -import static org.microg.gms.checkin.CheckinPreferences.hideLauncherIcon; -import static org.microg.gms.checkin.CheckinPreferences.isSpoofingEnabled; -import static org.microg.gms.checkin.CheckinPreferences.setSpoofingEnabled; +import static org.microg.gms.checkin.CheckinPrefs.hideLauncherIcon; +import static org.microg.gms.checkin.CheckinPrefs.isSpoofingEnabled; +import static org.microg.gms.checkin.CheckinPrefs.setSpoofingEnabled; import static org.microg.gms.common.Constants.GMS_PACKAGE_NAME; import static org.microg.gms.common.Constants.GMS_VERSION_CODE; @@ -161,10 +161,8 @@ public class LoginActivity extends AssistantActivity { super.onHuaweiButtonClicked(); state++; if (state == 1) { - if (SDK_INT >= 23) { - hideLauncherIcon(this, false); - UtilsKt.hideIcon(this, false); - } + hideLauncherIcon(this, false); + UtilsKt.hideIcon(this, false); if (!isSpoofingEnabled(this)) { LastCheckinInfo.clear(this); setSpoofingEnabled(this, true); @@ -201,22 +199,12 @@ public class LoginActivity extends AssistantActivity { authContent.addView(loading); setMessage(R.string.auth_connecting); CookieManager.getInstance().setAcceptCookie(true); - if (SDK_INT >= 21) { - CookieManager.getInstance().removeAllCookies(value -> start()); - } else { - //noinspection deprecation - CookieManager.getInstance().removeAllCookie(); - start(); - } + CookieManager.getInstance().removeAllCookies(value -> start()); } private static WebView createWebView(Context context) { WebView webView = new WebView(context); - if (SDK_INT < 21) { - webView.setVisibility(VISIBLE); - } else { - webView.setVisibility(INVISIBLE); - } + webView.setVisibility(INVISIBLE); webView.setLayoutParams(new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); webView.setBackgroundColor(Color.TRANSPARENT); @@ -283,10 +271,6 @@ public class LoginActivity extends AssistantActivity { webView.loadUrl(buildUrl(tmpl, Utils.getLocale(this))); } - protected void runScript(String js) { - runOnUiThread(() -> webView.loadUrl("javascript:" + js)); - } - private void closeWeb(boolean programmaticAuth) { setMessage(R.string.auth_finalize); runOnUiThread(() -> webView.setVisibility(INVISIBLE)); @@ -422,32 +406,12 @@ public class LoginActivity extends AssistantActivity { Log.d(TAG, "JSBridge: addAccount"); } - @JavascriptInterface - public final void attemptLogin(String accountName, String password) { - Log.d(TAG, "JSBridge: attemptLogin"); - } - - @JavascriptInterface - public void backupSyncOptIn(String accountName) { - Log.d(TAG, "JSBridge: backupSyncOptIn"); - } - - @JavascriptInterface - public void clearOldLoginAttempts() { - Log.d(TAG, "JSBridge: clearOldLoginAttempts"); - } - @JavascriptInterface public final void closeView() { Log.d(TAG, "JSBridge: closeView"); closeWeb(false); } - @JavascriptInterface - public void fetchIIDToken(String entity) { - Log.d(TAG, "JSBridge: fetchIIDToken"); - } - @JavascriptInterface public final String fetchVerifiedPhoneNumber() { Log.d(TAG, "JSBridge: fetchVerifiedPhoneNumber"); @@ -482,17 +446,12 @@ public class LoginActivity extends AssistantActivity { @JavascriptInterface public final int getAuthModuleVersionCode() { - return GMS_VERSION_CODE; + return 1; } @JavascriptInterface public final int getBuildVersionSdk() { - return Build.VERSION.SDK_INT; - } - - @JavascriptInterface - public int getDeviceContactsCount() { - return -1; + return SDK_INT; } @JavascriptInterface @@ -566,40 +525,15 @@ public class LoginActivity extends AssistantActivity { } @JavascriptInterface - public final void setAccountIdentifier(String accountName) { + public final void setAccountIdentifier(String accountIdentifier) { Log.d(TAG, "JSBridge: setAccountIdentifier"); } - @JavascriptInterface - public void setAllActionsEnabled(boolean z) { - Log.d(TAG, "JSBridge: setAllActionsEnabled"); - } - @JavascriptInterface public final void setNewAccountCreated() { Log.d(TAG, "JSBridge: setNewAccountCreated"); } - @JavascriptInterface - public void setPrimaryActionEnabled(boolean z) { - Log.d(TAG, "JSBridge: setPrimaryActionEnabled"); - } - - @JavascriptInterface - public void setPrimaryActionLabel(String str, int i) { - Log.d(TAG, "JSBridge: setPrimaryActionLabel: " + str); - } - - @JavascriptInterface - public void setSecondaryActionEnabled(boolean z) { - Log.d(TAG, "JSBridge: setSecondaryActionEnabled"); - } - - @JavascriptInterface - public void setSecondaryActionLabel(String str, int i) { - Log.d(TAG, "JSBridge: setSecondaryActionLabel: " + str); - } - @JavascriptInterface public final void showKeyboard() { inputMethodManager.showSoftInput(webView, SHOW_IMPLICIT); diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinClient.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinClient.java index df7c245b..98598a09 100755 --- a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinClient.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinClient.java @@ -80,7 +80,8 @@ public class CheckinClient { DeviceIdentifier deviceIdent, PhoneInfo phoneInfo, LastCheckinInfo checkinInfo, Locale locale, List accounts, Boolean brandSpoof) { - CheckinRequest.Builder builder = new CheckinRequest.Builder() + CheckinRequest.Builder builder; + builder = new CheckinRequest.Builder() .accountCookie(new ArrayList<>()) .androidId(checkinInfo.getAndroidId()) .checkin(new CheckinRequest.Checkin.Builder() @@ -136,7 +137,7 @@ public class CheckinClient { .loggingId(new Random().nextLong()) // TODO: static .meid(deviceIdent.meid) .otaCert(Collections.singletonList("71Q6Rn2DDZl1zPDVaaeEHItd")) - .serial(Build.SERIAL != null && !Build.SERIAL.isEmpty() ? Build.SERIAL : null) + .serial(Build.SERIAL) .timeZone(TimeZone.getDefault().getID()) .userName((String) TODO) .userSerialNumber((Integer) TODO) diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java index b9432ac6..355800d1 100755 --- a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java @@ -16,7 +16,7 @@ package org.microg.gms.checkin; -import static org.microg.gms.checkin.CheckinPreferences.isSpoofingEnabled; +import static org.microg.gms.checkin.CheckinPrefs.isSpoofingEnabled; import android.accounts.Account; import android.accounts.AccountManager; @@ -43,7 +43,7 @@ public class CheckinManager { LastCheckinInfo info = LastCheckinInfo.read(context); if (!force && info.getLastCheckin() > System.currentTimeMillis() - MIN_CHECKIN_INTERVAL) return null; - if (!CheckinPreferences.isEnabled(context)) + if (!CheckinPrefs.isEnabled(context)) return null; List accounts = new ArrayList<>(); AccountManager accountManager = AccountManager.get(context); @@ -71,8 +71,7 @@ public class CheckinManager { ContentResolver resolver = context.getContentResolver(); for (CheckinResponse.GservicesSetting setting : response.setting) { - if (setting.name != null && setting.value_ != null) - GServices.setString(resolver, setting.name.utf8(), setting.value_.utf8()); + GServices.setString(resolver, setting.name.utf8(), setting.value_.utf8()); } return info; diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java index 3f53ebcd..bd5bfabb 100755 --- a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java @@ -80,7 +80,7 @@ public class CheckinService extends IntentService { protected void onHandleIntent(Intent intent) { try { ForegroundServiceContext.completeForegroundService(this, intent, TAG); - if (CheckinPreferences.isEnabled(this)) { + if (CheckinPrefs.isEnabled(this)) { LastCheckinInfo info = CheckinManager.checkin(this, intent.getBooleanExtra(EXTRA_FORCE_CHECKIN, false)); if (info != null) { Log.d(TAG, "Checked in as " + Long.toHexString(info.getAndroidId())); @@ -124,7 +124,7 @@ public class CheckinService extends IntentService { static void schedule(Context context) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - PendingIntent pendingIntent = PendingIntent.getService(context, TriggerReceiver.class.getName().hashCode(), new Intent(context, TriggerReceiver.class), PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); + PendingIntent pendingIntent = PendingIntent.getService(context, TriggerReceiver.class.getName().hashCode(), new Intent(context, TriggerReceiver.class), PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); alarmManager.set(AlarmManager.RTC, Math.max(LastCheckinInfo.read(context).getLastCheckin() + REGULAR_CHECKIN_INTERVAL, System.currentTimeMillis() + BACKUP_CHECKIN_DELAY), pendingIntent); } } diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java b/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java index e41a954b..4b6551bd 100755 --- a/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java @@ -18,6 +18,7 @@ package org.microg.gms.checkin; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.os.Build.VERSION.SDK_INT; import static org.microg.gms.checkin.CheckinService.EXTRA_FORCE_CHECKIN; import static org.microg.gms.checkin.CheckinService.REGULAR_CHECKIN_INTERVAL; @@ -41,7 +42,7 @@ public class TriggerReceiver extends WakefulBroadcastReceiver { try { boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction()); - if (CheckinPreferences.isEnabled(context) || force) { + if (CheckinPrefs.isEnabled(context) || force) { if (LastCheckinInfo.read(context).getLastCheckin() > System.currentTimeMillis() - REGULAR_CHECKIN_INTERVAL && !force) { CheckinService.schedule(context); return; @@ -53,7 +54,7 @@ public class TriggerReceiver extends WakefulBroadcastReceiver { Intent subIntent = new Intent(context, CheckinService.class); subIntent.putExtra(EXTRA_FORCE_CHECKIN, force); startWakefulService(new ForegroundServiceContext(context), subIntent); - } else { + } else if (SDK_INT >= 23) { // no network, register a network callback to retry when we have internet NetworkRequest networkRequest = new NetworkRequest.Builder() .addCapability(NET_CAPABILITY_INTERNET) diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/GcmDatabase.java b/play-services-core/src/main/java/org/microg/gms/gcm/GcmDatabase.java index d19ce6ea..d9881dd8 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/GcmDatabase.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/GcmDatabase.java @@ -10,6 +10,7 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.os.Build; import android.text.TextUtils; import java.util.ArrayList; @@ -54,7 +55,9 @@ public class GcmDatabase extends SQLiteOpenHelper { public GcmDatabase(Context context) { super(context, DB_NAME, null, DB_VERSION); this.context = context; - this.setWriteAheadLoggingEnabled(true); + if (Build.VERSION.SDK_INT >= 16) { + this.setWriteAheadLoggingEnabled(true); + } } public static class App { 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 343d1721..a21d9137 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 @@ -19,42 +19,8 @@ package org.microg.gms.gcm; import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.os.Build.VERSION.SDK_INT; import static org.microg.gms.common.PackageUtils.warnIfNotPersistentProcess; -import static org.microg.gms.gcm.GcmConstants.ACTION_C2DM_RECEIVE; -import static org.microg.gms.gcm.GcmConstants.EXTRA_APP; -import static org.microg.gms.gcm.GcmConstants.EXTRA_APP_OVERRIDE; -import static org.microg.gms.gcm.GcmConstants.EXTRA_COLLAPSE_KEY; -import static org.microg.gms.gcm.GcmConstants.EXTRA_FROM; -import static org.microg.gms.gcm.GcmConstants.EXTRA_MESSAGE_ID; -import static org.microg.gms.gcm.GcmConstants.EXTRA_MESSENGER; -import static org.microg.gms.gcm.GcmConstants.EXTRA_RAWDATA; -import static org.microg.gms.gcm.GcmConstants.EXTRA_RAWDATA_BASE64; -import static org.microg.gms.gcm.GcmConstants.EXTRA_REGISTRATION_ID; -import static org.microg.gms.gcm.GcmConstants.EXTRA_SEND_FROM; -import static org.microg.gms.gcm.GcmConstants.EXTRA_SEND_TO; -import static org.microg.gms.gcm.GcmConstants.EXTRA_TTL; -import static org.microg.gms.gcm.McsConstants.ACTION_ACK; -import static org.microg.gms.gcm.McsConstants.ACTION_CONNECT; -import static org.microg.gms.gcm.McsConstants.ACTION_HEARTBEAT; -import static org.microg.gms.gcm.McsConstants.ACTION_RECONNECT; -import static org.microg.gms.gcm.McsConstants.ACTION_SEND; -import static org.microg.gms.gcm.McsConstants.EXTRA_REASON; -import static org.microg.gms.gcm.McsConstants.MCS_CLOSE_TAG; -import static org.microg.gms.gcm.McsConstants.MCS_DATA_MESSAGE_STANZA_TAG; -import static org.microg.gms.gcm.McsConstants.MCS_HEARTBEAT_ACK_TAG; -import static org.microg.gms.gcm.McsConstants.MCS_HEARTBEAT_PING_TAG; -import static org.microg.gms.gcm.McsConstants.MCS_IQ_STANZA_TAG; -import static org.microg.gms.gcm.McsConstants.MCS_LOGIN_REQUEST_TAG; -import static org.microg.gms.gcm.McsConstants.MCS_LOGIN_RESPONSE_TAG; -import static org.microg.gms.gcm.McsConstants.MSG_ACK; -import static org.microg.gms.gcm.McsConstants.MSG_CONNECT; -import static org.microg.gms.gcm.McsConstants.MSG_HEARTBEAT; -import static org.microg.gms.gcm.McsConstants.MSG_INPUT; -import static org.microg.gms.gcm.McsConstants.MSG_INPUT_ERROR; -import static org.microg.gms.gcm.McsConstants.MSG_OUTPUT; -import static org.microg.gms.gcm.McsConstants.MSG_OUTPUT_DONE; -import static org.microg.gms.gcm.McsConstants.MSG_OUTPUT_ERROR; -import static org.microg.gms.gcm.McsConstants.MSG_OUTPUT_READY; -import static org.microg.gms.gcm.McsConstants.MSG_TEARDOWN; +import static org.microg.gms.gcm.GcmConstants.*; +import static org.microg.gms.gcm.McsConstants.*; import android.annotation.SuppressLint; import android.app.AlarmManager; @@ -68,16 +34,15 @@ import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; -import android.os.Messenger; import android.os.Parcelable; import android.os.PowerManager; import android.os.SystemClock; import android.os.UserHandle; -import android.util.Base64; import android.util.Log; import androidx.annotation.Nullable; @@ -101,6 +66,7 @@ import org.microg.gms.gcm.mcs.IqStanza; import org.microg.gms.gcm.mcs.LoginRequest; import org.microg.gms.gcm.mcs.LoginResponse; import org.microg.gms.gcm.mcs.Setting; +import org.microg.mgms.settings.SettingsProvider; import java.io.Closeable; import java.lang.reflect.Field; @@ -171,10 +137,10 @@ public class McsService extends Service implements Handler.Callback { @Nullable private Method addPowerSaveTempWhitelistAppMethod; @Nullable - @RequiresApi(31) + @RequiresApi(Build.VERSION_CODES.S) private Object powerExemptionManager; @Nullable - @RequiresApi(31) + @RequiresApi(Build.VERSION_CODES.S) private Method addToTemporaryAllowListMethod; private class HandlerThread extends Thread { @@ -189,7 +155,7 @@ public class McsService extends Service implements Handler.Callback { wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "mcs"); wakeLock.setReferenceCounted(false); synchronized (McsService.class) { - rootHandler = new Handler(Objects.requireNonNull(Looper.myLooper()), McsService.this); + rootHandler = new Handler(Looper.myLooper(), McsService.this); if (connectIntent != null) { rootHandler.sendMessage(rootHandler.obtainMessage(MSG_CONNECT, connectIntent)); WakefulBroadcastReceiver.completeWakefulIntent(connectIntent); @@ -200,7 +166,7 @@ public class McsService extends Service implements Handler.Callback { } private static void logd(Context context, String msg) { - if (context == null || GcmPrefs.get(context).isGcmLogEnabled()) Log.d(TAG, msg); + if (context == null || Objects.requireNonNull(GcmPrefs.get(context)).isGcmLogEnabled()) Log.d(TAG, msg); } @Override @@ -209,12 +175,12 @@ public class McsService extends Service implements Handler.Callback { super.onCreate(); TriggerReceiver.register(this); database = new GcmDatabase(this); - heartbeatIntent = PendingIntent.getService(this, 0, new Intent(ACTION_HEARTBEAT, null, this, McsService.class), PendingIntent.FLAG_IMMUTABLE); + heartbeatIntent = PendingIntent.getService(this, 0, new Intent(ACTION_HEARTBEAT, null, this, McsService.class), 0); alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); powerManager = (PowerManager) getSystemService(POWER_SERVICE); if (checkSelfPermission("android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST") == PackageManager.PERMISSION_GRANTED) { try { - if (SDK_INT >= 31) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { Class powerExemptionManagerClass = Class.forName("android.os.PowerExemptionManager"); powerExemptionManager = getSystemService(powerExemptionManagerClass); addToTemporaryAllowListMethod = @@ -232,6 +198,7 @@ public class McsService extends Service implements Handler.Callback { deviceIdleController = Class.forName("android.os.IDeviceIdleController$Stub") .getMethod("asInterface", IBinder.class).invoke(null, binder); getUserIdMethod = UserHandle.class.getMethod("getUserId", int.class); + assert deviceIdleController != null; addPowerSaveTempWhitelistAppMethod = deviceIdleController.getClass() .getMethod("addPowerSaveTempWhitelistApp", String.class, long.class, int.class, String.class); } @@ -274,7 +241,7 @@ public class McsService extends Service implements Handler.Callback { return false; } // consider connection to be dead if we did not receive an ack within 90s to our ping - int heartbeatMs = GcmPrefs.get(context).getHeartbeatMsFor(activeNetworkPref); + int heartbeatMs = Objects.requireNonNull(GcmPrefs.get(context)).getHeartbeatMsFor(activeNetworkPref); // if disabled for active network, heartbeatMs will be -1 if (heartbeatMs < 0) { closeAll(); @@ -284,7 +251,7 @@ public class McsService extends Service implements Handler.Callback { long timeSinceLastPing = SystemClock.elapsedRealtime() - lastHeartbeatPingElapsedRealtime; if (noAckReceived && timeSinceLastPing > HEARTBEAT_ACK_AFTER_PING_TIMEOUT_MS) { logd(null, "No heartbeat for " + timeSinceLastPing / 1000 + "s, connection assumed to be dead after 90s"); - GcmPrefs.get(context).learnTimeout(context, activeNetworkPref); + Objects.requireNonNull(GcmPrefs.get(context)).learnTimeout(context, activeNetworkPref); return false; } } @@ -300,25 +267,26 @@ public class McsService extends Service implements Handler.Callback { AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE); long delay = getCurrentDelay(); logd(context, "Scheduling reconnect in " + delay / 1000 + " seconds..."); - PendingIntent pi = PendingIntent.getBroadcast(context, 1, new Intent(ACTION_RECONNECT, null, context, TriggerReceiver.class), PendingIntent.FLAG_IMMUTABLE); + PendingIntent pi = PendingIntent.getBroadcast(context, 1, new Intent(ACTION_RECONNECT, null, context, TriggerReceiver.class), 0); alarmManager.setExactAndAllowWhileIdle(ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delay, pi); } public void scheduleHeartbeat(Context context) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE); - int heartbeatMs = GcmPrefs.get(this).getHeartbeatMsFor(activeNetworkPref); + int heartbeatMs = Objects.requireNonNull(GcmPrefs.get(this)).getHeartbeatMsFor(activeNetworkPref); if (heartbeatMs < 0) { closeAll(); } logd(context, "Scheduling heartbeat in " + heartbeatMs / 1000 + " seconds..."); + // This is supposed to work even when running in idle and without battery optimization disabled alarmManager.setExactAndAllowWhileIdle(ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + heartbeatMs, heartbeatIntent); } public synchronized static long getCurrentDelay() { long delay = currentDelay == 0 ? 5000 : currentDelay; - if (currentDelay < 60000) currentDelay += 10000; - if (currentDelay >= 60000 && currentDelay < 600000) currentDelay += 60000; + if (currentDelay < SettingsProvider.INTERVAL) currentDelay += 10000; + if (currentDelay >= SettingsProvider.INTERVAL && currentDelay < 600000) currentDelay += SettingsProvider.INTERVAL; return delay; } @@ -358,7 +326,6 @@ public class McsService extends Service implements Handler.Callback { String messageId = intent.getStringExtra(EXTRA_MESSAGE_ID); String collapseKey = intent.getStringExtra(EXTRA_COLLAPSE_KEY); - Messenger messenger = intent.getParcelableExtra(EXTRA_MESSENGER); intent.removeExtra(EXTRA_MESSENGER); Parcelable app = intent.getParcelableExtra(EXTRA_APP); @@ -376,16 +343,8 @@ public class McsService extends Service implements Handler.Callback { } intent.removeExtra(EXTRA_APP); - int ttl; try { - if (intent.hasExtra(EXTRA_TTL)) { - ttl = Integer.parseInt(intent.getStringExtra(EXTRA_TTL)); - if (ttl < 0 || ttl > maxTtl) { - ttl = maxTtl; - } - } else { - ttl = maxTtl; - } + intent.hasExtra(EXTRA_TTL); } catch (NumberFormatException e) { // TODO: error TtlUnsupported Log.w(TAG, e); @@ -451,7 +410,7 @@ public class McsService extends Service implements Handler.Callback { } } - private boolean connect(int port) { + private void connect(int port) { try { wasTornDown = false; @@ -474,10 +433,8 @@ public class McsService extends Service implements Handler.Callback { 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() { @@ -485,8 +442,8 @@ public class McsService extends Service implements Handler.Callback { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo(); - activeNetworkPref = GcmPrefs.get(this).getNetworkPrefForInfo(activeNetworkInfo); - if (!GcmPrefs.get(this).isEnabledFor(activeNetworkInfo)) { + activeNetworkPref = Objects.requireNonNull(GcmPrefs.get(this)).getNetworkPrefForInfo(activeNetworkInfo); + if (!Objects.requireNonNull(GcmPrefs.get(this)).isEnabledFor(activeNetworkInfo)) { if (activeNetworkInfo != null) { logd(this, "Don't connect, because disabled for " + activeNetworkInfo.getTypeName()); } else { @@ -546,13 +503,14 @@ public class McsService extends Service implements Handler.Callback { } private void handleHeartbeatAck(HeartbeatAck ack) { - GcmPrefs.get(this).learnReached(this, activeNetworkPref, SystemClock.elapsedRealtime() - lastIncomingNetworkRealtime); + Objects.requireNonNull(GcmPrefs.get(this)).learnReached(this, activeNetworkPref, SystemClock.elapsedRealtime() - lastIncomingNetworkRealtime); lastHeartbeatAckElapsedRealtime = SystemClock.elapsedRealtime(); wakeLock.release(); } private LoginRequest buildLoginRequest() { LastCheckinInfo info = LastCheckinInfo.read(this); + assert info != null; return new LoginRequest.Builder() .adaptive_heartbeat(false) .auth_service(LoginRequest.AuthService.ANDROID_ID) @@ -565,7 +523,7 @@ public class McsService extends Service implements Handler.Callback { .user(Long.toString(info.getAndroidId())) .use_rmq2(true) .setting(Collections.singletonList(new Setting.Builder().name("new_vc").value_("1").build())) - .received_persistent_id(GcmPrefs.get(this).getLastPersistedIds()) + .received_persistent_id(Objects.requireNonNull(GcmPrefs.get(this)).getLastPersistedIds()) .build(); } @@ -578,17 +536,15 @@ public class McsService extends Service implements Handler.Callback { intent.setAction(ACTION_C2DM_RECEIVE); intent.putExtra(EXTRA_FROM, msg.from); intent.putExtra(EXTRA_MESSAGE_ID, msg.id); - if (msg.persistent_id != null) intent.putExtra(EXTRA_MESSAGE_ID, msg.persistent_id); - if (msg.token != null) intent.putExtra(EXTRA_COLLAPSE_KEY, msg.token); - if (msg.raw_data != null) { - intent.putExtra(EXTRA_RAWDATA_BASE64, Base64.encodeToString(msg.raw_data.toByteArray(), Base64.DEFAULT)); - intent.putExtra(EXTRA_RAWDATA, msg.raw_data.toByteArray()); + if (msg.persistent_id != null) { + intent.putExtra(EXTRA_MESSAGE_ID, msg.persistent_id); } if (app.wakeForDelivery) { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); } else { intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); } + if (msg.token != null) intent.putExtra(EXTRA_COLLAPSE_KEY, msg.token); for (AppData appData : msg.app_data) { intent.putExtra(appData.key, appData.value_); } @@ -612,7 +568,7 @@ public class McsService extends Service implements Handler.Callback { sendOrderedBroadcast(intent, null); } else { List infos = getPackageManager().queryBroadcastReceivers(intent, PackageManager.GET_RESOLVED_FILTER); - if (infos.isEmpty()) { + if (infos == null || infos.isEmpty()) { logd(this, "No target for message, wut?"); } else { for (ResolveInfo resolveInfo : infos) { @@ -634,7 +590,7 @@ public class McsService extends Service implements Handler.Callback { } private void addPowerSaveTempWhitelistApp(String packageName) { - if (SDK_INT >= 31) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { try { if (addToTemporaryAllowListMethod != null && powerExemptionManager != null) { logd(this, "Adding app " + packageName + " to the temp allowlist"); @@ -702,7 +658,7 @@ public class McsService extends Service implements Handler.Callback { if (msg.obj instanceof SocketException) { SocketException e = (SocketException) msg.obj; if ("Connection reset".equals(e.getMessage())) { - GcmPrefs.get(this).learnTimeout(this, activeNetworkPref); + Objects.requireNonNull(GcmPrefs.get(this)).learnTimeout(this, activeNetworkPref); } } rootHandler.sendMessage(rootHandler.obtainMessage(MSG_TEARDOWN, msg.obj)); diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterManager.java b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterManager.java index bc93194e..1dcfec44 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterManager.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterManager.java @@ -147,7 +147,7 @@ public class PushRegisterManager { resultBundle.putString(EXTRA_REGISTRATION_ID, attachRequestId(response.token, requestId)); } } else { - if (!request.app.equals(response.deleted) && !request.app.equals(response.token) && !request.sender.equals(response.token)) { + if (!request.app.equals(response.deleted) && !request.app.equals(response.token)) { database.noteAppRegistrationError(request.app, response.responseText); resultBundle.putString(EXTRA_ERROR, attachRequestId(ERROR_SERVICE_NOT_AVAILABLE, requestId)); } else { diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/RegisterRequest.java b/play-services-core/src/main/java/org/microg/gms/gcm/RegisterRequest.java index 80c7fd83..dbc21088 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/RegisterRequest.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/RegisterRequest.java @@ -123,7 +123,7 @@ public class RegisterRequest extends HttpFormClient.Request { public RegisterRequest extraParams(Bundle extraBundle) { for (String key : extraBundle.keySet()) { - if (!key.equals(GcmConstants.EXTRA_SENDER) && !key.equals(GcmConstants.EXTRA_DELETE) && !key.equals(GcmConstants.EXTRA_APP)) { + if (!key.equals(GcmConstants.EXTRA_SENDER) && !key.equals(GcmConstants.EXTRA_DELETE)) { extraParam(key, extraBundle.getString(key)); } } diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/TriggerReceiver.java b/play-services-core/src/main/java/org/microg/gms/gcm/TriggerReceiver.java index 83d182aa..245d5c2a 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/TriggerReceiver.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/TriggerReceiver.java @@ -17,6 +17,7 @@ package org.microg.gms.gcm; import static android.os.Build.VERSION.SDK_INT; +import static android.os.Build.VERSION_CODES.N; import static org.microg.gms.gcm.McsConstants.ACTION_CONNECT; import static org.microg.gms.gcm.McsConstants.ACTION_HEARTBEAT; import static org.microg.gms.gcm.McsConstants.EXTRA_REASON; @@ -30,7 +31,7 @@ import android.util.Log; import androidx.legacy.content.WakefulBroadcastReceiver; -import org.microg.gms.checkin.CheckinPreferences; +import org.microg.gms.checkin.CheckinPrefs; import org.microg.gms.checkin.LastCheckinInfo; import org.microg.gms.common.ForegroundServiceContext; @@ -43,7 +44,7 @@ public class TriggerReceiver extends WakefulBroadcastReceiver { * "Project Svelte" is just there to f**k things up... */ public synchronized static void register(Context context) { - if (SDK_INT >= 24 && !registered) { + if (SDK_INT >= N && !registered) { IntentFilter intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"); context.getApplicationContext().registerReceiver(new TriggerReceiver(), intentFilter); registered = true; @@ -67,7 +68,7 @@ public class TriggerReceiver extends WakefulBroadcastReceiver { if (LastCheckinInfo.read(context).getAndroidId() == 0) { Log.d(TAG, "Ignoring " + intent + ": need to checkin first."); - if (CheckinPreferences.isEnabled(context)) { + if (CheckinPrefs.isEnabled(context)) { // Do a check-in if we are not actually checked in, // but should be, e.g. cleared app data Log.d(TAG, "Requesting check-in..."); diff --git a/play-services-core/src/main/java/org/microg/gms/gservices/GServices.java b/play-services-core/src/main/java/org/microg/gms/gservices/GServices.java index 5c811f28..79543f47 100644 --- a/play-services-core/src/main/java/org/microg/gms/gservices/GServices.java +++ b/play-services-core/src/main/java/org/microg/gms/gservices/GServices.java @@ -21,12 +21,10 @@ import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; -import org.microg.gms.base.core.BuildConfig; - public class GServices { - public static final Uri CONTENT_URI = Uri.parse("content://" + BuildConfig.BASE_PACKAGE_NAME + ".android.gsf.gservices"); - public static final Uri MAIN_URI = Uri.parse("content://" + BuildConfig.BASE_PACKAGE_NAME + ".android.gsf.gservices/main"); - public static final Uri OVERRIDE_URI = Uri.parse("content://" + BuildConfig.BASE_PACKAGE_NAME + ".android.gsf.gservices/override"); + public static final Uri CONTENT_URI = Uri.parse("content://com.mgoogle.android.gsf.gservices"); + public static final Uri MAIN_URI = Uri.parse("content://com.mgoogle.android.gsf.gservices/main"); + public static final Uri OVERRIDE_URI = Uri.parse("content://com.mgoogle.android.gsf.gservices/override"); public static int setString(ContentResolver resolver, String key, String value) { ContentValues values = new ContentValues(); diff --git a/play-services-core/src/main/java/org/microg/gms/gservices/GServicesProvider.java b/play-services-core/src/main/java/org/microg/gms/gservices/GServicesProvider.java index 3d3a8189..2a95655b 100644 --- a/play-services-core/src/main/java/org/microg/gms/gservices/GServicesProvider.java +++ b/play-services-core/src/main/java/org/microg/gms/gservices/GServicesProvider.java @@ -29,8 +29,6 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; -import org.microg.gms.base.core.BuildConfig; - /** * Originally found in Google Services Framework (com.google.android.gsf), this provides a generic * key-value store, that is written by the checkin service and read from various Google Apps. @@ -39,7 +37,7 @@ import org.microg.gms.base.core.BuildConfig; * if certain "experiments" are enabled on the device. */ public class GServicesProvider extends ContentProvider { - public static final Uri CONTENT_URI = Uri.parse("content://" + BuildConfig.BASE_PACKAGE_NAME + ".android.gsf.gservices/"); + public static final Uri CONTENT_URI = Uri.parse("content://com.mgoogle.android.gsf.gservices/"); public static final Uri MAIN_URI = Uri.withAppendedPath(CONTENT_URI, "main"); public static final Uri OVERRIDE_URI = Uri.withAppendedPath(CONTENT_URI, "override"); public static final Uri PREFIX_URI = Uri.withAppendedPath(CONTENT_URI, "prefix"); diff --git a/play-services-core/src/main/java/org/microg/gms/ui/LegacyAccountSettingsActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/AccountSettingsActivity.java old mode 100644 new mode 100755 similarity index 91% rename from play-services-core/src/main/java/org/microg/gms/ui/LegacyAccountSettingsActivity.java rename to play-services-core/src/main/java/org/microg/gms/ui/AccountSettingsActivity.java index fc015f5e..fa099d49 --- a/play-services-core/src/main/java/org/microg/gms/ui/LegacyAccountSettingsActivity.java +++ b/play-services-core/src/main/java/org/microg/gms/ui/AccountSettingsActivity.java @@ -18,6 +18,7 @@ package org.microg.gms.ui; import android.accounts.Account; import android.accounts.AccountManager; +import android.os.Build; import android.os.Bundle; import androidx.annotation.Nullable; @@ -33,10 +34,9 @@ import org.microg.tools.ui.ResourceSettingsFragment; import static android.accounts.AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE; import static android.accounts.AccountManager.VISIBILITY_NOT_VISIBLE; import static android.accounts.AccountManager.VISIBILITY_VISIBLE; -import static android.os.Build.VERSION.SDK_INT; import static org.microg.gms.auth.AuthManager.PREF_AUTH_VISIBLE; -public class LegacyAccountSettingsActivity extends AbstractSettingsActivity { +public class AccountSettingsActivity extends AbstractSettingsActivity { @Override protected Fragment getFragment() { @@ -45,7 +45,7 @@ public class LegacyAccountSettingsActivity extends AbstractSettingsActivity { public static class AccountSettingsFragment extends ResourceSettingsFragment { public AccountSettingsFragment() { - preferencesResource = R.xml.preferences_google_more; + preferencesResource = R.xml.preferences_account; } @Override @@ -53,7 +53,7 @@ public class LegacyAccountSettingsActivity extends AbstractSettingsActivity { super.onCreatePreferences(savedInstanceState, rootKey); Preference pref = findPreference(PREF_AUTH_VISIBLE); if (pref != null) { - if (SDK_INT < 26) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { pref.setVisible(false); } else { pref.setOnPreferenceChangeListener((preference, newValue) -> { diff --git a/play-services-core/src/main/java/org/microg/gms/ui/MainSettingsActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java old mode 100644 new mode 100755 similarity index 60% rename from play-services-core/src/main/java/org/microg/gms/ui/MainSettingsActivity.java rename to play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java index b65b3806..32230055 --- a/play-services-core/src/main/java/org/microg/gms/ui/MainSettingsActivity.java +++ b/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java @@ -1,6 +1,6 @@ package org.microg.gms.ui; -import android.content.Intent; +import android.os.Build; import android.os.Bundle; import androidx.annotation.Nullable; @@ -10,33 +10,25 @@ import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.ui.AppBarConfiguration; import androidx.navigation.ui.NavigationUI; +import com.google.android.material.color.DynamicColors; import com.mgoogle.android.gms.R; -import org.microg.gms.ui.settings.SettingsProvider; -import static org.microg.gms.ui.settings.SettingsProviderKt.getAllSettingsProviders; +import java.util.Objects; -public class MainSettingsActivity extends AppCompatActivity { +public class SettingsActivity extends AppCompatActivity { private AppBarConfiguration appBarConfiguration; private NavController getNavController() { - return ((NavHostFragment)getSupportFragmentManager().findFragmentById(R.id.navhost)).getNavController(); + return ((NavHostFragment) Objects.requireNonNull(getSupportFragmentManager().findFragmentById(R.id.navhost))).getNavController(); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - Intent intent = getIntent(); - for (SettingsProvider settingsProvider : getAllSettingsProviders(this)) { - settingsProvider.preProcessSettingsIntent(intent); - } - setContentView(R.layout.settings_root_activity); - - for (SettingsProvider settingsProvider : getAllSettingsProviders(this)) { - settingsProvider.extendNavigation(getNavController()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + DynamicColors.applyToActivityIfAvailable(this); } - appBarConfiguration = new AppBarConfiguration.Builder(getNavController().getGraph()).build(); NavigationUI.setupActionBarWithNavController(this, getNavController(), appBarConfiguration); } @@ -45,4 +37,4 @@ public class MainSettingsActivity extends AppCompatActivity { public boolean onSupportNavigateUp() { return NavigationUI.navigateUp(getNavController(), appBarConfiguration) || super.onSupportNavigateUp(); } -} \ No newline at end of file +} diff --git a/play-services-core/src/main/java/org/microg/gms/settings/GoogleSettingsProvider.java b/play-services-core/src/main/java/org/microg/mgms/settings/GoogleSettingsProvider.java similarity index 97% rename from play-services-core/src/main/java/org/microg/gms/settings/GoogleSettingsProvider.java rename to play-services-core/src/main/java/org/microg/mgms/settings/GoogleSettingsProvider.java index da3e5094..3ab7f51c 100644 --- a/play-services-core/src/main/java/org/microg/gms/settings/GoogleSettingsProvider.java +++ b/play-services-core/src/main/java/org/microg/mgms/settings/GoogleSettingsProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.microg.gms.settings; +package org.microg.mgms.settings; import android.content.ContentProvider; import android.content.ContentValues; diff --git a/play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java b/play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java index 69d87394..4c596f32 100755 --- a/play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java +++ b/play-services-core/src/main/java/org/microg/tools/AccountPickerActivity.java @@ -16,15 +16,16 @@ package org.microg.tools; +import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import androidx.appcompat.app.AppCompatActivity; /** * This is just an activity that forwards to the systems native account picker */ -public class AccountPickerActivity extends AppCompatActivity { +public class AccountPickerActivity extends Activity { + private static final int REQUEST_CODE = AccountPickerActivity.class.hashCode(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -35,8 +36,16 @@ public class AccountPickerActivity extends AppCompatActivity { ComponentName.unflattenFromString("android/.accounts.ChooseTypeAndAccountActivity"); intent.setClassName(componentName.getPackageName(), componentName.getClassName()); intent.putExtras(extras); - intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - startActivity(intent); - finish(); + startActivityForResult(intent, REQUEST_CODE); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == REQUEST_CODE) { + setResult(resultCode, data); + finish(); + } else { + super.onActivityResult(requestCode, resultCode, data); + } } } diff --git a/play-services-core/src/main/kotlin/com/google/android/gms/common/GoogleCertificatesImpl.kt b/play-services-core/src/main/kotlin/com/google/android/gms/common/GoogleCertificatesImpl.kt deleted file mode 100644 index e1fb7a21..00000000 --- a/play-services-core/src/main/kotlin/com/google/android/gms/common/GoogleCertificatesImpl.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ -package com.google.android.gms.common - -import android.content.pm.PackageManager -import android.os.IBinder -import android.os.Parcel -import android.util.Log -import androidx.annotation.Keep -import com.google.android.gms.common.internal.CertData -import com.google.android.gms.common.internal.IGoogleCertificatesApi -import com.google.android.gms.dynamic.IObjectWrapper -import com.google.android.gms.dynamic.ObjectWrapper -import org.microg.gms.common.PackageUtils -import org.microg.gms.utils.warnOnTransactionIssues - -private const val TAG = "GoogleCertificates" - -@Keep -class GoogleCertificatesImpl : IGoogleCertificatesApi.Stub() { - private val googleCertificates = emptySet() - private val googleReleaseCertificates = emptySet() - - override fun getGoogleCertificates(): IObjectWrapper { - Log.d(TAG, "unimplemented Method: getGoogleCertificates") - return ObjectWrapper.wrap(googleCertificates.toTypedArray()) - } - - override fun getGoogleReleaseCertificates(): IObjectWrapper { - Log.d(TAG, "unimplemented Method: getGoogleReleaseCertificates") - return ObjectWrapper.wrap(googleReleaseCertificates.toTypedArray()) - } - - override fun isGoogleReleaseSigned(packageName: String, certData: IObjectWrapper): Boolean { - return PackageUtils.isGooglePackage(packageName, ObjectWrapper.unwrapTyped(certData, ByteArray::class.java)) - } - - override fun isGoogleSigned(packageName: String, certData: IObjectWrapper): Boolean { - return PackageUtils.isGooglePackage(packageName, ObjectWrapper.unwrapTyped(certData, ByteArray::class.java)) - } - - override fun isGoogleOrPlatformSigned(query: GoogleCertificatesQuery, packageManager: IObjectWrapper): Boolean { - val pm = ObjectWrapper.unwrapTyped(packageManager, PackageManager::class.java) - return if (query == null || query.callingPackage == null) { - false - } else if (query.getCertData() == null) { - if (pm == null) false else PackageUtils.isGooglePackage(pm, query.callingPackage) - } else { - PackageUtils.isGooglePackage(query.callingPackage, query.getCertData().bytes) - } - } - - override fun isPackageGoogleOrPlatformSigned(query: GoogleCertificatesLookupQuery): GoogleCertificatesLookupResponse { - return certificateLookup(query, true) - } - - override fun isPackageGoogleOrPlatformSignedAvailable(): Boolean { - return true - } - - override fun queryPackageSigned(query: GoogleCertificatesLookupQuery): GoogleCertificatesLookupResponse { - if (!isFineGrainedPackageVerificationAvailable) throw IllegalStateException("API unavailable") - return certificateLookup(query, false) - } - - override fun isFineGrainedPackageVerificationAvailable(): Boolean { - return true - } - - private fun certificateLookup(query: GoogleCertificatesLookupQuery, allowPlatform: Boolean): GoogleCertificatesLookupResponse { - val context = query.context - ?: return GoogleCertificatesLookupResponse(false, "context is null", 5, 1) - val packageManager = context.packageManager - ?: return GoogleCertificatesLookupResponse(false, "context has no package manager", 5, 1) - val callingPackage = query.callingPackage - ?: return GoogleCertificatesLookupResponse(false, "callingPackage is null", 5, 1) - val signatureDigest = PackageUtils.firstSignatureDigest(packageManager, callingPackage) - ?: return GoogleCertificatesLookupResponse(false, "callingPackage not found", 4, 1) - return if (PackageUtils.isGooglePackage(callingPackage, signatureDigest)) { - GoogleCertificatesLookupResponse(true, null, 1, 3) - } else { - GoogleCertificatesLookupResponse(false, "not allowed", 2, 1) - } - } - - override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = - warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) } -} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/LoaderActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/LoaderActivity.kt deleted file mode 100644 index c1a4a2da..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/LoaderActivity.kt +++ /dev/null @@ -1,165 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.accountsettings.ui - -import android.accounts.AccountManager -import android.content.Intent -import android.content.Intent.ACTION_VIEW -import android.content.Intent.CATEGORY_BROWSABLE -import android.content.Intent.FLAG_ACTIVITY_FORWARD_RESULT -import android.net.Uri -import android.os.Bundle -import android.util.Log -import androidx.appcompat.app.AppCompatActivity -import org.microg.gms.auth.AuthConstants.DEFAULT_ACCOUNT_TYPE -import org.microg.gms.common.PackageUtils -import org.microg.tools.AccountPickerActivity - -private const val TAG = "AccountSettingsLoader" - -private val ALLOWED_FALLBACK_PREFIXES = setOf("https://myaccount.google.com/", "https://takeout.google.com/") -private val BROWSABLE_SCREEN_IDS = setOf(1, 200, 400, 502, 527, 10003, 10050, 12700, 12701) -private val ACCOUNT_CHOOSER_URI = Uri.parse("https://accounts.google.com/AccountChooser") - -private const val QUERY_PARAM_CONTINUE = "continue" -private const val QUERY_PARAM_LANG = "hl" -private const val QUERY_PARAM_EMAIL = "Email" - -private const val EXTRA_ALLOWABLE_ACCOUNT_TYPES = "allowableAccountTypes" - -private const val REQUEST_ACCOUNT_PICKER = 1 - -@Suppress("DEPRECATION") -class LoaderActivity : AppCompatActivity() { - private var canAskForAccount = false - - private fun launchFallback() { - val fallbackUrl = intent?.getStringExtra(EXTRA_FALLBACK_URL) - - if (fallbackUrl == null) { - Log.d(TAG, "No fallback") - finishResult(RESULT_CANCELED) - } else if (fallbackUrl in ALLOWED_FALLBACK_PREFIXES) { - // TODO: Error screen? - Log.d(TAG, "Illegal fallback url") - finishResult(RESULT_CANCELED) - } else { - val fallbackAuth = intent?.getBooleanExtra(EXTRA_FALLBACK_AUTH, false) ?: false - val uri = if (fallbackAuth) { - val builder = ACCOUNT_CHOOSER_URI.buildUpon().appendQueryParameter(QUERY_PARAM_CONTINUE, fallbackUrl) - val accountName = intent?.getStringExtra(EXTRA_ACCOUNT_NAME) - if (!accountName.isNullOrBlank()) { - builder.appendQueryParameter(QUERY_PARAM_EMAIL, accountName) - } - val lang = Uri.parse(fallbackUrl).getQueryParameter(QUERY_PARAM_LANG) - if (lang != null) { - builder.appendQueryParameter(QUERY_PARAM_LANG, lang) - } - builder.build() - } else { - Uri.parse(fallbackUrl) - } - Log.d(TAG, "Opening fallback $fallbackUrl") - val intent = Intent(ACTION_VIEW, uri).apply { addCategory(CATEGORY_BROWSABLE) } - startActivity(intent) - finishResult(RESULT_OK) - } - } - - private fun launchMain() { - val requestedAccountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME) - val ignoreAccount = intent?.getBooleanExtra(EXTRA_IGNORE_ACCOUNT, false) ?: false - val accounts = AccountManager.get(this).getAccountsByType(DEFAULT_ACCOUNT_TYPE) - val account = if (requestedAccountName != null) { - val account = accounts.find { it.name == requestedAccountName } - if (account == null) { - // TODO: Error screen? - Log.d(TAG, "Account not found: $requestedAccountName") - return finishResult(RESULT_CANCELED) - } - account - } else if (accounts.isEmpty()) { - if (intent?.getStringExtra(EXTRA_FALLBACK_URL) != null) { - return launchFallback() - } else { - // TODO: Error screen? - Log.d(TAG, "No account configured") - return finishResult(RESULT_CANCELED) - } - } else if (accounts.size > 1) { - if (canAskForAccount) { - val intent = Intent(this, AccountPickerActivity::class.java) - intent.putExtra(EXTRA_ALLOWABLE_ACCOUNT_TYPES, arrayOf(DEFAULT_ACCOUNT_TYPE)) - startActivityForResult(intent, REQUEST_ACCOUNT_PICKER) - canAskForAccount = false - return - } else { - return finishResult(RESULT_CANCELED) - } - } else { - accounts.first() - } - - val intent = Intent(this, MainActivity::class.java).apply { - action = intent.action - if (intent.hasExtra(EXTRA_THEME_CHOICE)) putExtra(EXTRA_THEME_CHOICE, intent.getIntExtra(EXTRA_THEME_CHOICE, 0)) - putExtra(EXTRA_ACCOUNT_NAME, account.name) - if (ignoreAccount) putExtra(EXTRA_IGNORE_ACCOUNT, true) - putExtra(EXTRA_SCREEN_ID, intent.getIntExtra(EXTRA_SCREEN_ID, 1)) - for (it in intent.extras?.keySet().orEmpty()) { - if (it.startsWith(EXTRA_SCREEN_OPTIONS_PREFIX)) putExtra(it, intent.getStringExtra(it)) - } - putExtra(EXTRA_CALLING_PACKAGE_NAME, callingActivity?.packageName) - if (intent.action != ACTION_BROWSE_SETTINGS) { - addFlags(FLAG_ACTIVITY_FORWARD_RESULT) - } - } - - startActivity(intent) - - if (!isFinishing && !isChangingConfigurations) { - finishResult(RESULT_OK) - } - } - - @Deprecated("Deprecated in Java") - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == REQUEST_ACCOUNT_PICKER) { - if (resultCode == RESULT_OK && data?.hasExtra(AccountManager.KEY_ACCOUNT_NAME) == true) { - intent.putExtra(EXTRA_ACCOUNT_NAME, data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)) - launchMain() - } else { - finishResult(resultCode) - } - } else { - super.onActivityResult(requestCode, resultCode, data) - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - canAskForAccount = true - val extras = intent?.extras?.also { it.keySet() } - Log.d(TAG, "Invoked with ${intent.action} and extras $extras") - - super.onCreate(savedInstanceState) - - val isMainAllowed = if (intent == null || intent.action != ACTION_BROWSE_SETTINGS) - PackageUtils.isGooglePackage(this, callingActivity?.packageName) - else - extras?.getInt(EXTRA_SCREEN_ID, -1) in BROWSABLE_SCREEN_IDS - - if (!isMainAllowed) { - launchFallback() - } else if (!isFinishing && !isChangingConfigurations){ - launchMain() - } - } - - private fun finishResult(resultCode: Int) { - setResult(resultCode) - finish() - } -} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/MainActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/MainActivity.kt deleted file mode 100644 index 441a2e3b..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/MainActivity.kt +++ /dev/null @@ -1,185 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.accountsettings.ui - -import android.accounts.Account -import android.accounts.AccountManager -import android.os.Bundle -import android.util.Log -import android.view.View -import android.webkit.WebView -import android.widget.ProgressBar -import android.widget.RelativeLayout -import android.widget.RelativeLayout.LayoutParams.MATCH_PARENT -import android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT -import androidx.appcompat.app.AppCompatActivity -import org.microg.gms.auth.AuthConstants -import org.microg.gms.common.Constants - -private const val TAG = "AccountSettings" - -// TODO: There likely is some API to figure those out... -private val SCREEN_ID_TO_URL = hashMapOf( - 1 to "https://myaccount.google.com", - 200 to "https://myaccount.google.com/privacycheckup", - 203 to "https://myaccount.google.com/email", - 204 to "https://myaccount.google.com/phone", - 205 to "https://myaccount.google.com/birthday", - 206 to "https://myaccount.google.com/gender", - 210 to "https://myaccount.google.com/locationsharing", - 214 to "https://myaccount.google.com/dashboard", - 215 to "https://takeout.google.com", - 216 to "https://myaccount.google.com/inactive", - 219 to "https://myactivity.google.com/myactivity", - 220 to "https://www.google.com/maps/timeline", - 224 to "https://myactivity.google.com/activitycontrols?settings=search", - 227 to "https://myactivity.google.com/activitycontrols?settings=location", - 231 to "https://myactivity.google.com/activitycontrols?settings=youtube", - 235 to "https://myactivity.google.com/activitycontrols/youtube", - 238 to "https://www.google.com/setting/search/privateresults/", - 241 to "https://myaccount.google.com/communication-preferences", - 300 to "https://myaccount.google.com/language", - 301 to "https://drive.google.com/settings/storage", - 302 to "https://myaccount.google.com/deleteservices", - 303 to "https://myaccount.google.com/deleteaccount", - 307 to "https://payments.google.com/payments/home", - 308 to "https://myaccount.google.com/subscriptions", - 309 to "https://myaccount.google.com/purchases", - 310 to "https://myaccount.google.com/reservations", - 312 to "https://myaccount.google.com/accessibility", - 313 to "https://myaccount.google.com/inputtools", - 400 to "https://myaccount.google.com/security-checkup/", - 401 to "https://myaccount.google.com/signinoptions/password", - 403 to "https://myaccount.google.com/signinoptions/two-step-verification", - 406 to "https://myaccount.google.com/signinoptions/rescuephone", - 407 to "https://myaccount.google.com/recovery/email", - 409 to "https://myaccount.google.com/notifications", - 410 to "https://myaccount.google.com/device-activity", - 417 to "https://myaccount.google.com/find-your-phone", - 425 to "https://myaccount.google.com/account-enhanced-safe-browsing", - 426 to "https://myaccount.google.com/two-step-verification/authenticator", - 427 to "https://myaccount.google.com/two-step-verification/backup-codes", - 429 to "https://myaccount.google.com/two-step-verification/security-keys", - 430 to "https://myaccount.google.com/two-step-verification/prompt", - 431 to "https://myaccount.google.com/connections", - 432 to "https://myaccount.google.com/two-step-verification/phone-numbers", - 433 to "https://myaccount.google.com/signinoptions/passkeys", - 437 to "https://myaccount.google.com/signinoptions/passwordoptional", - 500 to "https://policies.google.com/privacy", - 503 to "https://policies.google.com/terms", - 519 to "https://myaccount.google.com/yourdata/maps", - 520 to "https://myaccount.google.com/yourdata/search", - 530 to "https://fit.google.com/privacy/settings", - 547 to "https://myactivity.google.com/product/search", - 562 to "https://myaccount.google.com/yourdata/youtube", - 10003 to "https://myaccount.google.com/personal-info", - 10004 to "https://myaccount.google.com/data-and-privacy", - 10005 to "https://myaccount.google.com/people-and-sharing", - 10006 to "https://myaccount.google.com/security", - 10007 to "https://myaccount.google.com/payments-and-subscriptions", - 10015 to "https://support.google.com/accounts", - 10050 to "https://myaccount.google.com/profile", - 10090 to "https://myaccount.google.com/profile/name", - 10704 to "https://www.google.com/account/about", - 10706 to "https://myaccount.google.com/profile/profiles-summary", - 10728 to "https://myaccount.google.com/data-and-privacy/how-data-improves-experience", - 10729 to "https://myaccount.google.com/data-and-privacy/data-visibility", - 10759 to "https://myaccount.google.com/address/home", - 10760 to "https://myaccount.google.com/address/work", -) - -private val ALLOWED_WEB_PREFIXES = setOf( - "https://accounts.google.com/", - "https://myaccount.google.com/", - "https://one.google.com/", - "https://myactivity.google.com/", - "https://timeline.google.com/", - "https://takeout.google.com/", - "https://www.google.com/maps/timeline", - "https://www.google.com/setting/", - "https://drive.google.com/settings/", - "https://drive.google.com/accounts/", - "https://drive.google.com/u/1/settings/", - "https://payments.google.com/", - "https://policies.google.com/", - "https://fit.google.com/privacy/settings", - "https://maps.google.com/maps/timeline" -) - -private val ACTION_TO_SCREEN_ID = hashMapOf( - ACTION_MY_ACCOUNT to 1, - ACTION_ACCOUNT_PREFERENCES_SETTINGS to 1, - ACTION_SECURITY_SETTINGS to 10006, - ACTION_PRIVACY_SETTINGS to 10004, -) - -@Suppress("DEPRECATION") -class MainActivity : AppCompatActivity() { - private lateinit var webView: WebView - - private fun getSelectedAccountName(): String? = null - - override fun onCreate(savedInstanceState: Bundle?) { - val extras = intent?.extras?.also { it.keySet() } - Log.d(TAG, "Invoked with ${intent.action} and extras $extras") - super.onCreate(savedInstanceState) - - val screenId = intent?.getIntExtra(EXTRA_SCREEN_ID, -1).takeIf { it != -1 } ?: ACTION_TO_SCREEN_ID[intent.action] ?: 1 - val screenOptions = intent.extras?.keySet().orEmpty() - .filter { it.startsWith(EXTRA_SCREEN_OPTIONS_PREFIX) } - .map { it.substring(EXTRA_SCREEN_OPTIONS_PREFIX.length) to intent.getStringExtra(it) } - .toMap() - - val callingPackage = intent?.getStringExtra(EXTRA_CALLING_PACKAGE_NAME) ?: callingActivity?.packageName ?: Constants.GMS_PACKAGE_NAME - - val ignoreAccount = intent?.getBooleanExtra(EXTRA_IGNORE_ACCOUNT, false) ?: false - val accountName = if (ignoreAccount) null else { - val accounts = AccountManager.get(this).getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE) - val accountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME) ?: intent.getParcelableExtra("account")?.name ?: getSelectedAccountName() - accounts.find { it.name.equals(accountName) }?.name - } - - if (accountName == null) { - Log.w(TAG, "No account, going without!") - } - - if (screenId in SCREEN_ID_TO_URL) { - val layout = RelativeLayout(this) - layout.addView(ProgressBar(this).apply { - layoutParams = RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { - addRule(RelativeLayout.CENTER_HORIZONTAL) - addRule(RelativeLayout.CENTER_VERTICAL) - } - isIndeterminate = true - }) - webView = WebView(this).apply { - layoutParams = RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) - visibility = View.INVISIBLE - } - layout.addView(webView) - setContentView(layout) - WebViewHelper(this, webView, ALLOWED_WEB_PREFIXES).openWebView(SCREEN_ID_TO_URL[screenId], accountName) - setResult(RESULT_OK) - } else { - Log.w(TAG, "Unknown screen id, can't open corresponding web page") - setResult(RESULT_CANCELED) - finish() - } - } - - override fun onDestroy() { - super.onDestroy() - } - - @Deprecated("Deprecated in Java") - override fun onBackPressed() { - if (this::webView.isInitialized && webView.canGoBack()) { - webView.goBack() - } else { - super.onBackPressed() - } - } -} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/WebViewHelper.kt b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/WebViewHelper.kt deleted file mode 100644 index 7ce98e9c..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/WebViewHelper.kt +++ /dev/null @@ -1,130 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.accountsettings.ui - -import android.content.Intent -import android.content.Intent.URI_INTENT_SCHEME -import android.net.Uri -import android.util.Log -import android.view.View -import android.webkit.WebResourceRequest -import android.webkit.WebSettings -import android.webkit.WebView -import androidx.appcompat.app.AppCompatActivity -import androidx.lifecycle.lifecycleScope -import androidx.webkit.WebResourceErrorCompat -import androidx.webkit.WebViewClientCompat -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.microg.gms.auth.AuthManager -import org.microg.gms.common.Constants.GMS_PACKAGE_NAME -import org.microg.gms.common.PackageUtils -import java.net.URLEncoder -import java.util.* - -private const val TAG = "AccountSettingsWebView" - -class WebViewHelper(private val activity: AppCompatActivity, private val webView: WebView, private val allowedPrefixes: Set = emptySet()) { - fun openWebView(url: String?, accountName: String?) { - prepareWebViewSettings(webView.settings) - webView.webViewClient = object : WebViewClientCompat() { - override fun onReceivedError(view: WebView, request: WebResourceRequest, error: WebResourceErrorCompat) { - Log.w(TAG, "Error loading: $error") - } - - override fun onPageFinished(view: WebView?, url: String?) { - super.onPageFinished(view, url) - webView.visibility = View.VISIBLE - } - - @Deprecated("Deprecated in Java") - override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { - Log.d(TAG, "Navigating to $url") - if (url.startsWith("intent:")) { - try { - val intent = Intent.parseUri(url, URI_INTENT_SCHEME) - if (intent.`package` == GMS_PACKAGE_NAME || PackageUtils.isGooglePackage(activity, intent.`package`)) { - // Only allow to start Google packages - activity.startActivity(intent) - } else { - Log.w(TAG, "Ignoring request to start non-Google app") - } - } catch (e: Exception) { - Log.w(TAG, "Error invoking intent", e) - } - return false - } - if (allowedPrefixes.isNotEmpty() && allowedPrefixes.none { url.startsWith(it) }) { - try { - activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { addCategory(Intent.CATEGORY_BROWSABLE) }) - } catch (e: Exception) { - Log.w(TAG, "Error forwarding to browser", e) - } - return true - } - return false - } - } - - val urlWithLanguage: String? = addLanguageParam(url) - if (accountName != null) { - activity.lifecycleScope.launch { - withContext(Dispatchers.IO) { - openWebWithAccount(accountName, urlWithLanguage) - } - } - } else { - loadWebViewUrl(urlWithLanguage) - } - } - - private fun loadWebViewUrl(url: String?) { - if (url != null) { - webView.loadUrl(url) - } else { - activity.finish() - } - } - - private fun addLanguageParam(url: String?): String? { - val language = Locale.getDefault().language - return if (language.isNotEmpty()) { - Uri.parse(url).buildUpon().appendQueryParameter("hl", language).toString() - } else { - url - } - } - - private fun openWebWithAccount(accountName: String, url: String?) { - try { - val service = "weblogin:continue=" + URLEncoder.encode(url, "utf-8") - val authManager = AuthManager(activity, accountName, GMS_PACKAGE_NAME, service) - val authUrl = authManager.requestAuth(false)?.auth - if (authUrl?.contains("WILL_NOT_SIGN_IN") == true) { - throw RuntimeException("Would not sign in") - } - Log.d(TAG, "Opening $authUrl") - webView.post { - loadWebViewUrl(authUrl) - } - } catch (e: Exception) { - Log.w(TAG, "Failed to get weblogin auth.", e) - activity.finish() - } - } - - private fun prepareWebViewSettings(settings: WebSettings) { - settings.javaScriptEnabled = true - settings.setSupportMultipleWindows(false) - settings.allowFileAccess = false - settings.databaseEnabled = false - settings.setNeedInitialFocus(false) - settings.useWideViewPort = false - settings.setSupportZoom(false) - settings.javaScriptCanOpenWindowsAutomatically = false - } -} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/extensions.kt b/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/extensions.kt deleted file mode 100644 index 5ca88fe7..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/accountsettings/ui/extensions.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.accountsettings.ui - -const val ACTION_BROWSE_SETTINGS = "com.google.android.gms.accountsettings.action.BROWSE_SETTINGS" -const val ACTION_MY_ACCOUNT = "com.google.android.gms.accountsettings.MY_ACCOUNT" -const val ACTION_ACCOUNT_PREFERENCES_SETTINGS = "com.google.android.gms.accountsettings.ACCOUNT_PREFERENCES_SETTINGS" -const val ACTION_PRIVACY_SETTINGS = "com.google.android.gms.accountsettings.PRIVACY_SETTINGS" -const val ACTION_SECURITY_SETTINGS = "com.google.android.gms.accountsettings.SECURITY_SETTINGS" - -const val EXTRA_CALLING_PACKAGE_NAME = "extra.callingPackageName" -const val EXTRA_IGNORE_ACCOUNT = "extra.ignoreAccount" -const val EXTRA_ACCOUNT_NAME = "extra.accountName" -const val EXTRA_SCREEN_ID = "extra.screenId" -const val EXTRA_SCREEN_OPTIONS_PREFIX = "extra.screen." -const val EXTRA_FALLBACK_URL = "extra.fallbackUrl" -const val EXTRA_FALLBACK_AUTH = "extra.fallbackAuth" -const val EXTRA_THEME_CHOICE = "extra.themeChoice" - -const val OPTION_SCREEN_FLAVOR = "screenFlavor" \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/auth/AuthPrefs.kt b/play-services-core/src/main/kotlin/org/microg/gms/auth/AuthPrefs.kt index ba5d2b2e..a86db122 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/auth/AuthPrefs.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/auth/AuthPrefs.kt @@ -1,29 +1,26 @@ package org.microg.gms.auth import android.content.Context -import org.microg.gms.settings.SettingsContract -import org.microg.gms.settings.SettingsContract.Auth +import org.microg.mgms.settings.SettingsContract +import org.microg.mgms.settings.SettingsContract.Auth object AuthPrefs { @JvmStatic - fun isTrustGooglePermitted(context: Context): Boolean { - return SettingsContract.getSettings(context, Auth.getContentUri(context), arrayOf(Auth.TRUST_GOOGLE)) { c -> - c.getInt(0) != 0 + fun isTrustGooglePermitted(context: Context): Boolean? { + return Auth.getContentUri(context)?.let { + SettingsContract.getSettings(context, it, arrayOf(Auth.TRUST_GOOGLE)) { c -> + c.getInt(0) != 0 + } } } @JvmStatic - fun isAuthVisible(context: Context): Boolean { - return SettingsContract.getSettings(context, Auth.getContentUri(context), arrayOf(Auth.VISIBLE)) { c -> - c.getInt(0) != 0 - } - } - - @JvmStatic - fun shouldIncludeAndroidId(context: Context): Boolean { - return SettingsContract.getSettings(context, Auth.getContentUri(context), arrayOf(Auth.INCLUDE_ANDROID_ID)) { c -> - c.getInt(0) != 0 + fun isAuthVisible(context: Context): Boolean? { + return Auth.getContentUri(context)?.let { + SettingsContract.getSettings(context, it, arrayOf(Auth.VISIBLE)) { c -> + c.getInt(0) != 0 + } } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/auth/appcert/AppCertManager.kt b/play-services-core/src/main/kotlin/org/microg/gms/auth/appcert/AppCertManager.kt index c99b3cc3..3120a555 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/auth/appcert/AppCertManager.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/auth/appcert/AppCertManager.kt @@ -7,7 +7,6 @@ package org.microg.gms.auth.appcert import android.content.Context import android.database.Cursor -import android.os.SystemClock import android.util.Base64 import android.util.Log import com.android.volley.NetworkResponse @@ -29,8 +28,8 @@ import org.microg.gms.gcm.RegisterRequest import org.microg.gms.gcm.completeRegisterRequest import org.microg.gms.profile.Build import org.microg.gms.profile.ProfileManager -import org.microg.gms.settings.SettingsContract.CheckIn -import org.microg.gms.settings.SettingsContract.getSettings +import org.microg.mgms.settings.SettingsContract.CheckIn +import org.microg.mgms.settings.SettingsContract.getSettings import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec import kotlin.random.Random @@ -63,7 +62,7 @@ class AppCertManager(private val context: Context) { Log.w(TAG, "DeviceKeys for app certifications are experimental") deviceKeyCacheTime = currentTime val lastCheckinInfo = LastCheckinInfo.read(context) - val androidId = lastCheckinInfo.androidId + val androidId = lastCheckinInfo?.androidId val sessionId = Random.nextLong() val token = completeRegisterRequest(context, GcmDatabase(context), RegisterRequest().build(context) .checkin(lastCheckinInfo) @@ -76,7 +75,7 @@ class AppCertManager(private val context: Context) { .extraParam("scope", REGISTER_SCOPE)) .getString(GcmConstants.EXTRA_REGISTRATION_ID) val request = DeviceKeyRequest( - androidId = lastCheckinInfo.androidId, + androidId = lastCheckinInfo?.androidId, sessionId = sessionId, versionInfo = DeviceKeyRequest.VersionInfo(Build.VERSION.SDK_INT, BuildConfig.VERSION_CODE), token = token @@ -97,11 +96,7 @@ class AppCertManager(private val context: Context) { } override fun deliverError(error: VolleyError) { - if (error.networkResponse != null) { - Log.d(TAG, "Error: ${Base64.encodeToString(error.networkResponse.data, 2)}") - } else { - Log.d(TAG, "Error: ${error.message}") - } + Log.d(TAG, "Error: ${Base64.encodeToString(error.networkResponse.data, 2)}") deviceKeyCacheTime = 0 deferredResponse.complete(null) } @@ -112,10 +107,10 @@ class AppCertManager(private val context: Context) { override fun getHeaders(): Map { return mapOf( - "User-Agent" to "GoogleAuth/1.4 (${Build.DEVICE} ${Build.ID}); gzip", - "content-type" to "application/octet-stream", - "app" to "com.google.android.gms", - "device" to androidId.toString(16) + "User-Agent" to "GoogleAuth/1.4 (${Build.DEVICE} ${Build.ID}); gzip", + "content-type" to "application/octet-stream", + "app" to "com.google.android.gms", + "device" to androidId!!.toString(16) ) } }) @@ -154,12 +149,14 @@ class AppCertManager(private val context: Context) { ) } else { Log.d(TAG, "Using fallback spatula header based on Android ID") - val androidId = getSettings(context, CheckIn.getContentUri(context), arrayOf(CheckIn.ANDROID_ID)) { cursor: Cursor -> cursor.getLong(0) } + val androidId = CheckIn.getContentUri(context)?.let { + getSettings(context, + it, arrayOf(CheckIn.ANDROID_ID, CheckIn.SECURITY_TOKEN)) { cursor: Cursor -> cursor.getLong(0) } + } SpatulaHeaderProto( packageInfo = SpatulaHeaderProto.PackageInfo(packageName, packageCertificateHash), deviceId = androidId ) - return null // TODO } Log.d(TAG, "Spatula Header: $proto") return Base64.encodeToString(proto.encode(), Base64.NO_WRAP) diff --git a/play-services-core/src/main/kotlin/org/microg/gms/auth/appcert/AppCertService.kt b/play-services-core/src/main/kotlin/org/microg/gms/auth/appcert/AppCertService.kt index 9b14af49..e73017e2 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/auth/appcert/AppCertService.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/auth/appcert/AppCertService.kt @@ -38,5 +38,5 @@ class AppCertServiceImpl(private val context: Context) : IAppCertService.Stub() return runBlocking { manager.getSpatulaHeader(packageName) } } - override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) } + override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags) { super.onTransact(code, data, reply, flags) } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/CredentialsService.kt b/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/CredentialsService.kt index 4e933426..adc0370b 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/CredentialsService.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/CredentialsService.kt @@ -52,5 +52,5 @@ class CredentialsServiceImpl : ICredentialsService.Stub() { callbacks.onStatus(Status.SUCCESS) } - override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) } + override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags) { super.onTransact(code, data, reply, flags) } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/auth/proxy/AuthProxyService.kt b/play-services-core/src/main/kotlin/org/microg/gms/auth/proxy/AuthProxyService.kt index ede33d26..e1cedd59 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/auth/proxy/AuthProxyService.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/auth/proxy/AuthProxyService.kt @@ -59,5 +59,5 @@ class AuthServiceImpl(private val context: Context, private val lifecycle: Lifec override fun getLifecycle(): Lifecycle = lifecycle - override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) } + override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags) { super.onTransact(code, data, reply, flags) } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPreferences.kt b/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPreferences.kt deleted file mode 100644 index eb78d498..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPreferences.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020, microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ -package org.microg.gms.checkin - -import android.content.Context -import android.content.Intent -import org.microg.gms.settings.SettingsContract -import org.microg.gms.settings.SettingsContract.CheckIn -import org.microg.gms.settings.SettingsContract.setSettings - -object CheckinPreferences { - - @JvmStatic - fun isEnabled(context: Context): Boolean { - val projection = arrayOf(CheckIn.ENABLED) - return SettingsContract.getSettings( - context, - CheckIn.getContentUri(context), - projection - ) { c -> - c.getInt(0) != 0 - } - } - - @JvmStatic - fun isSpoofingEnabled(context: Context): Boolean { - val projection = arrayOf(CheckIn.BRAND_SPOOF) - return SettingsContract.getSettings( - context, - CheckIn.getContentUri(context), - projection - ) { c -> - c.getInt(0) != 0 - } - } - - @JvmStatic - fun setSpoofingEnabled(context: Context, enabled: Boolean) { - setSettings(context, CheckIn.getContentUri(context)) { - put(CheckIn.BRAND_SPOOF, enabled) - } - } - - @JvmStatic - fun hideLauncherIcon(context: Context, enabled: Boolean) { - setSettings(context, CheckIn.getContentUri(context)) { - put(CheckIn.HIDE_LAUNCHER_ICON, enabled) - } - } - - @JvmStatic - fun setEnabled(context: Context, enabled: Boolean) { - SettingsContract.setSettings(context, CheckIn.getContentUri(context)) { - put(CheckIn.ENABLED, enabled) - } - if (enabled) { - context.sendOrderedBroadcast(Intent(context, TriggerReceiver::class.java), null) - } - } -} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPrefs.kt b/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPrefs.kt new file mode 100644 index 00000000..019ddfa9 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPrefs.kt @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package org.microg.gms.checkin + +import android.content.Context +import org.microg.mgms.settings.SettingsContract +import org.microg.mgms.settings.SettingsContract.CheckIn +import org.microg.mgms.settings.SettingsContract.setSettings + +object CheckinPrefs { + + @JvmStatic + fun isEnabled(context: Context): Boolean? { + val projection = arrayOf(CheckIn.ENABLED) + return CheckIn.getContentUri(context)?.let { + SettingsContract.getSettings(context, it, projection) { c -> + c.getInt(0) != 0 + } + } + } + + @JvmStatic + fun isSpoofingEnabled(context: Context): Boolean? { + val projection = arrayOf(CheckIn.BRAND_SPOOF) + return CheckIn.getContentUri(context)?.let { + SettingsContract.getSettings(context, it, projection) { c -> + c.getInt(0) != 0 + } + } + } + + @JvmStatic + fun setSpoofingEnabled(context: Context, enabled: Boolean) { + CheckIn.getContentUri(context)?.let { + setSettings(context, it) { + put(CheckIn.BRAND_SPOOF, enabled) + } + } + } + + @JvmStatic + fun hideLauncherIcon(context: Context, enabled: Boolean) { + CheckIn.getContentUri(context)?.let { + setSettings(context, it) { + put(CheckIn.HIDE_LAUNCHER_ICON, enabled) + } + } + } + +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/checkin/LastCheckinInfo.kt b/play-services-core/src/main/kotlin/org/microg/gms/checkin/LastCheckinInfo.kt index ab2dc042..e3e26f68 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/checkin/LastCheckinInfo.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/checkin/LastCheckinInfo.kt @@ -16,8 +16,8 @@ package org.microg.gms.checkin import android.content.Context -import org.microg.gms.settings.SettingsContract -import org.microg.gms.settings.SettingsContract.CheckIn +import org.microg.mgms.settings.SettingsContract +import org.microg.mgms.settings.SettingsContract.CheckIn data class LastCheckinInfo( val lastCheckin: Long, @@ -39,7 +39,7 @@ data class LastCheckinInfo( companion object { @JvmStatic - fun read(context: Context): LastCheckinInfo { + fun read(context: Context): LastCheckinInfo? { val projection = arrayOf( CheckIn.ANDROID_ID, CheckIn.DIGEST, @@ -48,35 +48,43 @@ data class LastCheckinInfo( CheckIn.VERSION_INFO, CheckIn.DEVICE_DATA_VERSION_INFO, ) - return SettingsContract.getSettings(context, CheckIn.getContentUri(context), projection) { c -> - LastCheckinInfo( - androidId = c.getLong(0), - digest = c.getString(1), - lastCheckin = c.getLong(2), - securityToken = c.getLong(3), - versionInfo = c.getString(4), - deviceDataVersionInfo = c.getString(5), - ) + return CheckIn.getContentUri(context)?.let { + SettingsContract.getSettings(context, it, projection) { c -> + LastCheckinInfo( + androidId = c.getLong(0), + digest = c.getString(1), + lastCheckin = c.getLong(2), + securityToken = c.getLong(3), + versionInfo = c.getString(4), + deviceDataVersionInfo = c.getString(5), + ) + } } } @JvmStatic - fun clear(context: Context) = SettingsContract.setSettings(context, CheckIn.getContentUri(context)) { - put(CheckIn.ANDROID_ID, 0L) - put(CheckIn.DIGEST, CheckIn.INITIAL_DIGEST) - put(CheckIn.LAST_CHECK_IN, 0L) - put(CheckIn.SECURITY_TOKEN, 0L) - put(CheckIn.VERSION_INFO, "") - put(CheckIn.DEVICE_DATA_VERSION_INFO, "") - } + fun clear(context: Context) = + CheckIn.getContentUri(context)?.let { + SettingsContract.setSettings(context, it) { + put(CheckIn.ANDROID_ID, 0L) + put(CheckIn.DIGEST, CheckIn.INITIAL_DIGEST) + put(CheckIn.LAST_CHECK_IN, 0L) + put(CheckIn.SECURITY_TOKEN, 0L) + put(CheckIn.VERSION_INFO, "") + put(CheckIn.DEVICE_DATA_VERSION_INFO, "") + } + } } - fun write(context: Context) = SettingsContract.setSettings(context, CheckIn.getContentUri(context)) { - put(CheckIn.ANDROID_ID, androidId) - put(CheckIn.DIGEST, digest) - put(CheckIn.LAST_CHECK_IN, lastCheckin) - put(CheckIn.SECURITY_TOKEN, securityToken) - put(CheckIn.VERSION_INFO, versionInfo) - put(CheckIn.DEVICE_DATA_VERSION_INFO, deviceDataVersionInfo) - } + fun write(context: Context) = + CheckIn.getContentUri(context)?.let { + SettingsContract.setSettings(context, it) { + put(CheckIn.ANDROID_ID, androidId) + put(CheckIn.DIGEST, digest) + put(CheckIn.LAST_CHECK_IN, lastCheckin) + put(CheckIn.SECURITY_TOKEN, securityToken) + put(CheckIn.VERSION_INFO, versionInfo) + put(CheckIn.DEVICE_DATA_VERSION_INFO, deviceDataVersionInfo) + } + } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/checkin/ServiceInfo.kt b/play-services-core/src/main/kotlin/org/microg/gms/checkin/ServiceInfo.kt index d42c9e03..67084e03 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/checkin/ServiceInfo.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/checkin/ServiceInfo.kt @@ -9,9 +9,9 @@ import android.content.Context import android.content.Intent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.microg.gms.settings.SettingsContract.CheckIn -import org.microg.gms.settings.SettingsContract.getSettings -import org.microg.gms.settings.SettingsContract.setSettings +import org.microg.mgms.settings.SettingsContract.CheckIn +import org.microg.mgms.settings.SettingsContract.getSettings +import org.microg.mgms.settings.SettingsContract.setSettings import java.io.Serializable data class ServiceInfo(val configuration: ServiceConfiguration, val lastCheckin: Long, val androidId: Long) : Serializable @@ -20,22 +20,26 @@ data class ServiceConfiguration(val enabled: Boolean) : Serializable suspend fun getCheckinServiceInfo(context: Context): ServiceInfo = withContext(Dispatchers.IO) { val projection = arrayOf(CheckIn.ENABLED, CheckIn.LAST_CHECK_IN, CheckIn.ANDROID_ID) - getSettings(context, CheckIn.getContentUri(context), projection) { c -> - ServiceInfo( - configuration = ServiceConfiguration(c.getInt(0) != 0), - lastCheckin = c.getLong(1), - androidId = c.getLong(2), - ) - } + CheckIn.getContentUri(context)?.let { + getSettings(context, it, projection) { c -> + ServiceInfo( + configuration = ServiceConfiguration(c.getInt(0) != 0), + lastCheckin = c.getLong(1), + androidId = c.getLong(2), + ) + } + }!! } suspend fun setCheckinServiceConfiguration(context: Context, configuration: ServiceConfiguration) = withContext(Dispatchers.IO) { val serviceInfo = getCheckinServiceInfo(context) if (serviceInfo.configuration == configuration) return@withContext // enabled state is not already set, setting it now - setSettings(context, CheckIn.getContentUri(context)) { + CheckIn.getContentUri(context)?.let { + setSettings(context, it) { put(CheckIn.ENABLED, configuration.enabled) } + } if (configuration.enabled) { context.sendOrderedBroadcast(Intent(context, TriggerReceiver::class.java), null) } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/gcm/GcmPrefs.kt b/play-services-core/src/main/kotlin/org/microg/gms/gcm/GcmPrefs.kt index c506ed62..77cf34b0 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/gcm/GcmPrefs.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/gcm/GcmPrefs.kt @@ -8,11 +8,10 @@ import android.net.ConnectivityManager import android.net.NetworkInfo import android.util.Log import org.microg.gms.gcm.TriggerReceiver.FORCE_TRY_RECONNECT -import org.microg.gms.settings.SettingsContract -import org.microg.gms.settings.SettingsContract.Gcm -import org.microg.gms.settings.SettingsContract.setSettings -import kotlin.math.max -import kotlin.math.min +import org.microg.mgms.settings.SettingsContract +import org.microg.mgms.settings.SettingsContract.Gcm +import org.microg.mgms.settings.SettingsContract.setSettings +import org.microg.mgms.settings.SettingsProvider data class GcmPrefs( val isGcmLogEnabled: Boolean, @@ -38,57 +37,49 @@ data class GcmPrefs( const val PREF_NETWORK_ROAMING = Gcm.NETWORK_ROAMING const val PREF_NETWORK_OTHER = Gcm.NETWORK_OTHER - private const val MIN_INTERVAL = 5 * 60 * 1000 // 5 minutes - private const val MAX_INTERVAL = 15 * 60 * 1000 // 15 minutes - @JvmStatic - fun get(context: Context): GcmPrefs { - return SettingsContract.getSettings(context, Gcm.getContentUri(context), Gcm.PROJECTION) { c -> - GcmPrefs( - isGcmLogEnabled = c.getInt(0) != 0, - lastPersistedId = c.getString(1), - gcmEnabled = c.getInt(2) != 0, - networkMobile = c.getInt(3), - networkWifi = c.getInt(4), - networkRoaming = c.getInt(5), - networkOther = c.getInt(6), - learntMobileInterval = c.getInt(7), - learntWifiInterval = c.getInt(8), - learntOtherInterval = c.getInt(9), - ) + fun get(context: Context): GcmPrefs? { + return Gcm.getContentUri(context)?.let { + SettingsContract.getSettings(context, it, Gcm.PROJECTION) { c -> + GcmPrefs( + isGcmLogEnabled = c.getInt(0) != 0, + lastPersistedId = c.getString(1), + gcmEnabled = c.getInt(2) != 0, + networkMobile = c.getInt(3), + networkWifi = c.getInt(4), + networkRoaming = c.getInt(5), + networkOther = c.getInt(6), + learntMobileInterval = c.getInt(7), + learntWifiInterval = c.getInt(8), + learntOtherInterval = c.getInt(9), + ) + } } } fun write(context: Context, config: ServiceConfiguration) { - val gcmPrefs = get(context) - setSettings(context, Gcm.getContentUri(context)) { - put(Gcm.ENABLE_GCM, config.enabled) - put(Gcm.NETWORK_MOBILE, config.mobile) - put(Gcm.NETWORK_WIFI, config.wifi) - put(Gcm.NETWORK_ROAMING, config.roaming) - put(Gcm.NETWORK_OTHER, config.other) + Gcm.getContentUri(context)?.let { + setSettings(context, it) { + put(Gcm.ENABLE_GCM, config.enabled) + put(Gcm.NETWORK_MOBILE, config.mobile) + put(Gcm.NETWORK_WIFI, config.wifi) + put(Gcm.NETWORK_ROAMING, config.roaming) + put(Gcm.NETWORK_OTHER, config.other) + } } - gcmPrefs.setEnabled(context, config.enabled) + get(context)?.setEnabled(context, config.enabled) } - fun setEnabled(context: Context, enabled: Boolean) { - val prefs = get(context) - setSettings(context, Gcm.getContentUri(context)) { - put(Gcm.ENABLE_GCM, enabled) - } - prefs.setEnabled(context, enabled) - } - - @JvmStatic fun clearLastPersistedId(context: Context) { - setSettings(context, Gcm.getContentUri(context)) { - put(Gcm.LAST_PERSISTENT_ID, "") + Gcm.getContentUri(context)?.let { + setSettings(context, it) { + put(Gcm.LAST_PERSISTENT_ID, "") + } } } } - /** * Call this whenever the enabled state of GCM has changed. */ @@ -102,7 +93,6 @@ data class GcmPrefs( } } - @Suppress("DEPRECATION") fun getNetworkPrefForInfo(info: NetworkInfo?): String { if (info == null) return PREF_NETWORK_OTHER return if (info.isRoaming) PREF_NETWORK_ROAMING else when (info.type) { @@ -112,37 +102,42 @@ data class GcmPrefs( } } - @Suppress("DEPRECATION") fun getHeartbeatMsFor(info: NetworkInfo?): Int { return getHeartbeatMsFor(getNetworkPrefForInfo(info)) } fun getHeartbeatMsFor(pref: String): Int { return if (PREF_NETWORK_ROAMING == pref) { - if (networkRoaming != 0) networkRoaming * 60000 else learntMobileInterval + if (networkRoaming != 0) networkRoaming * SettingsProvider.INTERVAL else learntMobileInterval } else if (PREF_NETWORK_MOBILE == pref) { - if (networkMobile != 0) networkMobile * 60000 else learntMobileInterval + if (networkMobile != 0) networkMobile * SettingsProvider.INTERVAL else learntMobileInterval } else if (PREF_NETWORK_WIFI == pref) { - if (networkWifi != 0) networkWifi * 60000 else learntWifiInterval + if (networkWifi != 0) networkWifi * SettingsProvider.INTERVAL else learntWifiInterval } else { - if (networkOther != 0) networkOther * 60000 else learntOtherInterval + if (networkOther != 0) networkOther * SettingsProvider.INTERVAL else learntOtherInterval } } fun learnTimeout(context: Context, pref: String) { Log.d("GmsGcmPrefs", "learnTimeout: $pref") when (pref) { - PREF_NETWORK_MOBILE, PREF_NETWORK_ROAMING -> setSettings(context, Gcm.getContentUri(context)) { - val newInterval = (learntMobileInterval * 0.95).toInt() - put(Gcm.LEARNT_MOBILE, max(MIN_INTERVAL, min(newInterval, MAX_INTERVAL))) + PREF_NETWORK_MOBILE, PREF_NETWORK_ROAMING -> Gcm.getContentUri(context)?.let { + setSettings(context, it) { + val newInterval = (learntMobileInterval * 0.95).toInt() + put(Gcm.LEARNT_MOBILE, newInterval) + } } - PREF_NETWORK_WIFI -> setSettings(context, Gcm.getContentUri(context)) { - val newInterval = (learntWifiInterval * 0.95).toInt() - put(Gcm.LEARNT_WIFI, max(MIN_INTERVAL, min(newInterval, MAX_INTERVAL))) + PREF_NETWORK_WIFI -> Gcm.getContentUri(context)?.let { + setSettings(context, it) { + val newInterval = (learntMobileInterval * 0.95).toInt() + put(Gcm.LEARNT_WIFI, newInterval) + } } - else -> setSettings(context, Gcm.getContentUri(context)) { - val newInterval = (learntOtherInterval * 0.95).toInt() - put(Gcm.LEARNT_OTHER, max(MIN_INTERVAL, min(newInterval, MAX_INTERVAL))) + else -> Gcm.getContentUri(context)?.let { + setSettings(context, it) { + val newInterval = (learntMobileInterval * 0.95).toInt() + put(Gcm.LEARNT_OTHER, newInterval) + } } } } @@ -152,40 +147,45 @@ data class GcmPrefs( when (pref) { PREF_NETWORK_MOBILE, PREF_NETWORK_ROAMING -> { if (time > learntMobileInterval / 4 * 3) { - val newInterval = (learntMobileInterval * 1.02).toInt() - setSettings(context, Gcm.getContentUri(context)) { - put(Gcm.LEARNT_MOBILE, max(MIN_INTERVAL, min(newInterval, MAX_INTERVAL))) + Gcm.getContentUri(context)?.let { + setSettings(context, it) { + put(Gcm.LEARNT_MOBILE, SettingsProvider.INTERVAL) + } } } } PREF_NETWORK_WIFI -> { if (time > learntWifiInterval / 4 * 3) { - val newInterval = (learntWifiInterval * 1.02).toInt() - setSettings(context, Gcm.getContentUri(context)) { - put(Gcm.LEARNT_WIFI, max(MIN_INTERVAL, min(newInterval, MAX_INTERVAL))) + Gcm.getContentUri(context)?.let { + setSettings(context, it) { + put(Gcm.LEARNT_WIFI, SettingsProvider.INTERVAL) + } } } } else -> { if (time > learntOtherInterval / 4 * 3) { - val newInterval = (learntOtherInterval * 1.02).toInt() - setSettings(context, Gcm.getContentUri(context)) { - put(Gcm.LEARNT_OTHER, max(MIN_INTERVAL, min(newInterval, MAX_INTERVAL))) + Gcm.getContentUri(context)?.let { + setSettings(context, it) { + put(Gcm.LEARNT_OTHER, SettingsProvider.INTERVAL) + } } } } } } - @Suppress("DEPRECATION") fun isEnabledFor(info: NetworkInfo?): Boolean { return isEnabled && info != null && getHeartbeatMsFor(info) >= 0 } fun extendLastPersistedId(context: Context, id: String) { val newId = if (lastPersistedId.isNullOrEmpty()) id else "$lastPersistedId|$id" - setSettings(context, Gcm.getContentUri(context)) { - put(Gcm.LAST_PERSISTENT_ID, newId) + Gcm.getContentUri(context)?.let { + setSettings(context, it) { + put(Gcm.LAST_PERSISTENT_ID, newId) + } } } + } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/gcm/PushRegisterService.kt b/play-services-core/src/main/kotlin/org/microg/gms/gcm/PushRegisterService.kt index 8d3b9a78..4b7b44bc 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/gcm/PushRegisterService.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/gcm/PushRegisterService.kt @@ -6,6 +6,7 @@ package org.microg.gms.gcm +import android.annotation.SuppressLint import android.app.PendingIntent import android.content.Context import android.content.Intent @@ -16,7 +17,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleService import androidx.lifecycle.lifecycleScope -import org.microg.gms.checkin.CheckinPreferences +import org.microg.gms.checkin.CheckinPrefs import org.microg.gms.checkin.CheckinService import org.microg.gms.checkin.LastCheckinInfo import org.microg.gms.common.ForegroundServiceContext @@ -29,30 +30,32 @@ import kotlin.coroutines.suspendCoroutine private const val TAG = "GmsGcmRegister" private suspend fun ensureCheckinIsUpToDate(context: Context) { - if (!CheckinPreferences.isEnabled(context)) throw RuntimeException("Checkin disabled") - val lastCheckin = LastCheckinInfo.read(context).lastCheckin - if (lastCheckin < System.currentTimeMillis() - CheckinService.MAX_VALID_CHECKIN_AGE) { - val resultData: Bundle = suspendCoroutine { continuation -> - val intent = Intent(context, CheckinService::class.java) - val continued = AtomicBoolean(false) - intent.putExtra(CheckinService.EXTRA_RESULT_RECEIVER, object : ResultReceiver(null) { - override fun onReceiveResult(resultCode: Int, resultData: Bundle?) { - if (continued.compareAndSet(false, true)) continuation.resume(resultData ?: Bundle.EMPTY) - } - }) - ForegroundServiceContext(context).startService(intent) - Handler().postDelayed({ - if (continued.compareAndSet(false, true)) continuation.resume(Bundle.EMPTY) - }, 10000L) - } - if (resultData.getLong(CheckinService.EXTRA_NEW_CHECKIN_TIME, 0L) + lastCheckin == 0L) { - throw RuntimeException("No checkin available") + if (!CheckinPrefs.isEnabled(context)!!) throw RuntimeException("Checkin disabled") + val lastCheckin = LastCheckinInfo.read(context)?.lastCheckin + if (lastCheckin != null) { + if (lastCheckin < System.currentTimeMillis() - CheckinService.MAX_VALID_CHECKIN_AGE) { + val resultData: Bundle = suspendCoroutine { continuation -> + val intent = Intent(context, CheckinService::class.java) + val continued = AtomicBoolean(false) + intent.putExtra(CheckinService.EXTRA_RESULT_RECEIVER, object : ResultReceiver(null) { + override fun onReceiveResult(resultCode: Int, resultData: Bundle?) { + if (continued.compareAndSet(false, true)) continuation.resume(resultData ?: Bundle.EMPTY) + } + }) + ForegroundServiceContext(context).startService(intent) + Handler().postDelayed({ + if (continued.compareAndSet(false, true)) continuation.resume(Bundle.EMPTY) + }, 10000L) + } + if (resultData.getLong(CheckinService.EXTRA_NEW_CHECKIN_TIME, 0L) + lastCheckin == 0L) { + throw RuntimeException("No checkin available") + } } } } private fun ensureAppRegistrationAllowed(context: Context, database: GcmDatabase, packageName: String) { - if (!GcmPrefs.get(context).isEnabled) throw RuntimeException("GCM disabled") + if (!GcmPrefs.get(context)?.isEnabled!!) throw RuntimeException("GCM disabled") val app = database.getApp(packageName) if (app?.allowRegister == false) { throw RuntimeException("Push permission not granted to $packageName") @@ -242,10 +245,11 @@ internal class PushRegisterHandler(private val context: Context, private val dat } private val selfAuthIntent: PendingIntent + @SuppressLint("UnspecifiedImmutableFlag") get() { val intent = Intent() intent.setPackage("com.google.example.invalidpackage") - return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) + return PendingIntent.getBroadcast(context, 0, intent, 0) } override fun handleMessage(msg: Message) { diff --git a/play-services-core/src/main/kotlin/org/microg/gms/gcm/ServiceInfo.kt b/play-services-core/src/main/kotlin/org/microg/gms/gcm/ServiceInfo.kt index be9c0f67..1fd34bac 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/gcm/ServiceInfo.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/gcm/ServiceInfo.kt @@ -36,14 +36,16 @@ class ServiceInfoReceiver : BroadcastReceiver() { context.sendOrderedBroadcast(Intent(ACTION_SERVICE_INFO_RESPONSE).apply { setPackage(context.packageName) val prefs = GcmPrefs.get(context) - val info = ServiceInfo( - configuration = prefs.toConfiguration(), + val info = prefs?.let { + ServiceInfo( + configuration = it.toConfiguration(), connected = McsService.isConnected(context), startTimestamp = McsService.getStartTimestamp(), learntMobileInterval = prefs.learntMobileInterval, learntWifiInterval = prefs.learntWifiInterval, learntOtherInterval = prefs.learntOtherInterval - ) + ) + } putExtra(EXTRA_SERVICE_INFO, info) }, null) } catch (e: Exception) { diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/AppHeadingPreference.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/AppHeadingPreference.kt deleted file mode 100644 index c3cf6185..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/AppHeadingPreference.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ -package org.microg.gms.ui -import android.content.Context -import android.content.Intent -import android.content.pm.ApplicationInfo -import android.net.Uri -import android.provider.Settings -import android.util.AttributeSet -import android.util.Log -import android.view.View -import android.widget.ImageView -import androidx.appcompat.content.res.AppCompatResources -import androidx.preference.Preference -import androidx.preference.PreferenceViewHolder -import org.microg.gms.base.core.R -class AppHeadingPreference : AppPreference, Preference.OnPreferenceClickListener { - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context) : super(context) - init { - layoutResource = R.layout.preference_app_heading - onPreferenceClickListener = this - } - override fun onPreferenceClick(preference: Preference): Boolean { - if (packageName != null) { - val intent = Intent() - intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS - val uri: Uri = Uri.fromParts("package", packageName, null) - intent.data = uri - try { - context.startActivity(intent) - } catch (e: Exception) { - Log.w(TAG, "Failed to launch app", e) - } - return true - } else { - return false - } - } -} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt index 1570c691..ef30f876 100755 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt @@ -11,10 +11,10 @@ import android.util.DisplayMetrics import android.widget.ImageView import androidx.preference.Preference import androidx.preference.PreferenceViewHolder -import android.content.pm.ApplicationInfo -class AppIconPreference : AppPreference { - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) +class AppIconPreference : Preference { + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super( + context, attrs, defStyleAttr, defStyleRes) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context) : super(context) diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/AppPreference.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/AppPreference.kt deleted file mode 100644 index 27626231..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/AppPreference.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ -package org.microg.gms.ui -import android.content.Context -import android.content.pm.ApplicationInfo -import android.util.AttributeSet -import androidx.appcompat.content.res.AppCompatResources -import androidx.preference.Preference -abstract class AppPreference : Preference { - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context) : super(context) - init { - isPersistent = false - } - private var packageNameField: String? = null - var applicationInfo: ApplicationInfo? - get() = context.packageManager.getApplicationInfoIfExists(packageNameField) - set(value) { - if (value == null && packageNameField != null) { - title = null - icon = null - } else if (value != null) { - val pm = context.packageManager - title = value.loadLabel(pm) ?: value.packageName - icon = value.loadIcon(pm) ?: AppCompatResources.getDrawable(context, android.R.mipmap.sym_def_app_icon) - } - packageNameField = value?.packageName - } - var packageName: String? - get() = packageNameField - set(value) { - if (value == null && packageNameField != null) { - title = null - icon = null - } else if (value != null) { - val pm = context.packageManager - val applicationInfo = pm.getApplicationInfoIfExists(value) - title = applicationInfo?.loadLabel(pm)?.toString() ?: value - icon = applicationInfo?.loadIcon(pm) ?: AppCompatResources.getDrawable(context, android.R.mipmap.sym_def_app_icon) - } - packageNameField = value - } -} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt index 8c668529..17887575 100755 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt @@ -5,163 +5,51 @@ package org.microg.gms.ui - -import android.annotation.SuppressLint -import android.net.Uri import android.os.Bundle -import android.os.Handler -import android.text.format.DateUtils -import android.util.Log -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope -import androidx.preference.ListPreference -import androidx.preference.Preference -import androidx.preference.PreferenceCategory -import androidx.preference.PreferenceFragmentCompat import com.mgoogle.android.gms.R -import org.microg.gms.checkin.CheckinPreferences +import com.mgoogle.android.gms.databinding.DeviceRegistrationFragmentBinding +import org.microg.gms.checkin.ServiceInfo import org.microg.gms.checkin.getCheckinServiceInfo -import org.microg.gms.profile.ProfileManager -import org.microg.gms.profile.ProfileManager.PROFILE_AUTO -import org.microg.gms.profile.ProfileManager.PROFILE_NATIVE -import org.microg.gms.profile.ProfileManager.PROFILE_REAL -import org.microg.gms.profile.ProfileManager.PROFILE_SYSTEM -import org.microg.gms.profile.ProfileManager.PROFILE_USER -import java.io.File -import java.io.FileOutputStream +import org.microg.gms.checkin.setCheckinServiceConfiguration -class DeviceRegistrationFragment : PreferenceFragmentCompat() { - private lateinit var switchBarPreference: SwitchBarPreference - private lateinit var deviceProfile: ListPreference - private lateinit var importProfile: Preference - private lateinit var serial: Preference - private lateinit var statusCategory: PreferenceCategory - private lateinit var status: Preference - private lateinit var androidId: Preference - private val handler = Handler() - private val updateRunnable = Runnable { updateStatus() } - private lateinit var profileFileImport: ActivityResultLauncher +class DeviceRegistrationFragment : Fragment(R.layout.device_registration_fragment) { + private lateinit var binding: DeviceRegistrationFragmentBinding - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - profileFileImport = registerForActivityResult(ActivityResultContracts.GetContent(), this::onFileSelected) - } - private fun onFileSelected(uri: Uri?) { - if (uri == null) return - try { - val context = requireContext() - val file = File.createTempFile("profile_", ".xml", context.cacheDir) - context.contentResolver.openInputStream(uri)?.use { inputStream -> - FileOutputStream(file).use { inputStream.copyTo(it) } - } - val success = ProfileManager.importUserProfile(context, file) - file.delete() - if (success && ProfileManager.isAutoProfile(context, PROFILE_USER)) { - ProfileManager.setProfile(context, PROFILE_USER) - } - updateStatus() - } catch (e: Exception) { - Log.w(TAG, e) - } - } - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - addPreferencesFromResource(R.xml.preferences_device_registration) - } - @SuppressLint("RestrictedApi") - override fun onBindPreferences() { - switchBarPreference = preferenceScreen.findPreference("pref_checkin_enabled") ?: switchBarPreference - deviceProfile = preferenceScreen.findPreference("pref_device_profile") ?: deviceProfile - importProfile = preferenceScreen.findPreference("pref_device_profile_import") ?: importProfile - serial = preferenceScreen.findPreference("pref_device_serial") ?: serial - statusCategory = preferenceScreen.findPreference("prefcat_device_registration_status") ?: statusCategory - status = preferenceScreen.findPreference("pref_device_registration_status") ?: status - androidId = preferenceScreen.findPreference("pref_device_registration_android_id") ?: androidId - deviceProfile.setOnPreferenceChangeListener { _, newValue -> - ProfileManager.setProfile(requireContext(), newValue as String? ?: PROFILE_AUTO) - updateStatus() - true - } - importProfile.setOnPreferenceClickListener { - profileFileImport.launch("text/xml") - true - } - switchBarPreference.setOnPreferenceChangeListener { _, newValue -> - val newStatus = newValue as Boolean - CheckinPreferences.setEnabled(requireContext(), newStatus) - true - } - } - private fun configureProfilePreference() { - val context = requireContext() - val configuredProfile = ProfileManager.getConfiguredProfile(context) - val autoProfile = ProfileManager.getAutoProfile(context) - val autoProfileName = when (autoProfile) { - PROFILE_NATIVE -> getString(R.string.profile_name_native) - PROFILE_REAL -> getString(R.string.profile_name_real) - else -> ProfileManager.getProfileName(context, autoProfile) - } - val profiles = - mutableListOf(PROFILE_AUTO, PROFILE_NATIVE, PROFILE_REAL) - val profileNames = mutableListOf(getString(R.string.profile_name_auto, autoProfileName), getString(R.string.profile_name_native), getString(R.string.profile_name_real)) - if (ProfileManager.hasProfile(context, PROFILE_SYSTEM)) { - profiles.add(PROFILE_SYSTEM) - profileNames.add(getString(R.string.profile_name_system, ProfileManager.getProfileName(context, PROFILE_SYSTEM))) - } - if (ProfileManager.hasProfile(context, PROFILE_USER)) { - profiles.add(PROFILE_USER) - profileNames.add(getString(R.string.profile_name_user, ProfileManager.getProfileName(context, PROFILE_USER))) - } - for (profile in R.xml::class.java.declaredFields.map { it.name } - .filter { it.startsWith("profile_") } - .map { it.substring(8) } - .sorted()) { - val profileName = ProfileManager.getProfileName(context, profile) - if (profileName != null) { - profiles.add(profile) - profileNames.add(profileName) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = DeviceRegistrationFragmentBinding.inflate(inflater, container, false) + binding.switchBarCallback = object : PreferenceSwitchBarCallback { + override fun onChecked(newStatus: Boolean) { + setEnabled(newStatus) } } - deviceProfile.entryValues = profiles.toTypedArray() - deviceProfile.entries = profileNames.toTypedArray() - deviceProfile.value = configuredProfile - deviceProfile.summary = - profiles.indexOf(configuredProfile).takeIf { it >= 0 }?.let { profileNames[it] } ?: "Unknown" + return binding.root + } + + fun setEnabled(newStatus: Boolean) { + val appContext = requireContext().applicationContext + lifecycleScope.launchWhenResumed { + val info = getCheckinServiceInfo(appContext) + val newConfiguration = info.configuration.copy(enabled = newStatus) + setCheckinServiceConfiguration(appContext, newConfiguration) + displayServiceInfo(info.copy(configuration = newConfiguration)) + } + } + + private fun displayServiceInfo(serviceInfo: ServiceInfo) { + binding.checkinEnabled = serviceInfo.configuration.enabled } override fun onResume() { super.onResume() - switchBarPreference.isChecked = CheckinPreferences.isEnabled(requireContext()) - updateStatus() - } - override fun onPause() { - super.onPause() - handler.removeCallbacks(updateRunnable) - } - private fun updateStatus() { - handler.removeCallbacks(updateRunnable) - handler.postDelayed(updateRunnable, UPDATE_INTERVAL) val appContext = requireContext().applicationContext lifecycleScope.launchWhenResumed { - configureProfilePreference() - serial.summary = ProfileManager.getSerial(appContext) - val serviceInfo = getCheckinServiceInfo(appContext) - statusCategory.isVisible = serviceInfo.configuration.enabled - if (serviceInfo.lastCheckin > 0) { - status.summary = getString( - R.string.checkin_last_registration, - DateUtils.getRelativeTimeSpanString(serviceInfo.lastCheckin, System.currentTimeMillis(), 0) - ) - androidId.isVisible = true - androidId.summary = serviceInfo.androidId.toString(16) - } else { - status.summary = getString(R.string.checkin_not_registered) - androidId.isVisible = false - } + displayServiceInfo(getCheckinServiceInfo(appContext)) } } - companion object { - private const val UPDATE_INTERVAL = 1000L - } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt new file mode 100755 index 00000000..a0b4ad13 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt @@ -0,0 +1,164 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.annotation.SuppressLint +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.text.format.DateUtils +import android.util.Log +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts +import androidx.lifecycle.lifecycleScope +import androidx.preference.ListPreference +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import com.mgoogle.android.gms.R +import org.microg.gms.checkin.getCheckinServiceInfo +import org.microg.gms.profile.ProfileManager +import org.microg.gms.profile.ProfileManager.PROFILE_AUTO +import org.microg.gms.profile.ProfileManager.PROFILE_NATIVE +import org.microg.gms.profile.ProfileManager.PROFILE_REAL +import org.microg.gms.profile.ProfileManager.PROFILE_SYSTEM +import org.microg.gms.profile.ProfileManager.PROFILE_USER +import java.io.File +import java.io.FileOutputStream + +@Suppress("Warnings") +class DeviceRegistrationPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var deviceProfile: ListPreference + private lateinit var importProfile: Preference + private lateinit var serial: Preference + private lateinit var statusCategory: PreferenceCategory + private lateinit var status: Preference + private lateinit var androidId: Preference + private val handler = Handler() + private val updateRunnable = Runnable { updateStatus() } + private lateinit var profileFileImport: ActivityResultLauncher + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + profileFileImport = registerForActivityResult(ActivityResultContracts.GetContent(), this::onFileSelected) + } + + private fun onFileSelected(uri: Uri?) { + if (uri == null) return + try { + val context = requireContext() + val file = File.createTempFile("profile_", ".xml", context.cacheDir) + context.contentResolver.openInputStream(uri)?.use { inputStream -> + FileOutputStream(file).use { inputStream.copyTo(it) } + } + val success = ProfileManager.importUserProfile(context, file) + file.delete() + if (success && ProfileManager.isAutoProfile(context, PROFILE_USER)) { + ProfileManager.setProfile(context, PROFILE_USER) + } + updateStatus() + } catch (e: Exception) { + Log.w(TAG, e) + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_device_registration) + } + + @SuppressLint("RestrictedApi") + override fun onBindPreferences() { + deviceProfile = preferenceScreen.findPreference("pref_device_profile") ?: deviceProfile + importProfile = preferenceScreen.findPreference("pref_device_profile_import") ?: importProfile + serial = preferenceScreen.findPreference("pref_device_serial") ?: serial + statusCategory = preferenceScreen.findPreference("prefcat_device_registration_status") ?: statusCategory + status = preferenceScreen.findPreference("pref_device_registration_status") ?: status + androidId = preferenceScreen.findPreference("pref_device_registration_android_id") ?: androidId + + deviceProfile.setOnPreferenceChangeListener { _, newValue -> + ProfileManager.setProfile(requireContext(), newValue as String? ?: PROFILE_AUTO) + updateStatus() + true + } + importProfile.setOnPreferenceClickListener { + profileFileImport.launch("text/xml") + true + } + } + + private fun configureProfilePreference() { + val context = requireContext() + val configuredProfile = ProfileManager.getConfiguredProfile(context) + val autoProfileName = when (val autoProfile = ProfileManager.getAutoProfile(context)) { + PROFILE_NATIVE -> getString(R.string.profile_name_native) + PROFILE_REAL -> getString(R.string.profile_name_real) + else -> ProfileManager.getProfileName(context, autoProfile) + } + val profiles = + mutableListOf(PROFILE_AUTO, PROFILE_NATIVE, PROFILE_REAL) + val profileNames = mutableListOf(getString(R.string.profile_name_auto, autoProfileName), getString(R.string.profile_name_native), getString(R.string.profile_name_real)) + if (ProfileManager.hasProfile(context, PROFILE_SYSTEM)) { + profiles.add(PROFILE_SYSTEM) + profileNames.add(getString(R.string.profile_name_system, ProfileManager.getProfileName(context, PROFILE_SYSTEM))) + } + if (ProfileManager.hasProfile(context, PROFILE_USER)) { + profiles.add(PROFILE_USER) + profileNames.add(getString(R.string.profile_name_user, ProfileManager.getProfileName(context, PROFILE_USER))) + } + for (profile in R.xml::class.java.declaredFields.map { it.name } + .filter { it.startsWith("profile_") } + .map { it.substring(8) } + .sorted()) { + val profileName = ProfileManager.getProfileName(context, profile) + if (profileName != null) { + profiles.add(profile) + profileNames.add(profileName) + } + } + deviceProfile.entryValues = profiles.toTypedArray() + deviceProfile.entries = profileNames.toTypedArray() + deviceProfile.value = configuredProfile + deviceProfile.summary = + profiles.indexOf(configuredProfile).takeIf { it >= 0 }?.let { profileNames[it] } ?: "Unknown" + } + + override fun onResume() { + super.onResume() + updateStatus() + } + + override fun onPause() { + super.onPause() + handler.removeCallbacks(updateRunnable) + } + + private fun updateStatus() { + handler.removeCallbacks(updateRunnable) + handler.postDelayed(updateRunnable, UPDATE_INTERVAL) + val appContext = requireContext().applicationContext + lifecycleScope.launchWhenResumed { + configureProfilePreference() + serial.summary = ProfileManager.getSerial(appContext) + val serviceInfo = getCheckinServiceInfo(appContext) + statusCategory.isVisible = serviceInfo.configuration.enabled + if (serviceInfo.lastCheckin > 0) { + status.summary = getString( + R.string.checkin_last_registration, + DateUtils.getRelativeTimeSpanString(serviceInfo.lastCheckin, System.currentTimeMillis(), 0) + ) + androidId.isVisible = true + androidId.summary = serviceInfo.androidId.toString(16) + } else { + status.summary = getString(R.string.checkin_not_registered) + androidId.isVisible = false + } + } + } + + companion object { + private const val UPDATE_INTERVAL = 1000L + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBarCallback.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBarCallback.kt new file mode 100755 index 00000000..b66f1119 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBarCallback.kt @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +interface PreferenceSwitchBarCallback { + fun onChecked(newStatus: Boolean) +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAdvancedFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAdvancedFragment.kt index 55b730f6..d3cef96f 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAdvancedFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAdvancedFragment.kt @@ -14,7 +14,7 @@ import com.mgoogle.android.gms.R import org.microg.gms.gcm.GcmPrefs import org.microg.gms.gcm.getGcmServiceInfo import org.microg.gms.gcm.setGcmServiceConfiguration -import org.microg.gms.settings.SettingsProvider +import org.microg.mgms.settings.SettingsProvider class PushNotificationAdvancedFragment : PreferenceFragmentCompat() { private lateinit var networkMobile: ListPreference @@ -37,7 +37,7 @@ class PushNotificationAdvancedFragment : PreferenceFragmentCompat() { val appContext = requireContext().applicationContext lifecycleScope.launchWhenResumed { (newValue as? String)?.toIntOrNull()?.let { - setGcmServiceConfiguration(appContext, getGcmServiceInfo(appContext).configuration.copy(mobile = it)) + setGcmServiceConfiguration(requireContext(), getGcmServiceInfo(appContext).configuration.copy(mobile = it)) } updateContent() } @@ -47,7 +47,7 @@ class PushNotificationAdvancedFragment : PreferenceFragmentCompat() { val appContext = requireContext().applicationContext lifecycleScope.launchWhenResumed { (newValue as? String)?.toIntOrNull()?.let { - setGcmServiceConfiguration(appContext, getGcmServiceInfo(appContext).configuration.copy(wifi = it)) + setGcmServiceConfiguration(appContext, getGcmServiceInfo(requireContext()).configuration.copy(wifi = it)) } updateContent() } @@ -57,7 +57,7 @@ class PushNotificationAdvancedFragment : PreferenceFragmentCompat() { val appContext = requireContext().applicationContext lifecycleScope.launchWhenResumed { (newValue as? String)?.toIntOrNull()?.let { - setGcmServiceConfiguration(appContext, getGcmServiceInfo(appContext).configuration.copy(roaming = it)) + setGcmServiceConfiguration(appContext, getGcmServiceInfo(requireContext()).configuration.copy(roaming = it)) } updateContent() } @@ -67,7 +67,7 @@ class PushNotificationAdvancedFragment : PreferenceFragmentCompat() { val appContext = requireContext().applicationContext lifecycleScope.launchWhenResumed { (newValue as? String)?.toIntOrNull()?.let { - setGcmServiceConfiguration(appContext, getGcmServiceInfo(appContext).configuration.copy(other = it)) + setGcmServiceConfiguration(appContext, getGcmServiceInfo(requireContext()).configuration.copy(other = it)) } updateContent() } @@ -98,13 +98,13 @@ class PushNotificationAdvancedFragment : PreferenceFragmentCompat() { private fun getSummaryString(value: Int, learnt: Int): String = when (value) { -1 -> getString(R.string.service_status_disabled_short) 0 -> getString(R.string.service_status_enabled_short) + " / " + getString(R.string.gcm_status_pref_default) + ": " + getHeartbeatString(learnt) - else -> getString(R.string.service_status_enabled_short) + " / " + getString(R.string.gcm_status_pref_manual) + ": " + getHeartbeatString(value * 60000) + else -> getString(R.string.service_status_enabled_short) + " / " + getString(R.string.gcm_status_pref_manual) + ": " + getHeartbeatString(value * SettingsProvider.INTERVAL) } private fun getHeartbeatString(heartbeatMs: Int): String { return if (heartbeatMs < 120000) { (heartbeatMs / 1000).toString() + " " + getString(R.string.gcm_status_pref_sec) - } else (heartbeatMs / 60000).toString() + " " + getString(R.string.gcm_status_pref_min) + } else (heartbeatMs / SettingsProvider.INTERVAL).toString() + " " + getString(R.string.gcm_status_pref_min) } companion object { diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt index 392e14d6..da3210e4 100755 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt @@ -56,12 +56,16 @@ class PushNotificationAllAppsFragment : PreferenceFragmentCompat() { lifecycleScope.launchWhenResumed { val apps = withContext(Dispatchers.IO) { val res = database.appList.map { app -> + app to context.packageManager.getApplicationInfoIfExists(app.packageName) + }.map { (app, applicationInfo) -> val pref = AppIconPreference(context) - pref.packageName = app.packageName + pref.title = applicationInfo?.loadLabel(context.packageManager) ?: app.packageName pref.summary = when { app.lastMessageTimestamp > 0 -> getString(R.string.gcm_last_message_at, DateUtils.getRelativeTimeSpanString(app.lastMessageTimestamp)) else -> null } + pref.icon = applicationInfo?.loadIcon(context.packageManager) + ?: AppCompatResources.getDrawable(context, android.R.mipmap.sym_def_app_icon) pref.onPreferenceClickListener = Preference.OnPreferenceClickListener { findNavController().navigate(requireContext(), R.id.openGcmAppDetailsFromAll, bundleOf( "package" to app.packageName diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt index 780e85e1..f83a5e5d 100755 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt @@ -5,135 +5,58 @@ package org.microg.gms.ui -import android.annotation.SuppressLint +import android.content.Intent +import android.net.Uri import android.os.Bundle -import android.text.format.DateUtils -import androidx.appcompat.app.AlertDialog +import android.provider.Settings +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.content.res.AppCompatResources +import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope -import androidx.preference.Preference -import androidx.preference.PreferenceCategory -import androidx.preference.PreferenceFragmentCompat -import androidx.preference.TwoStatePreference import com.mgoogle.android.gms.R -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.microg.gms.gcm.GcmDatabase -import org.microg.gms.gcm.PushRegisterManager +import com.mgoogle.android.gms.databinding.PushNotificationAppFragmentBinding -class PushNotificationAppFragment : PreferenceFragmentCompat() { - private lateinit var appHeadingPreference: AppHeadingPreference - private lateinit var wakeForDelivery: TwoStatePreference - private lateinit var allowRegister: TwoStatePreference - private lateinit var status: Preference - private lateinit var unregister: Preference - private lateinit var unregisterCat: PreferenceCategory - private lateinit var database: GcmDatabase - private val packageName: String? +class PushNotificationAppFragment : Fragment(R.layout.push_notification_fragment) { + lateinit var binding: PushNotificationAppFragmentBinding + val packageName: String? get() = arguments?.getString("package") - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - addPreferencesFromResource(R.xml.preferences_push_notifications_app) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - database = GcmDatabase(context) - } - - @SuppressLint("RestrictedApi") - override fun onBindPreferences() { - appHeadingPreference = preferenceScreen.findPreference("pref_push_app_heading") ?: appHeadingPreference - wakeForDelivery = preferenceScreen.findPreference("pref_push_app_wake_for_delivery") ?: wakeForDelivery - allowRegister = preferenceScreen.findPreference("pref_push_app_allow_register") ?: allowRegister - unregister = preferenceScreen.findPreference("pref_push_app_unregister") ?: unregister - unregisterCat = preferenceScreen.findPreference("prefcat_push_app_unregister") ?: unregisterCat - status = preferenceScreen.findPreference("pref_push_app_status") ?: status - wakeForDelivery.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> - database.setAppWakeForDelivery(packageName, newValue as Boolean) - database.close() - true - } - allowRegister.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> - val enabled = newValue as? Boolean ?: return@OnPreferenceChangeListener false - if (!enabled) { - val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList() - if (registrations.isNotEmpty()) { - showUnregisterConfirm(R.string.gcm_unregister_after_deny_message) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = PushNotificationAppFragmentBinding.inflate(inflater, container, false) + binding.callbacks = object : PushNotificationAppFragmentCallbacks { + override fun onAppClicked() { + val intent = Intent() + intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS + val uri: Uri = Uri.fromParts("package", packageName, null) + intent.data = uri + try { + context!!.startActivity(intent) + } catch (e: Exception) { + Log.w(TAG, "Failed to launch app", e) } } - database.setAppAllowRegister(packageName, enabled) - database.close() - true - } - unregister.onPreferenceClickListener = Preference.OnPreferenceClickListener { - showUnregisterConfirm(R.string.gcm_unregister_confirm_message) - true - } - } - - - private fun showUnregisterConfirm(unregisterConfirmDesc: Int) { - val pm = requireContext().packageManager - val applicationInfo = pm.getApplicationInfoIfExists(packageName) - AlertDialog.Builder(requireContext()) - .setTitle(getString(R.string.gcm_unregister_confirm_title, applicationInfo?.loadLabel(pm) - ?: packageName)) - .setMessage(unregisterConfirmDesc) - .setPositiveButton(android.R.string.yes) { _, _ -> unregister() } - .setNegativeButton(android.R.string.no) { _, _ -> }.show() - } - - private fun unregister() { - lifecycleScope.launchWhenResumed { - withContext(Dispatchers.IO) { - for (registration in database.getRegistrationsByApp(packageName)) { - PushRegisterManager.unregister(context, registration.packageName, registration.signature, null, null) - } - } - updateDetails() } + childFragmentManager.findFragmentById(R.id.sub_preferences)?.arguments = arguments + return binding.root } override fun onResume() { super.onResume() - updateDetails() - } - - private fun updateDetails() { + val context = requireContext() lifecycleScope.launchWhenResumed { - appHeadingPreference.packageName = packageName - val app = packageName?.let { database.getApp(it) } - wakeForDelivery.isChecked = app?.wakeForDelivery ?: true - allowRegister.isChecked = app?.allowRegister ?: true - val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList() - unregisterCat.isVisible = registrations.isNotEmpty() - - val sb = StringBuilder() - if ((app?.totalMessageCount ?: 0L) == 0L) { - sb.append(getString(R.string.gcm_no_message_yet)) - } else { - sb.append(getString(R.string.gcm_messages_counter, app?.totalMessageCount, app?.totalMessageBytes)) - if (app?.lastMessageTimestamp != 0L) { - sb.append("\n").append(getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(context, app?.lastMessageTimestamp ?: 0L, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))) - } - } - for (registration in registrations) { - sb.append("\n") - if (registration.timestamp == 0L) { - sb.append(getString(R.string.gcm_registered)) - } else { - sb.append(getString(R.string.gcm_registered_since, DateUtils.getRelativeDateTimeString(context, registration.timestamp, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))) - } - } - status.summary = sb.toString() - - database.close() + val pm = context.packageManager + val applicationInfo = pm.getApplicationInfoIfExists(packageName) + binding.appName = applicationInfo?.loadLabel(pm)?.toString() ?: packageName + binding.appIcon = applicationInfo?.loadIcon(pm) + ?: AppCompatResources.getDrawable(context, android.R.mipmap.sym_def_app_icon) } } +} - override fun onPause() { - super.onPause() - database.close() - } -} \ No newline at end of file +interface PushNotificationAppFragmentCallbacks { + fun onAppClicked() +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt new file mode 100755 index 00000000..7106e506 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt @@ -0,0 +1,137 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +@file:Suppress("DEPRECATION") + +package org.microg.gms.ui + +import android.annotation.SuppressLint +import android.os.Bundle +import android.text.format.DateUtils +import androidx.appcompat.app.AlertDialog +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.TwoStatePreference +import com.mgoogle.android.gms.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.microg.gms.gcm.GcmDatabase +import org.microg.gms.gcm.PushRegisterManager + +class PushNotificationAppPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var wakeForDelivery: TwoStatePreference + private lateinit var allowRegister: TwoStatePreference + private lateinit var status: Preference + private lateinit var unregister: Preference + private lateinit var unregisterCat: PreferenceCategory + + private lateinit var database: GcmDatabase + private val packageName: String? + get() = arguments?.getString("package") + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_push_notifications_app) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + database = GcmDatabase(context) + } + + @SuppressLint("RestrictedApi") + override fun onBindPreferences() { + wakeForDelivery = preferenceScreen.findPreference("pref_push_app_wake_for_delivery") ?: wakeForDelivery + allowRegister = preferenceScreen.findPreference("pref_push_app_allow_register") ?: allowRegister + unregister = preferenceScreen.findPreference("pref_push_app_unregister") ?: unregister + unregisterCat = preferenceScreen.findPreference("prefcat_push_app_unregister") ?: unregisterCat + status = preferenceScreen.findPreference("pref_push_app_status") ?: status + wakeForDelivery.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + database.setAppWakeForDelivery(packageName, newValue as Boolean) + database.close() + true + } + allowRegister.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + val enabled = newValue as? Boolean ?: return@OnPreferenceChangeListener false + if (!enabled) { + val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList() + if (registrations.isNotEmpty()) { + showUnregisterConfirm(R.string.gcm_unregister_after_deny_message) + } + } + database.setAppAllowRegister(packageName, enabled) + database.close() + true + } + unregister.onPreferenceClickListener = Preference.OnPreferenceClickListener { + showUnregisterConfirm(R.string.gcm_unregister_confirm_message) + true + } + } + + + private fun showUnregisterConfirm(unregisterConfirmDesc: Int) { + val pm = requireContext().packageManager + val applicationInfo = pm.getApplicationInfoIfExists(packageName) + AlertDialog.Builder(requireContext()) + .setTitle(getString(R.string.gcm_unregister_confirm_title, applicationInfo?.loadLabel(pm) + ?: packageName)) + .setMessage(unregisterConfirmDesc) + .setPositiveButton(android.R.string.yes) { _, _ -> unregister() } + .setNegativeButton(android.R.string.no) { _, _ -> }.show() + } + + private fun unregister() { + lifecycleScope.launchWhenResumed { + withContext(Dispatchers.IO) { + for (registration in database.getRegistrationsByApp(packageName)) { + PushRegisterManager.unregister(context, registration.packageName, registration.signature, null, null) + } + } + updateDetails() + } + } + + override fun onResume() { + super.onResume() + updateDetails() + } + + private fun updateDetails() { + lifecycleScope.launchWhenResumed { + val app = packageName?.let { database.getApp(it) } + wakeForDelivery.isChecked = app?.wakeForDelivery ?: true + allowRegister.isChecked = app?.allowRegister ?: true + val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList() + unregisterCat.isVisible = registrations.isNotEmpty() + + val sb = StringBuilder() + if ((app?.totalMessageCount ?: 0L) == 0L) { + sb.append(getString(R.string.gcm_no_message_yet)) + } else { + sb.append(getString(R.string.gcm_messages_counter, app?.totalMessageCount, app?.totalMessageBytes)) + if (app?.lastMessageTimestamp != 0L) { + sb.append("\n").append(getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(context, app?.lastMessageTimestamp ?: 0L, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))) + } + } + for (registration in registrations) { + sb.append("\n") + if (registration.timestamp == 0L) { + sb.append(getString(R.string.gcm_registered)) + } else { + sb.append(getString(R.string.gcm_registered_since, DateUtils.getRelativeDateTimeString(context, registration.timestamp, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))) + } + } + status.summary = sb.toString() + + database.close() + } + } + + override fun onPause() { + super.onPause() + database.close() + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt index d05afb3d..cb5aaa18 100755 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt @@ -2,142 +2,61 @@ * SPDX-FileCopyrightText: 2020, microG Project Team * SPDX-License-Identifier: Apache-2.0 */ - package org.microg.gms.ui -import android.annotation.SuppressLint import android.os.Bundle -import android.os.Handler -import android.text.format.DateUtils -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import androidx.core.os.bundleOf +import android.view.* +import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController -import androidx.preference.Preference -import androidx.preference.PreferenceCategory -import androidx.preference.PreferenceFragmentCompat import com.mgoogle.android.gms.R -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.microg.gms.checkin.CheckinPreferences -import org.microg.gms.gcm.GcmDatabase -import org.microg.gms.gcm.GcmPrefs +import com.mgoogle.android.gms.databinding.PushNotificationFragmentBinding +import org.microg.gms.checkin.getCheckinServiceInfo +import org.microg.gms.gcm.ServiceInfo import org.microg.gms.gcm.getGcmServiceInfo +import org.microg.gms.gcm.setGcmServiceConfiguration -class PushNotificationFragment : PreferenceFragmentCompat() { - private lateinit var switchBarPreference: SwitchBarPreference - private lateinit var pushStatusCategory: PreferenceCategory - private lateinit var pushStatus: Preference - private lateinit var pushApps: PreferenceCategory - private lateinit var pushAppsAll: Preference - private lateinit var pushAppsNone: Preference - private lateinit var database: GcmDatabase - private val handler = Handler() - private val updateRunnable = Runnable { updateStatus() } +@Suppress("Warnings") +class PushNotificationFragment : Fragment(R.layout.push_notification_fragment) { + lateinit var binding: PushNotificationFragmentBinding - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - database = GcmDatabase(context) + init { + setHasOptionsMenu(true) } - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - addPreferencesFromResource(R.xml.preferences_push_notifications) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = PushNotificationFragmentBinding.inflate(inflater, container, false) + binding.switchBarCallback = object : PreferenceSwitchBarCallback { + override fun onChecked(newStatus: Boolean) { + setEnabled(newStatus) + } + } + return binding.root } - @SuppressLint("RestrictedApi") - override fun onBindPreferences() { - switchBarPreference = preferenceScreen.findPreference("pref_push_enabled") ?: switchBarPreference - pushStatusCategory = preferenceScreen.findPreference("prefcat_push_status") ?: pushStatusCategory - pushStatus = preferenceScreen.findPreference("pref_push_status") ?: pushStatus - pushApps = preferenceScreen.findPreference("prefcat_push_apps") ?: pushApps - pushAppsAll = preferenceScreen.findPreference("pref_push_apps_all") ?: pushAppsAll - pushAppsNone = preferenceScreen.findPreference("pref_push_apps_none") ?: pushAppsNone - pushAppsAll.setOnPreferenceClickListener { - findNavController().navigate(requireContext(), R.id.openAllGcmApps) - true - } - switchBarPreference.setOnPreferenceChangeListener { _, newValue -> - val newStatus = newValue as Boolean - GcmPrefs.setEnabled(requireContext(), newStatus) - true + fun setEnabled(newStatus: Boolean) { + val appContext = requireContext().applicationContext + lifecycleScope.launchWhenResumed { + val info = getGcmServiceInfo(appContext) + val newConfiguration = info.configuration.copy(enabled = newStatus) + setGcmServiceConfiguration(appContext, newConfiguration) + displayServiceInfo(info.copy(configuration = newConfiguration)) } } + private fun displayServiceInfo(serviceInfo: ServiceInfo) { + binding.gcmEnabled = serviceInfo.configuration.enabled + } + override fun onResume() { super.onResume() - - switchBarPreference.isEnabled = CheckinPreferences.isEnabled(requireContext()) - switchBarPreference.isChecked = GcmPrefs.get(requireContext()).isEnabled - - updateStatus() - updateContent() - } - - override fun onPause() { - super.onPause() - database.close() - handler.removeCallbacks(updateRunnable) - } - - private fun updateStatus() { - handler.postDelayed(updateRunnable, UPDATE_INTERVAL) val appContext = requireContext().applicationContext - lifecycleScope.launchWhenStarted { - val statusInfo = getGcmServiceInfo(appContext) - switchBarPreference.isChecked = statusInfo.configuration.enabled - pushStatusCategory.isVisible = statusInfo != null && statusInfo.configuration.enabled - pushStatus.summary = if (statusInfo != null && statusInfo.connected) { - appContext.getString(R.string.gcm_network_state_connected, DateUtils.getRelativeTimeSpanString(statusInfo.startTimestamp, System.currentTimeMillis(), 0)) - } else { - appContext.getString(R.string.gcm_network_state_disconnected) - } - } - } - - private fun updateContent() { lifecycleScope.launchWhenResumed { - val context = requireContext() - val (apps, showAll) = withContext(Dispatchers.IO) { - val apps = database.appList.sortedByDescending { it.lastMessageTimestamp } - val res = apps.map { app -> - app to context.packageManager.getApplicationInfoIfExists(app.packageName) - }.mapNotNull { (app, info) -> - if (info == null) null else app to info - }.take(3).mapIndexed { idx, (app, applicationInfo) -> - val pref = AppIconPreference(context) - pref.order = idx - pref.applicationInfo = applicationInfo - pref.onPreferenceClickListener = Preference.OnPreferenceClickListener { - findNavController().navigate(requireContext(), R.id.openGcmAppDetails, bundleOf( - "package" to app.packageName - )) - true - } - pref.key = "pref_push_app_" + app.packageName - pref - }.let { it to (it.size < apps.size) } - database.close() - res - } - pushAppsAll.isVisible = showAll - pushApps.removeAll() - for (app in apps) { - pushApps.addPreference(app) - } - if (showAll) { - pushApps.addPreference(pushAppsAll) - } else if (apps.isEmpty()) { - pushApps.addPreference(pushAppsNone) - } + displayServiceInfo(getGcmServiceInfo(appContext)) + binding.checkinEnabled = getCheckinServiceInfo(appContext).configuration.enabled } } - init { - setHasOptionsMenu(true) - } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced) super.onCreateOptionsMenu(menu, inflater) @@ -154,7 +73,7 @@ class PushNotificationFragment : PreferenceFragmentCompat() { } companion object { - private const val UPDATE_INTERVAL = 1000L private const val MENU_ADVANCED = Menu.FIRST } -} \ No newline at end of file +} + diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt new file mode 100755 index 00000000..ef027a84 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +@file:Suppress("DEPRECATION") + +package org.microg.gms.ui + +import android.annotation.SuppressLint +import android.os.Bundle +import android.os.Handler +import android.text.format.DateUtils +import androidx.core.os.bundleOf +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import com.mgoogle.android.gms.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.microg.gms.gcm.GcmDatabase +import org.microg.gms.gcm.getGcmServiceInfo + +class PushNotificationPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var pushStatusCategory: PreferenceCategory + private lateinit var pushStatus: Preference + private lateinit var pushApps: PreferenceCategory + private lateinit var pushAppsAll: Preference + private lateinit var pushAppsNone: Preference + private lateinit var database: GcmDatabase + private val handler = Handler() + private val updateRunnable = Runnable { updateStatus() } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + database = GcmDatabase(context) + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_push_notifications) + } + + @SuppressLint("RestrictedApi") + override fun onBindPreferences() { + pushStatusCategory = preferenceScreen.findPreference("prefcat_push_status") ?: pushStatusCategory + pushStatus = preferenceScreen.findPreference("pref_push_status") ?: pushStatus + pushApps = preferenceScreen.findPreference("prefcat_push_apps") ?: pushApps + pushAppsAll = preferenceScreen.findPreference("pref_push_apps_all") ?: pushAppsAll + pushAppsNone = preferenceScreen.findPreference("pref_push_apps_none") ?: pushAppsNone + pushAppsAll.onPreferenceClickListener = Preference.OnPreferenceClickListener { + findNavController().navigate(requireContext(), R.id.openAllGcmApps) + true + } + } + + override fun onResume() { + super.onResume() + updateStatus() + updateContent() + } + + override fun onPause() { + super.onPause() + database.close() + handler.removeCallbacks(updateRunnable) + } + + private fun updateStatus() { + try { + handler.postDelayed(updateRunnable, UPDATE_INTERVAL) + val appContext = requireContext().applicationContext + lifecycleScope.launchWhenStarted { + val statusInfo = getGcmServiceInfo(appContext) + pushStatusCategory.isVisible = statusInfo.configuration.enabled + pushStatus.summary = if (statusInfo.connected) { + appContext.getString(R.string.gcm_network_state_connected, DateUtils.getRelativeTimeSpanString(statusInfo.startTimestamp, System.currentTimeMillis(), 0)) + } else { + appContext.getString(R.string.gcm_network_state_disconnected) + } + } + } catch (_: Exception) {} + } + + private fun updateContent() { + val appContext = requireContext().applicationContext + val context = requireContext() + lifecycleScope.launchWhenResumed { + val (apps, showAll) = withContext(Dispatchers.IO) { + val apps = database.appList.sortedByDescending { it.lastMessageTimestamp } + val res = apps.map { app -> + app to appContext.packageManager.getApplicationInfoIfExists(app.packageName) + }.mapNotNull { (app, info) -> + if (info == null) null else app to info + }.take(3).mapIndexed { idx, (app, applicationInfo) -> + val pref = AppIconPreference(appContext) + pref.order = idx + pref.title = applicationInfo.loadLabel(appContext.packageManager) + pref.icon = applicationInfo.loadIcon(appContext.packageManager) + pref.onPreferenceClickListener = Preference.OnPreferenceClickListener { + findNavController().navigate(context, R.id.openGcmAppDetails, bundleOf( + "package" to app.packageName + )) + true + } + pref.key = "pref_push_app_" + app.packageName + pref + }.let { it to (it.size < apps.size) } + database.close() + res + } + pushAppsAll.isVisible = showAll + pushApps.removeAll() + for (app in apps) { + pushApps.addPreference(app) + } + if (showAll) { + pushApps.addPreference(pushAppsAll) + } else if (apps.isEmpty()) { + pushApps.addPreference(pushAppsNone) + } + } + } + + companion object { + private const val UPDATE_INTERVAL = 1000L + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/SettingsFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/SettingsFragment.kt index e7f83c28..8d503a68 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/SettingsFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/SettingsFragment.kt @@ -8,25 +8,21 @@ package org.microg.gms.ui import android.content.ComponentName +import android.content.Context import android.content.pm.PackageManager import android.os.Bundle -import android.util.Log import androidx.preference.Preference -import androidx.preference.PreferenceCategory import androidx.preference.SwitchPreferenceCompat import com.mgoogle.android.gms.R -import org.microg.gms.checkin.CheckinPreferences +import org.microg.gms.checkin.CheckinPrefs import org.microg.gms.gcm.GcmDatabase -import org.microg.gms.gcm.GcmPrefs -import org.microg.gms.settings.SettingsContract -import org.microg.gms.ui.settings.SettingsProvider -import org.microg.gms.ui.settings.getAllSettingsProviders +import org.microg.gms.gcm.getGcmServiceInfo +import org.microg.mgms.settings.SettingsContract import org.microg.tools.ui.ResourceSettingsFragment import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController class SettingsFragment : ResourceSettingsFragment() { - private val createdPreferences = mutableListOf() override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { super.onCreatePreferences(savedInstanceState, rootKey) @@ -39,13 +35,11 @@ class SettingsFragment : ResourceSettingsFragment() { findNavController().navigate(requireContext(), R.id.openGcmSettings) true } - findPreference(PREF_ABOUT)!!.apply { - onPreferenceClickListener = Preference.OnPreferenceClickListener { - findNavController().navigate(requireContext(), R.id.openAbout) - true - } - summary = getString(org.microg.tools.ui.R.string.about_version_str, AboutFragment.getSelfVersion(context)) + findPreference(PREF_ABOUT)?.setOnPreferenceClickListener { + findNavController().navigate(requireContext(), R.id.openAbout) + true } + findPreference(PREF_ABOUT)?.summary = getString(R.string.about_version_str, AboutFragment.getSelfVersion(context)) findPreference(SettingsContract.CheckIn.HIDE_LAUNCHER_ICON)?.apply { setOnPreferenceChangeListener { _, newValue -> @@ -54,51 +48,19 @@ class SettingsFragment : ResourceSettingsFragment() { } } - - for (entry in getAllSettingsProviders(requireContext()).flatMap { it.getEntriesStatic(requireContext()) }) { - entry.createPreference() - } - } - - private fun SettingsProvider.Companion.Entry.createPreference(): Preference? { - val preference = Preference(requireContext()).fillFromEntry(this) - try { - if (findPreference(when (group) { - SettingsProvider.Companion.Group.HEADER -> "prefcat_header" - SettingsProvider.Companion.Group.GOOGLE -> "prefcat_google_services" - SettingsProvider.Companion.Group.OTHER -> "prefcat_other_services" - SettingsProvider.Companion.Group.FOOTER -> "prefcat_footer" - })?.addPreference(preference) == true) { - createdPreferences.add(preference) - return preference - } else { - Log.w(TAG, "Preference not added $key") - } - } catch (e: Exception) { - Log.w(TAG, "Failed adding preference $key", e) - } - return null - } - - private fun Preference.fillFromEntry(entry: SettingsProvider.Companion.Entry): Preference { - key = entry.key - title = entry.title - summary = entry.summary - icon = entry.icon - isPersistent = false - isVisible = true - setOnPreferenceClickListener { - findNavController().navigate(requireContext(), entry.navigationId) - true - } - return this } override fun onResume() { super.onResume() val context = requireContext() + lifecycleScope.launchWhenResumed { + updateDetails(context) + } + } - if (GcmPrefs.get(requireContext()).isEnabled) { + private suspend fun updateDetails(context: Context) { + val gcmServiceInfo = getGcmServiceInfo(context) + if (gcmServiceInfo.configuration.enabled) { val database = GcmDatabase(context) val regCount = database.registrationList.size database.close() @@ -107,26 +69,13 @@ class SettingsFragment : ResourceSettingsFragment() { findPreference(PREF_GCM)?.setSummary(R.string.service_status_disabled_short) } - findPreference(PREF_CHECKIN)?.setSummary(if (CheckinPreferences.isEnabled(context)) R.string.service_status_enabled_short else R.string.service_status_disabled_short) - - lifecycleScope.launchWhenResumed { - val entries = getAllSettingsProviders(requireContext()).flatMap { it.getEntriesDynamic(requireContext()) } - for (preference in createdPreferences) { - if (!entries.any { it.key == preference.key }) preference.isVisible = false - } - for (entry in entries) { - val preference = createdPreferences.find { it.key == entry.key } - if (preference != null) preference.fillFromEntry(entry) - else entry.createPreference() - } - } + findPreference(PREF_CHECKIN)?.setSummary(if (CheckinPrefs.isEnabled(context) == true) R.string.service_status_enabled_short else R.string.service_status_disabled_short) } companion object { const val PREF_ABOUT = "pref_about" const val PREF_GCM = "pref_gcm" const val PREF_CHECKIN = "pref_checkin" - const val PREF_PLAY = "pref_play" } init { diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/SwitchBarPreference.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/SwitchBarPreference.kt deleted file mode 100644 index 12802a1e..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/SwitchBarPreference.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.ui - -import android.content.Context -import android.util.AttributeSet -import androidx.appcompat.widget.SwitchCompat -import androidx.preference.PreferenceViewHolder -import androidx.preference.TwoStatePreference -import org.microg.gms.base.core.R - -// TODO -class SwitchBarPreference : TwoStatePreference { - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context) : super(context) - - init { - layoutResource = R.layout.preference_switch_bar - } - - override fun onBindViewHolder(holder: PreferenceViewHolder) { - super.onBindViewHolder(holder) - holder.isDividerAllowedBelow = false - holder.isDividerAllowedAbove = false - val switch = holder.findViewById(R.id.switch_widget) as SwitchCompat - switch.setOnCheckedChangeListener(null) - switch.isChecked = isChecked - switch.setOnCheckedChangeListener { view, isChecked -> - if (!callChangeListener(isChecked)) { - view.isChecked = !isChecked - return@setOnCheckedChangeListener - } - this.isChecked = isChecked - } - holder.itemView.setBackgroundColor(when { - isChecked -> androidx.appcompat.R.attr.colorControlActivated - isEnabled -> androidx.appcompat.R.attr.colorButtonNormal - else -> androidx.appcompat.R.attr.colorControlHighlight - }) - } -} - -@Deprecated("Get rid") -interface PreferenceSwitchBarCallback { - fun onChecked(newStatus: Boolean) -} \ No newline at end of file diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/TextPreference.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/TextPreference.kt index a718b876..956386a0 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/TextPreference.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/TextPreference.kt @@ -7,7 +7,6 @@ package org.microg.gms.ui import android.content.Context import android.util.AttributeSet -import android.util.TypedValue import android.view.Gravity import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.widget.LinearLayout @@ -16,7 +15,8 @@ import androidx.preference.Preference import androidx.preference.PreferenceViewHolder class TextPreference : Preference { - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super( + context, attrs, defStyleAttr, defStyleRes) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context) : super(context) diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/Utils.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/Utils.kt index b59142d3..998770e3 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/Utils.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/Utils.kt @@ -15,7 +15,6 @@ import android.os.Bundle import android.provider.Settings import android.util.Log import androidx.annotation.IdRes -import androidx.annotation.RequiresApi import androidx.navigation.NavController import androidx.navigation.navOptions import androidx.navigation.ui.R @@ -42,12 +41,12 @@ fun NavController.navigate(context: Context, @IdRes resId: Int, args: Bundle? = fun Context.hideIcon(hide: Boolean) { packageManager.setComponentEnabledSetting( - ComponentName.createRelative(this, "org.microg.gms.ui.SettingsActivityLauncher"), - when (hide) { - true -> PackageManager.COMPONENT_ENABLED_STATE_DISABLED - false -> PackageManager.COMPONENT_ENABLED_STATE_ENABLED - }, - PackageManager.DONT_KILL_APP + ComponentName.createRelative(this, "org.microg.gms.ui.SettingsActivityLauncher"), + when (hide) { + true -> PackageManager.COMPONENT_ENABLED_STATE_DISABLED + false -> PackageManager.COMPONENT_ENABLED_STATE_ENABLED + }, + PackageManager.DONT_KILL_APP ) } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/settings/SettingsProvider.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/settings/SettingsProvider.kt deleted file mode 100644 index ecebb042..00000000 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/settings/SettingsProvider.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 microG Project Team - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.microg.gms.ui.settings - -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.graphics.drawable.Drawable -import android.os.Bundle -import android.util.Log -import androidx.navigation.NavController - -private const val TAG = "SettingsProvider" - -interface SettingsProvider { - fun getEntriesStatic(context: Context): List - suspend fun getEntriesDynamic(context: Context): List = getEntriesStatic(context) - - fun preProcessSettingsIntent(intent: Intent) - - fun extendNavigation(navController: NavController) - - companion object { - enum class Group { - HEADER, - GOOGLE, - OTHER, - FOOTER - } - - data class Entry( - val key: String, - val group: Group, - val navigationId: Int, - val title: String, - val summary: String? = null, - val icon: Drawable? = null, - ) - } -} - -fun getAllSettingsProviders(context: Context): List { - val metaData = runCatching { context.packageManager.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA).metaData }.getOrNull() ?: Bundle.EMPTY - return metaData.keySet().asSequence().filter { - it.startsWith("org.microg.gms.ui.settings.entry:") - }.mapNotNull { - runCatching { metaData.getString(it) }.onFailure { Log.w(TAG, it) }.getOrNull() - }.mapNotNull { - runCatching { Class.forName(it) }.onFailure { Log.w(TAG, it) }.getOrNull() - }.filter { - SettingsProvider::class.java.isAssignableFrom(it) - }.mapNotNull { - runCatching { it.getDeclaredField("INSTANCE").get(null) as SettingsProvider }.onFailure { Log.w(TAG, it) }.getOrNull() - }.toList() -} \ No newline at end of file diff --git a/play-services-core/src/main/res/color/preferences_material_switch_color.xml b/play-services-core/src/main/res/color/preferences_material_switch_color.xml deleted file mode 100644 index 1a6c9037..00000000 --- a/play-services-core/src/main/res/color/preferences_material_switch_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/drawable/dots_horizontal.xml b/play-services-core/src/main/res/drawable/dots_horizontal.xml index 6278c1cd..6e0db150 100755 --- a/play-services-core/src/main/res/drawable/dots_horizontal.xml +++ b/play-services-core/src/main/res/drawable/dots_horizontal.xml @@ -1,7 +1,7 @@ - - - - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/drawable/ic_play.xml b/play-services-core/src/main/res/drawable/ic_play.xml deleted file mode 100644 index 9db10ec6..00000000 --- a/play-services-core/src/main/res/drawable/ic_play.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/layout/device_registration_fragment.xml b/play-services-core/src/main/res/layout/device_registration_fragment.xml new file mode 100755 index 00000000..fe6d1e51 --- /dev/null +++ b/play-services-core/src/main/res/layout/device_registration_fragment.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/preference_app_heading.xml b/play-services-core/src/main/res/layout/preference_app_heading.xml deleted file mode 100644 index cb7e4edf..00000000 --- a/play-services-core/src/main/res/layout/preference_app_heading.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/layout/preference_material_switch.xml b/play-services-core/src/main/res/layout/preference_material_switch.xml deleted file mode 100644 index 071caab2..00000000 --- a/play-services-core/src/main/res/layout/preference_material_switch.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/layout/preference_switch_bar.xml b/play-services-core/src/main/res/layout/preference_switch_bar.xml index 9818305b..d45909cd 100755 --- a/play-services-core/src/main/res/layout/preference_switch_bar.xml +++ b/play-services-core/src/main/res/layout/preference_switch_bar.xml @@ -1,42 +1,71 @@ - - + xmlns:tools="http://schemas.android.com/tools"> - + - + + + + + + + + + - \ No newline at end of file + tools:background="?attr/colorControlActivated"> + + + + + + diff --git a/play-services-core/src/main/res/layout/push_notification_app_fragment.xml b/play-services-core/src/main/res/layout/push_notification_app_fragment.xml new file mode 100755 index 00000000..dcc6e7ad --- /dev/null +++ b/play-services-core/src/main/res/layout/push_notification_app_fragment.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/push_notification_fragment.xml b/play-services-core/src/main/res/layout/push_notification_fragment.xml new file mode 100755 index 00000000..fdd799bd --- /dev/null +++ b/play-services-core/src/main/res/layout/push_notification_fragment.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/settings_root_activity.xml b/play-services-core/src/main/res/layout/settings_root_activity.xml index 18ea2241..d854b3a3 100755 --- a/play-services-core/src/main/res/layout/settings_root_activity.xml +++ b/play-services-core/src/main/res/layout/settings_root_activity.xml @@ -9,13 +9,6 @@ android:layout_height="match_parent" android:orientation="vertical"> - - إضافة حساب Google تلقي الإشعارات المراسلة السحابية هي موفر الإشعارات المستخدم من قبل العديد من تطبيقات الطرف الثالث. لاستخدامها يجب عليك تمكين تسجيل الجهاز. - حول Vanced+ microG + حول +Vanced microG إخفاء أيقونة التطبيق من درج التطبيقات Huawei تسجيل الجهاز - يسجل جهازك في خِدْمَات Google وينشئ معرفًا فريدًا للجهاز. Vanced+ microG يحدد أجزاء أخرى غير اسم حسابك في Google من بيانات التسجيل. + يسجل جهازك في خِدْمَات Google وينشئ معرفًا فريدًا للجهاز. +Vanced microG يحدد أجزاء أخرى غير اسم حسابك في Google من بيانات التسجيل. Android ID الحالة الافتراضي @@ -116,26 +116,4 @@ الرقم التسلسلي View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-az/strings.xml b/play-services-core/src/main/res/values-az/strings.xml index 740a9b11..21ead47d 100644 --- a/play-services-core/src/main/res/values-az/strings.xml +++ b/play-services-core/src/main/res/values-az/strings.xml @@ -73,11 +73,11 @@ Bu bir neçə dəqiqə çəkə bilər." Google hesabı əlavə et Push bildirişlərini alın Cloud Messaging bir çox üçüncü tərəf proqramları tərəfindən istifadə edilən təkan bildiriş təminatçısıdır. Onu istifadə etmək üçün cihazın qeydiyyatını aktiv etməlisiniz. - Vanced+ MicroG haqqında + MicroG haqqında Proqramın ikonunu başladıcıdan gizlət Huawei Cihaz qeydiyyat et - Cihazınızı Google xidmətlərində qeydiyyatdan keçirir və unikal cihaz identifikatoru yaradır. Vanced+ microG qeydiyyat məlumatlarından Google hesabınızın adından başqa müəyyən bitləri ayırır. + Cihazınızı Google xidmətlərində qeydiyyatdan keçirir və unikal cihaz identifikatoru yaradır. microG qeydiyyat məlumatlarından Google hesabınızın adından başqa müəyyən bitləri ayırır. Android ID Status Defolt @@ -116,26 +116,4 @@ Bu bir neçə dəqiqə çəkə bilər." Serial View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-be/strings.xml b/play-services-core/src/main/res/values-be/strings.xml index 1152301e..dbcf40ed 100644 --- a/play-services-core/src/main/res/values-be/strings.xml +++ b/play-services-core/src/main/res/values-be/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Наладзіць Vanced+ microG. + Наладзіць Vanced microG. Секунду… Кіраванне уліковымі запісамі Google Прабачце… @@ -73,11 +73,11 @@ Дадаць уліковы запіс Google Атрымліваць push-апавяшчэнні Cloud Messaging дазваляе атрымліваць апавяшчэнні ад многіх праграм. Каб выкарыстоўваць GCM, уключыце рэгістрацыю прылады ў Google. - Пра Vanced+ microG + Пра Vanced microG Схаваць іконку microG з меню праграм Huawei Зарэгістраваць прыладу - Рэгіструе вашу прыладу ў сэрвісах Google і стварае ўнікальны ідэнтыфікатар прылады. Vanced+ microG выкарыстоўвае толькі імя ўліковага запісу для рэгістрацыі. + Рэгіструе вашу прыладу ў сэрвісах Google і стварае ўнікальны ідэнтыфікатар прылады. Vanced microG выкарыстоўвае толькі імя ўліковага запісу для рэгістрацыі. Android ID Стан Прадвызначана @@ -116,26 +116,4 @@ Серыйны View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-bn/strings.xml b/play-services-core/src/main/res/values-bn/strings.xml index 0156013d..dd7dd123 100644 --- a/play-services-core/src/main/res/values-bn/strings.xml +++ b/play-services-core/src/main/res/values-bn/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Vanced+ microG সেটআপ। + Vanced microG সেটআপ। একটু অপেক্ষা করুন… গুগল একাউন্ট ম্যানেজার দুঃখিত… @@ -74,11 +74,11 @@ গুগল অ্যাকাউন্ট যুক্ত করুন পুশ বিজ্ঞপ্তি পান ক্লাউড ম্যাসেজিং হল পুশ বিজ্ঞপ্তি প্রদানকারী যা অনেক তৃতীয়-পক্ষ অ্যাপ্লিকেশনে ব্যবহার করা হয়। এটি ব্যবহার করতে অবশ্যই ডিভাইস রেজিস্ট্রেশন সচল করতে হবে। - Vanced+ microG সম্পর্কে + Vanced microG সম্পর্কে লঞ্চার থেকে আইকন লুকান হুয়াওয়েই ডিভাইস নিবন্ধন করুন - আপনার ডিভাইসটি গুগল সার্ভিসে নিবন্ধন করে এবং একটি ইউনিক ডিভাইস আইডি তৈরি করে। Vanced+ microG আপনার নিবন্ধন ডেটা থেকে গুগল একাউন্টের নাম ব্যতিত আপনার সনাক্তকারী বিটকে বিচ্যুত করে। + আপনার ডিভাইসটি গুগল সার্ভিসে নিবন্ধন করে এবং একটি ইউনিক ডিভাইস আইডি তৈরি করে। Vanced microG আপনার নিবন্ধন ডেটা থেকে গুগল একাউন্টের নাম ব্যতিত আপনার সনাক্তকারী বিটকে বিচ্যুত করে। অ্যান্ড্রয়েড আইডি অবস্থা পূর্ব-নির্ধারিত @@ -117,26 +117,4 @@ ক্রমিক View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-cs/strings.xml b/play-services-core/src/main/res/values-cs/strings.xml index 7e021dd8..48e10640 100644 --- a/play-services-core/src/main/res/values-cs/strings.xml +++ b/play-services-core/src/main/res/values-cs/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Nastavení Vanced+ microG. + Nastavení Vanced microG. Počkejte chviličku… Google Account Manager Promiňte… @@ -70,11 +70,11 @@ Tato akce může trvat několik minut." Přidat účet Google Přijímat push oznámení Cloud Messaging je poskytovatel push oznámení využívaný mnoha aplikacemi třetích stran. Chcete\u2011li jej použít, musíte povolit registraci zařízení. - O aplikaci Vanced+ microG + O aplikaci Vanced microG Skrýt ikonu ze spouštěče Huawei Registrovat zařízení - Zaregistruje vaše zařízení do služeb Google a vytvoří pro něj unikátní identifikátor. Vanced+ microG z dat nutných pro registraci odstraní všechny identifikační údaje kromě názvu vašeho účtu Google. + Zaregistruje vaše zařízení do služeb Google a vytvoří pro něj unikátní identifikátor. Vanced microG z dat nutných pro registraci odstraní všechny identifikační údaje kromě názvu vašeho účtu Google. Android ID Stav Výchozí @@ -113,26 +113,4 @@ Tato akce může trvat několik minut." Serial View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-es-rES/strings.xml b/play-services-core/src/main/res/values-es-rES/strings.xml index 5b090832..b493bd90 100644 --- a/play-services-core/src/main/res/values-es-rES/strings.xml +++ b/play-services-core/src/main/res/values-es-rES/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Configurar Vanced+ microG. + Configurar Vanced microG. Solo un momento… Administrador de Cuentas Google Disculpa… @@ -73,11 +73,11 @@ Esto puede tardar unos minutos." Añadir cuenta de Google Recibir notificaciones push Cloud Messaging es un proveedor de notificaciónes push usado por muchas aplicaciones de terceros. Pará usarlo tienes que activar registro de dispositivos. - Acerca de Vanced+ microG + Acerca de Vanced microG Ocultar microG del lanzador Huawei Registrar dispositivo - Registra tu dispositivo a los servicios de Google y crea un identificador de dispositivo único. Vanced+ microG remueve de los datos de registro partes de identificación a parte de él nombre de tu cuenta de Google. + Registra tu dispositivo a los servicios de Google y crea un identificador de dispositivo único. Vanced microG remueve de los datos de registro partes de identificación a parte de él nombre de tu cuenta de Google. Android ID Estado Predeterminado @@ -116,26 +116,4 @@ Esto puede tardar unos minutos." Número de serie View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-fr/strings.xml b/play-services-core/src/main/res/values-fr/strings.xml index 0fcac240..c5ee70db 100644 --- a/play-services-core/src/main/res/values-fr/strings.xml +++ b/play-services-core/src/main/res/values-fr/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Paramètres Vanced+ microG. + Paramètres Vanced microG. Juste un instant… Gestionnaire de comptes Google Désolé… @@ -73,11 +73,11 @@ Cela peut prendre quelques minutes." Ajouter un compte Google Recevoir vos notifications push Cloud Messaging est un fournisseur de notification push utilisé par de nombreuses applications tierces. Pour l\'utiliser, vous devez activer l\'enregistrement de l\'appareil. - À propos de Vanced+ microG + À propos de Vanced microG Masquer l’icône depuis le lanceur Huawei Enregistrer l\'appareil - Enregistre votre appareil aux services Google et crée un identifiant unique. Les bandes Vanced+ microG identifient les octets autres que le votre nom de compte Google depuis les données d\'enregistrement. + Enregistre votre appareil aux services Google et crée un identifiant unique. Les bandes Vanced microG identifient les octets autres que le votre nom de compte Google depuis les données d\'enregistrement. Identifiant Android Status Par défaut @@ -116,26 +116,4 @@ Cela peut prendre quelques minutes." Série View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-he/strings.xml b/play-services-core/src/main/res/values-he/strings.xml index 95511eb1..5389588b 100644 --- a/play-services-core/src/main/res/values-he/strings.xml +++ b/play-services-core/src/main/res/values-he/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - הגדרת Vanced+ microG. + הגדרת Vanced microG. רק רגע… ניהול חשבון גוגל סליחה… @@ -63,26 +63,4 @@ נתונים אישיים & פרטיות View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-hi/strings.xml b/play-services-core/src/main/res/values-hi/strings.xml index fdf8ea5a..6df8c993 100644 --- a/play-services-core/src/main/res/values-hi/strings.xml +++ b/play-services-core/src/main/res/values-hi/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - सेटअप Vanced+ microG. + सेटअप Vanced microG. सिर्फ एक सेकंड… गूगल खाता प्रबंधक माफ़ करना @@ -71,12 +71,12 @@ Google खाता जोड़ें पुश सूचनाएं प्राप्त करें क्लाउड मैसेजिंग एक पुश नोटिफिकेशन प्रदाता है जिसका उपयोग कई तृतीय-पक्ष एप्लिकेशन द्वारा किया जाता है। इसका उपयोग करने के लिए आपको डिवाइस पंजीकरण सक्षम करना होगा। - Vanced+ microG के बारे में + Vanced microG के बारे में लॉन्चर से आइकन छुपाएं Huawei रजिस्टर डिवाइस आपके उपकरण को Google सेवाओं में पंजीकृत करता है और एक अद्वितीय उपकरण पहचानकर्ता बनाता है। पंजीकरण डेटा से आपके Google खाते के नाम के अलावा अन्य बिट्स की पहचान करने वाली - Vanced+ microG स्ट्रिप्स। + Vanced microG स्ट्रिप्स। एंड्रॉयड ID स्थिति डिफॉल्ट @@ -115,26 +115,4 @@ क्रम संख्या View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-id/strings.xml b/play-services-core/src/main/res/values-id/strings.xml index ac8b9869..d20f44ed 100644 --- a/play-services-core/src/main/res/values-id/strings.xml +++ b/play-services-core/src/main/res/values-id/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Atur Vanced+ microG. + Atur Vanced microG. Tunggu sebentar… Pengelola akun Google Maaf… @@ -71,11 +71,11 @@ Ini bisa berlangsung beberapa menit." Tambahkan akun Google Terima notifikasi push Cloud Messaging adalah penyedia notifikasi push yang digunakan pada banyak aplikasi pihak ketiga. Untuk menggunakannya anda harus mengaktifkan device registration. - Tentang Vanced+ microG + Tentang Vanced microG Sembunyikan microG dari peluncur Huawei Registrasi perangkat - Registrasi perangkat anda ke layanan Google dan buat pengenal perangkat unik. Vanced+ microG strips mengenal bits selain dari akun Google anda dari data registrasi. + Registrasi perangkat anda ke layanan Google dan buat pengenal perangkat unik. Vanced microG strips mengenal bits selain dari akun Google anda dari data registrasi. Android ID Status Default @@ -114,26 +114,4 @@ Ini bisa berlangsung beberapa menit." Serial View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-it/strings.xml b/play-services-core/src/main/res/values-it/strings.xml index 07277b42..207a26b7 100755 --- a/play-services-core/src/main/res/values-it/strings.xml +++ b/play-services-core/src/main/res/values-it/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Configurazione di Vanced+ microG. + Configurazione di Vanced microG. Solo un secondo… Gestore Account Google Ci scusiamo… @@ -70,11 +70,11 @@ Questo potrà richiedere un paio di minuti" Aggiungi account Google Ricevi notifiche push Messaggistica Cloud è un fornitore di notifiche push presente in molte applicazioni di terze parti. Per utilizzarlo è necessario attivare la registrazione del dispositivo. - Informazioni su Vanced+ microG + Informazioni su Vanced microG Nascondi microG dal launcher Huawei Registra dispositivo - Registra il tuo dispositivo sui servizi Google e crea un identificatore univoco del dispositivo. Verranno rimossi dai Servizi Vanced+ microG alcuni bit utili per identificare i dati di registrazione, oltre al nome dell\'account Google. + Registra il tuo dispositivo sui servizi Google e crea un identificatore univoco del dispositivo. Verranno rimossi dai Servizi Vanced microG alcuni bit utili per identificare i dati di registrazione, oltre al nome dell\'account Google. ID Android Stato Predefinito @@ -113,26 +113,4 @@ Questo potrà richiedere un paio di minuti" Seriale View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-ja/strings.xml b/play-services-core/src/main/res/values-ja/strings.xml index 0d93256f..70a806c6 100644 --- a/play-services-core/src/main/res/values-ja/strings.xml +++ b/play-services-core/src/main/res/values-ja/strings.xml @@ -116,26 +116,4 @@ シリアル ソースコードを閲覧 GitHub でプロジェクトのソースコードを表示します - Google アカウントからログアウトしたい場合は、端末の設定 → アカウント に移動して該当するアカウントを選択し削除します - GitHub で Vanced+ microG の更新を確認する - 更新を確認 - 無効にすると、本来 Vanced+ microG によって行われる Google サーバーへのすべての接続が拒否されます。\nこれはサービス固有の設定を無視します。 - Google サーバーへの接続を許可する - Orbot がインストールされている必要があります。\nまだ実装されていません - Tor ネットワーク経由で Google に接続する - ビルド日時 - YouTube上のデータを閲覧 - YouTube のアクティビティを確認、削除できます。YouTube の利便性を向上させるために YouTube やその他の Google サービスのデータがどのように使用されているかを確認できます - Vanced+ microG で追加したGoogleアカウントはどうすれば削除できますか? - 端末の設定 → アカウント に移動して該当するアカウントを選択し削除します - GitLab で Vanced+ microG の更新を確認する - GitLab でプロジェクトのソースコードを表示します - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-ko/strings.xml b/play-services-core/src/main/res/values-ko/strings.xml index fa18f6d5..c7df827f 100644 --- a/play-services-core/src/main/res/values-ko/strings.xml +++ b/play-services-core/src/main/res/values-ko/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Vanced+ microG를 설정합니다 + Vanced microG를 설정합니다 잠시만 기다려주십시오… Google 계정 관리자 죄송합니다... @@ -73,11 +73,11 @@ Google 계정 추가 푸시 알림 수신 클라우드 메시징은 많은 타사 응용 프로그램에서 사용하는 푸시 알림 공급자입니다. 그것을 사용하려면 장치 등록을 활성화해야 합니다. - Vanced+ microG에 대하여 + Vanced microG에 대하여 런처에서 아이콘 숨기기 화웨이 장치 등록 - 기기를 Google 서비스에 등록하고 고유한 기기 식별자를 만듭니다. Vanced+ microG는 등록 데이터에서 Google 계정 이름 이외의 식별 비트를 제거합니다. + 기기를 Google 서비스에 등록하고 고유한 기기 식별자를 만듭니다. Vanced microG는 등록 데이터에서 Google 계정 이름 이외의 식별 비트를 제거합니다. 안드로이드 ID 상태 기본값 @@ -116,26 +116,4 @@ 일련번호 View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-lt/strings.xml b/play-services-core/src/main/res/values-lt/strings.xml index bdf153d4..4094cbe9 100644 --- a/play-services-core/src/main/res/values-lt/strings.xml +++ b/play-services-core/src/main/res/values-lt/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Nustatyti Vanced+ microG. + Nustatyti Vanced microG. Šiek tiek palaukite… Google paskyros valdytojas Atsiprašome… @@ -73,7 +73,7 @@ Tai gali užtrukti keletą minučių." Pridėti Google paskyrą Gauti aktyvuosius pranešimus Cloud Messaging yra tiesioginių pranešimų teikėjas, naudojamas daugelyje trečiųjų šalių programų. Norėdami jį naudoti, turite įjungti įrenginio registraciją. - Apie Vanced+ microG + Apie Vanced microG Slėpti piktogramą paleidimo priemonėje Huawei Registruoti įrenginį @@ -116,26 +116,4 @@ Tai gali užtrukti keletą minučių." Serijinis numeris View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-night-v23/themes.xml b/play-services-core/src/main/res/values-night-v23/themes.xml deleted file mode 100644 index 6ed526b7..00000000 --- a/play-services-core/src/main/res/values-night-v23/themes.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/values-night-v27/themes.xml b/play-services-core/src/main/res/values-night-v27/themes.xml deleted file mode 100644 index 0b22714a..00000000 --- a/play-services-core/src/main/res/values-night-v27/themes.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/values-night-v31/themes.xml b/play-services-core/src/main/res/values-night-v31/themes.xml index 7f89bd04..de5386e8 100644 --- a/play-services-core/src/main/res/values-night-v31/themes.xml +++ b/play-services-core/src/main/res/values-night-v31/themes.xml @@ -1,11 +1,14 @@ - - - \ No newline at end of file + diff --git a/play-services-core/src/main/res/values-pt-rBR/plurals.xml b/play-services-core/src/main/res/values-pt-rBR/plurals.xml index ab9eb731..35222efa 100644 --- a/play-services-core/src/main/res/values-pt-rBR/plurals.xml +++ b/play-services-core/src/main/res/values-pt-rBR/plurals.xml @@ -19,7 +19,7 @@ %1$d aplicativo registrado - %1$d aplicativos registrados + %1$d aplicativo registrado diff --git a/play-services-core/src/main/res/values-pt-rBR/strings.xml b/play-services-core/src/main/res/values-pt-rBR/strings.xml index 1120864e..c80ad8f9 100644 --- a/play-services-core/src/main/res/values-pt-rBR/strings.xml +++ b/play-services-core/src/main/res/values-pt-rBR/strings.xml @@ -15,16 +15,15 @@ ~ limitations under the License. --> - Vanced+ microG - Configurações do Vanced+ microG. + Configuração do Vanece microG. Um momento… Gerenciador de Contas do Google Desculpe… "Um aplicativo em seu dispositivo está tentando entrar em uma conta do Google. -Se isso foi intencional, use o botão Entrar (ou Huawei, se você tiver um dispositivo com esta marca) para se conectar à página de login do Google." - Entrar - "Estabelecendo uma conexão com os servidores do Google para entrar em sua conta. +Se isso foi intencional, use o Login (ou Huawei, se você tiver um dispositivo com esta marca) para se conectar à página de login do Google, se não, pressione Cancelar para voltar ao aplicativo que fez com que este diálogo aparecesse." + Iniciar sessão + "Estabelecendo uma conexão com os servidores do Google para fazer ‘login’. Isso pode levar alguns segundos." "Você não tem uma conexão de rede. @@ -36,66 +35,51 @@ Tente novamente mais tarde." "Seu dispositivo está entrando em contato com o Google para salvar informações em sua conta. Isso pode demorar alguns minutos." - Ouvir transmissões de estado interno Escutar mensagens C2DM Enviar mensagens C2DM para outros aplicativos Trocar mensagens e receber notificações de sincronização de servidores do Google Acesso estendido aos serviços do Google - Gerenciador de Contas do Google não foi totalmente implementado - Gerenciar sua conta do Google - Gerenciar as informações da sua conta do Google - Gerenciar atividades no YouTube - Gerenciar atividades do YouTube, como histórico de exibição ou pesquisa - + Google Account Manager not fully implemented + Manage your Google account + Manage your Google account information + Manage YouTube activities + Manage YouTube activities such as watch or search history Registro de dispositivos do Google Cloud Messaging - Ligado Desligado - Avançado Nenhum Veja tudo - Rede móvel Wi-Fi Roaming Outras redes - - Sobre Serviços do Google Mais - Não registrado Último registro: %1$s - Preferências da conta Informações pessoais & privacidade Entrar & segurança - Confiar permissões de aplicativos no Google Quando desativado, o usuário é solicitado antes que uma solicitação de autorização de aplicativos seja enviada ao Google. Alguns aplicativos não usarão a conta do Google se isso for desativado. Permitir que aplicativos encontrem contas Quando ativado, todos os aplicativos deste dispositivo poderão ver o endereço de e-mail de suas contas do Google sem autorização prévia. - Conta Adicionar conta do Google Receba notificações push Cloud Messaging é um provedor de notificação push usado por muitos aplicativos de terceiros. Para usá-lo, você deve ativar ao registro do dispositivo. - - Sobre o Vanced+ microG + Sobre o Vanced microG Ocultar ícone no menu - Huawei - Registar dispositivo - Registre seu dispositivo nos serviços do Google e cria um identificador de dispositivo exclusivo. Vanced+ microG identifica e tiras bits que não sejam o nome da sua conta do Google a partir de dados de registro. + Registre seu dispositivo nos serviços do Google e cria um identificador de dispositivo exclusivo. Vanced microG identifica e tiras bits que não sejam o nome da sua conta do Google a partir de dados de registro. ID do Android Status - Padrão Manual segundos @@ -111,7 +95,6 @@ Isso pode demorar alguns minutos." Mensagens: %1$d (%2$d bytes) Desconectado Conectado à %1$s - Permitir registro Permita que o aplicativo se registre para notificações push. Iniciar aplicativo na mensagem push @@ -121,7 +104,6 @@ Isso pode demorar alguns minutos." Aplicativos registrados Aplicativos não registrados Redes para usar em notificações push - Perfil do dispositivo Selecionar perfil Nativo @@ -132,28 +114,6 @@ Isso pode demorar alguns minutos." Importar perfil personalizado Importar perfil do dispositivo a partir do arquivo Serial - Ver código fonte - Veja o código fonte do projeto no GitHub - Para remover a conta do Google conectada, vá para Configurações do dispositivo -> Conta. - Verifique se há atualizações do Vanced+ microG no GitHub - Verifique se há atualizações - Se desativado, todas as conexões aos servidores do Google normalmente feitas pelo Vanced+ microG serão negadas. Isso substitui as configurações específicas do serviço. - Permitir conexão com servidores do Google - Requer que o Orbot esteja instalado\nAinda não é compatível - Conecte-se ao Google através da rede Tor - Data da Build - Seus dados no YouTube - Navegue ou exclua sua atividade no YouTube e descubra como seus dados fazem com que o YouTube e outros serviços do Google funcionem melhor para você - Deseja remover sua conta do Google do Vanced+ microG? - Conta para removê-las.]]> - Verificar se há atualizações do Vanced + microG no GitLab - Ver código fonte do projeto no GitLab - Verifique a conexão - Verifique a conexão com a Internet do seu dispositivo - Voltar ao YouTube - Toque para sair do Vanced+ microG e voltar ao YouTube - Informações do pacote - Gerenciar contas do Google conectadas - Isso abrirá as configurações do seu dispositivo ! - Configurações diversas + View source code + View project source code on GitHub diff --git a/play-services-core/src/main/res/values-ru/strings.xml b/play-services-core/src/main/res/values-ru/strings.xml index 61269e80..7093b8fe 100644 --- a/play-services-core/src/main/res/values-ru/strings.xml +++ b/play-services-core/src/main/res/values-ru/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Настроить Vanced+ microG. + Настроить Vanced microG. Секундочку… Настройки аккаунта Google Извините… @@ -73,11 +73,11 @@ Добавить аккаунт Google Получать push-уведомления Cloud Messaging позволяет получать пуш-уведомления от многих приложений. Чтобы использовать GCM, включите регистрацию устройства в Google. - О Vanced+ microG + О Vanced microG Скрыть иконку microG из меню приложений Huawei Зарегистрировать устройство - Регистрирует ваше устройство в сервисах Google и создает уникальный идентификатор устройства. Vanced+ microG использует только имя аккаунта для регистрации. + Регистрирует ваше устройство в сервисах Google и создает уникальный идентификатор устройства. Vanced microG использует только имя аккаунта для регистрации. Android ID Состояние По умолчанию @@ -116,26 +116,4 @@ Serial View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-th/strings.xml b/play-services-core/src/main/res/values-th/strings.xml index 3f2df561..ebb9142f 100644 --- a/play-services-core/src/main/res/values-th/strings.xml +++ b/play-services-core/src/main/res/values-th/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - การติดตั้ง Vanced+ microG. + การติดตั้ง Vanced microG. รอสักครู่… จัดการบัญชี Google ขอโทษ... @@ -66,11 +66,11 @@ เพิ่มบัญชี Google รับการแจ้งเตือนแบบพุช Cloud Messaging เป็นผู้ให้บริการการแจ้งเตือนแบบพุชที่ใช้โดยแอปพลิเคชันบุคคลที่สามจำนวนมาก ในการใช้งาน คุณต้องเปิดใช้งานการลงทะเบียนอุปกรณ์  - เกี่ยวกับ Vanced+ microG + เกี่ยวกับ Vanced microG ซ่อนไอคอนจากลั้นเชอร์ Huawei ลงทะเบียนอุปกรณ์  - ลงทะเบียนอุปกรณ์ของคุณกับบริการของ Google และสร้างตัวระบุอุปกรณ์ที่ไม่ซ้ำกัน. Vanced+ microG strips identifying bits อื่นที่ไม่ใช่ชื่อบัญชี Google ของคุณจากข้อมูลการลงทะเบียน. + ลงทะเบียนอุปกรณ์ของคุณกับบริการของ Google และสร้างตัวระบุอุปกรณ์ที่ไม่ซ้ำกัน. Vanced microG strips identifying bits อื่นที่ไม่ใช่ชื่อบัญชี Google ของคุณจากข้อมูลการลงทะเบียน. Android ID สถานะ: ค่าเริ่มต้น @@ -104,26 +104,4 @@ นำเข้าโปรไฟล์อุปกรณ์จากไฟล์  View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-tr/strings.xml b/play-services-core/src/main/res/values-tr/strings.xml index d5f5ddf5..79f05514 100644 --- a/play-services-core/src/main/res/values-tr/strings.xml +++ b/play-services-core/src/main/res/values-tr/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Vanced+ microG\'yi kurun. + Vanced microG\'yi kurun. Sadece bir saniye… Google Hesap Yöneticisi Afedersiniz… @@ -73,11 +73,11 @@ Bunu bilerek yaptıysanız, Google'ın oturum açma sayfasına bağlanmak için Yeni Google Hesabı Anlık bildirimler alın Bulut mesajlaşma, birçok üçüncü taraf uygulaması tarafından kullanılan bir anlık bildirim sağlayıcısıdır. Bunu kullanmak için cihaz kaydını etkinleştirmelisiniz. - Vanced+ microG hakkında + Vanced microG hakkında Başlatıcı simgesini gizle Huawei Cihazı kaydet - Cihazınızı Google hizmetlerine kaydeder ve benzersiz bir cihaz tanımlayıcısı oluşturur. Vanced+ microG, kayıt verilerinden Google hesap adınız dışındaki bitleri tanımlayan şeritler. + Cihazınızı Google hizmetlerine kaydeder ve benzersiz bir cihaz tanımlayıcısı oluşturur. Vanced microG, kayıt verilerinden Google hesap adınız dışındaki bitleri tanımlayan şeritler. Android kimliği Durum Varsayılan @@ -116,26 +116,4 @@ Bunu bilerek yaptıysanız, Google'ın oturum açma sayfasına bağlanmak için Seri View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-uk/strings.xml b/play-services-core/src/main/res/values-uk/strings.xml index a63b5a67..e6da5f62 100644 --- a/play-services-core/src/main/res/values-uk/strings.xml +++ b/play-services-core/src/main/res/values-uk/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Налаштувати Vanced+ microG. + Налаштувати Vanced microG. Секундочку… Менеджер облікових записів Google Вибачте… @@ -73,11 +73,11 @@ Додати Google аккаунт Отримувати push-сповіщення Хмарне повідомлення – це провайдер push-сповіщень, який використовується багатьма сторонніми програмами. Щоб скористатися нею, необхідно увімкнути реєстрацію пристрою. - Про Vanced+ microG + Про Vanced microG Сховати значок з лаунчера Huawei Зареєструвати пристрій - Реєструє ваш пристрій у службах Google і створює унікальний ідентифікатор пристрою. Vanced+ microG видаляє з реєстраційних даних біти, відмінні від імені вашого аккаунта Google. + Реєструє ваш пристрій у службах Google і створює унікальний ідентифікатор пристрою. Vanced microG видаляє з реєстраційних даних біти, відмінні від імені вашого аккаунта Google. Android ID Стан Типово @@ -116,26 +116,4 @@ Срійне ім\'я View source code View project source code on GitHub - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-v23/themes.xml b/play-services-core/src/main/res/values-v23/themes.xml deleted file mode 100644 index 9009e5c5..00000000 --- a/play-services-core/src/main/res/values-v23/themes.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/values-v27/themes.xml b/play-services-core/src/main/res/values-v27/themes.xml deleted file mode 100644 index 434c86ec..00000000 --- a/play-services-core/src/main/res/values-v27/themes.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/values-v31/themes.xml b/play-services-core/src/main/res/values-v31/themes.xml index 6e96e2b4..1719a989 100644 --- a/play-services-core/src/main/res/values-v31/themes.xml +++ b/play-services-core/src/main/res/values-v31/themes.xml @@ -1,11 +1,13 @@ - - - \ No newline at end of file + diff --git a/play-services-core/src/main/res/values-vi/strings.xml b/play-services-core/src/main/res/values-vi/strings.xml index df22a69d..453d067e 100644 --- a/play-services-core/src/main/res/values-vi/strings.xml +++ b/play-services-core/src/main/res/values-vi/strings.xml @@ -17,11 +17,11 @@ Thiết lập Vanced+ microG. Hãy đợi giây lát… - Quản lý/Thêm tài khoản Google + Quản lý tài khoản Google Xin lỗi… "Một ứng dụng nào đó trên thiết bị của bạn đang yêu cầu đăng nhập vào tài khoản Google. -Nếu điều này do bạn thực hiện, hãy sử dụng nút Đăng nhập (hoặc Huawei nếu bạn có thiết bị hãng này) để kết nối đến máy chủ đăng nhập của Google." +Nếu điều này do bạn thực hiện, hãy sử dụng nút Đăng nhập (hoặc Huawei nếu bạn có thiết bị hãng này) để kết nối đến máy chủ đăng nhập của Google. Nếu không, nhấn Hủy để quay lại ứng dụng khiến hộp thoại này xuất hiện." Đăng nhập "Đang thiết lập kết nối đến máy chủ của Google để đăng nhập cho bạn. @@ -50,7 +50,7 @@ Hãy thử lại sau." Bật Tắt Nâng cao - Không có gì ở đây cả, thật kỳ lạ... + Trống Xem tất cả Mạng di động Wi-Fi @@ -70,17 +70,15 @@ Hãy thử lại sau." Cho phép ứng dụng tìm tài khoản Khi được bật, tất cả các ứng dụng trên thiết bị này sẽ có thể xem địa chỉ email trong Tài khoản Google của bạn mà không cần ủy quyền trước. Tài khoản - Thêm tài khoản Google mới + Thêm tài khoản Google Nhận thông báo đẩy Thông báo đẩy qua đám mây hay Cloud Messaging là một nhà cung cấp dịch vụ thông báo đẩy được nhiều ứng dụng bên thứ ba tin dùng. Để sử dụng nó, bạn phải kích hoạt Đăng ký thiết bị. - Giới thiệu về Vanced+ microG + Giới thiệu về Vanced microG Ẩn biểu tượng khỏi launcher Huawei Đăng ký thiết bị - Đăng ký thiết bị của bạn với các dịch vụ của Google và tạo một mã nhận dạng thiết bị duy nhất. Vanced+ microG tách một ít thông tin nhận dạng không phải tên tài khoản Google của bạn từ dữ liệu đăng ký. + Đăng ký thiết bị của bạn với các dịch vụ của Google và tạo một mã nhận dạng thiết bị duy nhất. Vanced microG tách một ít thông tin nhận dạng không phải tên tài khoản Google của bạn từ dữ liệu đăng ký. ID Android - Xác thực với đăng ký thiết bị - Khi vô hiệu hóa, các yêu cầu xác thực sẽ không được liên kết với đăng ký thiết bị, điều này cho phép các thiết bị trái phép đăng nhập nhưng có thể gây ra những hậu quả về tài khoản. Trạng thái Mặc định Thủ công @@ -100,7 +98,7 @@ Hãy thử lại sau." Cho phép đăng ký Cho phép ứng dụng đăng ký nhận thông báo đẩy. Khởi động ứng dụng từ tin nhắn đẩy - Khởi động ứng dụng ở chế độ nền để nhận các thông báo đẩy đến. + Khởi động ứng dụng ở chế độ nền để nhận các tin nhắn đẩy đến. Trạng thái Ứng dụng sử dụng thông báo đẩy Ứng dụng đã đăng ký @@ -118,27 +116,4 @@ Hãy thử lại sau." Số sêri Xem mã nguồn Xem mã nguồn của dự án trên GitHub - Để gỡ bỏ tài khoản Google đã đăng nhập, hãy vào Cài đặt thiết bị -> Tài khoản. - Kiểm tra cập nhật mới của Vanced+ microG trên GitHub - Kiểm tra cập nhật mới - Nếu vô hiệu hóa, tất cả các kết nối tới máy chủ Google thường thực hiện bởi Vanced+ microG sẽ bị từ chối. Tùy chọn này sẽ ghi đè cài đặt đó. - Cho phép kết nối tới máy chủ Google - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Ngày dựng - Dữ liệu của bạn trong YouTube - Xem hoặc xóa hoạt động của bạn trên YouTube và khám phá cách dữ liệu của bạn có thể giúp YouTube và các dịch vụ khác của Google hoạt động hiệu quả hơn cho bạn. - Muốn đăng xuất hoặc gỡ tài khoản đã đăng nhập khỏi Vanced+ microG? - Quản lý Tài khoản và gỡ bỏ nó]]> hoặc nhấp vào đây. - Kiểm tra cập nhật Vanced+ microG trên GitLab - Xem mã nguồn dự án trên GitLab - Kiểm tra kết nối - Kiểm tra kết nối mạng của thiết bị - Quay lại YouTube Vanced+ - Nhấn để thoát Vanced+ microG và quay lại YouTube Vanced+ (nếu được cài đặt) - - Thông tin package - Quản lý tài khoản Google đã đăng nhập - Điều này sẽ mở cài đặt thiết bị của bạn ! - Cài đặt khác diff --git a/play-services-core/src/main/res/values-zh-rCN/strings.xml b/play-services-core/src/main/res/values-zh-rCN/strings.xml index 5dc520b8..b67db1d2 100644 --- a/play-services-core/src/main/res/values-zh-rCN/strings.xml +++ b/play-services-core/src/main/res/values-zh-rCN/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - 设置 Vanced+ microG。 + 设置 Vanced microG。 请稍等… Google 账号管理器 抱歉… @@ -73,11 +73,11 @@ 添加 Google 账号 接收推送通知 云端推送是第三方应用推送通知的渠道,要使用必须启用设备注册。 - 关于 Vanced+ microG + 关于 Vanced microG 隐藏桌面图标 华为 注册设备 - 注册您的设备到 Google 服务并创建独特的设备标识,Vanced+ microG 从注册数据种识别您的 Google 账号 名称以外的项目。 + 注册您的设备到 Google 服务并创建独特的设备标识,Vanced microG 从注册数据种识别您的 Google 账号 名称以外的项目。 Android ID 状态 默认 @@ -116,25 +116,4 @@ 序列号 View source code View project source code on GitHub - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values-zh-rTW/strings.xml b/play-services-core/src/main/res/values-zh-rTW/strings.xml index f4105881..0ac1e82c 100644 --- a/play-services-core/src/main/res/values-zh-rTW/strings.xml +++ b/play-services-core/src/main/res/values-zh-rTW/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - Vanced+ microG 設置 + Vanced microG 設置 請稍等一下… 管理Google帳號 很抱歉… @@ -76,12 +76,12 @@ 新增 Google 帳戶 接收應用的推播通知 連網通知推播是第三方應用推送通知的方式, 若欲啟用, 您必須先註冊裝置. - 關於 Vanced+ microG - 於桌面隱藏 Vanced+ microG + 關於 Vanced microG + 於桌面隱藏 Vanced microG 華為 裝置註冊 開啟後將產生一組屬於此裝置的識別碼 -Vanced+ microG 會把 Google 帳戶名稱以外的識別位 +Vanced microG 會把 Google 帳戶名稱以外的識別位 從註冊資訊中移除 Android ID 狀態 @@ -124,25 +124,4 @@ Vanced+ microG 會把 Google 帳戶名稱以外的識別位 序號 View source code View project source code on GitHub - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them.]]> - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values/colors.xml b/play-services-core/src/main/res/values/colors.xml index 12402999..85c87c33 100755 --- a/play-services-core/src/main/res/values/colors.xml +++ b/play-services-core/src/main/res/values/colors.xml @@ -16,9 +16,9 @@ - #ff9a82db - #ff9a82db - #ff9a82db + #ff4285f4 + #ff3367d6 + #ffffab40 #ff9a82db diff --git a/fake-signature/src/main/res/values/signature.xml b/play-services-core/src/main/res/values/signature.xml old mode 100644 new mode 100755 similarity index 56% rename from fake-signature/src/main/res/values/signature.xml rename to play-services-core/src/main/res/values/signature.xml index 282e0dc1..df53f65c --- a/fake-signature/src/main/res/values/signature.xml +++ b/play-services-core/src/main/res/values/signature.xml @@ -1,14 +1,21 @@ - - - + 308204433082032ba003020102020900c2e08746644a308d300d06092a864886f70d01010405003074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f6964301e170d3038303832313233313333345a170d3336303130373233313333345a3074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f696430820120300d06092a864886f70d01010105000382010d00308201080282010100ab562e00d83ba208ae0a966f124e29da11f2ab56d08f58e2cca91303e9b754d372f640a71b1dcb130967624e4656a7776a92193db2e5bfb724a91e77188b0e6a47a43b33d9609b77183145ccdf7b2e586674c9e1565b1f4c6a5955bff251a63dabf9c55c27222252e875e4f8154a645f897168c0b1bfc612eabf785769bb34aa7984dc7e2ea2764cae8307d8c17154d7ee5f64a51a44a602c249054157dc02cd5f5c0e55fbef8519fbe327f0b1511692c5a06f19d18385f5c4dbc2d6b93f68cc2979c70e18ab93866b3bd5db8999552a0e3b4c99df58fb918bedc182ba35e003c1b4b10dd244a8ee24fffd333872ab5221985edab0fc0d0b145b6aa192858e79020103a381d93081d6301d0603551d0e04160414c77d8cc2211756259a7fd382df6be398e4d786a53081a60603551d2304819e30819b8014c77d8cc2211756259a7fd382df6be398e4d786a5a178a4763074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f6964820900c2e08746644a308d300c0603551d13040530030101ff300d06092a864886f70d010104050003820101006dd252ceef85302c360aaace939bcff2cca904bb5d7a1661f8ae46b2994204d0ff4a68c7ed1a531ec4595a623ce60763b167297a7ae35712c407f208f0cb109429124d7b106219c084ca3eb3f9ad5fb871ef92269a8be28bf16d44c8d9a08e6cb2f005bb3fe2cb96447e868e731076ad45b33f6009ea19c161e62641aa99271dfd5228c5c587875ddb7f452758d661f6cc0cccb7352e424cc4365c523532f7325137593c4ae341f4db41edda0d0b1071a7c440f0fe9ea01cb627ca674369d084bd2fd911ff06cdbf2cfa10dc0f893ae35762919048c7efc64c7144178342f70581c9de573af55b390dd7fdb9418631895d5f759f30112687ff621410c069308a - - 308202ed308201d5a003020102020426ffa009300d06092a864886f70d01010b05003027310b300906035504061302444531183016060355040a130f4e4f47415050532050726f6a656374301e170d3132313030363132303533325a170d3337303933303132303533325a3027310b300906035504061302444531183016060355040a130f4e4f47415050532050726f6a65637430820122300d06092a864886f70d01010105000382010f003082010a02820101009a8d2a5336b0eaaad89ce447828c7753b157459b79e3215dc962ca48f58c2cd7650df67d2dd7bda0880c682791f32b35c504e43e77b43c3e4e541f86e35a8293a54fb46e6b16af54d3a4eda458f1a7c8bc1b7479861ca7043337180e40079d9cdccb7e051ada9b6c88c9ec635541e2ebf0842521c3024c826f6fd6db6fd117c74e859d5af4db04448965ab5469b71ce719939a06ef30580f50febf96c474a7d265bb63f86a822ff7b643de6b76e966a18553c2858416cf3309dd24278374bdd82b4404ef6f7f122cec93859351fc6e5ea947e3ceb9d67374fe970e593e5cd05c905e1d24f5a5484f4aadef766e498adf64f7cf04bddd602ae8137b6eea40722d0203010001a321301f301d0603551d0e04160414110b7aa9ebc840b20399f69a431f4dba6ac42a64300d06092a864886f70d01010b0500038201010007c32ad893349cf86952fb5a49cfdc9b13f5e3c800aece77b2e7e0e9c83e34052f140f357ec7e6f4b432dc1ed542218a14835acd2df2deea7efd3fd5e8f1c34e1fb39ec6a427c6e6f4178b609b369040ac1f8844b789f3694dc640de06e44b247afed11637173f36f5886170fafd74954049858c6096308fc93c1bc4dd5685fa7a1f982a422f2a3b36baa8c9500474cf2af91c39cbec1bc898d10194d368aa5e91f1137ec115087c31962d8f76cd120d28c249cf76f4c70f5baa08c70a7234ce4123be080cee789477401965cfe537b924ef36747e8caca62dfefdd1a6288dcb1c4fd2aaa6131a7ad254e9742022cfd597d2ca5c660ce9e41ff537e5a4041e37 - \ No newline at end of file diff --git a/play-services-core/src/main/res/values/strings.xml b/play-services-core/src/main/res/values/strings.xml index 236f1198..3f1c3e97 100755 --- a/play-services-core/src/main/res/values/strings.xml +++ b/play-services-core/src/main/res/values/strings.xml @@ -40,18 +40,17 @@ Try again later." This can take a couple of minutes." listen to internal status broadcasts - read Google service configuration listen to C2DM messages send C2DM messages to other apps exchange messages and receive sync notifications from Google servers Extended access to Google services - Google Account Manager not yet fully implemented + Google Account Manager not fully implemented Manage your Google account Manage your Google account information Manage YouTube activities Manage YouTube activities such as watch or search history View source code - View project source code on GitLab + View project source code on GitHub Google device registration @@ -82,8 +81,6 @@ This can take a couple of minutes." Personal info & privacy Sign-in & security - Authenticate with device registration - When disabled, authentication requests won\'t be linked to the device registration, which allows unauthorized devices to sign in, but may have unforeseen consequences. Trust Google for app permissions When disabled, the user is asked before an apps authorization request is sent to Google. Some applications will fail to use the Google account if this is disabled. Allow apps to find accounts @@ -100,7 +97,7 @@ This can take a couple of minutes." Huawei Register device - Registers your device to Google services and creates a unique device identifier. Vanced+ microG strips identifying bits other than your Google account name from registration data. + Registers your device to Google services and creates a unique device identifier. Vanced microG+ strips identifying bits other than your Google account name from registration data. Android ID Status @@ -140,26 +137,4 @@ This can take a couple of minutes." Import custom profile Import device profile from file Serial - To remove signed in Google account, go to Device Settings -> Account. - Check for Vanced+ microG updates on GitHub - Check for updates - If disabled, all connections to Google servers usually done by Vanced+ microG will be denied. This overrides service specific settings. - Allow connecting to Google servers - Requires Orbot to be installed\nNot yet supported - Connect to Google via Tor network - Build date - Your data in YouTube - Browse or delete your YouTube activity, and discover how your data makes YouTube and other Google services work better for you - Want to remove your Google account from Vanced+ microG? - Account to remove them]]> or click here. - Check for Vanced+ microG updates on GitLab - View project source code on GitLab - Check connection - Check your device internet connection - Back to YouTube Vanced+ - Tap to exit Vanced+ microG and back to YouTube Vanced+ (if installed) - Package information - Manage signed in Google accounts - This will open your device settings ! - Miscellaneous settings diff --git a/play-services-core/src/main/res/values/themes.xml b/play-services-core/src/main/res/values/themes.xml index 8e651928..d5cb5705 100755 --- a/play-services-core/src/main/res/values/themes.xml +++ b/play-services-core/src/main/res/values/themes.xml @@ -22,15 +22,6 @@ @color/m3_theme_primary_dark - - - - - - - - diff --git a/play-services-core/src/main/res/xml/authenticator.xml b/play-services-core/src/main/res/xml/authenticator.xml index 52772beb..72809e56 100644 --- a/play-services-core/src/main/res/xml/authenticator.xml +++ b/play-services-core/src/main/res/xml/authenticator.xml @@ -17,7 +17,7 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/play-services-core/src/main/res/xml/preferences_auth.xml b/play-services-core/src/main/res/xml/preferences_auth.xml index 18007889..7ff14e56 100755 --- a/play-services-core/src/main/res/xml/preferences_auth.xml +++ b/play-services-core/src/main/res/xml/preferences_auth.xml @@ -18,30 +18,16 @@ - + - + - - - - + diff --git a/play-services-core/src/main/res/xml/preferences_device_registration.xml b/play-services-core/src/main/res/xml/preferences_device_registration.xml index 3fa45eb5..ecd4b469 100755 --- a/play-services-core/src/main/res/xml/preferences_device_registration.xml +++ b/play-services-core/src/main/res/xml/preferences_device_registration.xml @@ -5,14 +5,7 @@ --> - - - + xmlns:tools="http://schemas.android.com/tools"> @@ -20,11 +13,16 @@ android:key="pref_device_profile" android:persistent="false" android:title="@string/profile_name" - tools:summary="Automatic" /> + tools:summary="Automatic (Google Pixel 3, Android 11)" /> + + tools:summary="Last registration: 13 hours ago" /> - + tools:summary="1953a59d1c1b7e4b" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications.xml b/play-services-core/src/main/res/xml/preferences_push_notifications.xml index 416cfac8..20862ae7 100755 --- a/play-services-core/src/main/res/xml/preferences_push_notifications.xml +++ b/play-services-core/src/main/res/xml/preferences_push_notifications.xml @@ -7,11 +7,6 @@ - - @@ -34,13 +29,6 @@ android:selectable="false" android:title="@string/prefcat_status_title" tools:summary="Connected since 15 minutes ago" /> - - - - - diff --git a/play-services-core/src/main/res/xml/preferences_start.xml b/play-services-core/src/main/res/xml/preferences_start.xml index e7372cee..60368d0f 100755 --- a/play-services-core/src/main/res/xml/preferences_start.xml +++ b/play-services-core/src/main/res/xml/preferences_start.xml @@ -16,14 +16,14 @@ - + + android:icon="@drawable/ic_add_account" + android:summary="@string/pref_add_account_summary" + android:title="@string/pref_add_account_title"> + android:targetClass="org.microg.gms.auth.login.LoginActivity" + android:targetPackage="com.mgoogle.android.gms" /> + + + - - - - + + + + - - - diff --git a/play-services-core/src/main/res/xml/profile_googlevr.xml b/play-services-core/src/main/res/xml/profile_googlevr.xml deleted file mode 100644 index 1d0c7fba..00000000 --- a/play-services-core/src/main/res/xml/profile_googlevr.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/xml/profile_lineage_xperiaxz2.xml b/play-services-core/src/main/res/xml/profile_lineage_xperiaxz2.xml deleted file mode 100644 index 6aa36bfa..00000000 --- a/play-services-core/src/main/res/xml/profile_lineage_xperiaxz2.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/xml/profile_projectinfinityx_redminote7.xml b/play-services-core/src/main/res/xml/profile_projectinfinityx_redminote7.xml deleted file mode 100644 index f92014ae..00000000 --- a/play-services-core/src/main/res/xml/profile_projectinfinityx_redminote7.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/xml/profile_sdk_gphone64_arm64_33.xml b/play-services-core/src/main/res/xml/profile_sdk_gphone64_arm64_33.xml deleted file mode 100644 index 62d223c5..00000000 --- a/play-services-core/src/main/res/xml/profile_sdk_gphone64_arm64_33.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/play-services-iid-api/build.gradle b/play-services-iid-api/build.gradle index 34ed3abb..0ea891dd 100644 --- a/play-services-iid-api/build.gradle +++ b/play-services-iid-api/build.gradle @@ -26,13 +26,13 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 11 + targetCompatibility = 11 } + namespace 'org.microg.gms.iid.api' buildFeatures { aidl true } - namespace 'org.microg.gms.iid.api' } dependencies { diff --git a/play-services-iid-api/src/main/AndroidManifest.xml b/play-services-iid-api/src/main/AndroidManifest.xml deleted file mode 100644 index ca617cfb..00000000 --- a/play-services-iid-api/src/main/AndroidManifest.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - \ No newline at end of file diff --git a/play-services-iid-api/src/main/java/com/google/android/gms/iid/MessengerCompat.java b/play-services-iid-api/src/main/java/com/google/android/gms/iid/MessengerCompat.java index 7aebf9b4..1cc87ae3 100644 --- a/play-services-iid-api/src/main/java/com/google/android/gms/iid/MessengerCompat.java +++ b/play-services-iid-api/src/main/java/com/google/android/gms/iid/MessengerCompat.java @@ -26,7 +26,7 @@ import android.os.Parcelable; import android.os.RemoteException; public class MessengerCompat implements Parcelable { - private Messenger messenger; + private final Messenger messenger; private IMessengerCompat messengerCompat; public MessengerCompat(IBinder binder) { @@ -48,7 +48,7 @@ public class MessengerCompat implements Parcelable { } public IBinder getBinder() { - return messenger != null ? messenger.getBinder() : messengerCompat.asBinder(); + return messenger.getBinder(); } @Override @@ -57,8 +57,7 @@ public class MessengerCompat implements Parcelable { } public void send(Message message) throws RemoteException { - if (messenger != null) messenger.send(message); - else messengerCompat.send(message); + messenger.send(message); } @Override diff --git a/play-services-tasks/build.gradle b/play-services-tasks/build.gradle index 068aeb92..204e8d9e 100644 --- a/play-services-tasks/build.gradle +++ b/play-services-tasks/build.gradle @@ -22,8 +22,8 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 11 + targetCompatibility = 11 } namespace 'org.microg.gms.tasks' } diff --git a/play-services-tasks/src/main/AndroidManifest.xml b/play-services-tasks/src/main/AndroidManifest.xml deleted file mode 100644 index c256eb44..00000000 --- a/play-services-tasks/src/main/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskCompletionSource.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskCompletionSource.java index 3cdf1f11..cbb0a9e6 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskCompletionSource.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/TaskCompletionSource.java @@ -84,14 +84,11 @@ public class TaskCompletionSource { * Completes the Task with the specified exception, unless the Task has already completed. * If the Task has already completed, the call does nothing. * - * @return {@code true} if the exception was set successfully, {@code false} otherwise */ - public boolean trySetException(Exception e) { + public void trySetException(Exception e) { try { setException(e); - return true; } catch (DuplicateTaskCompletionException ignored) { - return false; } } @@ -108,14 +105,11 @@ public class TaskCompletionSource { * Completes the Task with the specified result, unless the Task has already completed. * If the Task has already completed, the call does nothing. * - * @return {@code true} if the result was set successfully, {@code false} otherwise */ - public boolean trySetResult(TResult result) { + public void trySetResult(TResult result) { try { setResult(result); - return true; } catch (DuplicateTaskCompletionException ignored) { - return false; } } } diff --git a/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java b/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java index 8bbc7db6..1736b868 100644 --- a/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java +++ b/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java @@ -8,85 +8,17 @@ package com.google.android.gms.tasks; -import android.os.Handler; -import android.os.Looper; - import org.microg.gms.common.PublicApi; -import org.microg.gms.tasks.CancellationTokenImpl; -import org.microg.gms.tasks.TaskImpl; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; /** * {@link Task} utility methods. */ @PublicApi -@SuppressWarnings("unchecked") public final class Tasks { - /** - * Blocks until the specified Task is complete. - * - * @return the Task's result - * @throws ExecutionException if the Task fails - * @throws InterruptedException if an interrupt occurs while waiting for the Task to complete - * @throws TimeoutException if the specified timeout is reached before the Task completes - */ - public static TResult await(Task task, long timeout, TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException { - if (task == null) throw new IllegalArgumentException("Task must not be null"); - if (timeout <= 0) throw new IllegalArgumentException("Timeout must be positive"); - if (unit == null) throw new IllegalArgumentException("TimeUnit must not be null"); - if (task.isComplete()) return handleCompletedTask(task); - CountDownLatch latch = new CountDownLatch(1); - task.addOnCompleteListener(Runnable::run, completedTask -> latch.countDown()); - if (latch.await(timeout, unit)) { - return handleCompletedTask(task); - } - throw new TimeoutException("Timed out waiting for Task"); - } - - /** - * Blocks until the specified Task is complete. - * - * @return the Task's result - * @throws ExecutionException if the Task fails - * @throws InterruptedException if an interrupt occurs while waiting for the Task to complete - */ - public static TResult await(Task task) throws ExecutionException, InterruptedException { - if (Looper.getMainLooper().getThread() == Thread.currentThread()) - throw new IllegalStateException("Must not be invoked on main thread"); - if (task == null) throw new IllegalArgumentException("Task must not be null"); - if (task.isComplete()) return handleCompletedTask(task); - CountDownLatch latch = new CountDownLatch(1); - task.addOnCompleteListener(Runnable::run, completedTask -> latch.countDown()); - latch.await(); - return handleCompletedTask(task); - } - - private static TResult handleCompletedTask(Task task) throws ExecutionException { - if (task.isSuccessful()) { - return task.getResult(); - } - if (task.isCanceled()) { - throw new CancellationException("Task is already canceled"); - } - throw new ExecutionException(task.getException()); - } - /** * Returns a {@link Task} that will be completed with the result of the specified {@code Callable}. *

@@ -128,180 +60,4 @@ public final class Tasks { return taskCompletionSource.getTask(); } - /** - * Returns a canceled Task. - */ - public static Task forCancelled() { - TaskImpl task = new TaskImpl<>(); - task.cancel(); - return task; - } - - /** - * Returns a completed Task with the specified exception. - */ - public static Task forException(Exception e) { - TaskImpl task = new TaskImpl<>(); - task.setException(e); - return task; - } - - /** - * Returns a completed Task with the specified result. - */ - public static Task forResult(TResult result) { - TaskImpl task = new TaskImpl<>(); - task.setResult(result); - return task; - } - - /** - * Returns a Task that completes successfully when all of the specified Tasks complete - * successfully. Does not accept nulls. - *

- * The returned Task would fail if any of the provided Tasks fail. The returned Task would be set to canceled if - * any of the provided Tasks is canceled and no failure is detected. - * - * @throws NullPointerException if any of the provided Tasks are null - */ - public static Task whenAll(Collection> tasks) { - if (tasks == null || tasks.isEmpty()) { - return forResult(null); - } - for (Task task : tasks) { - if (task == null) throw new NullPointerException("null tasks are not accepted"); - } - TaskImpl allTask = new TaskImpl<>(); - AtomicInteger finishedTasks = new AtomicInteger(0); - AtomicInteger failedTasks = new AtomicInteger(0); - AtomicReference exceptionReference = new AtomicReference<>(null); - AtomicBoolean isCancelled = new AtomicBoolean(false); - for (Task task : tasks) { - task.addOnCompleteListener(Runnable::run, completedTask -> { - if (!completedTask.isSuccessful()) { - if (completedTask.isCanceled()) { - isCancelled.set(true); - } else { - exceptionReference.set(completedTask.getException()); - failedTasks.incrementAndGet(); - } - } - if (finishedTasks.incrementAndGet() != tasks.size()) return; - Exception exception = exceptionReference.get(); - if (exception != null) { - allTask.setException(new ExecutionException(failedTasks.get() + " out of " + tasks.size() + " underlying tasks failed", exception)); - } else if (isCancelled.get()) { - allTask.cancel(); - } else { - allTask.setResult(null); - } - }); - } - return allTask; - } - - /** - * Returns a Task that completes successfully when all of the specified Tasks complete - * successfully. Does not accept nulls. - *

- * The returned Task would fail if any of the provided Tasks fail. The returned Task would be set to canceled if - * any of the provided Tasks is canceled and no failure is detected. - * - * @throws NullPointerException if any of the provided Tasks are null - */ - public static Task whenAll(Task... tasks) { - if (tasks == null || tasks.length == 0) { - return forResult(null); - } - return whenAll(Arrays.asList(tasks)); - } - - /** - * Returns a Task with a list of Tasks that completes successfully when all of the specified Tasks complete. This - * Task would always succeed even if any of the provided Tasks fail or canceled. Does not accept nulls. - * - * @throws NullPointerException if any of the provided Tasks are null - */ - public static Task>> whenAllComplete(Task... tasks) { - if (tasks == null || tasks.length == 0) { - return forResult(Collections.emptyList()); - } - return whenAllComplete(Arrays.asList(tasks)); - } - - /** - * Returns a Task with a list of Tasks that completes successfully when all of the specified Tasks complete. This - * Task would always succeed even if any of the provided Tasks fail or canceled. Does not accept nulls. - * - * @throws NullPointerException if any of the provided Tasks are null - */ - public static Task>> whenAllComplete(Collection> tasks) { - if (tasks == null || tasks.isEmpty()) { - return forResult(Collections.emptyList()); - } - return whenAll(tasks).continueWithTask(TaskExecutors.MAIN_THREAD, allTask -> forResult(new ArrayList<>(tasks))); - } - - /** - * Returns a Task with a list of Task results that completes successfully when all of the specified Tasks complete - * successfully. This Task would fail if any of the provided Tasks fail. Does not accept nulls. - *

- * This Task would be set to canceled if any of the provided Tasks is canceled and no failure is detected. - * - * @throws NullPointerException if any of the provided Tasks are null - */ - public static Task> whenAllSuccess(Task... tasks) { - if (tasks == null || tasks.length == 0) { - return forResult(Collections.emptyList()); - } - return whenAllSuccess(Arrays.asList(tasks)); - } - - /** - * Returns a Task with a list of Task results that completes successfully when all of the specified Tasks complete - * successfully. This Task would fail if any of the provided Tasks fail. Does not accept nulls. - *

- * This Task would be set to canceled if any of the provided Tasks is canceled and no failure is detected. - * - * @throws NullPointerException if any of the provided Tasks are null - */ - public static Task> whenAllSuccess(Collection> tasks) { - if (tasks == null || tasks.isEmpty()) { - return forResult(Collections.emptyList()); - } - return whenAll(tasks).continueWithTask(TaskExecutors.MAIN_THREAD, allTask -> { - List results = new ArrayList<>(tasks.size()); - for (Task task : tasks) { - results.add(task.getResult()); - } - return forResult(results); - }); - } - - /** - * Returns a new Task which will return a TimeoutException if a result is not returned within the specified time - * period. - * - * @return A new Task. - */ - public static Task withTimeout(Task task, long timeout, TimeUnit unit) { - if (task == null) throw new IllegalArgumentException("Task must not be null"); - if (timeout <= 0) throw new IllegalArgumentException("Timeout must be positive"); - if (unit == null) throw new IllegalArgumentException("TimeUnit must not be null"); - CancellationTokenImpl cancellationToken = new CancellationTokenImpl(); - TaskCompletionSource taskCompletionSource = new TaskCompletionSource<>(cancellationToken); - Handler handler = new Handler(Looper.getMainLooper()); - handler.postDelayed(() -> taskCompletionSource.trySetException(new TimeoutException()), unit.toMillis(timeout)); - task.addOnCompleteListener(completedTask -> { - handler.removeCallbacksAndMessages(null); - if (completedTask.isSuccessful()) { - taskCompletionSource.trySetResult(completedTask.getResult()); - } else if (completedTask.isCanceled()) { - cancellationToken.cancel(); - } else { - taskCompletionSource.trySetException(completedTask.getException()); - } - }); - return taskCompletionSource.getTask(); - } } diff --git a/play-services-tasks/src/main/java/org/microg/gms/tasks/TaskImpl.java b/play-services-tasks/src/main/java/org/microg/gms/tasks/TaskImpl.java index 67b54ea8..1354fb7e 100644 --- a/play-services-tasks/src/main/java/org/microg/gms/tasks/TaskImpl.java +++ b/play-services-tasks/src/main/java/org/microg/gms/tasks/TaskImpl.java @@ -17,6 +17,7 @@ import com.google.android.gms.tasks.RuntimeExecutionException; import com.google.android.gms.tasks.SuccessContinuation; import com.google.android.gms.tasks.Task; +import java.util.Objects; import java.util.Queue; import java.util.concurrent.CancellationException; import java.util.concurrent.Executor; @@ -138,7 +139,7 @@ public class TaskImpl extends Task { synchronized (lock) { if (!completed) throw new IllegalStateException("Task is not yet complete"); if (cancelled) throw new CancellationException("Task is canceled"); - if (exceptionType.isInstance(exception)) throw exceptionType.cast(exception); + if (exceptionType.isInstance(exception)) throw Objects.requireNonNull(exceptionType.cast(exception)); if (exception != null) throw new RuntimeExecutionException(exception); return result; } diff --git a/proguard.flags b/proguard.flags index 7e287ce2..fba8c5e2 100644 --- a/proguard.flags +++ b/proguard.flags @@ -11,24 +11,16 @@ -dontwarn com.caverock.androidsvg.** -dontwarn org.slf4j.** -dontwarn org.codehaus.jackson.** --dontwarn com.android.location.provider.** --dontwarn java.lang.instrument.ClassFileTransformer --dontwarn sun.misc.SignalHandler --dontwarn com.android.org.conscrypt.SSLParametersImpl --dontwarn org.apache.harmony.xnet.provider.jsse.SSLParametersImpl # Disable ProGuard Notes, they won't help here -dontnote # Keep dynamically loaded GMS classes -keep public class com.google.android.gms.common.security.ProviderInstallerImpl { public *; } --keep public class com.google.android.gms.dynamic.IObjectWrapper { public *; } --keep public class com.google.android.gms.dynamite.descriptors.** { public *; } # Keep AutoSafeParcelables -keep public class * extends org.microg.safeparcel.AutoSafeParcelable { @org.microg.safeparcel.SafeParceled *; - (...); } # Keep form data @@ -37,12 +29,7 @@ } # Keep our stuff --keep class org.microg** { *; } --keep class com.google.android.gms** { *; } --keep class com.mgoogle** { *; } --keepdirectories org/microg** --keepdirectories com/google/android/gms** --keepdirectories com/mgoogle** +-keep class org.microg.** { *; } # Keep asInterface method cause it's accessed from SafeParcel -keepattributes InnerClasses diff --git a/settings.gradle b/settings.gradle index 78cd762d..7725a9a8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,3 @@ -include ':fake-signature' - include ':play-services-basement' include ':play-services-tasks' @@ -15,4 +13,7 @@ include ':play-services-core:microg-ui-tools' // Legacy include ':play-services-core' include ':play-services-base' -include ':play-services-base-core' \ No newline at end of file +include ':play-services-base-core' + +include ':play-services-cast-framework' +include ':play-services-cast' \ No newline at end of file