diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/AbstractDoNotKillMeFragment.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/AbstractDoNotKillMeFragment.java deleted file mode 100644 index 77ebbcebb870acef30f3bca562f2fb10bc1d865d..0000000000000000000000000000000000000000 --- a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/AbstractDoNotKillMeFragment.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.briarproject.android.dontkillmelib; - -import android.annotation.SuppressLint; -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ProgressBar; - -import org.briarproject.android.dontkillmelib.PowerView.OnCheckedChangedListener; - -import androidx.activity.result.ActivityResult; -import androidx.activity.result.ActivityResultCallback; -import androidx.activity.result.ActivityResultLauncher; -import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import static android.view.View.INVISIBLE; -import static android.view.View.VISIBLE; -import static org.briarproject.android.dontkillmelib.PowerUtils.getDozeWhitelistingIntent; -import static org.briarproject.android.dontkillmelib.PowerUtils.showOnboardingDialog; - -public abstract class AbstractDoNotKillMeFragment extends Fragment - implements OnCheckedChangedListener, - ActivityResultCallback<ActivityResult> { - - private DozeView dozeView; - private HuaweiProtectedAppsView huaweiProtectedAppsView; - private HuaweiAppLaunchView huaweiAppLaunchView; - private XiaomiView xiaomiView; - private Button next; - private boolean secondAttempt = false; - private boolean buttonWasClicked = false; - - private final ActivityResultLauncher<Intent> dozeLauncher = - registerForActivityResult(new StartActivityForResult(), this); - - @Override - public View onCreateView(LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - requireActivity().setTitle(getString(R.string.setup_doze_title)); - setHasOptionsMenu(false); - View v = inflater.inflate(R.layout.fragment_dont_kill_me, container, - false); - dozeView = v.findViewById(R.id.dozeView); - dozeView.setOnCheckedChangedListener(this); - huaweiProtectedAppsView = v.findViewById(R.id.huaweiProtectedAppsView); - huaweiProtectedAppsView.setOnCheckedChangedListener(this); - huaweiAppLaunchView = v.findViewById(R.id.huaweiAppLaunchView); - huaweiAppLaunchView.setOnCheckedChangedListener(this); - xiaomiView = v.findViewById(R.id.xiaomiView); - xiaomiView.setOnCheckedChangedListener(this); - next = v.findViewById(R.id.next); - ProgressBar progressBar = v.findViewById(R.id.progress); - - dozeView.setOnButtonClickListener(this::askForDozeWhitelisting); - next.setOnClickListener(view -> { - buttonWasClicked = true; - next.setVisibility(INVISIBLE); - progressBar.setVisibility(VISIBLE); - onButtonClicked(); - }); - - // restore UI state if button was clicked already - buttonWasClicked = savedInstanceState != null && - savedInstanceState.getBoolean("buttonWasClicked", false); - if (buttonWasClicked) { - next.setVisibility(INVISIBLE); - progressBar.setVisibility(VISIBLE); - } - - return v; - } - - protected abstract void onButtonClicked(); - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean("buttonWasClicked", buttonWasClicked); - } - - @Override - public void onActivityResult(ActivityResult result) { - // we allow the user to proceed after also denying the second attempt - if (!dozeView.needsToBeShown() || secondAttempt) { - dozeView.setChecked(true); - } else if (getContext() != null) { - secondAttempt = true; - String s = getString(R.string.setup_doze_explanation); - showOnboardingDialog(getContext(), s); - } - } - - @Override - public void onCheckedChanged() { - next.setEnabled(dozeView.isChecked() && - huaweiProtectedAppsView.isChecked() && - huaweiAppLaunchView.isChecked() && - xiaomiView.isChecked()); - } - - @SuppressLint("BatteryLife") - private void askForDozeWhitelisting() { - if (getContext() == null) return; - dozeLauncher.launch(getDozeWhitelistingIntent(getContext())); - } -} diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelperImpl.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelperImpl.java index 7a284b703ca2314bbd549008dd64d8da4fe72cef..d01e9583a7d9818f26d01a4db78b5ec2d628d926 100644 --- a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelperImpl.java +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelperImpl.java @@ -2,6 +2,9 @@ package org.briarproject.android.dontkillmelib; import android.content.Context; +import static org.briarproject.android.dontkillmelib.PowerUtils.huaweiAppLaunchNeedsToBeShown; +import static org.briarproject.android.dontkillmelib.PowerUtils.huaweiProtectedAppsNeedsToBeShown; +import static org.briarproject.android.dontkillmelib.PowerUtils.isXiaomiOrRedmiDevice; import static org.briarproject.android.dontkillmelib.PowerUtils.needsDozeWhitelisting; public class DozeHelperImpl implements DozeHelper { @@ -9,8 +12,8 @@ public class DozeHelperImpl implements DozeHelper { public boolean needToShowDoNotKillMeFragment(Context context) { Context appContext = context.getApplicationContext(); return needsDozeWhitelisting(appContext) || - HuaweiProtectedAppsView.needsToBeShown(appContext) || - HuaweiAppLaunchView.needsToBeShown(appContext) || - XiaomiView.isXiaomiOrRedmiDevice(); + huaweiProtectedAppsNeedsToBeShown(appContext) || + huaweiAppLaunchNeedsToBeShown(appContext) || + isXiaomiOrRedmiDevice(); } } diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeView.java deleted file mode 100644 index b9e87aea78c243f72fc2c86dd1a711d3661ac7fb..0000000000000000000000000000000000000000 --- a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeView.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.briarproject.android.dontkillmelib; - -import android.content.Context; -import android.util.AttributeSet; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; - -import static org.briarproject.android.dontkillmelib.PowerUtils.needsDozeWhitelisting; - -@UiThread -class DozeView extends PowerView { - - @Nullable - private Runnable onButtonClickListener; - - public DozeView(Context context) { - this(context, null); - } - - public DozeView(Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public DozeView(Context context, @Nullable AttributeSet attrs, - int defStyleAttr) { - super(context, attrs, defStyleAttr); - setText(R.string.setup_doze_intro); - setButtonText(R.string.setup_doze_button); - } - - @Override - public boolean needsToBeShown() { - return needsToBeShown(getContext()); - } - - public static boolean needsToBeShown(Context context) { - return needsDozeWhitelisting(context); - } - - @Override - protected int getHelpText() { - return R.string.setup_doze_explanation; - } - - @Override - protected void onButtonClick() { - if (onButtonClickListener == null) throw new IllegalStateException(); - onButtonClickListener.run(); - } - - public void setOnButtonClickListener(@NonNull Runnable runnable) { - onButtonClickListener = runnable; - } - -} diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiAppLaunchView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiAppLaunchView.java deleted file mode 100644 index 7a84c52aa3caf13d29efeea1839a977da8130024..0000000000000000000000000000000000000000 --- a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiAppLaunchView.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.briarproject.android.dontkillmelib; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.util.AttributeSet; - -import java.util.List; - -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.annotation.UiThread; - -import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; -import static android.os.Build.VERSION.SDK_INT; - -@UiThread -class HuaweiAppLaunchView extends PowerView { - - private final static String PACKAGE_NAME = "com.huawei.systemmanager"; - private final static String CLASS_NAME = - PACKAGE_NAME + ".power.ui.HwPowerManagerActivity"; - - public HuaweiAppLaunchView(Context context) { - this(context, null); - } - - public HuaweiAppLaunchView(Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public HuaweiAppLaunchView(Context context, @Nullable AttributeSet attrs, - int defStyleAttr) { - super(context, attrs, defStyleAttr); - setText(R.string.setup_huawei_app_launch_text); - setButtonText(R.string.setup_huawei_app_launch_button); - } - - @Override - public boolean needsToBeShown() { - return needsToBeShown(getContext()); - } - - public static boolean needsToBeShown(Context context) { - // "App launch" was introduced in EMUI 8 (Android 8.0) - if (SDK_INT < 26) return false; - PackageManager pm = context.getPackageManager(); - List<ResolveInfo> resolveInfos = pm.queryIntentActivities(getIntent(), - MATCH_DEFAULT_ONLY); - return !resolveInfos.isEmpty(); - } - - @Override - @StringRes - protected int getHelpText() { - return R.string.setup_huawei_app_launch_help; - } - - @Override - protected void onButtonClick() { - getContext().startActivity(getIntent()); - setChecked(true); - } - - private static Intent getIntent() { - Intent intent = new Intent(); - intent.setClassName(PACKAGE_NAME, CLASS_NAME); - return intent; - } - -} diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiProtectedAppsView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiProtectedAppsView.java deleted file mode 100644 index 3d63bed36549fb5a93167ccd0fcebbee50354bc6..0000000000000000000000000000000000000000 --- a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiProtectedAppsView.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.briarproject.android.dontkillmelib; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.util.AttributeSet; - -import java.util.List; - -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.annotation.UiThread; - -import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; -import static android.os.Build.VERSION.SDK_INT; - -@UiThread -class HuaweiProtectedAppsView extends PowerView { - - private final static String PACKAGE_NAME = "com.huawei.systemmanager"; - private final static String CLASS_NAME = - PACKAGE_NAME + ".optimize.process.ProtectActivity"; - - public HuaweiProtectedAppsView(Context context) { - this(context, null); - } - - public HuaweiProtectedAppsView(Context context, - @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public HuaweiProtectedAppsView(Context context, - @Nullable AttributeSet attrs, - int defStyleAttr) { - super(context, attrs, defStyleAttr); - setText(R.string.setup_huawei_text); - setButtonText(R.string.setup_huawei_button); - } - - @Override - public boolean needsToBeShown() { - return needsToBeShown(getContext()); - } - - public static boolean needsToBeShown(Context context) { - // "Protected apps" no longer exists on Huawei EMUI 5.0 (Android 7.0) - if (SDK_INT >= 24) return false; - PackageManager pm = context.getPackageManager(); - List<ResolveInfo> resolveInfos = pm.queryIntentActivities(getIntent(), - MATCH_DEFAULT_ONLY); - return !resolveInfos.isEmpty(); - } - - @Override - @StringRes - protected int getHelpText() { - return R.string.setup_huawei_help; - } - - @Override - protected void onButtonClick() { - getContext().startActivity(getIntent()); - setChecked(true); - } - - private static Intent getIntent() { - Intent intent = new Intent(); - intent.setClassName(PACKAGE_NAME, CLASS_NAME); - return intent; - } - -} diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerUtils.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerUtils.java index ba5892df35dbdb530b8306ba5fc0084797656710..361d04000da1a66e90970bb187ec93d1741d07ba 100644 --- a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerUtils.java +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerUtils.java @@ -4,22 +4,34 @@ import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.PowerManager; import java.io.IOException; +import java.util.List; import java.util.Scanner; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import static android.content.Context.POWER_SERVICE; +import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; +import static android.os.Build.BRAND; import static android.os.Build.VERSION.SDK_INT; import static android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS; import static java.lang.Runtime.getRuntime; public class PowerUtils { + private final static String PACKAGE_NAME_HUAWEI = + "com.huawei.systemmanager"; + private final static String CLASS_NAME_POWER_MANAGER = + PACKAGE_NAME_HUAWEI + ".power.ui.HwPowerManagerActivity"; + private final static String CLASS_NAME_PROTECTED_APPS = + PACKAGE_NAME_HUAWEI + ".optimize.process.ProtectActivity"; + public static boolean needsDozeWhitelisting(Context ctx) { if (SDK_INT < 23) return false; PowerManager pm = (PowerManager) ctx.getSystemService(POWER_SERVICE); @@ -45,8 +57,64 @@ public class PowerUtils { .show(); } + /** + * Determine whether a Huawei "Protected apps" feature is available on the + * device. + */ + public static boolean huaweiAppLaunchNeedsToBeShown(Context context) { + // "App launch" was introduced in EMUI 8 (Android 8.0) + if (SDK_INT < 26) return false; + PackageManager pm = context.getPackageManager(); + List<ResolveInfo> resolveInfos = + pm.queryIntentActivities(getHuaweiProtectedAppsIntent(), + MATCH_DEFAULT_ONLY); + return !resolveInfos.isEmpty(); + } + + /** + * Determine whether a Huawei "Protected apps" feature is available on the + * device. + */ + public static boolean huaweiProtectedAppsNeedsToBeShown(Context context) { + // "Protected apps" no longer exists on Huawei EMUI 5.0 (Android 7.0) + if (SDK_INT >= 24) return false; + PackageManager pm = context.getPackageManager(); + List<ResolveInfo> resolveInfos = pm.queryIntentActivities( + getHuaweiPowerManagerIntent(), + MATCH_DEFAULT_ONLY); + return !resolveInfos.isEmpty(); + } + + public static Intent getHuaweiPowerManagerIntent() { + Intent intent = new Intent(); + intent.setClassName(PACKAGE_NAME_HUAWEI, CLASS_NAME_POWER_MANAGER); + return intent; + } + + public static Intent getHuaweiProtectedAppsIntent() { + Intent intent = new Intent(); + intent.setClassName(PACKAGE_NAME_HUAWEI, CLASS_NAME_PROTECTED_APPS); + return intent; + } + + public static boolean isXiaomiOrRedmiDevice() { + return "Xiaomi".equalsIgnoreCase(BRAND) || + "Redmi".equalsIgnoreCase(BRAND); + } + + public static boolean isMiuiTenOrLater() { + String version = getSystemProperty("ro.miui.ui.version.name"); + if (version == null || version.equals("")) return false; + version = version.replaceAll("[^\\d]", ""); + try { + return Integer.parseInt(version) >= 10; + } catch (NumberFormatException e) { + return false; + } + } + @Nullable - public static String getSystemProperty(String propName) { + private static String getSystemProperty(String propName) { try { Process p = getRuntime().exec("getprop " + propName); Scanner s = new Scanner(p.getInputStream()); diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerView.java deleted file mode 100644 index 8144e7cbeef93fef95ab18dee5d4779f4eb5cce5..0000000000000000000000000000000000000000 --- a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerView.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.briarproject.android.dontkillmelib; - -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.Button; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.annotation.UiThread; -import androidx.constraintlayout.widget.ConstraintLayout; - -import static android.content.Context.LAYOUT_INFLATER_SERVICE; -import static org.briarproject.android.dontkillmelib.PowerUtils.showOnboardingDialog; - -@UiThread -abstract class PowerView extends ConstraintLayout { - - private final TextView textView; - private final ImageView checkImage; - private final Button button; - - private boolean checked = false; - - @Nullable - private OnCheckedChangedListener onCheckedChangedListener; - - public PowerView(Context context) { - this(context, null); - } - - public PowerView(Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public PowerView(Context context, @Nullable AttributeSet attrs, - int defStyleAttr) { - super(context, attrs, defStyleAttr); - - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(LAYOUT_INFLATER_SERVICE); - View v = inflater.inflate(R.layout.power_view, this, true); - - textView = v.findViewById(R.id.textView); - checkImage = v.findViewById(R.id.checkImage); - button = v.findViewById(R.id.button); - button.setOnClickListener(view -> onButtonClick()); - ImageButton helpButton = v.findViewById(R.id.helpButton); - helpButton.setOnClickListener(view -> onHelpButtonClick()); - - // we need to manage the checkImage state ourselves, because automatic - // state saving is done based on the view's ID and there can be - // multiple ImageViews with the same ID in the view hierarchy - setSaveFromParentEnabled(true); - - if (!isInEditMode() && !needsToBeShown()) { - setVisibility(GONE); - } - } - - @Nullable - @Override - protected Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.value = new boolean[] {checked}; - return ss; - } - - @Override - protected void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - setChecked(ss.value[0]); // also calls listener - } - - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - public abstract boolean needsToBeShown(); - - public void setChecked(boolean checked) { - this.checked = checked; - if (checked) { - checkImage.setVisibility(VISIBLE); - } else { - checkImage.setVisibility(INVISIBLE); - } - if (onCheckedChangedListener != null) { - onCheckedChangedListener.onCheckedChanged(); - } - } - - public boolean isChecked() { - return getVisibility() == GONE || checked; - } - - public void setOnCheckedChangedListener(@NonNull - OnCheckedChangedListener onCheckedChangedListener) { - this.onCheckedChangedListener = onCheckedChangedListener; - } - - @StringRes - protected abstract int getHelpText(); - - protected void setText(@StringRes int res) { - textView.setText(res); - } - - protected void setButtonText(@StringRes int res) { - button.setText(res); - } - - protected abstract void onButtonClick(); - - private void onHelpButtonClick() { - showOnboardingDialog(getContext(), - getContext().getString(getHelpText())); - } - - private static class SavedState extends BaseSavedState { - private boolean[] value = {false}; - - private SavedState(@Nullable Parcelable superState) { - super(superState); - } - - private SavedState(Parcel in) { - super(in); - in.readBooleanArray(value); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeBooleanArray(value); - } - - static final Parcelable.Creator<SavedState> CREATOR - = new Parcelable.Creator<SavedState>() { - @Override - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - @Override - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - interface OnCheckedChangedListener { - void onCheckedChanged(); - } - -} diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/XiaomiView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/XiaomiView.java deleted file mode 100644 index 0233b1ad24a71b1a7f173fcc0c8c4dad8a9fdb70..0000000000000000000000000000000000000000 --- a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/XiaomiView.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.briarproject.android.dontkillmelib; - -import android.content.Context; -import android.util.AttributeSet; - -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.annotation.UiThread; - -import static android.os.Build.BRAND; -import static org.briarproject.android.dontkillmelib.PowerUtils.getSystemProperty; -import static org.briarproject.android.dontkillmelib.PowerUtils.showOnboardingDialog; - -@UiThread -class XiaomiView extends PowerView { - - public XiaomiView(Context context) { - this(context, null); - } - - public XiaomiView(Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public XiaomiView(Context context, @Nullable AttributeSet attrs, - int defStyleAttr) { - super(context, attrs, defStyleAttr); - setText(R.string.setup_xiaomi_text); - setButtonText(R.string.setup_xiaomi_button); - } - - @Override - public boolean needsToBeShown() { - return isXiaomiOrRedmiDevice(); - } - - public static boolean isXiaomiOrRedmiDevice() { - return "Xiaomi".equalsIgnoreCase(BRAND) || - "Redmi".equalsIgnoreCase(BRAND); - } - - @Override - @StringRes - protected int getHelpText() { - return R.string.setup_xiaomi_help; - } - - @Override - protected void onButtonClick() { - int bodyRes = isMiuiTenOrLater() - ? R.string.setup_xiaomi_dialog_body_new - : R.string.setup_xiaomi_dialog_body_old; - showOnboardingDialog(getContext(), getContext().getString(bodyRes)); - setChecked(true); - } - - private boolean isMiuiTenOrLater() { - String version = getSystemProperty("ro.miui.ui.version.name"); - if (version == null || version.equals("")) return false; - version = version.replaceAll("[^\\d]", ""); - try { - return Integer.parseInt(version) >= 10; - } catch (NumberFormatException e) { - return false; - } - } -} diff --git a/dont-kill-me-lib/src/main/res/layout/fragment_dont_kill_me.xml b/dont-kill-me-lib/src/main/res/layout/fragment_dont_kill_me.xml deleted file mode 100644 index 9e04975d6fe6c15bbddc3714ce90aa79abdfb740..0000000000000000000000000000000000000000 --- a/dont-kill-me-lib/src/main/res/layout/fragment_dont_kill_me.xml +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:fillViewport="true"> - - <androidx.constraintlayout.widget.ConstraintLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:padding="16dp"> - - <org.briarproject.android.dontkillmelib.DozeView - android:id="@+id/dozeView" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingBottom="16dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <org.briarproject.android.dontkillmelib.HuaweiProtectedAppsView - android:id="@+id/huaweiProtectedAppsView" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingBottom="16dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/dozeView" /> - - <org.briarproject.android.dontkillmelib.HuaweiAppLaunchView - android:id="@+id/huaweiAppLaunchView" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingBottom="16dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/huaweiProtectedAppsView" /> - - <org.briarproject.android.dontkillmelib.XiaomiView - android:id="@+id/xiaomiView" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingBottom="16dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/huaweiAppLaunchView" /> - - <Button - android:id="@+id/next" - style="@style/DoNotKillMeButton" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:enabled="false" - android:text="@string/create_account_button" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/xiaomiView" - app:layout_constraintVertical_bias="1.0" - tools:enabled="true" /> - - <ProgressBar - android:id="@+id/progress" - style="?android:attr/progressBarStyle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:visibility="invisible" - app:layout_constraintBottom_toBottomOf="@+id/next" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="@+id/next" /> - - </androidx.constraintlayout.widget.ConstraintLayout> - -</ScrollView> diff --git a/dont-kill-me-lib/src/main/res/layout/power_view.xml b/dont-kill-me-lib/src/main/res/layout/power_view.xml deleted file mode 100644 index 11a95e95569bbde6e673b5acf2349a75c5a01c7f..0000000000000000000000000000000000000000 --- a/dont-kill-me-lib/src/main/res/layout/power_view.xml +++ /dev/null @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="wrap_content" - tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> - - <TextView - android:id="@+id/textView" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginLeft="16dp" - android:layout_marginTop="16dp" - android:layout_marginEnd="16dp" - android:layout_marginRight="16dp" - android:textSize="16sp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - tools:text="@string/setup_huawei_text" /> - - <androidx.appcompat.widget.AppCompatImageView - android:id="@+id/checkImage" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_margin="8dp" - android:visibility="invisible" - app:layout_constraintBottom_toBottomOf="@+id/button" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="@+id/button" - app:srcCompat="@drawable/ic_check_white" - app:tint="?attr/colorControlNormal" - tools:ignore="ContentDescription" /> - - <Button - android:id="@+id/button" - style="@style/DoNotKillMeButton" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_margin="8dp" - app:layout_constraintEnd_toStartOf="@+id/helpButton" - app:layout_constraintStart_toEndOf="@+id/checkImage" - app:layout_constraintTop_toBottomOf="@+id/textView" - tools:text="@string/setup_huawei_button" /> - - <ImageButton - android:id="@+id/helpButton" - style="@style/HelpButton" - android:layout_width="48dp" - android:layout_height="48dp" - android:background="?attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/help" - app:layout_constraintBottom_toBottomOf="@+id/button" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="@+id/button" - app:srcCompat="@drawable/ic_help_outline_white" /> - -</merge> diff --git a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/AbstractDoNotKillMeFragment.java b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/AbstractDoNotKillMeFragment.java index 591b0a82dd0ba559c6a8e7eeae8b07597e1c36dc..7bdd35e8dbc7d6921fce460993410589263b6546 100644 --- a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/AbstractDoNotKillMeFragment.java +++ b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/AbstractDoNotKillMeFragment.java @@ -44,28 +44,20 @@ public abstract class AbstractDoNotKillMeFragment extends Fragment public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - requireActivity().setTitle(getString( - org.briarproject.android.dontkillmelib.R.string.setup_doze_title)); + requireActivity().setTitle(getString(R.string.setup_doze_title)); setHasOptionsMenu(false); - View v = inflater.inflate( - R.layout.fragment_dont_kill_me2, - container, + View v = inflater.inflate(R.layout.fragment_dont_kill_me, container, false); - dozeView = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.dozeView); + dozeView = v.findViewById(R.id.dozeView); dozeView.setOnCheckedChangedListener(this); - huaweiProtectedAppsView = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.huaweiProtectedAppsView); + huaweiProtectedAppsView = v.findViewById(R.id.huaweiProtectedAppsView); huaweiProtectedAppsView.setOnCheckedChangedListener(this); - huaweiAppLaunchView = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.huaweiAppLaunchView); + huaweiAppLaunchView = v.findViewById(R.id.huaweiAppLaunchView); huaweiAppLaunchView.setOnCheckedChangedListener(this); - xiaomiView = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.xiaomiView); + xiaomiView = v.findViewById(R.id.xiaomiView); xiaomiView.setOnCheckedChangedListener(this); - next = v.findViewById(org.briarproject.android.dontkillmelib.R.id.next); - ProgressBar progressBar = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.progress); + next = v.findViewById(R.id.next); + ProgressBar progressBar = v.findViewById(R.id.progress); dozeView.setOnButtonClickListener(this::askForDozeWhitelisting); next.setOnClickListener(view -> { diff --git a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/HuaweiAppLaunchView.java b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/HuaweiAppLaunchView.java index feb93b21e664f06c7e6c611f5e1672a3e401192d..0b5e3b2c83308a70034425e7320f495cd7b33e1c 100644 --- a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/HuaweiAppLaunchView.java +++ b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/HuaweiAppLaunchView.java @@ -1,29 +1,20 @@ package org.briarproject.mailbox.android.dontkillme; import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.util.AttributeSet; import org.briarproject.mailbox.R; -import java.util.List; - import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.UiThread; -import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; -import static android.os.Build.VERSION.SDK_INT; +import static org.briarproject.android.dontkillmelib.PowerUtils.getHuaweiPowerManagerIntent; +import static org.briarproject.android.dontkillmelib.PowerUtils.huaweiAppLaunchNeedsToBeShown; @UiThread public class HuaweiAppLaunchView extends PowerView { - private final static String PACKAGE_NAME = "com.huawei.systemmanager"; - private final static String CLASS_NAME = - PACKAGE_NAME + ".power.ui.HwPowerManagerActivity"; - public HuaweiAppLaunchView(Context context) { this(context, null); } @@ -43,17 +34,7 @@ public class HuaweiAppLaunchView extends PowerView { @Override public boolean needsToBeShown() { - return needsToBeShown(getContext()); - } - - public static boolean needsToBeShown(Context context) { - // "App launch" was introduced in EMUI 8 (Android 8.0) - if (1 == 1) return true; - if (SDK_INT < 26) return false; - PackageManager pm = context.getPackageManager(); - List<ResolveInfo> resolveInfos = pm.queryIntentActivities(getIntent(), - MATCH_DEFAULT_ONLY); - return !resolveInfos.isEmpty(); + return huaweiAppLaunchNeedsToBeShown(getContext()); } @Override @@ -64,14 +45,8 @@ public class HuaweiAppLaunchView extends PowerView { @Override protected void onButtonClick() { - getContext().startActivity(getIntent()); + getContext().startActivity(getHuaweiPowerManagerIntent()); setChecked(true); } - private static Intent getIntent() { - Intent intent = new Intent(); - intent.setClassName(PACKAGE_NAME, CLASS_NAME); - return intent; - } - } diff --git a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/HuaweiProtectedAppsView.java b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/HuaweiProtectedAppsView.java index b7f6c03a0ded08f6c4fd6a911d2186de019c4524..e218dc05eb809dcc4ec1ff71f1aaccac19cb7acb 100644 --- a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/HuaweiProtectedAppsView.java +++ b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/HuaweiProtectedAppsView.java @@ -1,27 +1,19 @@ package org.briarproject.mailbox.android.dontkillme; import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.util.AttributeSet; -import java.util.List; +import org.briarproject.android.dontkillmelib.PowerUtils; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.UiThread; -import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; -import static android.os.Build.VERSION.SDK_INT; +import static org.briarproject.android.dontkillmelib.PowerUtils.getHuaweiProtectedAppsIntent; @UiThread public class HuaweiProtectedAppsView extends PowerView { - private final static String PACKAGE_NAME = "com.huawei.systemmanager"; - private final static String CLASS_NAME = - PACKAGE_NAME + ".optimize.process.ProtectActivity"; - public HuaweiProtectedAppsView(Context context) { this(context, null); } @@ -42,16 +34,7 @@ public class HuaweiProtectedAppsView extends PowerView { @Override public boolean needsToBeShown() { - return needsToBeShown(getContext()); - } - - public static boolean needsToBeShown(Context context) { - // "Protected apps" no longer exists on Huawei EMUI 5.0 (Android 7.0) - if (SDK_INT >= 24) return false; - PackageManager pm = context.getPackageManager(); - List<ResolveInfo> resolveInfos = pm.queryIntentActivities(getIntent(), - MATCH_DEFAULT_ONLY); - return !resolveInfos.isEmpty(); + return PowerUtils.huaweiProtectedAppsNeedsToBeShown(getContext()); } @Override @@ -62,14 +45,8 @@ public class HuaweiProtectedAppsView extends PowerView { @Override protected void onButtonClick() { - getContext().startActivity(getIntent()); + getContext().startActivity(getHuaweiProtectedAppsIntent()); setChecked(true); } - private static Intent getIntent() { - Intent intent = new Intent(); - intent.setClassName(PACKAGE_NAME, CLASS_NAME); - return intent; - } - } diff --git a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/PowerView.java b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/PowerView.java index 6cb99eeef605d3b9ce81fa1492cbff001aae9259..47e0864f7375148c1a500fd48dfb7186ec683bb5 100644 --- a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/PowerView.java +++ b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/PowerView.java @@ -51,18 +51,14 @@ abstract class PowerView extends ConstraintLayout { LayoutInflater inflater = (LayoutInflater) context .getSystemService(LAYOUT_INFLATER_SERVICE); - View v = inflater.inflate(R.layout.power_view2, this, true); - - textView = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.textView); - icon = v.findViewById(org.briarproject.android.dontkillmelib.R.id.icon); - checkImage = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.checkImage); - button = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.button); + View v = inflater.inflate(R.layout.power_view, this, true); + + textView = v.findViewById(R.id.textView); + icon = v.findViewById(R.id.icon); + checkImage = v.findViewById(R.id.checkImage); + button = v.findViewById(R.id.button); button.setOnClickListener(view -> onButtonClick()); - ImageButton helpButton = v.findViewById( - org.briarproject.android.dontkillmelib.R.id.helpButton); + ImageButton helpButton = v.findViewById(R.id.helpButton); helpButton.setOnClickListener(view -> onHelpButtonClick()); // we need to manage the checkImage state ourselves, because automatic diff --git a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/XiaomiView.java b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/XiaomiView.java index 25545050bad0c36b772f6cff5da1fe30993bc903..d48aa9851b8fafe8e9d70eec3c40a0be41ca8814 100644 --- a/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/XiaomiView.java +++ b/mailbox-android/src/main/java/org/briarproject/mailbox/android/dontkillme/XiaomiView.java @@ -7,8 +7,8 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.UiThread; -import static android.os.Build.BRAND; -import static org.briarproject.android.dontkillmelib.PowerUtils.getSystemProperty; +import static org.briarproject.android.dontkillmelib.PowerUtils.isMiuiTenOrLater; +import static org.briarproject.android.dontkillmelib.PowerUtils.isXiaomiOrRedmiDevice; import static org.briarproject.android.dontkillmelib.PowerUtils.showOnboardingDialog; @UiThread @@ -35,11 +35,6 @@ public class XiaomiView extends PowerView { return isXiaomiOrRedmiDevice(); } - public static boolean isXiaomiOrRedmiDevice() { - return "Xiaomi".equalsIgnoreCase(BRAND) || - "Redmi".equalsIgnoreCase(BRAND); - } - @Override @StringRes protected int getHelpText() { @@ -56,15 +51,4 @@ public class XiaomiView extends PowerView { showOnboardingDialog(getContext(), getContext().getString(bodyRes)); setChecked(true); } - - private boolean isMiuiTenOrLater() { - String version = getSystemProperty("ro.miui.ui.version.name"); - if (version == null || version.equals("")) return false; - version = version.replaceAll("[^\\d]", ""); - try { - return Integer.parseInt(version) >= 10; - } catch (NumberFormatException e) { - return false; - } - } } diff --git a/mailbox-android/src/main/res/layout/fragment_dont_kill_me2.xml b/mailbox-android/src/main/res/layout/fragment_dont_kill_me.xml similarity index 100% rename from mailbox-android/src/main/res/layout/fragment_dont_kill_me2.xml rename to mailbox-android/src/main/res/layout/fragment_dont_kill_me.xml diff --git a/mailbox-android/src/main/res/layout/power_view2.xml b/mailbox-android/src/main/res/layout/power_view.xml similarity index 100% rename from mailbox-android/src/main/res/layout/power_view2.xml rename to mailbox-android/src/main/res/layout/power_view.xml