From a1c5bf17cacf194de28b5f0fb774e28998c63819 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 26 Oct 2021 15:58:32 -0300 Subject: [PATCH] Factor out power management UI code into library --- briar-android/build.gradle | 7 +- .../briar/android/PromoVideoTest.java | 2 +- .../briar/android/SetupDataTest.java | 2 +- briar-android/src/main/AndroidManifest.xml | 4 - .../briar/android/AndroidComponent.java | 3 + .../briar/android/DozeWatchdogImpl.java | 49 +------- .../android/account/DoNotKillMeFragment.java | 38 ++++++ .../briar/android/account/DozeFragment.java | 119 ------------------ .../briar/android/account/DozeHelper.java | 8 -- .../android/account/DozeHelperModule.java | 3 + .../briar/android/account/SetupActivity.java | 8 +- .../briar/android/account/SetupViewModel.java | 3 +- .../briar/android/activity/BriarActivity.java | 2 +- .../controller/BriarControllerImpl.java | 2 +- .../android/navdrawer/NavDrawerViewModel.java | 2 +- .../briar/android/util/UiUtils.java | 22 ---- .../res/layout/activity_rss_feed_manage.xml | 10 -- briar-android/src/main/res/values/styles.xml | 6 + .../android/account/SetupViewModelTest.java | 3 +- build.gradle | 4 + dont-kill-me-lib/.gitignore | 1 + dont-kill-me-lib/build.gradle | 32 +++++ dont-kill-me-lib/consumer-rules.pro | 0 dont-kill-me-lib/proguard-rules.pro | 21 ++++ dont-kill-me-lib/src/main/AndroidManifest.xml | 13 ++ .../AbstractDoNotKillMeFragment.java | 115 +++++++++++++++++ .../AbstractDozeWatchdogImpl.java | 49 ++++++++ .../android/dontkillmelib/DozeHelper.java | 7 ++ .../dontkillmelib}/DozeHelperImpl.java | 8 +- .../android/dontkillmelib}/DozeView.java | 8 +- .../dontkillmelib}/HuaweiAppLaunchView.java | 9 +- .../HuaweiProtectedAppsView.java | 9 +- .../android/dontkillmelib/PowerUtils.java | 60 +++++++++ .../android/dontkillmelib}/PowerView.java | 8 +- .../android/dontkillmelib}/XiaomiView.java | 16 +-- .../src/main/res/drawable/ic_check_white.xml | 9 ++ .../res/drawable/ic_help_outline_white.xml | 9 ++ .../main/res/layout/fragment_dont_kill_me.xml | 20 +-- .../src/main/res/layout/power_view.xml | 29 +++-- .../src/main/res/values/strings.xml | 29 +++++ .../src/main/res/values/styles.xml | 12 ++ settings.gradle | 1 + 42 files changed, 477 insertions(+), 285 deletions(-) create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/account/DoNotKillMeFragment.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/account/DozeFragment.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelper.java delete mode 100644 briar-android/src/main/res/layout/activity_rss_feed_manage.xml create mode 100644 dont-kill-me-lib/.gitignore create mode 100644 dont-kill-me-lib/build.gradle create mode 100644 dont-kill-me-lib/consumer-rules.pro create mode 100644 dont-kill-me-lib/proguard-rules.pro create mode 100644 dont-kill-me-lib/src/main/AndroidManifest.xml create mode 100644 dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/AbstractDoNotKillMeFragment.java create mode 100644 dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/AbstractDozeWatchdogImpl.java create mode 100644 dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelper.java rename {briar-android/src/main/java/org/briarproject/briar/android/account => dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib}/DozeHelperImpl.java (54%) rename {briar-android/src/main/java/org/briarproject/briar/android/account => dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib}/DozeView.java (82%) rename {briar-android/src/main/java/org/briarproject/briar/android/account => dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib}/HuaweiAppLaunchView.java (90%) rename {briar-android/src/main/java/org/briarproject/briar/android/account => dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib}/HuaweiProtectedAppsView.java (90%) create mode 100644 dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerUtils.java rename {briar-android/src/main/java/org/briarproject/briar/android/account => dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib}/PowerView.java (94%) rename {briar-android/src/main/java/org/briarproject/briar/android/account => dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib}/XiaomiView.java (75%) create mode 100644 dont-kill-me-lib/src/main/res/drawable/ic_check_white.xml create mode 100644 dont-kill-me-lib/src/main/res/drawable/ic_help_outline_white.xml rename briar-android/src/main/res/layout/fragment_setup_doze.xml => dont-kill-me-lib/src/main/res/layout/fragment_dont_kill_me.xml (83%) rename {briar-android => dont-kill-me-lib}/src/main/res/layout/power_view.xml (72%) create mode 100644 dont-kill-me-lib/src/main/res/values/strings.xml create mode 100644 dont-kill-me-lib/src/main/res/values/styles.xml diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 98072b273..caaf93c34 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -99,13 +99,14 @@ dependencies { implementation project(path: ':briar-core', configuration: 'default') implementation project(path: ':bramble-core', configuration: 'default') implementation project(':bramble-android') + implementation project(':dont-kill-me-lib') - implementation 'androidx.fragment:fragment:1.3.4' + implementation "androidx.fragment:fragment:$androidx_fragment_version" implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.exifinterface:exifinterface:1.3.2' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' - implementation 'com.google.android.material:material:1.3.0' + implementation "androidx.constraintlayout:constraintlayout:$androidx_constraintlayout_version" + implementation "com.google.android.material:material:$google_material_version" implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' implementation 'info.guardianproject.panic:panic:1.0' diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/PromoVideoTest.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/PromoVideoTest.java index 6b808c5d1..1824c3245 100644 --- a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/PromoVideoTest.java +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/PromoVideoTest.java @@ -39,11 +39,11 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static java.lang.Thread.sleep; +import static org.briarproject.android.dontkillmelib.PowerUtils.needsDozeWhitelisting; import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID; import static org.briarproject.briar.android.OverlayTapViewAction.visualClick; import static org.briarproject.briar.android.ViewActions.waitFor; import static org.briarproject.briar.android.ViewActions.waitUntilMatches; -import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; import static org.hamcrest.CoreMatchers.allOf; import static org.junit.Assert.assertTrue; diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/SetupDataTest.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/SetupDataTest.java index b0d3f6a4d..c61462d8a 100644 --- a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/SetupDataTest.java +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/SetupDataTest.java @@ -26,9 +26,9 @@ import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; +import static org.briarproject.android.dontkillmelib.PowerUtils.needsDozeWhitelisting; import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID; import static org.briarproject.briar.android.ViewActions.waitUntilMatches; -import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; import static org.hamcrest.Matchers.allOf; import static org.junit.Assert.assertTrue; diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index 27956ce43..b9e709d1e 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -34,7 +34,6 @@ tools:ignore="ScopedStorage" /> - @@ -477,9 +476,6 @@ - - - diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java index 42d6570e2..c2cb4eca6 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java @@ -33,6 +33,7 @@ import org.briarproject.bramble.plugin.tor.CircumventionProvider; import org.briarproject.bramble.system.ClockModule; import org.briarproject.briar.BriarCoreEagerSingletons; import org.briarproject.briar.BriarCoreModule; +import org.briarproject.briar.android.account.DoNotKillMeFragment; import org.briarproject.briar.android.attachment.AttachmentModule; import org.briarproject.briar.android.attachment.media.MediaModule; import org.briarproject.briar.android.contact.connect.BluetoothIntroFragment; @@ -239,4 +240,6 @@ public interface AndroidComponent void inject(ReceiveFragment receiveFragment); void inject(BluetoothIntroFragment bluetoothIntroFragment); + + void inject(DoNotKillMeFragment dozeFragment); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java index e6cf8e227..b6a39eb10 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java @@ -1,57 +1,16 @@ package org.briarproject.briar.android; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.PowerManager; +import org.briarproject.android.dontkillmelib.AbstractDozeWatchdogImpl; import org.briarproject.bramble.api.lifecycle.Service; -import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.briar.api.android.DozeWatchdog; -import java.util.concurrent.atomic.AtomicBoolean; - -import static android.content.Context.POWER_SERVICE; -import static android.os.Build.VERSION.SDK_INT; -import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED; - -class DozeWatchdogImpl implements DozeWatchdog, Service { - - private final Context appContext; - private final AtomicBoolean dozed = new AtomicBoolean(false); - private final BroadcastReceiver receiver = new DozeBroadcastReceiver(); +class DozeWatchdogImpl extends AbstractDozeWatchdogImpl + implements DozeWatchdog, Service { DozeWatchdogImpl(Context appContext) { - this.appContext = appContext; + super(appContext); } - @Override - public boolean getAndResetDozeFlag() { - return dozed.getAndSet(false); - } - - @Override - public void startService() throws ServiceException { - if (SDK_INT < 23) return; - IntentFilter filter = new IntentFilter(ACTION_DEVICE_IDLE_MODE_CHANGED); - appContext.registerReceiver(receiver, filter); - } - - @Override - public void stopService() throws ServiceException { - if (SDK_INT < 23) return; - appContext.unregisterReceiver(receiver); - } - - private class DozeBroadcastReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - if (SDK_INT < 23) return; - PowerManager pm = - (PowerManager) appContext.getSystemService(POWER_SERVICE); - if (pm.isDeviceIdleMode()) dozed.set(true); - } - } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/DoNotKillMeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/account/DoNotKillMeFragment.java new file mode 100644 index 000000000..29d7fdd76 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/DoNotKillMeFragment.java @@ -0,0 +1,38 @@ +package org.briarproject.briar.android.account; + +import android.content.Context; + +import org.briarproject.android.dontkillmelib.AbstractDoNotKillMeFragment; +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; + +import javax.inject.Inject; + +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; + +import static org.briarproject.briar.android.AppModule.getAndroidComponent; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class DoNotKillMeFragment extends AbstractDoNotKillMeFragment { + + @Inject + ViewModelProvider.Factory viewModelFactory; + SetupViewModel viewModel; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + FragmentActivity activity = requireActivity(); + getAndroidComponent(activity).inject(this); + viewModel = new ViewModelProvider(activity, viewModelFactory) + .get(SetupViewModel.class); + } + + @Override + protected void onButtonClicked() { + viewModel.dozeExceptionConfirmed(); + } + +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/account/DozeFragment.java deleted file mode 100644 index 5f5706632..000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeFragment.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.briarproject.briar.android.account; - -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.bramble.api.nullsafety.MethodsNotNullByDefault; -import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; -import org.briarproject.briar.R; -import org.briarproject.briar.android.account.PowerView.OnCheckedChangedListener; -import org.briarproject.briar.android.util.UiUtils; - -import androidx.annotation.Nullable; - -import static android.view.View.INVISIBLE; -import static android.view.View.VISIBLE; -import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING; -import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog; - -@MethodsNotNullByDefault -@ParametersNotNullByDefault -public class DozeFragment extends SetupFragment - implements OnCheckedChangedListener { - - private final static String TAG = DozeFragment.class.getName(); - - private DozeView dozeView; - private HuaweiProtectedAppsView huaweiProtectedAppsView; - private HuaweiAppLaunchView huaweiAppLaunchView; - private XiaomiView xiaomiView; - private Button next; - private boolean secondAttempt = false; - - public static DozeFragment newInstance() { - return new DozeFragment(); - } - - @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_setup_doze, 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(this); - - viewModel.getIsCreatingAccount() - .observe(getViewLifecycleOwner(), isCreatingAccount -> { - if (isCreatingAccount) { - next.setVisibility(INVISIBLE); - progressBar.setVisibility(VISIBLE); - } - }); - - return v; - } - - @Override - public String getUniqueTag() { - return TAG; - } - - @Override - protected String getHelpText() { - return getString(R.string.setup_doze_explanation); - } - - @Override - public void onActivityResult(int request, int result, - @Nullable Intent data) { - super.onActivityResult(request, result, data); - if (request == REQUEST_DOZE_WHITELISTING) { - if (!dozeView.needsToBeShown() || secondAttempt) { - dozeView.setChecked(true); - } else if (getContext() != null) { - secondAttempt = true; - showOnboardingDialog(getContext(), getHelpText()); - } - } - } - - @Override - public void onCheckedChanged() { - next.setEnabled(dozeView.isChecked() && - huaweiProtectedAppsView.isChecked() && - huaweiAppLaunchView.isChecked() && - xiaomiView.isChecked()); - } - - @SuppressLint("BatteryLife") - private void askForDozeWhitelisting() { - if (getContext() == null) return; - Intent i = UiUtils.getDozeWhitelistingIntent(getContext()); - startActivityForResult(i, REQUEST_DOZE_WHITELISTING); - } - - @Override - public void onClick(View view) { - viewModel.dozeExceptionConfirmed(); - } -} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelper.java b/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelper.java deleted file mode 100644 index f56431488..000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelper.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.briarproject.briar.android.account; - -import android.content.Context; - -interface DozeHelper { - - boolean needToShowDozeFragment(Context context); -} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelperModule.java b/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelperModule.java index fbbff364f..bbc6726c5 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelperModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelperModule.java @@ -1,5 +1,8 @@ package org.briarproject.briar.android.account; +import org.briarproject.android.dontkillmelib.DozeHelper; +import org.briarproject.android.dontkillmelib.DozeHelperImpl; + import dagger.Module; import dagger.Provides; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/SetupActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/account/SetupActivity.java index 076cd4a10..6e6f00bba 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/SetupActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/SetupActivity.java @@ -14,12 +14,14 @@ import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener import javax.annotation.Nullable; import javax.inject.Inject; +import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; +import static androidx.lifecycle.Lifecycle.State.STARTED; import static org.briarproject.briar.android.BriarApplication.ENTRY_ACTIVITY; import static org.briarproject.briar.android.account.SetupViewModel.State.AUTHOR_NAME; import static org.briarproject.briar.android.account.SetupViewModel.State.CREATED; @@ -28,6 +30,7 @@ import static org.briarproject.briar.android.account.SetupViewModel.State.FAILED import static org.briarproject.briar.android.account.SetupViewModel.State.SET_PASSWORD; import static org.briarproject.briar.android.util.UiUtils.setInputStateAlwaysVisible; import static org.briarproject.briar.android.util.UiUtils.setInputStateHidden; +import static org.briarproject.briar.android.util.UiUtils.showFragment; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -77,7 +80,10 @@ public class SetupActivity extends BaseActivity @TargetApi(23) void showDozeFragment() { - showNextFragment(DozeFragment.newInstance()); + Fragment f = new DoNotKillMeFragment(); + String tag = DoNotKillMeFragment.TAG; + if (!getLifecycle().getCurrentState().isAtLeast(STARTED)) return; + showFragment(getSupportFragmentManager(), f, tag); } void showApp() { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/SetupViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/account/SetupViewModel.java index 322d4fd24..0c1243e29 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/SetupViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/SetupViewModel.java @@ -2,6 +2,7 @@ package org.briarproject.briar.android.account; import android.app.Application; +import org.briarproject.android.dontkillmelib.DozeHelper; import org.briarproject.bramble.api.account.AccountManager; import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator; import org.briarproject.bramble.api.lifecycle.IoExecutor; @@ -95,7 +96,7 @@ class SetupViewModel extends AndroidViewModel { } boolean needToShowDozeFragment() { - return dozeHelper.needToShowDozeFragment(getApplication()); + return dozeHelper.needToShowDoNotKillMeFragment(getApplication()); } void dozeExceptionConfirmed() { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java index eae436236..85b965b6c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java @@ -36,11 +36,11 @@ import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION; import static android.os.Build.VERSION.SDK_INT; import static java.util.logging.Level.INFO; import static java.util.logging.Logger.getLogger; +import static org.briarproject.android.dontkillmelib.PowerUtils.getDozeWhitelistingIntent; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_UNLOCK; import static org.briarproject.briar.android.util.UiUtils.excludeSystemUi; -import static org.briarproject.briar.android.util.UiUtils.getDozeWhitelistingIntent; import static org.briarproject.briar.android.util.UiUtils.isSamsung7; @MethodsNotNullByDefault diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java index e0c166bf0..2a6c412f7 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java @@ -27,10 +27,10 @@ import androidx.annotation.CallSuper; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; +import static org.briarproject.android.dontkillmelib.PowerUtils.needsDozeWhitelisting; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STARTING_SERVICES; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE; -import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; @NotNullByDefault public class BriarControllerImpl implements BriarController { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java index 6107eef7f..fd2c9f546 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java @@ -25,11 +25,11 @@ import androidx.lifecycle.MutableLiveData; import static java.util.concurrent.TimeUnit.DAYS; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; +import static org.briarproject.android.dontkillmelib.PowerUtils.needsDozeWhitelisting; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE; import static org.briarproject.briar.android.controller.BriarControllerImpl.DOZE_ASK_AGAIN; import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE; -import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; @NotNullByDefault public class NavDrawerViewModel extends DbViewModel { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java index ae1e43131..fd5b33b2b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java @@ -1,7 +1,5 @@ package org.briarproject.briar.android.util; -import android.annotation.SuppressLint; -import android.annotation.TargetApi; import android.app.Activity; import android.app.KeyguardManager; import android.content.ActivityNotFoundException; @@ -12,7 +10,6 @@ import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.location.LocationManager; import android.net.Uri; -import android.os.PowerManager; import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; @@ -68,13 +65,11 @@ import androidx.lifecycle.Observer; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; import static android.content.Context.KEYGUARD_SERVICE; -import static android.content.Context.POWER_SERVICE; import static android.content.Intent.CATEGORY_DEFAULT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.os.Build.MANUFACTURER; import static android.os.Build.VERSION.SDK_INT; import static android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS; -import static android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.FORMAT_ABBREV_ALL; import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH; @@ -323,23 +318,6 @@ public class UiUtils { .show(); } - public static boolean needsDozeWhitelisting(Context ctx) { - if (SDK_INT < 23) return false; - PowerManager pm = (PowerManager) ctx.getSystemService(POWER_SERVICE); - String packageName = ctx.getPackageName(); - if (pm == null) throw new AssertionError(); - return !pm.isIgnoringBatteryOptimizations(packageName); - } - - @TargetApi(23) - @SuppressLint("BatteryLife") - public static Intent getDozeWhitelistingIntent(Context ctx) { - Intent i = new Intent(); - i.setAction(ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); - i.setData(Uri.parse("package:" + ctx.getPackageName())); - return i; - } - /** * @return true if location is enabled, * or it isn't required due to this being a SDK < 28 device. diff --git a/briar-android/src/main/res/layout/activity_rss_feed_manage.xml b/briar-android/src/main/res/layout/activity_rss_feed_manage.xml deleted file mode 100644 index bc3b9ba65..000000000 --- a/briar-android/src/main/res/layout/activity_rss_feed_manage.xml +++ /dev/null @@ -1,10 +0,0 @@ - - \ No newline at end of file diff --git a/briar-android/src/main/res/values/styles.xml b/briar-android/src/main/res/values/styles.xml index e8094ba3e..3c373115a 100644 --- a/briar-android/src/main/res/values/styles.xml +++ b/briar-android/src/main/res/values/styles.xml @@ -65,6 +65,12 @@ @dimen/button_size + + + diff --git a/briar-android/src/test/java/org/briarproject/briar/android/account/SetupViewModelTest.java b/briar-android/src/test/java/org/briarproject/briar/android/account/SetupViewModelTest.java index e64693789..dede851fa 100644 --- a/briar-android/src/test/java/org/briarproject/briar/android/account/SetupViewModelTest.java +++ b/briar-android/src/test/java/org/briarproject/briar/android/account/SetupViewModelTest.java @@ -3,6 +3,7 @@ package org.briarproject.briar.android.account; import android.app.Application; import android.content.Context; +import org.briarproject.android.dontkillmelib.DozeHelper; import org.briarproject.bramble.api.account.AccountManager; import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator; import org.briarproject.bramble.test.BrambleMockTestCase; @@ -48,7 +49,7 @@ public class SetupViewModelTest extends BrambleMockTestCase { context.checking(new Expectations() {{ oneOf(accountManager).accountExists(); will(returnValue(false)); - allowing(dozeHelper).needToShowDozeFragment(app); + allowing(dozeHelper).needToShowDoNotKillMeFragment(app); allowing(app).getApplicationContext(); will(returnValue(appContext)); allowing(appContext).getPackageManager(); diff --git a/build.gradle b/build.gradle index 840ff1ada..5f859b24f 100644 --- a/build.gradle +++ b/build.gradle @@ -36,4 +36,8 @@ buildscript { ext.dagger_version = "2.33" ext.junit_version = "4.13.2" ext.jmock_version = '2.12.0' + + ext.androidx_fragment_version = '1.3.4' + ext.androidx_constraintlayout_version = '2.0.4' + ext.google_material_version = '1.3.0' } diff --git a/dont-kill-me-lib/.gitignore b/dont-kill-me-lib/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/dont-kill-me-lib/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/dont-kill-me-lib/build.gradle b/dont-kill-me-lib/build.gradle new file mode 100644 index 000000000..9c180a0b0 --- /dev/null +++ b/dont-kill-me-lib/build.gradle @@ -0,0 +1,32 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdkVersion 31 + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 30 + + vectorDrawables.useSupportLibrary = true + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation "androidx.fragment:fragment:$androidx_fragment_version" + implementation "androidx.constraintlayout:constraintlayout:$androidx_constraintlayout_version" + implementation "com.google.android.material:material:$google_material_version" +} diff --git a/dont-kill-me-lib/consumer-rules.pro b/dont-kill-me-lib/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/dont-kill-me-lib/proguard-rules.pro b/dont-kill-me-lib/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/dont-kill-me-lib/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/dont-kill-me-lib/src/main/AndroidManifest.xml b/dont-kill-me-lib/src/main/AndroidManifest.xml new file mode 100644 index 000000000..c186d0bf2 --- /dev/null +++ b/dont-kill-me-lib/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + 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 new file mode 100644 index 000000000..4b0b47a20 --- /dev/null +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/AbstractDoNotKillMeFragment.java @@ -0,0 +1,115 @@ +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 { + + public final static String TAG = + AbstractDoNotKillMeFragment.class.getName(); + + 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 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) { + 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/AbstractDozeWatchdogImpl.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/AbstractDozeWatchdogImpl.java new file mode 100644 index 000000000..57240726f --- /dev/null +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/AbstractDozeWatchdogImpl.java @@ -0,0 +1,49 @@ +package org.briarproject.android.dontkillmelib; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.PowerManager; + +import java.util.concurrent.atomic.AtomicBoolean; + +import static android.content.Context.POWER_SERVICE; +import static android.os.Build.VERSION.SDK_INT; +import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED; + +public abstract class AbstractDozeWatchdogImpl { + + private final Context appContext; + private final AtomicBoolean dozed = new AtomicBoolean(false); + private final BroadcastReceiver receiver = new DozeBroadcastReceiver(); + + public AbstractDozeWatchdogImpl(Context appContext) { + this.appContext = appContext; + } + + public boolean getAndResetDozeFlag() { + return dozed.getAndSet(false); + } + + public void startService() { + if (SDK_INT < 23) return; + IntentFilter filter = new IntentFilter(ACTION_DEVICE_IDLE_MODE_CHANGED); + appContext.registerReceiver(receiver, filter); + } + + public void stopService() { + if (SDK_INT < 23) return; + appContext.unregisterReceiver(receiver); + } + + private class DozeBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (SDK_INT < 23) return; + PowerManager pm = + (PowerManager) appContext.getSystemService(POWER_SERVICE); + if (pm.isDeviceIdleMode()) dozed.set(true); + } + } +} diff --git a/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelper.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelper.java new file mode 100644 index 000000000..ea80f78bb --- /dev/null +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelper.java @@ -0,0 +1,7 @@ +package org.briarproject.android.dontkillmelib; + +import android.content.Context; + +public interface DozeHelper { + boolean needToShowDoNotKillMeFragment(Context context); +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelperImpl.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelperImpl.java similarity index 54% rename from briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelperImpl.java rename to dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelperImpl.java index 3ae0638ed..7a284b703 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeHelperImpl.java +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeHelperImpl.java @@ -1,12 +1,12 @@ -package org.briarproject.briar.android.account; +package org.briarproject.android.dontkillmelib; import android.content.Context; -import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; +import static org.briarproject.android.dontkillmelib.PowerUtils.needsDozeWhitelisting; -class DozeHelperImpl implements DozeHelper { +public class DozeHelperImpl implements DozeHelper { @Override - public boolean needToShowDozeFragment(Context context) { + public boolean needToShowDoNotKillMeFragment(Context context) { Context appContext = context.getApplicationContext(); return needsDozeWhitelisting(appContext) || HuaweiProtectedAppsView.needsToBeShown(appContext) || diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeView.java similarity index 82% rename from briar-android/src/main/java/org/briarproject/briar/android/account/DozeView.java rename to dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeView.java index c036f657b..51743d274 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeView.java +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/DozeView.java @@ -1,19 +1,15 @@ -package org.briarproject.briar.android.account; +package org.briarproject.android.dontkillmelib; import android.content.Context; import android.util.AttributeSet; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.R; - import androidx.annotation.Nullable; import androidx.annotation.UiThread; -import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; +import static org.briarproject.android.dontkillmelib.PowerUtils.needsDozeWhitelisting; @UiThread -@NotNullByDefault class DozeView extends PowerView { @Nullable diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiAppLaunchView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiAppLaunchView.java similarity index 90% rename from briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiAppLaunchView.java rename to dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiAppLaunchView.java index bd5dac903..038f38c55 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiAppLaunchView.java +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiAppLaunchView.java @@ -1,4 +1,4 @@ -package org.briarproject.briar.android.account; +package org.briarproject.android.dontkillmelib; import android.content.Context; @@ -7,13 +7,9 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.util.AttributeSet; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.R; - import java.util.List; -import javax.annotation.Nullable; - +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.UiThread; @@ -21,7 +17,6 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; import static android.os.Build.VERSION.SDK_INT; @UiThread -@NotNullByDefault class HuaweiAppLaunchView extends PowerView { private final static String PACKAGE_NAME = "com.huawei.systemmanager"; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiProtectedAppsView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiProtectedAppsView.java similarity index 90% rename from briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiProtectedAppsView.java rename to dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiProtectedAppsView.java index c86c6e7ae..4d03e0567 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiProtectedAppsView.java +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/HuaweiProtectedAppsView.java @@ -1,4 +1,4 @@ -package org.briarproject.briar.android.account; +package org.briarproject.android.dontkillmelib; import android.content.Context; @@ -7,13 +7,9 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.util.AttributeSet; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.R; - import java.util.List; -import javax.annotation.Nullable; - +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.UiThread; @@ -21,7 +17,6 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; import static android.os.Build.VERSION.SDK_INT; @UiThread -@NotNullByDefault class HuaweiProtectedAppsView extends PowerView { private final static String PACKAGE_NAME = "com.huawei.systemmanager"; 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 new file mode 100644 index 000000000..8b130f6ad --- /dev/null +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerUtils.java @@ -0,0 +1,60 @@ +package org.briarproject.android.dontkillmelib; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.PowerManager; + +import java.io.IOException; +import java.util.Scanner; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; + +import static android.content.Context.POWER_SERVICE; +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 { + + public static boolean needsDozeWhitelisting(Context ctx) { + if (SDK_INT < 23) return false; + PowerManager pm = (PowerManager) ctx.getSystemService(POWER_SERVICE); + String packageName = ctx.getPackageName(); + if (pm == null) throw new AssertionError(); + return !pm.isIgnoringBatteryOptimizations(packageName); + } + + @TargetApi(23) + @SuppressLint("BatteryLife") + public static Intent getDozeWhitelistingIntent(Context ctx) { + Intent i = new Intent(); + i.setAction(ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + i.setData(Uri.parse("package:" + ctx.getPackageName())); + return i; + } + + static void showOnboardingDialog(Context ctx, String text) { + new AlertDialog.Builder(ctx, R.style.OnboardingDialogTheme) + .setMessage(text) + .setNeutralButton(R.string.got_it, + (dialog, which) -> dialog.cancel()) + .show(); + } + + @Nullable + static String getSystemProperty(String propName) { + try { + Process p = getRuntime().exec("getprop " + propName); + Scanner s = new Scanner(p.getInputStream()); + String line = s.nextLine(); + s.close(); + return line; + } catch (SecurityException | IOException e) { + return null; + } + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/PowerView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerView.java similarity index 94% rename from briar-android/src/main/java/org/briarproject/briar/android/account/PowerView.java rename to dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerView.java index 6cf3401e3..ff7ba623a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/PowerView.java +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/PowerView.java @@ -1,4 +1,4 @@ -package org.briarproject.briar.android.account; +package org.briarproject.android.dontkillmelib; import android.content.Context; import android.os.Parcel; @@ -11,19 +11,15 @@ import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.R; - 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.briar.android.util.UiUtils.showOnboardingDialog; +import static org.briarproject.android.dontkillmelib.PowerUtils.showOnboardingDialog; @UiThread -@NotNullByDefault abstract class PowerView extends ConstraintLayout { private final TextView textView; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/XiaomiView.java b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/XiaomiView.java similarity index 75% rename from briar-android/src/main/java/org/briarproject/briar/android/account/XiaomiView.java rename to dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/XiaomiView.java index 91a7412b9..7b5163005 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/XiaomiView.java +++ b/dont-kill-me-lib/src/main/java/org/briarproject/android/dontkillmelib/XiaomiView.java @@ -1,24 +1,18 @@ -package org.briarproject.briar.android.account; +package org.briarproject.android.dontkillmelib; import android.content.Context; import android.util.AttributeSet; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.R; - -import javax.annotation.Nullable; - +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.UiThread; import static android.os.Build.BRAND; -import static org.briarproject.bramble.util.AndroidUtils.getSystemProperty; -import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; -import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog; +import static org.briarproject.android.dontkillmelib.PowerUtils.getSystemProperty; +import static org.briarproject.android.dontkillmelib.PowerUtils.showOnboardingDialog; @UiThread -@NotNullByDefault class XiaomiView extends PowerView { public XiaomiView(Context context) { @@ -63,7 +57,7 @@ class XiaomiView extends PowerView { private boolean isMiuiTenOrLater() { String version = getSystemProperty("ro.miui.ui.version.name"); - if (isNullOrEmpty(version)) return false; + if (version == null || version.equals("")) return false; version = version.replaceAll("[^\\d]", ""); try { return Integer.parseInt(version) >= 10; diff --git a/dont-kill-me-lib/src/main/res/drawable/ic_check_white.xml b/dont-kill-me-lib/src/main/res/drawable/ic_check_white.xml new file mode 100644 index 000000000..93a0bc27d --- /dev/null +++ b/dont-kill-me-lib/src/main/res/drawable/ic_check_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/dont-kill-me-lib/src/main/res/drawable/ic_help_outline_white.xml b/dont-kill-me-lib/src/main/res/drawable/ic_help_outline_white.xml new file mode 100644 index 000000000..8b07d94a0 --- /dev/null +++ b/dont-kill-me-lib/src/main/res/drawable/ic_help_outline_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/briar-android/src/main/res/layout/fragment_setup_doze.xml b/dont-kill-me-lib/src/main/res/layout/fragment_dont_kill_me.xml similarity index 83% rename from briar-android/src/main/res/layout/fragment_setup_doze.xml rename to dont-kill-me-lib/src/main/res/layout/fragment_dont_kill_me.xml index e32cf10b0..248b6af2a 100644 --- a/briar-android/src/main/res/layout/fragment_setup_doze.xml +++ b/dont-kill-me-lib/src/main/res/layout/fragment_dont_kill_me.xml @@ -9,47 +9,47 @@ + android:padding="16dp"> - - - -