/******************************************************************************* * Copyright 2013-2016 alladin-IT GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package at.alladin.rmbt.android.main; import java.net.InetAddress; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; import android.location.Location; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.telephony.TelephonyManager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import at.alladin.openrmbt.android.R; import at.alladin.rmbt.android.main.InfoCollector.InfoCollectorType; import at.alladin.rmbt.android.main.InfoCollector.OnInformationChangedListener; import at.alladin.rmbt.android.main.titlepage.IpCheckRunnable; import at.alladin.rmbt.android.main.titlepage.IpCheckRunnable.OnIpCheckFinishedListener; import at.alladin.rmbt.android.main.titlepage.NetworkWatcherRunnable; import at.alladin.rmbt.android.main.titlepage.NetworkWatcherRunnable.OnActiveNetworkChangeListener; import at.alladin.rmbt.android.util.CheckIpTask.IpVersionType; import at.alladin.rmbt.android.util.ConfigHelper; import at.alladin.rmbt.android.util.Helperfunctions; import at.alladin.rmbt.android.util.InformationCollector; import at.alladin.rmbt.android.util.net.InterfaceTrafficGatherer; import at.alladin.rmbt.android.util.net.InterfaceTrafficGatherer.TrafficClassificationEnum; import at.alladin.rmbt.android.util.net.NetworkFamilyEnum; import at.alladin.rmbt.android.util.net.NetworkInfoCollector; import at.alladin.rmbt.android.util.net.NetworkInfoCollector.CaptivePortalStatusEnum; import at.alladin.rmbt.android.util.net.NetworkInfoCollector.OnNetworkInfoChangedListener; import at.alladin.rmbt.android.util.net.NetworkUtil; import at.alladin.rmbt.android.util.net.NetworkUtil.MinMax; /** * * @author * */ public class RMBTMainMenuFragment extends Fragment { public static enum OverlayType { IPV4(R.string.title_screen_ipv4_overlay, R.id.title_page_ipv4_button), IPV6(R.string.title_screen_ipv6_overlay, R.id.title_page_ipv6_button), TRAFFIC(R.string.title_screen_traffic, R.id.title_page_traffic_button), LOCATION(R.string.result_page_title_map, R.id.title_page_location_button); protected int resId; protected int buttonId; OverlayType(int resId, int buttonId) { this.resId = resId; this.buttonId = buttonId; } public int getResourceId() { return resId; } public int getButtonId() { return buttonId; } } public final static String BUNDLE_INFO_LAST_ANTENNA_IMAGE = "last_antenna_image"; public final static String BUNDLE_INFO_CAPTIVE_PORTAL_STATUS = "captive_portal_status"; public final static String BUNDLE_INFO_COLLECTOR = "info"; public final static int BACKGROUND_TRAFFIC_MEASUREMENT_TIME = 1000; public final static int INFORMATION_COLLECTOR_TIME = 1000; private InformationCollector informationCollector; /** * */ private static final String DEBUG_TAG = "RMBTMainMenuFragment"; private TextView startButtonText; private TextView infoNetwork; private TextView infoNetworkLabel; private TextView infoNetworkType; private TextView infoSignalStrength; private TextView infoSignalStrengthExtra; //private TextView infoIp; //private TextView infoTraffic; private View ipv4Button; private View ipv6Button; private View locationButton; private View trafficButton; private View startButton; private ImageView ipv4View; private ImageView ipv6View; private ImageView locationView; private ImageView antennaView; private ImageView ulSpeedView; private ImageView dlSpeedView; private ImageView captivePortalWarning; public boolean runInfoRunnable = false; public Handler infoHandler = new Handler(); private InfoCollector infoCollector = InfoCollector.getInstance(); private InterfaceTrafficGatherer interfaceTrafficGatherer; private Animation pulseAnimation; private NetworkWatcherRunnable networkWatcherRunnable; private IpCheckRunnable ipv4CheckRunnable; private IpCheckRunnable ipv6CheckRunnable; private Integer lastSignal; private ListView infoOverlayList; private RelativeLayout infoOverlay; private TextView infoOverlayTitle; private Map<OverlayType, InfoArrayAdapter> infoValueListAdapterMap = new HashMap<RMBTMainMenuFragment.OverlayType, InfoArrayAdapter>(); //developer code info private TextView developerCodeInfoView; /** * number format used for ul/dl traffic */ DecimalFormat speedFormat; /** * */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); Log.i(DEBUG_TAG, "onCreate"); pulseAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.pulse); interfaceTrafficGatherer = new InterfaceTrafficGatherer(); informationCollector = new InformationCollector(getActivity(), false, false); speedFormat = new DecimalFormat(String.format("@@ %s", getActivity().getResources().getString(R.string.test_mbps))); ipv4CheckRunnable = new IpCheckRunnable(getActivity(), IpVersionType.V4, true); ipv4CheckRunnable.addListener(new OnIpCheckFinishedListener() { @Override public void onFinish(InetAddress privAddress, InetAddress pubAddress, InetAddress oldPrivAddress, InetAddress oldPubAddress) { if ((privAddress != null && !privAddress.equals(oldPrivAddress)) || (pubAddress != null && !pubAddress.equals(oldPubAddress)) || (privAddress == null && oldPrivAddress != null || pubAddress == null && oldPubAddress != null)) { Log.d(DEBUG_TAG, "new ipv4, run captive portal check..."); ((RMBTMainActivity) getActivity()).getNetworkInfoCollector().checkForCaptivePortal(); } } }); ipv6CheckRunnable = new IpCheckRunnable(getActivity(), IpVersionType.V6, true); ipv6CheckRunnable.addListener(new OnIpCheckFinishedListener() { @Override public void onFinish(InetAddress privAddress, InetAddress pubAddress, InetAddress oldPrivAddress, InetAddress oldPubAddress) { if ((privAddress != null && !privAddress.equals(oldPrivAddress)) || (pubAddress != null && !pubAddress.equals(oldPubAddress)) || (privAddress == null && oldPrivAddress != null || pubAddress == null && oldPubAddress != null)) { Log.d(DEBUG_TAG, "new ipv6, run captive portal check..."); ((RMBTMainActivity) getActivity()).getNetworkInfoCollector().checkForCaptivePortal(); } } }); networkWatcherRunnable = new NetworkWatcherRunnable(getActivity()); networkWatcherRunnable.addListener(new OnActiveNetworkChangeListener() { @Override public void onChange(Set<InetAddress> oldInterfaceSet, Set<InetAddress> newInterfaceSet, String oldSsid, String newSsid) { ipv4CheckRunnable.clearIps(); ipv6CheckRunnable.clearIps(); ((RMBTMainActivity) getActivity()).getNetworkInfoCollector().checkForCaptivePortal(); } }); } /** * * @return */ public RMBTMainActivity getMainActivity() { return (RMBTMainActivity) getActivity(); } /** * */ @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.title_screen, container, false); return createView(view, inflater, savedInstanceState); } /** * * @param view * @param inflater * @param savedInstanceState * @return */ private View createView(View view, LayoutInflater inflater, Bundle savedInstanceState) { startButton = view.findViewById(R.id.title_page_start_button); startButtonText = (TextView) view.findViewById(R.id.title_page_start_button_text); if (startButton != null) { startButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { ((RMBTMainActivity) getActivity()).checkPermissionsAndStartTest();} }); } final View startButtonLayout = view.findViewById(R.id.title_page_start_button_layout); if (startButtonLayout != null) { final Animation delayedPulseAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.delayed_pulse); delayedPulseAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { startButtonLayout.startAnimation(animation); } }); startButtonLayout.startAnimation(delayedPulseAnimation); } //infoLocation = (TextView) view.findViewById(R.id.info_gps_location); //infoLocation.setVisibility(View.GONE); infoNetwork = (TextView) view.findViewById(R.id.info_network_name); setViewVisibility(infoNetwork, View.GONE); infoNetworkLabel = (TextView) view.findViewById(R.id.info_network_name_label); setViewVisibility(infoNetworkLabel, View.GONE); infoNetworkType = (TextView) view.findViewById(R.id.info_network_type); setViewVisibility(infoNetworkType, View.GONE); infoSignalStrength = (TextView) view.findViewById(R.id.info_signal_strength); setViewVisibility(infoSignalStrength, View.GONE); infoSignalStrengthExtra = (TextView) view.findViewById(R.id.info_signal_strength_extra); setViewVisibility(infoSignalStrengthExtra, View.INVISIBLE); locationView = (ImageView) view.findViewById(R.id.location_image); setViewVisibility(locationView, View.INVISIBLE); locationButton = view.findViewById(R.id.title_page_location_button); if (locationButton != null) { locationButton.setOnClickListener(detailShowOnClickListener); } ipv4View = (ImageView) view.findViewById(R.id.ipv4_status); ipv4Button = view.findViewById(R.id.title_page_ipv4_button); if (ipv4Button != null) { ipv4Button.setOnClickListener(detailShowOnClickListener); } ipv6View = (ImageView) view.findViewById(R.id.ipv6_status); ipv6Button = view.findViewById(R.id.title_page_ipv6_button); if (ipv6Button != null) { ipv6Button.setOnClickListener(detailShowOnClickListener); } trafficButton = view.findViewById(R.id.title_page_traffic_button); if (trafficButton != null) { trafficButton.setOnClickListener(detailShowOnClickListener); } infoOverlayList = (ListView) view.findViewById(R.id.info_overlay_list); if (infoOverlayList != null) { infoValueListAdapterMap.put(OverlayType.TRAFFIC, new InfoArrayAdapter(getActivity(), OverlayType.TRAFFIC, InfoOverlayEnum.DL_TRAFFIC,InfoOverlayEnum.UL_TRAFFIC)); infoValueListAdapterMap.put(OverlayType.IPV4, new InfoArrayAdapter(getActivity(), OverlayType.IPV4, InfoOverlayEnum.IPV4, InfoOverlayEnum.IPV4_PUB)); infoValueListAdapterMap.put(OverlayType.IPV6, new InfoArrayAdapter(getActivity(), OverlayType.IPV6, InfoOverlayEnum.IPV6, InfoOverlayEnum.IPV6_PUB)); infoValueListAdapterMap.put(OverlayType.LOCATION, new InfoArrayAdapter(getActivity(), OverlayType.LOCATION, InfoOverlayEnum.LOCATION)); } infoOverlayTitle = (TextView) view.findViewById(R.id.info_overlay_title); infoOverlay = (RelativeLayout) view.findViewById(R.id.info_overlay); if (infoOverlay != null) { if (infoOverlay.getVisibility() == View.GONE) { infoOverlay.setOnClickListener(detailHideOnClickListener); infoOverlayList.setOnItemClickListener(detailHideOnItemClickListener); } } captivePortalWarning = (ImageView) view.findViewById(R.id.captive_portal_image); antennaView = (ImageView) view.findViewById(R.id.antenne_image); if (antennaView != null) { //antennaView.setOnClickListener(detailShowOnClickListener); if (savedInstanceState != null && savedInstanceState.containsKey(BUNDLE_INFO_LAST_ANTENNA_IMAGE)) { int antennaImageId = savedInstanceState.getInt(BUNDLE_INFO_LAST_ANTENNA_IMAGE); antennaView.setImageResource(antennaImageId); antennaView.setTag(antennaImageId); } } ulSpeedView = (ImageView) view.findViewById(R.id.traffic_ul_image); dlSpeedView = (ImageView) view.findViewById(R.id.traffic_dl_image); developerCodeInfoView = (TextView) view.findViewById(R.id.developerCodeInfo); return view; } @Override public void onPause() { Log.i(DEBUG_TAG, "onPause"); super.onPause(); infoCollector.removeListener(onInfoChangedListener); NetworkInfoCollector.getInstance().removeOnNetworkInfoChangedListener(onNetworkChangedListener); runInfoRunnable = false; //infoLocation.setVisibility(View.GONE); setViewVisibility(infoNetwork, View.GONE); setViewVisibility(infoNetworkLabel, View.GONE); setViewVisibility(infoNetworkType, View.GONE); setViewVisibility(infoSignalStrength, View.GONE); setViewVisibility(infoSignalStrengthExtra, View.INVISIBLE); setViewVisibility(locationView, View.INVISIBLE); if (informationCollector != null) { informationCollector.unload(); } infoHandler.removeCallbacks(infoRunnable); infoHandler.removeCallbacks(interfaceTrafficRunnable); } @Override public void onResume() { Log.i(DEBUG_TAG, "onResume"); super.onResume(); if (startButtonText != null) { startButtonText.setText(ConfigHelper.isLoopMode(getActivity()) ? R.string.menu_button_loop : R.string.menu_button_start); } infoCollector.addListener(onInfoChangedListener); NetworkInfoCollector.getInstance().addOnNetworkChangedListener(onNetworkChangedListener); if (informationCollector != null) { runInfoRunnable = true; informationCollector.init(); } infoHandler.post(infoRunnable); infoHandler.post(interfaceTrafficRunnable); infoCollector.refresh(); getActivity().getActionBar().show(); ((RMBTMainActivity) getActivity()).setLockNavigationDrawer(false); } public Runnable interfaceTrafficRunnable = new Runnable() { @Override public void run() { if (interfaceTrafficGatherer != null) { interfaceTrafficGatherer.run(); final long rxRate = interfaceTrafficGatherer.getRxRate(); final long txRate = interfaceTrafficGatherer.getTxRate(); TrafficClassificationEnum rxTrafficClass = TrafficClassificationEnum.classify(rxRate); TrafficClassificationEnum txTrafficClass = TrafficClassificationEnum.classify(txRate); infoCollector.setUlTraffic(txTrafficClass); infoCollector.setDlTraffic(rxTrafficClass); } if (infoOverlay != null && infoOverlay.getVisibility() == View.VISIBLE) { ((BaseAdapter) infoOverlayList.getAdapter()).notifyDataSetChanged(); } infoHandler.postDelayed(interfaceTrafficRunnable, BACKGROUND_TRAFFIC_MEASUREMENT_TIME); } }; /** * */ public Runnable infoRunnable = new Runnable() { @Override public void run() { if (informationCollector != null) { String signalTerm = getActivity().getString(R.string.term_signal); Location loc = informationCollector.getLocationInfo(); infoCollector.setLocation(loc); int lastNetworkType = informationCollector.getNetwork(); String lastNetworkTypeString = Helperfunctions.getNetworkTypeName(lastNetworkType); //System.out.println("lastNetworkType: " + lastNetworkType + ", lastNetworkTypeString: " + lastNetworkTypeString); Integer curSignal = lastSignal; if (!"UNKNOWN".equals(lastNetworkTypeString)) { setViewVisibility(infoSignalStrength, View.VISIBLE); Integer signal = informationCollector.getSignal(); if (!"BLUETOOTH".equals(lastNetworkTypeString) && !"ETHERNET".equals(lastNetworkTypeString)) { if (signal != null && signal > Integer.MIN_VALUE && signal < 0) { int signalType = informationCollector.getSignalType(); curSignal = signal; if (signalType == InformationCollector.SINGAL_TYPE_RSRP) { infoSignalStrength.setText(getString(R.string.term_signal) + ": " + signal + " dBm"); infoCollector.setSignal(signal); Integer signalRsrq = informationCollector.getSignalRsrq(); if (signalRsrq != null) { if (infoSignalStrengthExtra.getVisibility() == View.INVISIBLE) { infoSignalStrengthExtra.setVisibility(View.VISIBLE); } infoCollector.setSignalRsrq(signalRsrq); infoSignalStrengthExtra.setText(getString(R.string.term_signal_quality) + ": " + signalRsrq + " dB"); } else { infoSignalStrengthExtra.setVisibility(View.INVISIBLE); } } else { infoCollector.setSignal(curSignal); infoSignalStrength.setText(signalTerm + ": " + signal + " dBm"); infoSignalStrengthExtra.setVisibility(View.INVISIBLE); } } else { curSignal = Integer.MIN_VALUE; infoSignalStrength.setVisibility(View.INVISIBLE); infoSignalStrengthExtra.setVisibility(View.INVISIBLE); } } } if (infoNetworkType != null) { if (lastNetworkTypeString != null && !"UNKNOWN".equals(lastNetworkTypeString)) { if (infoNetwork != null) { if (infoNetwork.getVisibility() == View.GONE) { infoNetwork.setVisibility(View.VISIBLE); setViewVisibility(infoNetworkLabel, View.VISIBLE); } String networkName = informationCollector.getOperatorName(); if (networkName != null && !"()".equals(networkName)) { infoCollector.setNetworkName(networkName); infoNetwork.setText(networkName); } else { infoCollector.setNetworkName(networkName); infoNetwork.setVisibility(View.GONE); setViewVisibility(infoNetworkLabel, View.GONE); } } if (antennaView != null && antennaView.getVisibility() != View.VISIBLE) { antennaView.setVisibility(View.VISIBLE); } lastSignal = curSignal; NetworkFamilyEnum networkFamily = NetworkFamilyEnum.getFamilyByNetworkId(lastNetworkTypeString); if (NetworkFamilyEnum.UNKNOWN.equals(networkFamily)) { infoNetworkType.setVisibility(View.GONE); infoCollector.setNetworkTypeString(lastNetworkTypeString); infoNetworkType.setText(lastNetworkTypeString); } else { if (lastNetworkTypeString.equals(NetworkFamilyEnum.WLAN.getNetworkFamily())) { infoNetworkType.setVisibility(View.GONE); } else { infoNetworkType.setVisibility(View.VISIBLE); if (lastNetworkTypeString.equals(networkFamily.getNetworkFamily())) { infoCollector.setNetworkTypeString(lastNetworkTypeString); infoNetworkType.setText(lastNetworkTypeString); } else { infoCollector.setNetworkTypeString(networkFamily.getNetworkFamily() + "/" + lastNetworkTypeString); infoNetworkType.setText(networkFamily.getNetworkFamily() + "/" + lastNetworkTypeString); } } } } else { curSignal = Integer.MIN_VALUE; lastSignal = curSignal; // Log.d(DEBUG_TAG,"lastNetworkTypeString: " + lastNetworkTypeString); infoCollector.setSignal(lastSignal); infoCollector.setNetworkName(null); infoNetworkType.setVisibility(View.GONE); infoNetwork.setVisibility(View.GONE); setViewVisibility(infoNetworkLabel, View.GONE); setViewVisibility(infoSignalStrength, View.GONE); setViewVisibility(infoSignalStrengthExtra, View.INVISIBLE); if (antennaView != null && antennaView.getVisibility() != View.VISIBLE) { refreshAntennaImage(curSignal); } } } else if (antennaView != null && antennaView.getVisibility() != View.VISIBLE) { // Log.d(DEBUG_TAG,"lastNetworkTypeString: " + lastNetworkTypeString); curSignal = Integer.MIN_VALUE; lastSignal = curSignal; infoCollector.setSignal(lastSignal); refreshAntennaImage(Integer.MIN_VALUE); } if (curSignal != null) { refreshAntennaImage(curSignal); } //infoCollector.setIpv4(ConfigHelper.getLastIp(getActivity())); networkWatcherRunnable.run(); ipv4CheckRunnable.run(); ipv6CheckRunnable.run(); infoCollector.refreshIpAndAntenna(); infoCollector.dispatchInfoChangedEvent(InfoCollectorType.IPV4, null, infoCollector.getIpv4()); infoCollector.dispatchInfoChangedEvent(InfoCollectorType.IPV6, null, infoCollector.getIpv6()); final NetworkInfoCollector netInfo = ((RMBTMainActivity) getActivity()).getNetworkInfoCollector(); if (netInfo != null) { infoCollector.setCaptivePortalFound(netInfo.getCaptivePortalStatus().equals(CaptivePortalStatusEnum.FOUND)); } // if (netInfo != null) { // if (ConfigHelper.isIpPolling(getActivity())) { // netInfo.gatherIpInformation(true); // } // else { // if (NetworkInfoCollector.IP_METHOD == NetworkInfoCollector.IP_METHOD_NETWORKINTERFACE) { // netInfo.gatherInterfaceInformation(true); // } // else { // netInfo.gatherIpInformation(false); // } // } // // infoCollector.setHasControlServerConnection(netInfo.hasIpFromControlServer()); // infoCollector.setCaptivePortalFound(netInfo.getCaptivePortalStatus().equals(CaptivePortalStatusEnum.FOUND)); // infoCollector.refreshIpAndAntenna(); // infoCollector.dispatchInfoChangedEvent(InfoCollectorType.IPV4, null, infoCollector.getIpv4()); // infoCollector.dispatchInfoChangedEvent(InfoCollectorType.IPV6, null, infoCollector.getIpv6()); // // netInfo.onNetworkChange(getActivity(), null); // } if (netInfo.getCaptivePortalStatus() == CaptivePortalStatusEnum.FOUND || netInfo.getCaptivePortalStatus() == CaptivePortalStatusEnum.NOT_FOUND) { setCaptivePortalStatus(netInfo.getCaptivePortalStatus() == CaptivePortalStatusEnum.FOUND); } } if (runInfoRunnable) { informationCollector.reInit(); infoHandler.postDelayed(infoRunnable, INFORMATION_COLLECTOR_TIME); } if (developerCodeInfoView != null && ConfigHelper.isDevEnabled(getActivity())) { setViewText(developerCodeInfoView, getActivity().getString(R.string.title_screen_developer)); setViewVisibility(developerCodeInfoView, View.VISIBLE); } } }; public void refreshAntennaImage(int signal) { if (antennaView.getVisibility() != View.VISIBLE) { antennaView.setVisibility(View.VISIBLE); } int antennaImageRes = getAntennaImageResourceId(signal); antennaView.setImageResource(antennaImageRes); antennaView.setTag(antennaImageRes); } /** * * @param signal * @return */ private int getAntennaImageResourceId(int signal) { int lastNetworkType = informationCollector.getNetwork(); String lastNetworkTypeString = Helperfunctions.getNetworkTypeName(lastNetworkType); if (lastNetworkType == TelephonyManager.NETWORK_TYPE_UNKNOWN) // || signal == Integer.MIN_VALUE) return R.drawable.signal_no_connection; boolean wlan = "WLAN".equals(lastNetworkTypeString); int signalType = informationCollector.getSignalType(); double relativeSignal = -1d; MinMax<Integer> signalBounds = NetworkUtil.getSignalStrengthBounds(signalType); //System.out.println("SIGNAL STRENGTH TYPE: " + signalType + " -> " + signalBounds + " / SIGNAL: " + signal); if (! (signalBounds.min == Integer.MIN_VALUE || signalBounds.max == Integer.MAX_VALUE)) { relativeSignal = (double)(signal - signalBounds.min) / (double)(signalBounds.max - signalBounds.min); } //System.out.println("relativeSignal: " + relativeSignal + ", networkType: " + networkType + ", lastNetworkTypeString: " + lastNetworkTypeString); if (relativeSignal < 0.25d) { return (wlan ? R.drawable.signal_wlan_25 : R.drawable.signal_mobile_25); } else if (relativeSignal < 0.5d) { return (wlan ? R.drawable.signal_wlan_50 : R.drawable.signal_mobile_50); } else if (relativeSignal < 0.75d) { return (wlan ? R.drawable.signal_wlan_75 : R.drawable.signal_mobile_75); } else { return (wlan ? R.drawable.signal_wlan : R.drawable.signal_mobile); } } /** * */ private final OnInformationChangedListener onInfoChangedListener = new OnInformationChangedListener() { @Override public void onInformationChanged(InfoCollectorType type, Object oldValue, Object newValue) { switch (type) { case LOCATION: if (locationView != null) { if (locationView.getVisibility() == View.INVISIBLE) { locationView.setVisibility(View.VISIBLE); } locationView.setImageResource(newValue != null ? R.drawable.ic_action_location_found : R.drawable.ic_action_location_off); } if (newValue == null) { infoValueListAdapterMap.get(OverlayType.LOCATION).removeElement(InfoOverlayEnum.LOCATION_ACCURACY); infoValueListAdapterMap.get(OverlayType.LOCATION).removeElement(InfoOverlayEnum.LOCATION_AGE); infoValueListAdapterMap.get(OverlayType.LOCATION).removeElement(InfoOverlayEnum.LOCATION_SOURCE); infoValueListAdapterMap.get(OverlayType.LOCATION).removeElement(InfoOverlayEnum.LOCATION_ALTITUDE); } else { infoValueListAdapterMap.get(OverlayType.LOCATION).addElement(InfoOverlayEnum.LOCATION_ACCURACY); infoValueListAdapterMap.get(OverlayType.LOCATION).addElement(InfoOverlayEnum.LOCATION_AGE); infoValueListAdapterMap.get(OverlayType.LOCATION).addElement(InfoOverlayEnum.LOCATION_SOURCE); infoValueListAdapterMap.get(OverlayType.LOCATION).addElement(InfoOverlayEnum.LOCATION_ALTITUDE); } break; case NETWORK_TYPE: if (antennaView != null) { //System.out.println("NETWORK_TYPE changed to: " + newValue); Integer signal = informationCollector.getSignal(); refreshAntennaImage(signal != null ? signal : Integer.MIN_VALUE); } //no break; here!! //if the network type or the network family changes, the same label TextView is used case NETWORK_FAMILY: if (infoNetworkType != null && infoNetworkType.getVisibility() == View.VISIBLE) { infoNetworkType.startAnimation(pulseAnimation); //((RMBTMainActivity)getActivity()).checkIp(); } break; case NETWORK_NAME: //reset all IPs on network change name: ipv4CheckRunnable.clearIps(); ipv6CheckRunnable.clearIps(); ((RMBTMainActivity) getActivity()).getNetworkInfoCollector().checkForCaptivePortal(); if (infoNetwork != null && infoNetwork.getVisibility() == View.VISIBLE) { if (newValue != null && !((String) newValue).trim().equals("()")) { Log.d(DEBUG_TAG, "networkName: " + newValue); infoNetwork.startAnimation(pulseAnimation); } } break; case SIGNAL_RSRQ: if (infoSignalStrengthExtra != null && infoSignalStrengthExtra.getVisibility() == View.VISIBLE) { if (oldValue != null && ((Integer)oldValue != 0)) { infoSignalStrengthExtra.startAnimation(pulseAnimation); } } break; case SIGNAL: if (antennaView != null && antennaView.getVisibility() == View.VISIBLE && newValue != null) { refreshAntennaImage((Integer) newValue); } if (type.equals(InfoCollectorType.SIGNAL) && infoSignalStrength != null && infoSignalStrength.getVisibility() == View.VISIBLE) { if (oldValue != null && ((Integer)oldValue != 0)) { infoSignalStrength.startAnimation(pulseAnimation); } } break; case IPV4: case IPV6: if (getActivity() != null) { NetworkInfoCollector netInfo = ((RMBTMainActivity) getActivity()).getNetworkInfoCollector(); if (netInfo != null) { if (ipv4CheckRunnable.getPubAddress() != null) { infoValueListAdapterMap.get(OverlayType.IPV4).addElement(InfoOverlayEnum.IPV4_PUB); } else { infoValueListAdapterMap.get(OverlayType.IPV4).removeElement(InfoOverlayEnum.IPV4_PUB); } if (ipv6CheckRunnable.getPubAddress() != null) { infoValueListAdapterMap.get(OverlayType.IPV6).addElement(InfoOverlayEnum.IPV6_PUB); } else { infoValueListAdapterMap.get(OverlayType.IPV6).removeElement(InfoOverlayEnum.IPV6_PUB); } if (ipv4View != null) { ipv4View.setImageResource(ipv4CheckRunnable.getIpStatus(ipv6CheckRunnable).getResourceId()); } if (ipv6View != null) { ipv6View.setImageResource(ipv6CheckRunnable.getIpStatus(ipv4CheckRunnable).getResourceId()); } } } break; case UL_TRAFFIC: if (ulSpeedView != null) { TrafficClassificationEnum trafficEnum = (TrafficClassificationEnum) newValue; ulSpeedView.setImageResource(trafficEnum.getResId()); ulSpeedView.setRotation(180f); } break; case DL_TRAFFIC: if (dlSpeedView != null) { TrafficClassificationEnum trafficEnum = (TrafficClassificationEnum) newValue; dlSpeedView.setImageResource(trafficEnum.getResId()); } break; case CAPTIVE_PORTAL_STATUS: setCaptivePortalStatus((Boolean) newValue); break; default: break; } } }; /** * * @param hasCaptivePortal */ private void setCaptivePortalStatus(boolean hasCaptivePortal) { if (captivePortalWarning != null) { captivePortalWarning.setVisibility(hasCaptivePortal ? View.VISIBLE : View.GONE); } if (!hasCaptivePortal) { infoValueListAdapterMap.get(OverlayType.IPV4).removeElement(InfoOverlayEnum.CAPTIVE_PORTAL_STATUS); infoValueListAdapterMap.get(OverlayType.IPV6).removeElement(InfoOverlayEnum.CAPTIVE_PORTAL_STATUS); } else { infoValueListAdapterMap.get(OverlayType.IPV4).addElement(InfoOverlayEnum.CAPTIVE_PORTAL_STATUS); infoValueListAdapterMap.get(OverlayType.IPV6).addElement(InfoOverlayEnum.CAPTIVE_PORTAL_STATUS); } } /** * */ private final OnClickListener detailShowOnClickListener = new OnClickListener() { @Override public void onClick(View v) { if (infoOverlay != null) { switch (v.getId()) { case R.id.title_page_ipv4_button: infoOverlayTitle.setText(getResources().getText(OverlayType.IPV4.getResourceId())); infoOverlayList.setAdapter(infoValueListAdapterMap.get(OverlayType.IPV4)); break; case R.id.title_page_ipv6_button: infoOverlayTitle.setText(getResources().getText(OverlayType.IPV6.getResourceId())); infoOverlayList.setAdapter(infoValueListAdapterMap.get(OverlayType.IPV6)); break; case R.id.title_page_location_button: infoOverlayTitle.setText(getResources().getText(R.string.title_screen_info_overlay_location)); infoOverlayList.setAdapter(infoValueListAdapterMap.get(OverlayType.LOCATION)); break; case R.id.title_page_traffic_button: default: infoOverlayTitle.setText(getResources().getText(OverlayType.TRAFFIC.getResourceId())); infoOverlayList.setAdapter(infoValueListAdapterMap.get(OverlayType.TRAFFIC)); break; } //System.out.println("SHOWING INFO OVERLAY"); if (ipv4Button != null) { ipv4Button.setOnClickListener(detailHideOnClickListener); } if (ipv6Button != null) { ipv6Button.setOnClickListener(detailHideOnClickListener); } //antennaView.setOnClickListener(detailHideOnClickListener); trafficButton.setOnClickListener(detailHideOnClickListener); locationButton.setOnClickListener(detailHideOnClickListener); infoOverlay.setVisibility(View.VISIBLE); infoOverlay.bringToFront(); infoOverlayList.invalidate(); } } }; /** * */ private final OnClickListener detailHideOnClickListener = new OnClickListener() { @Override public void onClick(View v) { if (infoOverlay != null) { if ((((InfoArrayAdapter) infoOverlayList.getAdapter()).getOverlayType().getButtonId() == v.getId()) || v.getId() == R.id.info_overlay) { hideOverlayAndReenableOnClickListeners(); } else { detailShowOnClickListener.onClick(v); } } } }; /** * */ OnItemClickListener detailHideOnItemClickListener = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { hideOverlayAndReenableOnClickListeners(); } }; /** * */ private void hideOverlayAndReenableOnClickListeners() { infoOverlay.setVisibility(View.GONE); if (ipv4Button != null) { ipv4Button.setOnClickListener(detailShowOnClickListener); } if (ipv6Button != null) { ipv6Button.setOnClickListener(detailShowOnClickListener); } //antennaView.setOnClickListener(detailShowOnClickListener); trafficButton.setOnClickListener(detailShowOnClickListener); locationButton.setOnClickListener(detailShowOnClickListener); } /** * */ private OnNetworkInfoChangedListener onNetworkChangedListener = new OnNetworkInfoChangedListener() { @Override public void onChange(InfoFlagEnum infoFlag, Object newValue) { switch (infoFlag) { case NETWORK_CONNECTION_CHANGED: if ((Boolean) newValue) { if (startButton != null && startButtonText != null) { startButton.setAlpha(1f); startButton.setEnabled(true); startButtonText.setAlpha(1f); } } else { if (startButton != null && startButtonText != null) { startButton.setAlpha(0.3f); startButtonText.setAlpha(0.3f); startButton.setEnabled(false); } } break; default: if (infoCollector != null) { if (infoFlag == InfoFlagEnum.PRIVATE_IPV4_CHANGED || infoFlag == InfoFlagEnum.PRIVATE_IPV6_CHANGED) { if (NetworkInfoCollector.getInstance().hasConnectionFromAndroidApi()) { infoCollector.dispatchInfoChangedEvent(InfoCollectorType.SIGNAL, 0, infoCollector.getSignal()); infoCollector.dispatchInfoChangedEvent(InfoCollectorType.SIGNAL_RSRQ, 0, infoCollector.getSignalRsrq()); } else { infoCollector.setSignal(Integer.MIN_VALUE); infoCollector.setSignalRsrq(null); } } infoCollector.dispatchInfoChangedEvent(InfoCollectorType.IPV4, infoCollector.getIpv4(), newValue); infoCollector.dispatchInfoChangedEvent(InfoCollectorType.IPV6, infoCollector.getIpv6(), newValue); } } } }; /** * * @author lb * */ private class InfoArrayAdapter extends ArrayAdapter<InfoOverlayEnum> { private List<InfoOverlayEnum> infoList; private final Activity context; private final OverlayType overlayType; class ViewHolder { public TextView name; public TextView value; } public InfoArrayAdapter(Activity context, OverlayType overlayType, InfoOverlayEnum... infoArray) { super(context, R.layout.test_result_detail_item); this.context = context; this.overlayType = overlayType; this.infoList = new ArrayList<RMBTMainMenuFragment.InfoOverlayEnum>(); for (InfoOverlayEnum e : infoArray) { infoList.add(e); } } public OverlayType getOverlayType() { return overlayType; } public void removeElement(InfoOverlayEnum e) { if (this.infoList.contains(e)) { //System.out.println("removing element: " + e); this.infoList.remove(e); notifyDataSetChanged(); } } public void addElement(InfoOverlayEnum e) { addElement(e, Integer.MAX_VALUE); } public void addElement(InfoOverlayEnum e, int index) { if (!this.infoList.contains(e)) { //System.out.println("adding element: " + e); if (index > this.infoList.size()) { this.infoList.add(e); } else { this.infoList.add(index, e); } notifyDataSetChanged(); } } @Override public int getCount() { return (infoList != null ? infoList.size() : 0); } @Override public View getView(int position, View convertView, ViewGroup parent) { View rowView = convertView; // reuse views if (rowView == null) { LayoutInflater inflater = context.getLayoutInflater(); rowView = inflater.inflate(R.layout.info_overlay_detail_item, null); // configure view holder ViewHolder viewHolder = new ViewHolder(); viewHolder.name = (TextView) rowView.findViewById(R.id.name); viewHolder.value = (TextView) rowView.findViewById(R.id.value); rowView.setTag(viewHolder); } // fill data NetworkInfoCollector netInfo = ((RMBTMainActivity) getActivity()).getNetworkInfoCollector(); ViewHolder holder = (ViewHolder) rowView.getTag(); holder.name.setText(infoList.get(position).getTitle(context)); switch (infoList.get(position)) { case DL_TRAFFIC: holder.value.setText(speedFormat.format(((double)interfaceTrafficGatherer.getRxRate() / 125000D))); break; case UL_TRAFFIC: holder.value.setText(speedFormat.format(((double)interfaceTrafficGatherer.getTxRate() / 125000D))); break; case LOCATION: String locationString = ""; if (infoCollector.getLocation() != null) { locationString = Helperfunctions.getLocationString(getActivity(), getResources(), infoCollector.getLocation() ,0); } else { locationString = getResources().getString(R.string.not_available); } holder.value.setText(locationString); break; case LOCATION_ACCURACY: locationString = ""; if (infoCollector.getLocation() != null) { final int satellites; if (infoCollector.getLocation().getExtras() != null) satellites = infoCollector.getLocation().getExtras().getInt("satellites"); else satellites = 0; locationString = Helperfunctions.convertLocationAccuracy(getResources(), infoCollector.getLocation().hasAccuracy(), infoCollector.getLocation().getAccuracy(), satellites); } holder.value.setText(locationString); break; case LOCATION_AGE: locationString = ""; if (infoCollector.getLocation() != null) { locationString = Helperfunctions.convertLocationTime(infoCollector.getLocation().getTime()); } holder.value.setText(locationString); break; case LOCATION_SOURCE: locationString = ""; if (infoCollector.getLocation() != null) { locationString = Helperfunctions.convertLocationProvider(getResources(), infoCollector.getLocation().getProvider()); } holder.value.setText(locationString); break; case LOCATION_ALTITUDE: locationString = ""; if (infoCollector.getLocation() != null) { if (infoCollector.getLocation().hasAltitude()) { locationString = Helperfunctions.convertLocationAltitude(getResources(), infoCollector.getLocation().hasAltitude(), infoCollector.getLocation().getAltitude()); } else { locationString = getActivity().getString(R.string.not_available); } } holder.value.setText(locationString); break; case IPV4: if (ipv4CheckRunnable.getPrivAddress() != null) { holder.value.setText(ipv4CheckRunnable.getPrivAddress().getHostAddress()); } else { holder.name.setText(""); holder.value.setText(getResources().getString(R.string.not_available)); } break; case IPV6: if (ipv6CheckRunnable.getPrivAddress() != null) { holder.value.setText(ipv6CheckRunnable.getPrivAddress().getHostAddress()); } else { holder.name.setText(""); holder.value.setText(getResources().getString(R.string.not_available)); } break; case IPV4_PUB: if (ipv4CheckRunnable.getPubAddress() != null) { holder.value.setText(ipv4CheckRunnable.getPubAddress().getHostAddress()); } else { holder.value.setText(getResources().getString(R.string.not_available)); } break; case IPV6_PUB: if (ipv6CheckRunnable.getPubAddress() != null) { holder.value.setText(ipv6CheckRunnable.getPubAddress().getHostAddress()); } else { holder.value.setText(getResources().getString(R.string.not_available)); } break; case CAPTIVE_PORTAL_STATUS: holder.value.setText(netInfo.getCaptivePortalStatus().getTitle(context)); break; case IS_LINK_LOCAL6: if (ipv6CheckRunnable.getPrivAddress() != null) { holder.value.setText("" + ipv6CheckRunnable.getPrivAddress().isLinkLocalAddress()); } break; case IS_LOOPBACK6: if (ipv6CheckRunnable.getPrivAddress() != null) { holder.value.setText("" + ipv6CheckRunnable.getPrivAddress().isLoopbackAddress()); } break; case IS_LOOPBACK4: if (ipv4CheckRunnable.getPrivAddress() != null) { holder.value.setText("" + ipv4CheckRunnable.getPrivAddress().isLoopbackAddress()); } break; default: break; } return rowView; } } public static enum InfoOverlayEnum { IPV4(R.string.title_screen_info_overlay_ipv4_private), IS_LOOPBACK4(R.string.title_screen_info_overlay_is_loopback), IPV6(R.string.title_screen_info_overlay_ipv6_private), IS_LOOPBACK6(R.string.title_screen_info_overlay_is_loopback), IS_LINK_LOCAL6(R.string.title_screen_info_overlay_is_link_local), IPV4_PUB(R.string.title_screen_info_overlay_ipv4_public), IPV6_PUB(R.string.title_screen_info_overlay_ipv6_public), UL_TRAFFIC(R.string.title_screen_info_overlay_ul_traffic), DL_TRAFFIC(R.string.title_screen_info_overlay_dl_traffic), CONTROL_SERVER_CONNECTION(R.string.title_screen_info_overlay_control_server_conn), CAPTIVE_PORTAL_STATUS(R.string.title_screen_info_overlay_captive_portal_status), LOCATION_ACCURACY(R.string.title_screen_info_overlay_location_accuracy), LOCATION_AGE(R.string.title_screen_info_overlay_location_age), LOCATION_SOURCE(R.string.title_screen_info_overlay_location_source), LOCATION_ALTITUDE(R.string.title_screen_info_overlay_location_altitude), LOCATION(R.string.title_screen_info_overlay_location_position); protected final int resourceId; protected final String title; private InfoOverlayEnum(final String title) { this.title = title; this.resourceId = -1; } private InfoOverlayEnum(final int resourceId) { this.resourceId = resourceId; this.title = null; } public int getResourceId() { return this.resourceId; } public String getTitle(Context context) { if (title != null) { return title; } return context.getString(resourceId); } } /** * * @return */ public boolean onBackPressed() { int screenSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; if (infoOverlay.getVisibility() == View.VISIBLE && screenSize < Configuration.SCREENLAYOUT_SIZE_LARGE) { infoOverlay.setVisibility(View.GONE); return true; } return false; } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (antennaView != null && antennaView.getTag() != null) { outState.putInt(BUNDLE_INFO_LAST_ANTENNA_IMAGE, (Integer) antennaView.getTag()); } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); LayoutInflater inflater = LayoutInflater.from(getActivity()); populateViewForOrientation(inflater, (ViewGroup) getView()); } /** * * @param inflater * @param view */ private void populateViewForOrientation(LayoutInflater inflater, ViewGroup view) { int antennaResId = Integer.MIN_VALUE; if (antennaView != null && antennaView.getTag() != null) { antennaResId = (Integer) antennaView.getTag(); } view.removeAllViewsInLayout(); View v = inflater.inflate(R.layout.title_screen, view); createView(v, inflater, null); if (antennaResId != Integer.MIN_VALUE) { antennaView.setImageResource(antennaResId); antennaView.setVisibility(View.VISIBLE); } //restore all information now: infoCollector.refresh(); infoCollector.dispatchInfoChangedEvent(InfoCollectorType.DL_TRAFFIC, null, TrafficClassificationEnum.classify(interfaceTrafficGatherer.getRxRate())); infoCollector.dispatchInfoChangedEvent(InfoCollectorType.UL_TRAFFIC, null, TrafficClassificationEnum.classify(interfaceTrafficGatherer.getTxRate())); if (startButtonText != null) { startButtonText.setText(ConfigHelper.isLoopMode(getActivity()) ? R.string.menu_button_loop : R.string.menu_button_start); } } /** * * @return */ public InformationCollector getInformationCollector() { return informationCollector; } public void setViewVisibility(View view, int visibility) { if (view != null && view.getVisibility()!=visibility) { view.setVisibility(visibility); } } public void setViewText(TextView view, String text) { setViewText(view, text, null); } public void setViewText(TextView view, String text, TextView alternativeView) { if (view != null) { view.setText(text); } else if (alternativeView != null) { alternativeView.setText(alternativeView.getText() + " " + text); } } }