Java tutorial
/* * Copyright (C) 2012-2016 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * 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. */ package org.strongswan.android.ui.fragment; import android.app.Service; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import org.strongswan.android.R; import org.strongswan.android.data.VpnProfile; import org.strongswan.android.logic.VpnStateService; import org.strongswan.android.logic.VpnStateService.ErrorState; import org.strongswan.android.logic.VpnStateService.State; import org.strongswan.android.logic.VpnStateService.VpnStateListener; import org.strongswan.android.logic.imc.ImcState; import org.strongswan.android.logic.imc.RemediationInstruction; import org.strongswan.android.ui.activity.LogActivity; import org.strongswan.android.ui.activity.RemediationInstructionsActivity; import java.util.ArrayList; import java.util.List; public class VpnStateFragment extends Fragment implements VpnStateListener { private static final String KEY_ERROR_CONNECTION_ID = "error_connection_id"; private static final String KEY_DISMISSED_CONNECTION_ID = "dismissed_connection_id"; private TextView mProfileNameTextView;//??? private TextView mProfileTextView;//????? private TextView mStateTextView;//? private Button mActionButton;// private ProgressBar mProgress;//? private AlertDialog mErrorDialog; private long mErrorConnectionID; private long mDismissedConnectionID; private VpnStateService mService; private final ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { //?? mService = ((VpnStateService.LocalBinder) service).getService(); //??? mService.registerListener(VpnStateFragment.this); // updateView(); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* bind to the service only seems to work from the ApplicationContext */ Context context = getActivity().getApplicationContext(); context.bindService(new Intent(context, VpnStateService.class), mServiceConnection, Service.BIND_AUTO_CREATE); mErrorConnectionID = 0; mDismissedConnectionID = 0; if (savedInstanceState != null && savedInstanceState.containsKey(KEY_ERROR_CONNECTION_ID)) { mErrorConnectionID = (Long) savedInstanceState.getSerializable(KEY_ERROR_CONNECTION_ID); mDismissedConnectionID = (Long) savedInstanceState.getSerializable(KEY_DISMISSED_CONNECTION_ID); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putSerializable(KEY_ERROR_CONNECTION_ID, mErrorConnectionID); outState.putSerializable(KEY_DISMISSED_CONNECTION_ID, mDismissedConnectionID); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.vpn_state_fragment, null); mProgress = (ProgressBar) view.findViewById(R.id.progress); mStateTextView = (TextView) view.findViewById(R.id.vpn_state); mProfileTextView = (TextView) view.findViewById(R.id.vpn_profile_label); mProfileNameTextView = (TextView) view.findViewById(R.id.vpn_profile_name); mActionButton = (Button) view.findViewById(R.id.action); mActionButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //? if (mService != null) { mService.disconnect(); } } }); enableActionButton(null);//?? return view; } @Override public void onStart() { super.onStart(); //? if (mService != null) { mService.registerListener(this); //? updateView(); } } @Override public void onStop() { super.onStop(); //? if (mService != null) { mService.unregisterListener(this); } hideErrorDialog(); } @Override public void onDestroy() { super.onDestroy(); if (mService != null) { getActivity().getApplicationContext().unbindService(mServiceConnection); } } @Override public void stateChanged() { //?????? updateView(); } /** * ?? */ public void updateView() { long connectionID = mService.getConnectionID();//?id VpnProfile profile = mService.getProfile();//? State state = mService.getState();//? ErrorState error = mService.getErrorState();//? ImcState imcState = mService.getImcState();// String name = ""; String gateway = ""; if (profile != null) { name = profile.getName(); gateway = profile.getGateway(); } if (reportError(connectionID, name, error, imcState)) { return; } mProfileNameTextView.setText(name); switch (state) { case DISABLED://? showProfile(false); mProgress.setVisibility(View.GONE); enableActionButton(null);//?? mStateTextView.setText(R.string.state_disabled); break; case CONNECTING:// showProfile(true); mProgress.setVisibility(View.VISIBLE); enableActionButton(getString(android.R.string.cancel)); mStateTextView.setText(R.string.state_connecting); break; case CONNECTED:// showProfile(true); mProgress.setVisibility(View.GONE); enableActionButton(getString(R.string.disconnect)); mStateTextView.setText(R.string.state_connected); break; case DISCONNECTING:// showProfile(true); mProgress.setVisibility(View.VISIBLE); enableActionButton(null);//?? mStateTextView.setText(R.string.state_disconnecting); break; } } private boolean reportError(long connectionID, String name, ErrorState error, ImcState imcState) { if (connectionID > mDismissedConnectionID) { /* report error if it hasn't been dismissed yet */ mErrorConnectionID = connectionID; } else { /* ignore all other errors */ error = ErrorState.NO_ERROR; } if (error == ErrorState.NO_ERROR) { hideErrorDialog(); return false; } else if (mErrorDialog != null) { /* we already show the dialog */ return true; } mProfileNameTextView.setText(name); showProfile(true); mProgress.setVisibility(View.GONE); enableActionButton(null);//?? mStateTextView.setText(R.string.state_error); switch (error) { case AUTH_FAILED: if (imcState == ImcState.BLOCK) { showErrorDialog(R.string.error_assessment_failed); } else { showErrorDialog(R.string.error_auth_failed); } break; case PEER_AUTH_FAILED: showErrorDialog(R.string.error_peer_auth_failed); break; case LOOKUP_FAILED: showErrorDialog(R.string.error_lookup_failed); break; case UNREACHABLE: showErrorDialog(R.string.error_unreachable); break; default: showErrorDialog(R.string.error_generic); break; } return true; } /** * ??? * * @param show ?? */ private void showProfile(boolean show) { mProfileTextView.setVisibility(show ? View.VISIBLE : View.GONE); mProfileNameTextView.setVisibility(show ? View.VISIBLE : View.GONE); } //?? private void enableActionButton(String text) { mActionButton.setText(text);// mActionButton.setEnabled(text != null);//?? mActionButton.setVisibility(text != null ? View.VISIBLE : View.GONE);//?? } /** * ??? */ private void hideErrorDialog() { if (mErrorDialog != null) { mErrorDialog.dismiss(); mErrorDialog = null; } } // private void clearError() { if (mService != null) { mService.disconnect(); } mDismissedConnectionID = mErrorConnectionID; updateView(); } /** * dialog * * @param textid textid */ private void showErrorDialog(int textid) { final List<RemediationInstruction> instructions = mService.getRemediationInstructions(); final boolean show_instructions = mService.getImcState() == ImcState.BLOCK && !instructions.isEmpty(); int text = show_instructions ? R.string.show_remediation_instructions : R.string.show_log; mErrorDialog = new AlertDialog.Builder(getActivity()) .setMessage(getString(R.string.error_introduction) + " " + getString(textid)).setCancelable(false) .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<>(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(); //?dialog?GC mErrorDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { mErrorDialog = null; } }); mErrorDialog.show(); } }