Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 081823cf authored by Alexandru Chircu's avatar Alexandru Chircu
Browse files

Imported patch from GitHub, modified code as per recommendations.

parent 01749d9e
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@

    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission
        android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"
        tools:ignore="ProtectedPermissions"/>
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.util.Log;
import com.google.android.gms.checkin.internal.ICheckinService;

import org.microg.gms.auth.AuthConstants;
import org.microg.gms.common.ForegroundServiceContext;
import org.microg.gms.gcm.McsService;
import org.microg.gms.people.PeopleManager;

@@ -55,6 +56,7 @@ public class CheckinService extends IntentService {
    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            ForegroundServiceContext.completeForegroundService(this, intent, TAG);
            if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PREF_ENABLE_CHECKIN, true)) {
                LastCheckinInfo info = CheckinManager.checkin(this, intent.getBooleanExtra(EXTRA_FORCE_CHECKIN, false));
                if (info != null) {
+23 −15
Original line number Diff line number Diff line
@@ -24,15 +24,20 @@ import android.preference.PreferenceManager;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

import org.microg.gms.common.ForegroundServiceContext;

import static org.microg.gms.checkin.CheckinService.EXTRA_FORCE_CHECKIN;

public class TriggerReceiver extends WakefulBroadcastReceiver {
    private static final String TAG = "GmsCheckinTrigger";
    public static final String PREF_ENABLE_CHECKIN = "checkin_enable_service";
    public static final String FORCE_TRY_RECONNECT = "org.microg.gms.checkin.FORCE_TRY_RECONNECT";
    public static final String FORCE_CHECKIN = "org.microg.gms.checkin.FORCE_CHECKIN";
    private static final long REGULAR_CHECKIN_INTERVAL = 12 * 60 * 60 * 1000; // 12 hours

    @Override
    public void onReceive(Context context, Intent intent) {
        boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction()) || FORCE_TRY_RECONNECT.equals(intent.getAction());
        try {
            boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction()) || FORCE_CHECKIN.equals(intent.getAction());
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

            if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_ENABLE_CHECKIN, true) || force) {
@@ -44,11 +49,14 @@ public class TriggerReceiver extends WakefulBroadcastReceiver {
                NetworkInfo networkInfo = cm.getActiveNetworkInfo();
                if (networkInfo != null && networkInfo.isConnected() || force) {
                    Intent subIntent = new Intent(context, CheckinService.class);
                subIntent.putExtra(CheckinService.EXTRA_FORCE_CHECKIN, force);
                startWakefulService(context, subIntent);
                    subIntent.putExtra(EXTRA_FORCE_CHECKIN, force);
                    startWakefulService(new ForegroundServiceContext(context), subIntent);
                }
            } else {
                Log.d(TAG, "Ignoring " + intent + ": checkin is disabled");
            }
        } catch (Exception e) {
            Log.w(TAG, e);
        }
    }
}
+80 −0
Original line number Diff line number Diff line
package org.microg.gms.common;

import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.os.Build;
import android.os.PowerManager;
import android.support.annotation.RequiresApi;
import android.util.Log;

import com.google.android.gms.R;

import java.util.List;

public class ForegroundServiceContext extends ContextWrapper {
    private static final String TAG = "ForegroundService";
    public static final String EXTRA_FOREGROUND = "foreground";

    public ForegroundServiceContext(Context base) {
        super(base);
    }

    @Override
    public ComponentName startService(Intent service) {
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isIgnoringBatteryOptimizations() && !isAppOnForeground()) {
            Log.d(TAG, "Starting in foreground mode.");
            service.putExtra(EXTRA_FOREGROUND, true);
            return super.startForegroundService(service);
        }
        return super.startService(service);
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private boolean isIgnoringBatteryOptimizations() {
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        return powerManager.isIgnoringBatteryOptimizations(getPackageName());
    }

    private boolean isAppOnForeground() {
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if (appProcesses == null) {
            return false;
        }
        final String packageName = getPackageName();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }

    public static void completeForegroundService(Service service, Intent intent, String tag) {
        if (intent.getBooleanExtra(EXTRA_FOREGROUND, false) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Log.d(tag, "Started in foreground mode.");
            service.startForeground(tag.hashCode(), buildForegroundNotification(service));
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private static Notification buildForegroundNotification(Context context) {
        NotificationChannel channel = new NotificationChannel("foreground-service", "Foreground Service", NotificationManager.IMPORTANCE_NONE);
        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
        channel.setShowBadge(false);
        channel.setVibrationPattern(new long[0]);
        context.getSystemService(NotificationManager.class).createNotificationChannel(channel);
        return new Notification.Builder(context, channel.getId())
                .setOngoing(true)
                .setContentTitle("Running in background")
                .setSmallIcon(R.drawable.gcm_bell)
                .build();
    }
}
+6 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.os.Build.VERSION.SDK_INT;
@@ -198,9 +199,12 @@ public class PackageUtils {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (manager == null) return null;
        if (pid <= 0) return null;
        for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = manager.getRunningAppProcesses();
        if (runningAppProcesses != null) {
            for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcesses) {
                if (processInfo.pid == pid) return processInfo.processName;
            }
        }
        return null;
    }

Loading