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 void startService(final Context context, final Intent intent) {
41 try {
42 if (Compatibility.twentySix()) {
43 intent.putExtra(EXTRA_NEEDS_FOREGROUND_SERVICE, true);
44 context.startForegroundService(intent);
45 } else {
46 context.startService(intent);
47 }
48 } catch (final RuntimeException e) {
49 Log.d(
50 Config.LOGTAG,
51 context.getClass().getSimpleName() + " was unable to start service");
52 }
53 }
54
55 @SuppressLint("UnsupportedChromeOsCameraSystemFeature")
56 public static boolean hasFeatureCamera(final Context context) {
57 final PackageManager packageManager = context.getPackageManager();
58 return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
59 }
60
61 @RequiresApi(api = Build.VERSION_CODES.N)
62 public static int getRestrictBackgroundStatus(
63 @NonNull final ConnectivityManager connectivityManager) {
64 try {
65 return connectivityManager.getRestrictBackgroundStatus();
66 } catch (final Exception e) {
67 Log.d(
68 Config.LOGTAG,
69 "platform bug detected. Unable to get restrict background status",
70 e);
71 return ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
72 }
73 }
74
75 @RequiresApi(api = Build.VERSION_CODES.N)
76 public static boolean isActiveNetworkMetered(
77 @NonNull final ConnectivityManager connectivityManager) {
78 try {
79 return connectivityManager.isActiveNetworkMetered();
80 } catch (final RuntimeException e) {
81 // when in doubt better assume it's metered
82 return true;
83 }
84 }
85
86 public static Bundle pgpStartIntentSenderOptions() {
87 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
88 return ActivityOptions.makeBasic()
89 .setPendingIntentBackgroundActivityStartMode(
90 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
91 .toBundle();
92 } else {
93 return null;
94 }
95 }
96}