Commit c647c526 authored by Torsten Grote's avatar Torsten Grote
Browse files

Merge branch '2009-xiaomi-setup-screen' into 'master'

Show instructions for locking Briar to the Xiaomi recent apps list

Closes #2009

See merge request !1451
parents 21fd7f5e cad5edcf
Pipeline #6622 failed with stages
in 61 minutes and 46 seconds
......@@ -10,17 +10,20 @@ import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Scanner;
import javax.annotation.Nullable;
import static android.content.Context.MODE_PRIVATE;
import static android.os.Build.VERSION.SDK_INT;
import static java.lang.Runtime.getRuntime;
import static java.util.Arrays.asList;
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
......@@ -118,4 +121,17 @@ public class AndroidUtils {
public static String[] getSupportedImageContentTypes() {
return new String[] {"image/jpeg", "image/png", "image/gif"};
}
@Nullable
public 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;
}
}
}
......@@ -104,8 +104,7 @@
<activity
android:name="org.briarproject.briar.android.account.SetupActivity"
android:label="@string/setup_title"
android:windowSoftInputMode="adjustResize|stateAlwaysVisible" />
android:label="@string/setup_title" />
<activity
android:name="org.briarproject.briar.android.splash.SplashScreenActivity"
......
......@@ -32,6 +32,7 @@ public class DozeFragment extends SetupFragment
private DozeView dozeView;
private HuaweiProtectedAppsView huaweiProtectedAppsView;
private HuaweiAppLaunchView huaweiAppLaunchView;
private XiaomiView xiaomiView;
private Button next;
private boolean secondAttempt = false;
......@@ -53,6 +54,8 @@ public class DozeFragment extends SetupFragment
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);
......@@ -98,7 +101,8 @@ public class DozeFragment extends SetupFragment
public void onCheckedChanged() {
next.setEnabled(dozeView.isChecked() &&
huaweiProtectedAppsView.isChecked() &&
huaweiAppLaunchView.isChecked());
huaweiAppLaunchView.isChecked() &&
xiaomiView.isChecked());
}
@SuppressLint("BatteryLife")
......
......@@ -10,6 +10,7 @@ class DozeHelperImpl implements DozeHelper {
Context appContext = context.getApplicationContext();
return needsDozeWhitelisting(appContext) ||
HuaweiProtectedAppsView.needsToBeShown(appContext) ||
HuaweiAppLaunchView.needsToBeShown(appContext);
HuaweiAppLaunchView.needsToBeShown(appContext) ||
XiaomiView.isXiaomiOrRedmiDevice();
}
}
......@@ -118,7 +118,7 @@ public class SetPasswordFragment extends SetupFragment {
@Override
public void onClick(View view) {
IBinder token = passwordEntry.getWindowToken();
Object o = getContext().getSystemService(INPUT_METHOD_SERVICE);
Object o = requireContext().getSystemService(INPUT_METHOD_SERVICE);
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
viewModel.setPassword(passwordEntry.getText().toString());
}
......
......@@ -26,6 +26,8 @@ import static org.briarproject.briar.android.account.SetupViewModel.State.CREATE
import static org.briarproject.briar.android.account.SetupViewModel.State.DOZE;
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;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
......@@ -55,10 +57,13 @@ public class SetupActivity extends BaseActivity
private void onStateChanged(SetupViewModel.State state) {
if (state == AUTHOR_NAME) {
setInputStateAlwaysVisible(this);
showInitialFragment(AuthorNameFragment.newInstance());
} else if (state == SET_PASSWORD) {
setInputStateAlwaysVisible(this);
showPasswordFragment();
} else if (state == DOZE) {
setInputStateHidden(this);
showDozeFragment();
} else if (state == CREATED || state == FAILED) {
// TODO: Show an error if failed
......
package org.briarproject.briar.android.account;
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.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;
@UiThread
@NotNullByDefault
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 (isNullOrEmpty(version)) return false;
version = version.replaceAll("[^\\d]", "");
try {
return Integer.parseInt(version) >= 10;
} catch (NumberFormatException e) {
return false;
}
}
}
......@@ -2,6 +2,7 @@ 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;
import android.content.Context;
......@@ -90,6 +91,9 @@ import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static android.text.format.DateUtils.YEAR_IN_MILLIS;
import static android.view.KeyEvent.ACTION_DOWN;
import static android.view.KeyEvent.KEYCODE_ENTER;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
import static android.view.inputmethod.EditorInfo.IME_NULL;
import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT;
import static android.widget.Toast.LENGTH_LONG;
......@@ -537,4 +541,14 @@ public class UiUtils {
Toast.makeText(context, msg, LENGTH_LONG).show();
});
}
public static void setInputStateAlwaysVisible(Activity activity) {
activity.getWindow().setSoftInputMode(SOFT_INPUT_ADJUST_RESIZE |
SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
public static void setInputStateHidden(Activity activity) {
activity.getWindow().setSoftInputMode(SOFT_INPUT_ADJUST_RESIZE |
SOFT_INPUT_STATE_HIDDEN);
}
}
......@@ -38,6 +38,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/huaweiProtectedAppsView" />
<org.briarproject.briar.android.account.XiaomiView
android:id="@+id/xiaomiView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/margin_large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/huaweiAppLaunchView" />
<Button
android:id="@+id/next"
style="@style/BriarButton"
......@@ -48,7 +57,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/huaweiAppLaunchView"
app:layout_constraintTop_toBottomOf="@+id/xiaomiView"
app:layout_constraintVertical_bias="1.0"
tools:enabled="true" />
......
......@@ -30,6 +30,11 @@
<string name="setup_huawei_app_launch_text">Please tap the button below, open the \"App launch\" screen and make sure Briar is set to \"Manage manually\".</string>
<string name="setup_huawei_app_launch_button">Open Battery Settings</string>
<string name="setup_huawei_app_launch_help">If Briar is not set to \"Manage manually\" in the \"App launch\" screen, it will not be able to run in the background.</string>
<string name="setup_xiaomi_text">To run in the background, Briar needs to be locked to the recent apps list.</string>
<string name="setup_xiaomi_button">Protect Briar</string>
<string name="setup_xiaomi_help">If Briar is not locked to the recent apps list, it will be unable to run in the background.</string>
<string name="setup_xiaomi_dialog_body_old">1. Open the recent apps list (also called the app switcher)\n\n2. Swipe down on the image of Briar to show the padlock icon\n\n3. If the padlock is not locked, tap to lock it</string>
<string name="setup_xiaomi_dialog_body_new">1. Open the recent apps list (also called the app switcher)\n\n2. Press and hold the image of Briar until the padlock button appears\n\n3. If the padlock is not locked, tap to lock it</string>
<string name="warning_dozed">%s was unable to run in the background</string>
<!-- Login -->
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment