/* * This source is part of the * _____ ___ ____ * __ / / _ \/ _ | / __/___ _______ _ * / // / , _/ __ |/ _/_/ _ \/ __/ _ `/ * \___/_/|_/_/ |_/_/ (_)___/_/ \_, / * /___/ * repository. * * Copyright (C) 2013 Benoit 'BoD' Lubek (BoD@JRAF.org) * Copyright (C) 2013-2015 Carmen Alvarez (c@rmen.ca) * * 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 ca.rmen.android.networkmonitor.app.main; import android.Manifest; import android.app.ActivityManager; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Bundle; import android.os.StrictMode; import android.os.StrictMode.ThreadPolicy; import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.SwitchPreferenceCompat; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import ca.rmen.android.networkmonitor.Constants; import ca.rmen.android.networkmonitor.R; import ca.rmen.android.networkmonitor.app.bus.NetMonBus; import ca.rmen.android.networkmonitor.app.dbops.backend.DBOpIntentService; import ca.rmen.android.networkmonitor.app.dbops.ui.Share; import ca.rmen.android.networkmonitor.app.dialog.ChoiceDialogFragment; import ca.rmen.android.networkmonitor.app.dialog.ConfirmDialogFragment; import ca.rmen.android.networkmonitor.app.dialog.DialogFragmentFactory; import ca.rmen.android.networkmonitor.app.prefs.NetMonPreferenceFragmentCompat; import ca.rmen.android.networkmonitor.app.prefs.NetMonPreferences; import ca.rmen.android.networkmonitor.app.service.NetMonService; import ca.rmen.android.networkmonitor.app.speedtest.SpeedTestPreferences; import ca.rmen.android.networkmonitor.util.Log; import permissions.dispatcher.NeedsPermission; import permissions.dispatcher.OnPermissionDenied; import permissions.dispatcher.OnShowRationale; import permissions.dispatcher.PermissionRequest; import permissions.dispatcher.RuntimePermissions; @RuntimePermissions public class MainActivity extends AppCompatActivity implements ConfirmDialogFragment.DialogButtonListener, ChoiceDialogFragment.DialogItemListener, WarningDialogFragment.DialogButtonListener { private static final String TAG = Constants.TAG + MainActivity.class.getSimpleName(); private GPSVerifier mGPSVerifier; private NetMonPreferenceFragmentCompat mPreferenceFragment; private static final String PREF_SHARE = "PREF_SHARE"; private static final String PREF_CLEAR_LOG_FILE = "PREF_CLEAR_LOG_FILE"; private static final int ID_ACTION_SHARE = 1; private static final int ID_ACTION_CLEAR = 2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPreferenceFragment = NetMonPreferenceFragmentCompat.newInstance(R.xml.preferences); getSupportFragmentManager(). beginTransaction(). replace(android.R.id.content, mPreferenceFragment). commit(); getSupportFragmentManager().executePendingTransactions(); mGPSVerifier = new GPSVerifier(this); if (getSupportActionBar() != null) { getSupportActionBar().setIcon(R.drawable.ic_launcher); getSupportActionBar().setDisplayShowHomeEnabled(true); } if (NetMonPreferences.getInstance(this).isServiceEnabled()) { startService(new Intent(MainActivity.this, NetMonService.class)); MainActivityPermissionsDispatcher.requestPermissionsWithCheck(this); } // Use strict mode for monkey tests. We can't enable strict mode for normal use // because, when sharing (exporting), the mail app may read the attachment in // the main thread. if (ActivityManager.isUserAMonkey()) StrictMode.setThreadPolicy(new ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().penaltyLog().penaltyDeath().build()); mPreferenceFragment.findPreference(PREF_SHARE).setOnPreferenceClickListener(mOnPreferenceClickListener); mPreferenceFragment.findPreference(PREF_CLEAR_LOG_FILE).setOnPreferenceClickListener(mOnPreferenceClickListener); } @NeedsPermission({Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}) void requestPermissions() { Log.v(TAG, "Permissions granted"); } @OnShowRationale({Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}) void showRationaleForPermissions(final PermissionRequest request) { new AlertDialog.Builder(this) .setMessage(R.string.permission_location_rationale) .setPositiveButton(R.string.permission_button_allow, (dialogInterface, i) -> request.proceed()) .setNegativeButton(R.string.permission_button_deny, (dialogInterface, i) -> request.cancel()) .show(); } @OnPermissionDenied({Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}) void onPermissionsDenied() { Snackbar.make(getWindow().getDecorView().getRootView(), R.string.permission_location_denied, Snackbar.LENGTH_LONG).show(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // NOTE: delegate the permission handling to generated method MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); } @Override protected void onStart() { super.onStart(); PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(mOnSharedPreferenceChangeListener); enableDBOperationPreferences(); NetMonBus.getBus().register(this); } @Override protected void onStop() { PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(mOnSharedPreferenceChangeListener); NetMonBus.getBus().unregister(this); super.onStop(); mGPSVerifier.dismissGPSDialog(); } @Override public void onWindowFocusChanged(boolean hasFocus) { if (hasFocus) { // Refresh the 'enabled' preference view boolean enabled = NetMonPreferences.getInstance(this).isServiceEnabled(); ((SwitchPreferenceCompat) mPreferenceFragment.findPreference(NetMonPreferences.PREF_SERVICE_ENABLED)).setChecked(enabled); } } @Override public void onBackPressed() { Log.v(TAG, "onBackPressed"); // Prevent the monkey from exiting the app, to maximize the time the monkey spends testing the app. if (ActivityManager.isUserAMonkey()) { Log.v(TAG, "Sorry, monkeys must stay in the cage"); return; } super.onBackPressed(); } @SuppressWarnings("unused") @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) public void onDBOperationStarted(NetMonBus.DBOperationStarted event) { Log.d(TAG, "onDBOperationStarted() called with " + "event = [" + event + "]"); disableDBOperationPreferences(event.name); } @SuppressWarnings("unused") @Subscribe public void onDBOperationEnded(NetMonBus.DBOperationEnded event) { Log.d(TAG, "onDBOperationEnded() called with " + "event = [" + event + "]"); enableDBOperationPreferences(); } private void disableDBOperationPreferences(String summary) { mPreferenceFragment.findPreference(PREF_SHARE).setEnabled(false); mPreferenceFragment.findPreference(PREF_SHARE).setSummary(summary); mPreferenceFragment.findPreference(PREF_CLEAR_LOG_FILE).setEnabled(false); mPreferenceFragment.findPreference(PREF_CLEAR_LOG_FILE).setSummary(summary); } private void enableDBOperationPreferences() { mPreferenceFragment.findPreference(PREF_SHARE).setEnabled(true); mPreferenceFragment.findPreference(PREF_SHARE).setSummary(""); mPreferenceFragment.findPreference(PREF_CLEAR_LOG_FILE).setEnabled(true); mPreferenceFragment.findPreference(PREF_CLEAR_LOG_FILE).setSummary(null); } private final OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { NetMonPreferences prefs = NetMonPreferences.getInstance(MainActivity.this); if (NetMonPreferences.PREF_SERVICE_ENABLED.equals(key)) { if (sharedPreferences.getBoolean(NetMonPreferences.PREF_SERVICE_ENABLED, NetMonPreferences.PREF_SERVICE_ENABLED_DEFAULT)) { mGPSVerifier.verifyGPS(); if (prefs.getShowAppWarning()) { WarningDialogFragment.show(MainActivity.this); } else { onAppWarningOkClicked(); } MainActivityPermissionsDispatcher.requestPermissionsWithCheck(MainActivity.this); } } else if (NetMonPreferences.PREF_UPDATE_INTERVAL.equals(key)) { if (prefs.isFastPollingEnabled()) { prefs.setConnectionTestEnabled(false); if (prefs.getDBRecordCount() < 0) prefs.setDBRecordCount(10000); SpeedTestPreferences.getInstance(MainActivity.this).setEnabled(false); DialogFragmentFactory.showWarningDialog(MainActivity.this, getString(R.string.warning_fast_polling_title), getString(R.string.warning_fast_polling_message)); } } } }; @Override public void onOkClicked(int actionId, Bundle extras) { if (actionId == ID_ACTION_CLEAR) { Log.v(TAG, "Clicked ok to clear log"); DBOpIntentService.startActionPurge(this, 0); } } @Override public void onCancelClicked(int actionId, Bundle extras) { } @Override public void onItemSelected(int actionId, int which) { // The user picked a file format to export. if (actionId == ID_ACTION_SHARE) { String[] exportChoices = getResources().getStringArray(R.array.export_choices); String selectedShareFormat = exportChoices[which]; Share.share(this, selectedShareFormat); } } @Override public void onAppWarningOkClicked() { startService(new Intent(MainActivity.this, NetMonService.class)); } @Override public void onAppWarningCancelClicked() { NetMonPreferences.getInstance(this).setServiceEnabled(false); } private final Preference.OnPreferenceClickListener mOnPreferenceClickListener = preference -> { if (PREF_SHARE.equals(preference.getKey())) { DialogFragmentFactory.showChoiceDialog(MainActivity.this, getString(R.string.export_choice_title), getResources().getStringArray(R.array.export_choices), -1, ID_ACTION_SHARE); } else if (PREF_CLEAR_LOG_FILE.equals(preference.getKey())) { DialogFragmentFactory.showConfirmDialog(MainActivity.this, getString(R.string.action_clear), getString(R.string.confirm_logs_clear), ID_ACTION_CLEAR, null); } return false; }; }