diff --git a/README.md b/README.md index 29f47891..90b361b6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This fork tweaks MicroG to be usable by applications that require Google authentication such as [YouTube Vanced+](https://gitlab.com/cuynu/vancedx). ## 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 does not works in ReVanced/RVX in future as recent changes from ReVanced/RVX to use with they specific MicroG called ReVanced MicroG with different package name ! ## Notable changes diff --git a/build.gradle b/build.gradle index bcf0bcbe..0ef88b7d 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ buildscript { ext.wireVersion = '4.8.0' - ext.androidBuildGradleVersion = '8.0.2' + ext.androidBuildGradleVersion = '7.4.2' ext.androidBuildVersionTools = '33.0.2' ext.androidMinSdk = 23 @@ -48,7 +48,7 @@ buildscript { } -def gmsVersion = "25.09.34" +def gmsVersion = "24.17.17" def gmsVersionCode = Integer.parseInt(gmsVersion.replaceAll('\\.', '')) def ourVersionBase = "0.3.0" diff --git a/fake-signature/build.gradle b/fake-signature/build.gradle index e04d9893..19f0fc40 100644 --- a/fake-signature/build.gradle +++ b/fake-signature/build.gradle @@ -17,8 +17,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } } diff --git a/gradle.properties b/gradle.properties index 126b7d28..976747da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,3 @@ android.useAndroidX=true +android.disableAutomaticComponentCreation=true org.gradle.jvmargs=-Xmx2048m -XX:+UseParallelGC -android.defaults.buildfeatures.buildconfig=true -android.nonTransitiveRClass=false -android.nonFinalResIds=false diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd491..afba1092 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..b1624c47 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip networkTimeout=10000 -validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1aa94a42..65dcd68d 100755 --- a/gradlew +++ b/gradlew @@ -83,8 +83,10 @@ done # This is normally unused # shellcheck disable=SC2034 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 +APP_HOME=$( cd "${APP_HOME:-./}" && 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 @@ -131,13 +133,10 @@ 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. @@ -145,7 +144,7 @@ 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 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,15 +197,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" \ diff --git a/play-services-api/build.gradle b/play-services-api/build.gradle index 20d8bea5..e254f48d 100644 --- a/play-services-api/build.gradle +++ b/play-services-api/build.gradle @@ -26,13 +26,9 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } - 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 index 359a9b71..d4a4d07a 100644 --- a/play-services-api/src/main/AndroidManifest.xml +++ b/play-services-api/src/main/AndroidManifest.xml @@ -15,4 +15,4 @@ ~ limitations under the License. --> - + diff --git a/play-services-base-api/build.gradle b/play-services-base-api/build.gradle index 23b6b07c..b806da4c 100644 --- a/play-services-base-api/build.gradle +++ b/play-services-base-api/build.gradle @@ -34,11 +34,7 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } - 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 index 055d07d5..7c8eeef3 100644 --- a/play-services-base-api/src/main/AndroidManifest.xml +++ b/play-services-base-api/src/main/AndroidManifest.xml @@ -3,4 +3,4 @@ ~ SPDX-FileCopyrightText: 2020, microG Project Team ~ SPDX-License-Identifier: Apache-2.0 --> - + diff --git a/play-services-base-core/build.gradle b/play-services-base-core/build.gradle index 34288f21..ad962700 100644 --- a/play-services-base-core/build.gradle +++ b/play-services-base-core/build.gradle @@ -21,6 +21,7 @@ android { buildToolsVersion androidBuildVersionTools defaultConfig { + versionName version minSdkVersion androidMinSdk targetSdkVersion androidTargetSdk @@ -32,8 +33,7 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } - namespace 'org.microg.gms.base.core' } \ No newline at end of file diff --git a/play-services-base-core/src/main/AndroidManifest.xml b/play-services-base-core/src/main/AndroidManifest.xml index 369707e7..39554ca3 100644 --- a/play-services-base-core/src/main/AndroidManifest.xml +++ b/play-services-base-core/src/main/AndroidManifest.xml @@ -4,20 +4,14 @@ ~ SPDX-License-Identifier: Apache-2.0 --> - - - + xmlns:android="http://schemas.android.com/apk/res/android" + package="org.microg.gms.base.core"> + android:exported="false" /> - - - - - - \ 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/build.gradle b/play-services-base/build.gradle index e1cff12a..8857d222 100644 --- a/play-services-base/build.gradle +++ b/play-services-base/build.gradle @@ -26,10 +26,9 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } - namespace 'org.microg.gms.base' } dependencies { diff --git a/play-services-base/src/main/AndroidManifest.xml b/play-services-base/src/main/AndroidManifest.xml index c31f1c05..3ab02d97 100644 --- a/play-services-base/src/main/AndroidManifest.xml +++ b/play-services-base/src/main/AndroidManifest.xml @@ -15,7 +15,8 @@ ~ limitations under the License. --> - + - + diff --git a/play-services-core-proto/build.gradle b/play-services-core-proto/build.gradle index 6edfcb4b..2cfb351e 100644 --- a/play-services-core-proto/build.gradle +++ b/play-services-core-proto/build.gradle @@ -21,9 +21,9 @@ sourceSets { } compileKotlin { - kotlinOptions.jvmTarget = 17 + kotlinOptions.jvmTarget = 1.8 } compileTestKotlin { - kotlinOptions.jvmTarget = 17 + kotlinOptions.jvmTarget = 1.8 } \ No newline at end of file diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index 22e0b42c..5cb9aedd 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -57,7 +57,7 @@ android { defaultConfig { versionName version versionCode appVersionCode - resourceConfigurations += ['xxhdpi'] + resConfigs 'xxhdpi' minSdkVersion androidMinSdk targetSdkVersion androidTargetSdk @@ -109,8 +109,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } packagingOptions { diff --git a/play-services-core/microg-ui-tools/build.gradle b/play-services-core/microg-ui-tools/build.gradle index 260aa6a5..b6b2018d 100644 --- a/play-services-core/microg-ui-tools/build.gradle +++ b/play-services-core/microg-ui-tools/build.gradle @@ -28,15 +28,14 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } lintOptions { // TODO: Remove MissingTranslation once we have stable strings and proper translations. disable 'MissingTranslation', 'GetLocales' } - 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 index 359a9b71..004f299c 100644 --- a/play-services-core/microg-ui-tools/src/main/AndroidManifest.xml +++ b/play-services-core/microg-ui-tools/src/main/AndroidManifest.xml @@ -15,4 +15,4 @@ ~ limitations under the License. --> - + 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..a771a9ea 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,7 +3,7 @@ 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; @@ -19,7 +19,6 @@ 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); } 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"> - - - @@ -56,7 +53,7 @@ - + @@ -65,8 +62,7 @@ - + @@ -94,7 +90,7 @@ 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"> @@ -105,7 +101,7 @@ + android:exported="false" /> @@ -120,15 +116,13 @@ - + - + @@ -156,7 +150,6 @@ @@ -168,7 +161,6 @@ @@ -181,7 +173,6 @@ @@ -194,7 +185,6 @@ @@ -218,7 +208,6 @@ @@ -231,8 +220,7 @@ - + @@ -290,7 +278,6 @@ @@ -298,22 +285,19 @@ - + - + - + @@ -321,8 +305,7 @@ @@ -353,11 +336,10 @@ @@ -380,7 +362,7 @@ android:name="com.google.android.gms.app.settings.GoogleSettingsLink" android:process=":ui" android:exported="true" - android:targetActivity="org.microg.gms.ui.MainSettingsActivity" + android:targetActivity="org.microg.gms.ui.SettingsActivity" android:taskAffinity="org.microg.gms.settings"> @@ -398,8 +380,7 @@ @@ -428,16 +409,14 @@ - + - + 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..5d836001 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; diff --git a/play-services-core/src/main/java/org/microg/gms/auth/loginservice/AccountAuthenticator.java b/play-services-core/src/main/java/org/microg/gms/auth/loginservice/AccountAuthenticator.java index fa4eb2bc..89ee692f 100644 --- a/play-services-core/src/main/java/org/microg/gms/auth/loginservice/AccountAuthenticator.java +++ b/play-services-core/src/main/java/org/microg/gms/auth/loginservice/AccountAuthenticator.java @@ -104,7 +104,7 @@ class AccountAuthenticator extends AbstractAccountAuthenticator { } } catch (Exception e) { Log.w(TAG, e); - throw new NetworkErrorException(e); + return null; } return null; } 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..dc67b444 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); 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..752b8119 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 @@ -41,7 +41,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; 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..f4766b4a 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 @@ -209,7 +209,7 @@ 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) { @@ -300,7 +300,7 @@ 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); } 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..e94b2f02 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 @@ -30,7 +30,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; @@ -67,7 +67,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/ui/MainSettingsActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java old mode 100644 new mode 100755 similarity index 66% 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..f0777081 --- 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,7 @@ package org.microg.gms.ui; -import android.content.Intent; +import static android.os.Build.VERSION.SDK_INT; + import android.os.Bundle; import androidx.annotation.Nullable; @@ -10,12 +11,10 @@ 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; - -public class MainSettingsActivity extends AppCompatActivity { +public class SettingsActivity extends AppCompatActivity { private AppBarConfiguration appBarConfiguration; private NavController getNavController() { @@ -25,18 +24,10 @@ public class MainSettingsActivity extends AppCompatActivity { @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 (SDK_INT >= 31) { + DynamicColors.applyToActivityIfAvailable(this); } - appBarConfiguration = new AppBarConfiguration.Builder(getNavController().getGraph()).build(); NavigationUI.setupActionBarWithNavController(this, getNavController(), appBarConfiguration); } @@ -45,4 +36,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/kotlin/org/microg/gms/checkin/CheckinPreferences.kt b/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPrefs.kt similarity index 60% rename from play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPreferences.kt rename to play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPrefs.kt index eb78d498..e2ab990a 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPreferences.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/checkin/CheckinPrefs.kt @@ -5,21 +5,16 @@ 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 { +object CheckinPrefs { @JvmStatic fun isEnabled(context: Context): Boolean { val projection = arrayOf(CheckIn.ENABLED) - return SettingsContract.getSettings( - context, - CheckIn.getContentUri(context), - projection - ) { c -> + return SettingsContract.getSettings(context, CheckIn.getContentUri(context), projection) { c -> c.getInt(0) != 0 } } @@ -27,11 +22,7 @@ object CheckinPreferences { @JvmStatic fun isSpoofingEnabled(context: Context): Boolean { val projection = arrayOf(CheckIn.BRAND_SPOOF) - return SettingsContract.getSettings( - context, - CheckIn.getContentUri(context), - projection - ) { c -> + return SettingsContract.getSettings(context, CheckIn.getContentUri(context), projection) { c -> c.getInt(0) != 0 } } @@ -50,13 +41,4 @@ object CheckinPreferences { } } - @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/gcm/GcmPrefs.kt b/play-services-core/src/main/kotlin/org/microg/gms/gcm/GcmPrefs.kt index c506ed62..86e7a37d 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 @@ -71,15 +71,6 @@ data class GcmPrefs( gcmPrefs.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)) { @@ -88,7 +79,6 @@ data class GcmPrefs( } } - /** * Call this whenever the enabled state of GCM has changed. */ @@ -188,4 +178,5 @@ data class GcmPrefs( 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..1f27e4b6 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 @@ -16,7 +16,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,7 +29,7 @@ import kotlin.coroutines.suspendCoroutine private const val TAG = "GmsGcmRegister" private suspend fun ensureCheckinIsUpToDate(context: Context) { - if (!CheckinPreferences.isEnabled(context)) throw RuntimeException("Checkin disabled") + if (!CheckinPrefs.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 -> 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..de5020c0 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,9 +11,8 @@ import android.util.DisplayMetrics import android.widget.ImageView import androidx.preference.Preference import androidx.preference.PreferenceViewHolder -import android.content.pm.ApplicationInfo -class AppIconPreference : AppPreference { +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) 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/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..da861c0b --- /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) { + getString(R.string.gcm_network_state_connected, DateUtils.getRelativeTimeSpanString(statusInfo.startTimestamp, System.currentTimeMillis(), 0)) + } else { + 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..86dd492d 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 @@ -15,7 +15,7 @@ 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 @@ -39,13 +39,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 -> @@ -107,7 +105,7 @@ 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) + findPreference(PREF_CHECKIN)?.setSummary(if (CheckinPrefs.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()) } @@ -126,7 +124,6 @@ class SettingsFragment : ResourceSettingsFragment() { 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/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/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"> - - - - - \ 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-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/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/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" /> - + android:summary="DD MM YYYY - nightly"> 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..9c250f95 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 @@ - - diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml b/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml index 5cf81e5b..01d83e52 100755 --- a/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml +++ b/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml @@ -6,11 +6,6 @@ - - diff --git a/play-services-core/src/main/res/xml/profile_bullhead_27.xml b/play-services-core/src/main/res/xml/profile_bullhead_27.xml new file mode 100644 index 00000000..186a4356 --- /dev/null +++ b/play-services-core/src/main/res/xml/profile_bullhead_27.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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_falcon_25.xml b/play-services-core/src/main/res/xml/profile_lineage_falcon_25.xml new file mode 100644 index 00000000..57beb5d4 --- /dev/null +++ b/play-services-core/src/main/res/xml/profile_lineage_falcon_25.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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_redfin_33.xml b/play-services-core/src/main/res/xml/profile_redfin_33.xml new file mode 100644 index 00000000..52c57f88 --- /dev/null +++ b/play-services-core/src/main/res/xml/profile_redfin_33.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/profile_sdk_gphone64_x86_64_33.xml b/play-services-core/src/main/res/xml/profile_sdk_gphone64_x86_64_33.xml new file mode 100644 index 00000000..b616c365 --- /dev/null +++ b/play-services-core/src/main/res/xml/profile_sdk_gphone64_x86_64_33.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-iid-api/build.gradle b/play-services-iid-api/build.gradle index 34ed3abb..603c53b4 100644 --- a/play-services-iid-api/build.gradle +++ b/play-services-iid-api/build.gradle @@ -26,13 +26,9 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } - 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 index ca617cfb..e979258e 100644 --- a/play-services-iid-api/src/main/AndroidManifest.xml +++ b/play-services-iid-api/src/main/AndroidManifest.xml @@ -15,4 +15,4 @@ ~ limitations under the License. --> - \ No newline at end of file + \ No newline at end of file diff --git a/play-services-tasks/build.gradle b/play-services-tasks/build.gradle index 068aeb92..0eb84bbf 100644 --- a/play-services-tasks/build.gradle +++ b/play-services-tasks/build.gradle @@ -22,10 +22,9 @@ android { } compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 1.8 + targetCompatibility = 1.8 } - namespace 'org.microg.gms.tasks' } dependencies { diff --git a/play-services-tasks/src/main/AndroidManifest.xml b/play-services-tasks/src/main/AndroidManifest.xml index c256eb44..c7b833fe 100644 --- a/play-services-tasks/src/main/AndroidManifest.xml +++ b/play-services-tasks/src/main/AndroidManifest.xml @@ -4,4 +4,4 @@ ~ SPDX-License-Identifier: Apache-2.0 --> - +