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 ContextCompat.startForegroundService(context, 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}