android: Show connection errors as banner, not as modal dialog
This commit is contained in:
+46
-64
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2016 Tobias Brunner
|
* Copyright (C) 2012-2018 Tobias Brunner
|
||||||
* Copyright (C) 2012 Giuliano Grassi
|
* Copyright (C) 2012 Giuliano Grassi
|
||||||
* Copyright (C) 2012 Ralf Sager
|
* Copyright (C) 2012 Ralf Sager
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
@@ -20,19 +20,18 @@ package org.strongswan.android.ui;
|
|||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@@ -60,7 +59,10 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
|||||||
private int mColorStateSuccess;
|
private int mColorStateSuccess;
|
||||||
private Button mActionButton;
|
private Button mActionButton;
|
||||||
private ProgressBar mProgress;
|
private ProgressBar mProgress;
|
||||||
private AlertDialog mErrorDialog;
|
private LinearLayout mErrorView;
|
||||||
|
private TextView mErrorText;
|
||||||
|
private Button mErrorDetails;
|
||||||
|
private Button mDismissError;
|
||||||
private long mErrorConnectionID;
|
private long mErrorConnectionID;
|
||||||
private VpnStateService mService;
|
private VpnStateService mService;
|
||||||
private final ServiceConnection mServiceConnection = new ServiceConnection()
|
private final ServiceConnection mServiceConnection = new ServiceConnection()
|
||||||
@@ -128,12 +130,25 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
|||||||
});
|
});
|
||||||
enableActionButton(null);
|
enableActionButton(null);
|
||||||
|
|
||||||
|
mErrorView = view.findViewById(R.id.vpn_error);
|
||||||
|
mErrorText = view.findViewById(R.id.vpn_error_text);
|
||||||
|
mErrorDetails = view.findViewById(R.id.error_details);
|
||||||
|
mDismissError = view.findViewById(R.id.dismiss_error);
|
||||||
mProgress = (ProgressBar)view.findViewById(R.id.progress);
|
mProgress = (ProgressBar)view.findViewById(R.id.progress);
|
||||||
mStateView = (TextView)view.findViewById(R.id.vpn_state);
|
mStateView = (TextView)view.findViewById(R.id.vpn_state);
|
||||||
mColorStateBase = mStateView.getCurrentTextColor();
|
mColorStateBase = mStateView.getCurrentTextColor();
|
||||||
mProfileView = (TextView)view.findViewById(R.id.vpn_profile_label);
|
mProfileView = (TextView)view.findViewById(R.id.vpn_profile_label);
|
||||||
mProfileNameView = (TextView)view.findViewById(R.id.vpn_profile_name);
|
mProfileNameView = (TextView)view.findViewById(R.id.vpn_profile_name);
|
||||||
|
|
||||||
|
mDismissError.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
clearError();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +171,6 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
|||||||
{
|
{
|
||||||
mService.unregisterListener(this);
|
mService.unregisterListener(this);
|
||||||
}
|
}
|
||||||
hideErrorDialog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -238,13 +252,10 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
|||||||
{
|
{
|
||||||
if (error == ErrorState.NO_ERROR)
|
if (error == ErrorState.NO_ERROR)
|
||||||
{
|
{
|
||||||
hideErrorDialog();
|
mErrorView.setVisibility(View.GONE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (mErrorDialog != null)
|
|
||||||
{ /* we already show the dialog */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
mErrorConnectionID = connectionID;
|
mErrorConnectionID = connectionID;
|
||||||
mProfileNameView.setText(name);
|
mProfileNameView.setText(name);
|
||||||
showProfile(true);
|
showProfile(true);
|
||||||
@@ -257,24 +268,24 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
|||||||
case AUTH_FAILED:
|
case AUTH_FAILED:
|
||||||
if (imcState == ImcState.BLOCK)
|
if (imcState == ImcState.BLOCK)
|
||||||
{
|
{
|
||||||
showErrorDialog(R.string.error_assessment_failed);
|
showError(R.string.error_assessment_failed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
showErrorDialog(R.string.error_auth_failed);
|
showError(R.string.error_auth_failed);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PEER_AUTH_FAILED:
|
case PEER_AUTH_FAILED:
|
||||||
showErrorDialog(R.string.error_peer_auth_failed);
|
showError(R.string.error_peer_auth_failed);
|
||||||
break;
|
break;
|
||||||
case LOOKUP_FAILED:
|
case LOOKUP_FAILED:
|
||||||
showErrorDialog(R.string.error_lookup_failed);
|
showError(R.string.error_lookup_failed);
|
||||||
break;
|
break;
|
||||||
case UNREACHABLE:
|
case UNREACHABLE:
|
||||||
showErrorDialog(R.string.error_unreachable);
|
showError(R.string.error_unreachable);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
showErrorDialog(R.string.error_generic);
|
showError(R.string.error_generic);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -293,75 +304,46 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
|||||||
mActionButton.setVisibility(text != null ? View.VISIBLE : View.GONE);
|
mActionButton.setVisibility(text != null ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hideErrorDialog()
|
|
||||||
{
|
|
||||||
if (mErrorDialog != null)
|
|
||||||
{
|
|
||||||
mErrorDialog.dismiss();
|
|
||||||
mErrorDialog = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearError()
|
private void clearError()
|
||||||
{
|
{
|
||||||
if (mService != null)
|
if (mService != null)
|
||||||
{
|
{
|
||||||
mService.disconnect();
|
|
||||||
if (mService.getConnectionID() == mErrorConnectionID)
|
if (mService.getConnectionID() == mErrorConnectionID)
|
||||||
{
|
{
|
||||||
|
mService.disconnect();
|
||||||
mService.setError(ErrorState.NO_ERROR);
|
mService.setError(ErrorState.NO_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateView();
|
updateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showErrorDialog(int textid)
|
private void showError(int textid)
|
||||||
{
|
{
|
||||||
final List<RemediationInstruction> instructions = mService.getRemediationInstructions();
|
final List<RemediationInstruction> instructions = mService.getRemediationInstructions();
|
||||||
final boolean show_instructions = mService.getImcState() == ImcState.BLOCK && !instructions.isEmpty();
|
final boolean show_instructions = mService.getImcState() == ImcState.BLOCK && !instructions.isEmpty();
|
||||||
int text = show_instructions ? R.string.show_remediation_instructions : R.string.show_log;
|
int text = show_instructions ? R.string.show_remediation_instructions : R.string.show_log;
|
||||||
|
|
||||||
mErrorDialog = new AlertDialog.Builder(getActivity())
|
mErrorText.setText(getString(R.string.error_introduction) + " " + getString(textid));
|
||||||
.setMessage(getString(R.string.error_introduction) + " " + getString(textid))
|
mErrorDetails.setText(text);
|
||||||
.setCancelable(false)
|
mErrorDetails.setOnClickListener(new OnClickListener()
|
||||||
.setNeutralButton(text, new DialogInterface.OnClickListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which)
|
|
||||||
{
|
|
||||||
clearError();
|
|
||||||
dialog.dismiss();
|
|
||||||
Intent intent;
|
|
||||||
if (show_instructions)
|
|
||||||
{
|
|
||||||
intent = new Intent(getActivity(), RemediationInstructionsActivity.class);
|
|
||||||
intent.putParcelableArrayListExtra(RemediationInstructionsFragment.EXTRA_REMEDIATION_INSTRUCTIONS,
|
|
||||||
new ArrayList<RemediationInstruction>(instructions));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
intent = new Intent(getActivity(), LogActivity.class);
|
|
||||||
}
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int id)
|
|
||||||
{
|
|
||||||
clearError();
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
}).create();
|
|
||||||
mErrorDialog.setOnDismissListener(new DialogInterface.OnDismissListener()
|
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onDismiss(DialogInterface dialog)
|
public void onClick(View v)
|
||||||
{
|
{
|
||||||
mErrorDialog = null;
|
Intent intent;
|
||||||
|
if (show_instructions)
|
||||||
|
{
|
||||||
|
intent = new Intent(getActivity(), RemediationInstructionsActivity.class);
|
||||||
|
intent.putParcelableArrayListExtra(RemediationInstructionsFragment.EXTRA_REMEDIATION_INSTRUCTIONS,
|
||||||
|
new ArrayList<RemediationInstruction>(instructions));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
intent = new Intent(getActivity(), LogActivity.class);
|
||||||
|
}
|
||||||
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mErrorDialog.show();
|
mErrorView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2018 Tobias Brunner
|
||||||
|
HSR Hochschule fuer Technik Rapperswil
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
-->
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<solid
|
||||||
|
android:color="@color/panel_separator" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:bottom="2dp">
|
||||||
|
<shape>
|
||||||
|
<solid
|
||||||
|
android:color="@android:color/white" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingBottom="2dp"
|
|
||||||
android:background="@drawable/state_background"
|
android:background="@drawable/state_background"
|
||||||
android:orientation="vertical" >
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
|||||||
@@ -18,80 +18,137 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingBottom="2dp"
|
android:orientation="vertical"
|
||||||
android:background="@drawable/state_background"
|
android:animateLayoutChanges="true" >
|
||||||
android:orientation="vertical" >
|
|
||||||
|
|
||||||
<GridLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/vpn_error"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="10dp"
|
|
||||||
android:layout_marginLeft="20dp"
|
|
||||||
android:layout_marginRight="20dp"
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:columnCount="2"
|
|
||||||
android:rowCount="2" >
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginRight="5dp"
|
|
||||||
android:gravity="top"
|
|
||||||
android:text="@string/state_label"
|
|
||||||
android:textColor="?android:textColorPrimary"
|
|
||||||
android:textSize="20sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/vpn_state"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="top"
|
|
||||||
android:text="@string/state_disabled"
|
|
||||||
android:textColor="?android:textColorSecondary"
|
|
||||||
android:textSize="20sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/vpn_profile_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginRight="5dp"
|
|
||||||
android:gravity="top"
|
|
||||||
android:text="@string/profile_label"
|
|
||||||
android:textColor="?android:textColorPrimary"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:visibility="gone" >
|
|
||||||
</TextView>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/vpn_profile_name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="top"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:visibility="gone" >
|
|
||||||
</TextView>
|
|
||||||
</GridLayout>
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progress"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="10dp"
|
|
||||||
android:layout_marginLeft="20dp"
|
|
||||||
android:layout_marginRight="20dp"
|
|
||||||
android:indeterminate="true"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/action"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginBottom="10dp"
|
android:background="@drawable/error_background"
|
||||||
android:layout_marginLeft="20dp"
|
android:orientation="vertical" >
|
||||||
android:layout_marginRight="20dp"
|
|
||||||
android:text="@string/disconnect"
|
|
||||||
style="?android:attr/borderlessButtonStyle" >
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vpn_error_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:text="Failed to establish VPN: Server is unreachable"
|
||||||
|
android:textColor="@color/primary_dark"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="end" >
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/dismiss_error"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:text="@string/dismiss"
|
||||||
|
android:textColor="@color/primary"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
style="?android:attr/borderlessButtonStyle" >
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/error_details"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/show_log"
|
||||||
|
android:textColor="@color/primary"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
style="?android:attr/borderlessButtonStyle" >
|
||||||
|
</Button>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/state_background"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<GridLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:columnCount="2"
|
||||||
|
android:rowCount="2" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
|
android:gravity="top"
|
||||||
|
android:text="@string/state_label"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vpn_state"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="top"
|
||||||
|
android:text="@string/state_disabled"
|
||||||
|
android:textColor="?android:textColorSecondary"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vpn_profile_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
|
android:gravity="top"
|
||||||
|
android:text="@string/profile_label"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:visibility="gone" >
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/vpn_profile_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="top"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:visibility="gone" >
|
||||||
|
</TextView>
|
||||||
|
</GridLayout>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/action"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:text="@string/disconnect"
|
||||||
|
style="?android:attr/borderlessButtonStyle" >
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -163,6 +163,7 @@
|
|||||||
<string name="state_disconnecting">Trennen…</string>
|
<string name="state_disconnecting">Trennen…</string>
|
||||||
<string name="state_disabled">Kein aktives Profil</string>
|
<string name="state_disabled">Kein aktives Profil</string>
|
||||||
<string name="state_error">Fehler</string>
|
<string name="state_error">Fehler</string>
|
||||||
|
<string name="dismiss">Ausblenden</string>
|
||||||
|
|
||||||
<!-- IMC state fragment -->
|
<!-- IMC state fragment -->
|
||||||
<string name="imc_state_label">Assessment:</string>
|
<string name="imc_state_label">Assessment:</string>
|
||||||
|
|||||||
@@ -163,6 +163,7 @@
|
|||||||
<string name="state_disconnecting">Przerywam połączenie…</string>
|
<string name="state_disconnecting">Przerywam połączenie…</string>
|
||||||
<string name="state_disabled">Brak aktywnego VPN</string>
|
<string name="state_disabled">Brak aktywnego VPN</string>
|
||||||
<string name="state_error">Błąd</string>
|
<string name="state_error">Błąd</string>
|
||||||
|
<string name="dismiss">Dismiss</string>
|
||||||
|
|
||||||
<!-- IMC state fragment -->
|
<!-- IMC state fragment -->
|
||||||
<string name="imc_state_label">Assessment:</string>
|
<string name="imc_state_label">Assessment:</string>
|
||||||
|
|||||||
@@ -160,6 +160,7 @@
|
|||||||
<string name="state_disconnecting">Отключение…</string>
|
<string name="state_disconnecting">Отключение…</string>
|
||||||
<string name="state_disabled">Нет активных VPN</string>
|
<string name="state_disabled">Нет активных VPN</string>
|
||||||
<string name="state_error">Ошибка</string>
|
<string name="state_error">Ошибка</string>
|
||||||
|
<string name="dismiss">Dismiss</string>
|
||||||
|
|
||||||
<!-- IMC state fragment -->
|
<!-- IMC state fragment -->
|
||||||
<string name="imc_state_label">Assessment:</string>
|
<string name="imc_state_label">Assessment:</string>
|
||||||
|
|||||||
@@ -161,6 +161,7 @@
|
|||||||
<string name="state_disconnecting">Роз\'єднання…</string>
|
<string name="state_disconnecting">Роз\'єднання…</string>
|
||||||
<string name="state_disabled">Немає активних VPN</string>
|
<string name="state_disabled">Немає активних VPN</string>
|
||||||
<string name="state_error">Помилка</string>
|
<string name="state_error">Помилка</string>
|
||||||
|
<string name="dismiss">Dismiss</string>
|
||||||
|
|
||||||
<!-- IMC state fragment -->
|
<!-- IMC state fragment -->
|
||||||
<string name="imc_state_label">Assessment:</string>
|
<string name="imc_state_label">Assessment:</string>
|
||||||
|
|||||||
@@ -160,6 +160,7 @@
|
|||||||
<string name="state_disconnecting">断开连接中…</string>
|
<string name="state_disconnecting">断开连接中…</string>
|
||||||
<string name="state_disabled">无活跃VPN</string>
|
<string name="state_disabled">无活跃VPN</string>
|
||||||
<string name="state_error">错误</string>
|
<string name="state_error">错误</string>
|
||||||
|
<string name="dismiss">Dismiss</string>
|
||||||
|
|
||||||
<!-- IMC state fragment -->
|
<!-- IMC state fragment -->
|
||||||
<string name="imc_state_label">评估详情:</string>
|
<string name="imc_state_label">评估详情:</string>
|
||||||
|
|||||||
@@ -160,6 +160,7 @@
|
|||||||
<string name="state_disconnecting">結束連線中…</string>
|
<string name="state_disconnecting">結束連線中…</string>
|
||||||
<string name="state_disabled">無運作中的VPN</string>
|
<string name="state_disabled">無運作中的VPN</string>
|
||||||
<string name="state_error">錯誤</string>
|
<string name="state_error">錯誤</string>
|
||||||
|
<string name="dismiss">Dismiss</string>
|
||||||
|
|
||||||
<!-- IMC state fragment -->
|
<!-- IMC state fragment -->
|
||||||
<string name="imc_state_label">評估詳情:</string>
|
<string name="imc_state_label">評估詳情:</string>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
name="primary">#A2042C</color>
|
name="primary">#A2042C</color>
|
||||||
|
|
||||||
<color
|
<color
|
||||||
name="primary_dark">#000000</color>
|
name="primary_dark">#323232</color>
|
||||||
|
|
||||||
<color
|
<color
|
||||||
name="error_text">#D9192C</color>
|
name="error_text">#D9192C</color>
|
||||||
|
|||||||
@@ -163,6 +163,7 @@
|
|||||||
<string name="state_disconnecting">Disconnecting…</string>
|
<string name="state_disconnecting">Disconnecting…</string>
|
||||||
<string name="state_disabled">No active VPN</string>
|
<string name="state_disabled">No active VPN</string>
|
||||||
<string name="state_error">Error</string>
|
<string name="state_error">Error</string>
|
||||||
|
<string name="dismiss">Dismiss</string>
|
||||||
|
|
||||||
<!-- IMC state fragment -->
|
<!-- IMC state fragment -->
|
||||||
<string name="imc_state_label">Assessment:</string>
|
<string name="imc_state_label">Assessment:</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user