2 * Copyright (C) 2013 Tobias Brunner
4 * Copyright (C) secunet Security Networks AG
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 package org
.strongswan
.android
.ui
;
19 import android
.app
.Service
;
20 import android
.content
.ComponentName
;
21 import android
.content
.Context
;
22 import android
.content
.Intent
;
23 import android
.content
.ServiceConnection
;
24 import android
.os
.Bundle
;
25 import android
.os
.IBinder
;
26 import android
.view
.GestureDetector
;
27 import android
.view
.LayoutInflater
;
28 import android
.view
.MotionEvent
;
29 import android
.view
.View
;
30 import android
.view
.View
.OnClickListener
;
31 import android
.view
.View
.OnTouchListener
;
32 import android
.view
.ViewConfiguration
;
33 import android
.view
.ViewGroup
;
34 import android
.widget
.LinearLayout
;
35 import android
.widget
.TextView
;
37 import org
.strongswan
.android
.R
;
38 import org
.strongswan
.android
.logic
.VpnStateService
;
39 import org
.strongswan
.android
.logic
.VpnStateService
.VpnStateListener
;
40 import org
.strongswan
.android
.logic
.imc
.ImcState
;
41 import org
.strongswan
.android
.logic
.imc
.RemediationInstruction
;
43 import java
.util
.ArrayList
;
45 import androidx
.core
.content
.ContextCompat
;
46 import androidx
.fragment
.app
.Fragment
;
47 import androidx
.fragment
.app
.FragmentManager
;
48 import androidx
.fragment
.app
.FragmentTransaction
;
50 public class ImcStateFragment
extends Fragment
implements VpnStateListener
52 private int mColorIsolate
;
53 private int mColorBlock
;
54 private boolean mVisible
;
55 private TextView mStateView
;
56 private TextView mAction
;
57 private LinearLayout mButton
;
58 private VpnStateService mService
;
59 private final ServiceConnection mServiceConnection
= new ServiceConnection()
62 public void onServiceDisconnected(ComponentName name
)
68 public void onServiceConnected(ComponentName name
, IBinder service
)
70 mService
= ((VpnStateService
.LocalBinder
)service
).getService();
73 mService
.registerListener(ImcStateFragment
.this);
80 public void onCreate(Bundle savedInstanceState
)
82 super.onCreate(savedInstanceState
);
84 mColorIsolate
= ContextCompat
.getColor(getActivity(), R
.color
.warning_text
);
85 mColorBlock
= ContextCompat
.getColor(getActivity(), R
.color
.error_text
);
87 /* bind to the service only seems to work from the ApplicationContext */
88 Context context
= getActivity().getApplicationContext();
89 context
.bindService(new Intent(context
, VpnStateService
.class),
90 mServiceConnection
, Service
.BIND_AUTO_CREATE
);
91 /* hide it initially */
92 getParentFragmentManager().beginTransaction().hide(this).commit();
96 public View
onCreateView(LayoutInflater inflater
, ViewGroup container
,
97 Bundle savedInstanceState
)
99 View view
= inflater
.inflate(R
.layout
.imc_state_fragment
, container
, false);
101 mButton
= (LinearLayout
)view
.findViewById(R
.id
.imc_state_button
);
102 mButton
.setOnClickListener(new OnClickListener()
105 public void onClick(View v
)
108 if (mService
!= null && !mService
.getRemediationInstructions().isEmpty())
110 intent
= new Intent(getActivity(), RemediationInstructionsActivity
.class);
111 intent
.putParcelableArrayListExtra(RemediationInstructionsFragment
.EXTRA_REMEDIATION_INSTRUCTIONS
,
112 new ArrayList
<RemediationInstruction
>(mService
.getRemediationInstructions()));
116 intent
= new Intent(getActivity(), LogActivity
.class);
118 startActivity(intent
);
121 final GestureDetector gestures
= new GestureDetector(getActivity(), new GestureDetector
.SimpleOnGestureListener()
123 /* a better value would be getScaledTouchExplorationTapSlop() but that is hidden */
124 private final int mMinDistance
= ViewConfiguration
.get(getActivity()).getScaledTouchSlop() * 4;
127 public boolean onFling(MotionEvent e1
, MotionEvent e2
, float velocityX
, float velocityY
)
129 if (Math
.abs(e1
.getX() - e2
.getX()) >= mMinDistance
)
130 { /* only if the user swiped a minimum horizontal distance */
131 if (mService
!= null)
133 mService
.setImcState(ImcState
.UNKNOWN
);
140 mButton
.setOnTouchListener(new OnTouchListener()
143 public boolean onTouch(View v
, MotionEvent event
)
145 return gestures
.onTouchEvent(event
);
149 mStateView
= (TextView
)view
.findViewById(R
.id
.imc_state
);
150 mAction
= (TextView
)view
.findViewById(R
.id
.action
);
156 public void onResume()
160 if (mService
!= null)
162 mService
.registerListener(this);
168 public void onPause()
172 if (mService
!= null)
174 mService
.unregisterListener(this);
179 public void onDestroy()
182 if (mService
!= null)
184 getActivity().getApplicationContext().unbindService(mServiceConnection
);
189 public void stateChanged()
194 public void updateView()
196 FragmentManager fm
= getParentFragmentManager();
201 FragmentTransaction ft
= fm
.beginTransaction();
203 switch (mService
.getImcState())
210 mStateView
.setText(R
.string
.imc_state_isolate
);
211 mStateView
.setTextColor(mColorIsolate
);
215 mStateView
.setText(R
.string
.imc_state_block
);
216 mStateView
.setTextColor(mColorBlock
);
222 mAction
.setText(mService
.getRemediationInstructions().isEmpty() ? R
.string
.show_log
223 : R
.string
.show_remediation_instructions
);