mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Merge branch '2039-implement-hotspot-error-fragment' into '1081-share-app-via-wifi-hotspot'
Resolve "Implement HotspotErrorFragment" See merge request briar/briar!1469
This commit is contained in:
@@ -36,7 +36,7 @@ import org.briarproject.briar.android.attachment.AttachmentModule;
|
|||||||
import org.briarproject.briar.android.attachment.media.MediaModule;
|
import org.briarproject.briar.android.attachment.media.MediaModule;
|
||||||
import org.briarproject.briar.android.conversation.glide.BriarModelLoader;
|
import org.briarproject.briar.android.conversation.glide.BriarModelLoader;
|
||||||
import org.briarproject.briar.android.hotspot.AbstractTabsFragment;
|
import org.briarproject.briar.android.hotspot.AbstractTabsFragment;
|
||||||
import org.briarproject.briar.android.hotspot.HotspotHelpFragment;
|
import org.briarproject.briar.android.hotspot.FallbackFragment;
|
||||||
import org.briarproject.briar.android.hotspot.HotspotIntroFragment;
|
import org.briarproject.briar.android.hotspot.HotspotIntroFragment;
|
||||||
import org.briarproject.briar.android.hotspot.ManualHotspotFragment;
|
import org.briarproject.briar.android.hotspot.ManualHotspotFragment;
|
||||||
import org.briarproject.briar.android.hotspot.QrHotspotFragment;
|
import org.briarproject.briar.android.hotspot.QrHotspotFragment;
|
||||||
@@ -224,5 +224,5 @@ public interface AndroidComponent
|
|||||||
|
|
||||||
void inject(ManualHotspotFragment manualHotspotFragment);
|
void inject(ManualHotspotFragment manualHotspotFragment);
|
||||||
|
|
||||||
void inject(HotspotHelpFragment hotspotHelpFragment);
|
void inject(FallbackFragment fallbackFragment);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ public class ErrorFragment extends BaseFragment {
|
|||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
Bundle args = getArguments();
|
Bundle args = requireArguments();
|
||||||
if (args == null) throw new AssertionError();
|
|
||||||
errorMessage = args.getString(ERROR_MSG);
|
errorMessage = args.getString(ERROR_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package org.briarproject.briar.android.hotspot;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.net.Uri;
|
||||||
|
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.fragment.BaseFragment;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import static android.content.Intent.ACTION_SEND;
|
||||||
|
import static android.content.Intent.EXTRA_STREAM;
|
||||||
|
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||||
|
import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
import static android.view.View.INVISIBLE;
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
|
import static androidx.activity.result.contract.ActivityResultContracts.CreateDocument;
|
||||||
|
import static androidx.transition.TransitionManager.beginDelayedTransition;
|
||||||
|
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||||
|
import static org.briarproject.briar.android.hotspot.HotspotViewModel.getApkFileName;
|
||||||
|
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public class FallbackFragment extends BaseFragment {
|
||||||
|
|
||||||
|
public static final String TAG = FallbackFragment.class.getName();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
|
private HotspotViewModel viewModel;
|
||||||
|
private final ActivityResultLauncher<String> launcher =
|
||||||
|
registerForActivityResult(new CreateDocument(),
|
||||||
|
this::onDocumentCreated);
|
||||||
|
private Button fallbackButton;
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
FragmentActivity activity = requireActivity();
|
||||||
|
getAndroidComponent(activity).inject(this);
|
||||||
|
viewModel = new ViewModelProvider(activity, viewModelFactory)
|
||||||
|
.get(HotspotViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
return inflater
|
||||||
|
.inflate(R.layout.fragment_hotspot_save_apk, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(v, savedInstanceState);
|
||||||
|
|
||||||
|
fallbackButton = v.findViewById(R.id.fallbackButton);
|
||||||
|
progressBar = v.findViewById(R.id.progressBar);
|
||||||
|
fallbackButton.setOnClickListener(view -> {
|
||||||
|
beginDelayedTransition((ViewGroup) v);
|
||||||
|
fallbackButton.setVisibility(INVISIBLE);
|
||||||
|
progressBar.setVisibility(VISIBLE);
|
||||||
|
|
||||||
|
if (SDK_INT >= 19) launcher.launch(getApkFileName());
|
||||||
|
else viewModel.exportApk();
|
||||||
|
});
|
||||||
|
viewModel.getSavedApkToUri()
|
||||||
|
.observeEvent(this, uri -> shareUri(this, uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDocumentCreated(@Nullable Uri uri) {
|
||||||
|
showButton();
|
||||||
|
if (uri != null) viewModel.exportApk(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showButton() {
|
||||||
|
beginDelayedTransition((ViewGroup) requireView());
|
||||||
|
fallbackButton.setVisibility(VISIBLE);
|
||||||
|
progressBar.setVisibility(INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shareUri(Fragment fragment, Uri uri) {
|
||||||
|
Intent i = new Intent(ACTION_SEND);
|
||||||
|
i.putExtra(EXTRA_STREAM, uri);
|
||||||
|
i.setType("*/*"); // gives us all sharing options
|
||||||
|
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
Context ctx = fragment.requireContext();
|
||||||
|
if (SDK_INT <= 19) {
|
||||||
|
// Workaround for Android bug:
|
||||||
|
// ctx.grantUriPermission also needed for Android 4
|
||||||
|
List<ResolveInfo> resInfoList = ctx.getPackageManager()
|
||||||
|
.queryIntentActivities(i, MATCH_DEFAULT_ONLY);
|
||||||
|
for (ResolveInfo resolveInfo : resInfoList) {
|
||||||
|
String packageName = resolveInfo.activityInfo.packageName;
|
||||||
|
ctx.grantUriPermission(packageName, uri,
|
||||||
|
FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment.startActivity(Intent.createChooser(i, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
|||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
import org.briarproject.briar.android.fragment.ErrorFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
||||||
import org.briarproject.briar.android.hotspot.HotspotState.HotspotError;
|
import org.briarproject.briar.android.hotspot.HotspotState.HotspotError;
|
||||||
import org.briarproject.briar.android.hotspot.HotspotState.HotspotStarted;
|
import org.briarproject.briar.android.hotspot.HotspotState.HotspotStarted;
|
||||||
|
|
||||||
@@ -26,7 +26,8 @@ import static org.briarproject.briar.api.android.AndroidNotificationManager.ACTI
|
|||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class HotspotActivity extends BriarActivity {
|
public class HotspotActivity extends BriarActivity
|
||||||
|
implements BaseFragmentListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
@@ -60,9 +61,8 @@ public class HotspotActivity extends BriarActivity {
|
|||||||
showFragment(fm, new HotspotFragment(), tag);
|
showFragment(fm, new HotspotFragment(), tag);
|
||||||
}
|
}
|
||||||
} else if (hotspotState instanceof HotspotError) {
|
} else if (hotspotState instanceof HotspotError) {
|
||||||
String error = ((HotspotError) hotspotState).getError();
|
HotspotError error = ((HotspotError) hotspotState);
|
||||||
Fragment f = ErrorFragment.newInstance(error);
|
showErrorFragment(error.getError());
|
||||||
showFragment(getSupportFragmentManager(), f, ErrorFragment.TAG);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -74,6 +74,15 @@ public class HotspotActivity extends BriarActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showErrorFragment(String error) {
|
||||||
|
FragmentManager fm = getSupportFragmentManager();
|
||||||
|
String tag = HotspotErrorFragment.TAG;
|
||||||
|
if (fm.findFragmentByTag(tag) == null) {
|
||||||
|
Fragment f = HotspotErrorFragment.newInstance(error);
|
||||||
|
showFragment(fm, f, tag, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (item.getItemId() == android.R.id.home) {
|
if (item.getItemId() == android.R.id.home) {
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package org.briarproject.briar.android.hotspot;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.triggerFeedback;
|
||||||
|
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public class HotspotErrorFragment extends BaseFragment {
|
||||||
|
|
||||||
|
public static final String TAG = HotspotErrorFragment.class.getName();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
|
private static final String ERROR_MSG = "errorMessage";
|
||||||
|
|
||||||
|
public static HotspotErrorFragment newInstance(String message) {
|
||||||
|
HotspotErrorFragment f = new HotspotErrorFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(ERROR_MSG, message);
|
||||||
|
f.setArguments(args);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
Bundle args = requireArguments();
|
||||||
|
errorMessage = args.getString(ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
requireActivity().setTitle(R.string.error);
|
||||||
|
return inflater
|
||||||
|
.inflate(R.layout.fragment_hotspot_error, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(v, savedInstanceState);
|
||||||
|
TextView msg = v.findViewById(R.id.errorMessageDetail);
|
||||||
|
msg.setText(errorMessage);
|
||||||
|
|
||||||
|
Button feedbackButton = v.findViewById(R.id.feedbackButton);
|
||||||
|
feedbackButton.setOnClickListener(
|
||||||
|
button -> triggerFeedback(requireContext(), errorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,41 +1,16 @@
|
|||||||
package org.briarproject.briar.android.hotspot;
|
package org.briarproject.briar.android.hotspot;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
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.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
|
|
||||||
import static android.content.Intent.ACTION_SEND;
|
|
||||||
import static android.content.Intent.EXTRA_STREAM;
|
|
||||||
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
|
||||||
import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
|
||||||
import static android.view.View.INVISIBLE;
|
|
||||||
import static android.view.View.VISIBLE;
|
|
||||||
import static androidx.transition.TransitionManager.beginDelayedTransition;
|
|
||||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
|
||||||
import static org.briarproject.briar.android.hotspot.HotspotViewModel.getApkFileName;
|
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -43,25 +18,6 @@ public class HotspotHelpFragment extends Fragment {
|
|||||||
|
|
||||||
public final static String TAG = HotspotHelpFragment.class.getName();
|
public final static String TAG = HotspotHelpFragment.class.getName();
|
||||||
|
|
||||||
@Inject
|
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
|
||||||
|
|
||||||
private HotspotViewModel viewModel;
|
|
||||||
private final ActivityResultLauncher<String> launcher =
|
|
||||||
registerForActivityResult(new CreateDocument(),
|
|
||||||
this::onDocumentCreated);
|
|
||||||
private Button button;
|
|
||||||
private ProgressBar progressBar;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Context context) {
|
|
||||||
super.onAttach(context);
|
|
||||||
FragmentActivity activity = requireActivity();
|
|
||||||
getAndroidComponent(activity).inject(this);
|
|
||||||
viewModel = new ViewModelProvider(activity, viewModelFactory)
|
|
||||||
.get(HotspotViewModel.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater,
|
public View onCreateView(LayoutInflater inflater,
|
||||||
@Nullable ViewGroup container,
|
@Nullable ViewGroup container,
|
||||||
@@ -70,51 +26,4 @@ public class HotspotHelpFragment extends Fragment {
|
|||||||
.inflate(R.layout.fragment_hotspot_help, container, false);
|
.inflate(R.layout.fragment_hotspot_help, container, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(v, savedInstanceState);
|
|
||||||
button = v.findViewById(R.id.fallbackButton);
|
|
||||||
progressBar = v.findViewById(R.id.progressBar);
|
|
||||||
button.setOnClickListener(view -> {
|
|
||||||
beginDelayedTransition((ViewGroup) v);
|
|
||||||
button.setVisibility(INVISIBLE);
|
|
||||||
progressBar.setVisibility(VISIBLE);
|
|
||||||
|
|
||||||
if (SDK_INT >= 19) launcher.launch(getApkFileName());
|
|
||||||
else viewModel.exportApk();
|
|
||||||
});
|
|
||||||
viewModel.getSavedApkToUri().observeEvent(this, this::shareUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onDocumentCreated(@Nullable Uri uri) {
|
|
||||||
showButton();
|
|
||||||
if (uri != null) viewModel.exportApk(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shareUri(Uri uri) {
|
|
||||||
Intent i = new Intent(ACTION_SEND);
|
|
||||||
i.putExtra(EXTRA_STREAM, uri);
|
|
||||||
i.setType("*/*"); // gives us all sharing options
|
|
||||||
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
|
||||||
Context ctx = requireContext();
|
|
||||||
if (SDK_INT <= 19) {
|
|
||||||
// Workaround for Android bug:
|
|
||||||
// ctx.grantUriPermission also needed for Android 4
|
|
||||||
List<ResolveInfo> resInfoList = ctx.getPackageManager()
|
|
||||||
.queryIntentActivities(i, MATCH_DEFAULT_ONLY);
|
|
||||||
for (ResolveInfo resolveInfo : resInfoList) {
|
|
||||||
String packageName = resolveInfo.activityInfo.packageName;
|
|
||||||
ctx.grantUriPermission(packageName, uri,
|
|
||||||
FLAG_GRANT_READ_URI_PERMISSION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startActivity(Intent.createChooser(i, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showButton() {
|
|
||||||
beginDelayedTransition((ViewGroup) requireView());
|
|
||||||
button.setVisibility(VISIBLE);
|
|
||||||
progressBar.setVisibility(INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import static android.os.Build.VERSION.SDK_INT;
|
|||||||
import static android.os.Environment.DIRECTORY_DOWNLOADS;
|
import static android.os.Environment.DIRECTORY_DOWNLOADS;
|
||||||
import static android.os.Environment.getExternalStoragePublicDirectory;
|
import static android.os.Environment.getExternalStoragePublicDirectory;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||||
import static org.briarproject.briar.BuildConfig.DEBUG;
|
import static org.briarproject.briar.BuildConfig.DEBUG;
|
||||||
@@ -144,7 +145,10 @@ class HotspotViewModel extends DbViewModel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHotspotError(String error) {
|
public void onHotspotError(String error) {
|
||||||
state.setValue(new HotspotError(error));
|
if (LOG.isLoggable(WARNING)) {
|
||||||
|
LOG.warning("Hotspot error: " + error);
|
||||||
|
}
|
||||||
|
state.postValue(new HotspotError(error));
|
||||||
ioExecutor.execute(webServerManager::stopWebServer);
|
ioExecutor.execute(webServerManager::stopWebServer);
|
||||||
notificationManager.clearHotspotNotification();
|
notificationManager.clearHotspotNotification();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class BriarExceptionHandler implements UncaughtExceptionHandler {
|
|||||||
|
|
||||||
// activity runs in its own process, so we can kill the old one
|
// activity runs in its own process, so we can kill the old one
|
||||||
startDevReportActivity(app.getApplicationContext(),
|
startDevReportActivity(app.getApplicationContext(),
|
||||||
CrashReportActivity.class, e, appStartTime, logKey);
|
CrashReportActivity.class, e, appStartTime, logKey, null);
|
||||||
Process.killProcess(Process.myPid());
|
Process.killProcess(Process.myPid());
|
||||||
System.exit(10);
|
System.exit(10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import static java.util.Objects.requireNonNull;
|
|||||||
public class CrashReportActivity extends BaseActivity
|
public class CrashReportActivity extends BaseActivity
|
||||||
implements BaseFragmentListener {
|
implements BaseFragmentListener {
|
||||||
|
|
||||||
|
public static final String EXTRA_INITIAL_COMMENT = "initialComment";
|
||||||
public static final String EXTRA_THROWABLE = "throwable";
|
public static final String EXTRA_THROWABLE = "throwable";
|
||||||
public static final String EXTRA_APP_START_TIME = "appStartTime";
|
public static final String EXTRA_APP_START_TIME = "appStartTime";
|
||||||
public static final String EXTRA_APP_LOGCAT = "logcat";
|
public static final String EXTRA_APP_LOGCAT = "logcat";
|
||||||
@@ -55,10 +56,11 @@ public class CrashReportActivity extends BaseActivity
|
|||||||
setContentView(R.layout.activity_dev_report);
|
setContentView(R.layout.activity_dev_report);
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
|
String initialComment = intent.getStringExtra(EXTRA_INITIAL_COMMENT);
|
||||||
Throwable t = (Throwable) intent.getSerializableExtra(EXTRA_THROWABLE);
|
Throwable t = (Throwable) intent.getSerializableExtra(EXTRA_THROWABLE);
|
||||||
long appStartTime = intent.getLongExtra(EXTRA_APP_START_TIME, -1);
|
long appStartTime = intent.getLongExtra(EXTRA_APP_START_TIME, -1);
|
||||||
byte[] logKey = intent.getByteArrayExtra(EXTRA_APP_LOGCAT);
|
byte[] logKey = intent.getByteArrayExtra(EXTRA_APP_LOGCAT);
|
||||||
viewModel.init(t, appStartTime, logKey);
|
viewModel.init(t, appStartTime, logKey, initialComment);
|
||||||
viewModel.getShowReport().observeEvent(this, show -> {
|
viewModel.getShowReport().observeEvent(this, show -> {
|
||||||
if (show) displayFragment(true);
|
if (show) displayFragment(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -78,6 +78,9 @@ public class ReportFormFragment extends BaseFragment {
|
|||||||
list = v.findViewById(R.id.list);
|
list = v.findViewById(R.id.list);
|
||||||
progress = v.findViewById(R.id.progress_wheel);
|
progress = v.findViewById(R.id.progress_wheel);
|
||||||
|
|
||||||
|
if (viewModel.getInitialComment() != null)
|
||||||
|
userCommentView.setText(viewModel.getInitialComment());
|
||||||
|
|
||||||
if (viewModel.isFeedback()) {
|
if (viewModel.isFeedback()) {
|
||||||
includeDebugReport
|
includeDebugReport
|
||||||
.setText(getString(R.string.include_debug_report_feedback));
|
.setText(getString(R.string.include_debug_report_feedback));
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ class ReportViewModel extends AndroidViewModel {
|
|||||||
private final MutableLiveEvent<Integer> closeReport =
|
private final MutableLiveEvent<Integer> closeReport =
|
||||||
new MutableLiveEvent<>();
|
new MutableLiveEvent<>();
|
||||||
private boolean isFeedback;
|
private boolean isFeedback;
|
||||||
|
@Nullable
|
||||||
|
private String initialComment;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ReportViewModel(@NonNull Application application,
|
ReportViewModel(@NonNull Application application,
|
||||||
@@ -80,7 +82,8 @@ class ReportViewModel extends AndroidViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init(@Nullable Throwable t, long appStartTime,
|
void init(@Nullable Throwable t, long appStartTime,
|
||||||
@Nullable byte[] logKey) {
|
@Nullable byte[] logKey, @Nullable String initialComment) {
|
||||||
|
this.initialComment = initialComment;
|
||||||
isFeedback = t == null;
|
isFeedback = t == null;
|
||||||
if (reportData.getValue() == null) new SingleShotAndroidExecutor(() -> {
|
if (reportData.getValue() == null) new SingleShotAndroidExecutor(() -> {
|
||||||
String decryptedLogs;
|
String decryptedLogs;
|
||||||
@@ -103,6 +106,11 @@ class ReportViewModel extends AndroidViewModel {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
String getInitialComment() {
|
||||||
|
return initialComment;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isFeedback() {
|
boolean isFeedback() {
|
||||||
return isFeedback;
|
return isFeedback;
|
||||||
}
|
}
|
||||||
@@ -140,7 +148,7 @@ class ReportViewModel extends AndroidViewModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The content of the report that will be loaded after
|
* The content of the report that will be loaded after
|
||||||
* {@link #init(Throwable, long, byte[])} was called.
|
* {@link #init(Throwable, long, byte[], String)} was called.
|
||||||
*/
|
*/
|
||||||
LiveData<ReportData> getReportData() {
|
LiveData<ReportData> getReportData() {
|
||||||
return reportData;
|
return reportData;
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import androidx.core.util.Consumer;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
@@ -117,6 +118,7 @@ import static org.briarproject.briar.BuildConfig.APPLICATION_ID;
|
|||||||
import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE;
|
import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE;
|
||||||
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_LOGCAT;
|
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_LOGCAT;
|
||||||
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_START_TIME;
|
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_START_TIME;
|
||||||
|
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_INITIAL_COMMENT;
|
||||||
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_THROWABLE;
|
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_THROWABLE;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -143,13 +145,18 @@ public class UiUtils {
|
|||||||
|
|
||||||
public static void showFragment(FragmentManager fm, Fragment f,
|
public static void showFragment(FragmentManager fm, Fragment f,
|
||||||
@Nullable String tag) {
|
@Nullable String tag) {
|
||||||
fm.beginTransaction()
|
showFragment(fm, f, tag, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showFragment(FragmentManager fm, Fragment f,
|
||||||
|
@Nullable String tag, boolean addToBackStack) {
|
||||||
|
FragmentTransaction ta = fm.beginTransaction()
|
||||||
.setCustomAnimations(R.anim.step_next_in,
|
.setCustomAnimations(R.anim.step_next_in,
|
||||||
R.anim.step_previous_out, R.anim.step_previous_in,
|
R.anim.step_previous_out, R.anim.step_previous_in,
|
||||||
R.anim.step_next_out)
|
R.anim.step_next_out)
|
||||||
.replace(R.id.fragmentContainer, f, tag)
|
.replace(R.id.fragmentContainer, f, tag);
|
||||||
.addToBackStack(tag)
|
if (addToBackStack) ta.addToBackStack(tag);
|
||||||
.commit();
|
ta.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getContactDisplayName(Author author,
|
public static String getContactDisplayName(Author author,
|
||||||
@@ -428,17 +435,25 @@ public class UiUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void triggerFeedback(Context ctx) {
|
public static void triggerFeedback(Context ctx) {
|
||||||
startDevReportActivity(ctx, FeedbackActivity.class, null, null, null);
|
triggerFeedback(ctx, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void triggerFeedback(Context ctx,
|
||||||
|
@Nullable String initialComment) {
|
||||||
|
startDevReportActivity(ctx, FeedbackActivity.class, null, null, null,
|
||||||
|
initialComment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startDevReportActivity(Context ctx,
|
public static void startDevReportActivity(Context ctx,
|
||||||
Class<? extends FragmentActivity> activity, @Nullable Throwable t,
|
Class<? extends FragmentActivity> activity, @Nullable Throwable t,
|
||||||
@Nullable Long appStartTime, @Nullable byte[] logKey) {
|
@Nullable Long appStartTime, @Nullable byte[] logKey, @Nullable
|
||||||
|
String initialComment) {
|
||||||
final Intent dialogIntent = new Intent(ctx, activity);
|
final Intent dialogIntent = new Intent(ctx, activity);
|
||||||
dialogIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
|
dialogIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
|
||||||
dialogIntent.putExtra(EXTRA_THROWABLE, t);
|
dialogIntent.putExtra(EXTRA_THROWABLE, t);
|
||||||
dialogIntent.putExtra(EXTRA_APP_START_TIME, appStartTime);
|
dialogIntent.putExtra(EXTRA_APP_START_TIME, appStartTime);
|
||||||
dialogIntent.putExtra(EXTRA_APP_LOGCAT, logKey);
|
dialogIntent.putExtra(EXTRA_APP_LOGCAT, logKey);
|
||||||
|
dialogIntent.putExtra(EXTRA_INITIAL_COMMENT, initialComment);
|
||||||
ctx.startActivity(dialogIntent);
|
ctx.startActivity(dialogIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,7 @@
|
|||||||
android:id="@+id/errorIcon"
|
android:id="@+id/errorIcon"
|
||||||
android:layout_width="128dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="128dp"
|
android:layout_height="128dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_margin="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@@ -25,11 +21,7 @@
|
|||||||
android:id="@+id/errorTitle"
|
android:id="@+id/errorTitle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_margin="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:text="@string/sorry"
|
android:text="@string/sorry"
|
||||||
android:textSize="@dimen/text_size_xlarge"
|
android:textSize="@dimen/text_size_xlarge"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|||||||
80
briar-android/src/main/res/layout/fragment_hotspot_error.xml
Normal file
80
briar-android/src/main/res/layout/fragment_hotspot_error.xml
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?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">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/errorIcon"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_marginVertical="8dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/errorMessageIntro"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/errorMessageIntro"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/alerts_and_states_error"
|
||||||
|
app:tint="@color/briar_red_500"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/errorMessageIntro"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:text="@string/hotspot_error_intro"
|
||||||
|
android:textSize="@dimen/text_size_medium"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/errorIcon"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/errorMessageDetail"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginVertical="16dp"
|
||||||
|
android:background="@color/briar_orange_200"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:textColor="@color/briar_text_primary"
|
||||||
|
android:textSize="@dimen/text_size_medium"
|
||||||
|
android:typeface="monospace"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/errorMessageIntro"
|
||||||
|
tools:text="@string/hotspot_error_no_wifi_direct" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/feedbackButton"
|
||||||
|
style="@style/BriarButtonFlat.Positive"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/send_feedback"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/errorMessageDetail" />
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@+id/fallbackFragment"
|
||||||
|
android:name="org.briarproject.briar.android.hotspot.FallbackFragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/feedbackButton"
|
||||||
|
tools:layout="@layout/fragment_hotspot_save_apk" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -110,49 +111,15 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/site3View" />
|
app:layout_constraintTop_toBottomOf="@+id/site3View" />
|
||||||
|
|
||||||
<TextView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/fallbackTitleView"
|
android:id="@+id/fallbackFragment"
|
||||||
android:layout_width="0dp"
|
android:name="org.briarproject.briar.android.hotspot.FallbackFragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="32dp"
|
|
||||||
android:text="@string/hotspot_help_fallback_title"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/site4View" />
|
app:layout_constraintTop_toBottomOf="@+id/site4View"
|
||||||
|
tools:layout="@layout/fragment_hotspot_save_apk" />
|
||||||
<TextView
|
|
||||||
android:id="@+id/fallbackIntroView"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:text="@string/hotspot_help_fallback_intro"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/fallbackTitleView" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/fallbackButton"
|
|
||||||
style="@style/BriarButtonFlat.Positive"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:text="@string/hotspot_help_fallback_button"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/fallbackIntroView" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progressBar"
|
|
||||||
style="?android:progressBarStyle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="invisible"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/fallbackButton"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/fallbackButton" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@id/fallbackTitleView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:text="@string/hotspot_help_fallback_title"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fallbackIntro"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/hotspot_help_fallback_intro"
|
||||||
|
android:textSize="@dimen/text_size_medium"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/fallbackTitleView" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/fallbackButton"
|
||||||
|
style="@style/BriarButtonFlat.Positive"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/hotspot_help_fallback_button"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/fallbackIntro" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
style="?android:progressBarStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="invisible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/fallbackButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/fallbackButton" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
<color name="briar_blue_600">#1b69b6</color>
|
<color name="briar_blue_600">#1b69b6</color>
|
||||||
<color name="briar_blue_400">#418cd8</color>
|
<color name="briar_blue_400">#418cd8</color>
|
||||||
|
|
||||||
|
<color name="briar_orange_200">#fed69f</color>
|
||||||
<color name="briar_orange_500">#fc9403</color>
|
<color name="briar_orange_500">#fc9403</color>
|
||||||
|
|
||||||
<color name="briar_red_500">#db3b21</color>
|
<color name="briar_red_500">#db3b21</color>
|
||||||
|
|||||||
@@ -160,6 +160,7 @@
|
|||||||
<string name="sorry">Sorry</string>
|
<string name="sorry">Sorry</string>
|
||||||
<string name="error_start_activity">Unavailable on your system</string>
|
<string name="error_start_activity">Unavailable on your system</string>
|
||||||
<string name="status_heading">Status:</string>
|
<string name="status_heading">Status:</string>
|
||||||
|
<string name="error">Error</string>
|
||||||
|
|
||||||
<!-- Contacts and Private Conversations-->
|
<!-- Contacts and Private Conversations-->
|
||||||
<string name="no_contacts">No contacts to show</string>
|
<string name="no_contacts">No contacts to show</string>
|
||||||
@@ -708,6 +709,7 @@
|
|||||||
<string name="wifi_settings_request_enable_body">To create a Wi-Fi hotspot, Briar needs to use Wi-Fi. Please enable it.</string>
|
<string name="wifi_settings_request_enable_body">To create a Wi-Fi hotspot, Briar needs to use Wi-Fi. Please enable it.</string>
|
||||||
<string name="wifi_settings_request_denied_body">You have denied to enable Wi-Fi, but Briar needs to use Wi-Fi.\n\nPlease consider enabling it.</string>
|
<string name="wifi_settings_request_denied_body">You have denied to enable Wi-Fi, but Briar needs to use Wi-Fi.\n\nPlease consider enabling it.</string>
|
||||||
|
|
||||||
|
<string name="hotspot_error_intro">Something went wrong while trying to share the app via Wi-Fi:</string>
|
||||||
<string name="hotspot_error_no_wifi_direct">Device does not support Wi-Fi Direct</string>
|
<string name="hotspot_error_no_wifi_direct">Device does not support Wi-Fi Direct</string>
|
||||||
<string name="hotspot_error_start_callback_failed">Hotspot failed to start: error %s</string>
|
<string name="hotspot_error_start_callback_failed">Hotspot failed to start: error %s</string>
|
||||||
<string name="hotspot_error_start_callback_failed_unknown">Hotspot failed to start with an unknown error, reason %d</string>
|
<string name="hotspot_error_start_callback_failed_unknown">Hotspot failed to start with an unknown error, reason %d</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user