1package eu.siacs.conversations.utils;
  2
  3import static eu.siacs.conversations.receiver.SystemEventReceiver.EXTRA_NEEDS_FOREGROUND_SERVICE;
  4
  5import android.annotation.SuppressLint;
  6import android.app.ActivityOptions;
  7import android.content.Context;
  8import android.content.Intent;
  9import android.content.pm.PackageManager;
 10import android.net.ConnectivityManager;
 11import android.os.Build;
 12import android.os.Bundle;
 13import android.util.Log;
 14import androidx.annotation.NonNull;
 15import androidx.annotation.RequiresApi;
 16import androidx.core.content.ContextCompat;
 17import eu.siacs.conversations.Config;
 18
 19public class Compatibility {
 20
 21    public static boolean hasStoragePermission(final Context context) {
 22        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
 23                || ContextCompat.checkSelfPermission(
 24                                context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
 25                        == PackageManager.PERMISSION_GRANTED;
 26    }
 27
 28    public static boolean s() {
 29        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
 30    }
 31
 32    public static boolean twentySix() {
 33        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
 34    }
 35
 36    public static boolean twentyEight() {
 37        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
 38    }
 39
 40    public static boolean thirtyFour() {
 41        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
 42    }
 43
 44    public static void startService(final Context context, final Intent intent) {
 45        try {
 46            if (Compatibility.twentySix()) {
 47                intent.putExtra(EXTRA_NEEDS_FOREGROUND_SERVICE, true);
 48                context.startForegroundService(intent);
 49            } else {
 50                context.startService(intent);
 51            }
 52        } catch (final RuntimeException e) {
 53            Log.d(
 54                    Config.LOGTAG,
 55                    context.getClass().getSimpleName() + " was unable to start service");
 56        }
 57    }
 58
 59    @SuppressLint("UnsupportedChromeOsCameraSystemFeature")
 60    public static boolean hasFeatureCamera(final Context context) {
 61        final PackageManager packageManager = context.getPackageManager();
 62        return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
 63    }
 64
 65    @RequiresApi(api = Build.VERSION_CODES.N)
 66    public static int getRestrictBackgroundStatus(
 67            @NonNull final ConnectivityManager connectivityManager) {
 68        try {
 69            return connectivityManager.getRestrictBackgroundStatus();
 70        } catch (final Exception e) {
 71            Log.d(
 72                    Config.LOGTAG,
 73                    "platform bug detected. Unable to get restrict background status",
 74                    e);
 75            return ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
 76        }
 77    }
 78
 79    @RequiresApi(api = Build.VERSION_CODES.N)
 80    public static boolean isActiveNetworkMetered(
 81            @NonNull final ConnectivityManager connectivityManager) {
 82        try {
 83            return connectivityManager.isActiveNetworkMetered();
 84        } catch (final RuntimeException e) {
 85            // when in doubt better assume it's metered
 86            return true;
 87        }
 88    }
 89
 90    public static Bundle pgpStartIntentSenderOptions() {
 91        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
 92            return ActivityOptions.makeBasic()
 93                    .setPendingIntentBackgroundActivityStartMode(
 94                            ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
 95                    .toBundle();
 96        } else {
 97            return null;
 98        }
 99    }
100}