diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 009dce3..3375466 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -63,11 +63,6 @@ android:launchMode="singleTask" android:label="@string/action_about"> - - \ No newline at end of file diff --git a/app/src/main/java/org/itxtech/daedalus/Daedalus.java b/app/src/main/java/org/itxtech/daedalus/Daedalus.java index adf5568..b441735 100644 --- a/app/src/main/java/org/itxtech/daedalus/Daedalus.java +++ b/app/src/main/java/org/itxtech/daedalus/Daedalus.java @@ -83,6 +83,48 @@ public class Daedalus extends Application { prefs = null; } + public Intent getServiceIntent() { + return new Intent(this, DaedalusVpnService.class); + } + + + public boolean isAppOnForeground() { + // Returns a list of application processes that are running on the + // device + + ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); + String packageName = getApplicationContext().getPackageName(); + + List appProcesses = activityManager + .getRunningAppProcesses(); + if (appProcesses == null) + return false; + + for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { + // The name of the process that this object is associated with. + if (appProcess.processName.equals(packageName) + && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { + return true; + } + } + return false; + } + + public void deactivateService() { + startService(getServiceIntent().setAction(DaedalusVpnService.ACTION_DEACTIVATE)); + stopService(getServiceIntent()); + } + + public boolean isServiceActivated() { + ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if (DaedalusVpnService.class.getName().equals(service.service.getClassName())) { + return true; + } + } + return false; + } + public static void updateShortcut(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { Log.d("Daedalus", "Updating shortcut"); diff --git a/app/src/main/java/org/itxtech/daedalus/activity/MainActivity.java b/app/src/main/java/org/itxtech/daedalus/activity/MainActivity.java index e93e173..8a5016c 100644 --- a/app/src/main/java/org/itxtech/daedalus/activity/MainActivity.java +++ b/app/src/main/java/org/itxtech/daedalus/activity/MainActivity.java @@ -1,12 +1,10 @@ package org.itxtech.daedalus.activity; -import android.app.ActivityManager; -import android.content.Context; +import android.app.FragmentManager; +import android.app.FragmentTransaction; import android.content.Intent; import android.net.Uri; -import android.net.VpnService; import android.os.Bundle; -import android.support.design.widget.FloatingActionButton; import android.support.design.widget.NavigationView; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; @@ -14,18 +12,13 @@ import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; -import android.view.Menu; import android.view.MenuItem; -import android.view.View; -import android.widget.Button; import android.widget.TextView; import org.itxtech.daedalus.BuildConfig; import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.R; -import org.itxtech.daedalus.service.DaedalusVpnService; -import org.itxtech.daedalus.util.DnsServer; - -import java.util.List; +import org.itxtech.daedalus.fragment.DNSTestFragment; +import org.itxtech.daedalus.fragment.MainFragment; /** * Daedalus Project @@ -43,8 +36,16 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On public static final int LAUNCH_ACTION_ACTIVATE = 1; public static final int LAUNCH_ACTION_DEACTIVATE = 2; + private static final int FRAGMENT_MAIN = 0; + private static final int FRAGMENT_DNS_TEST = 1; + + private static int currentFragment = FRAGMENT_MAIN; + private static MainActivity instance = null; + private MainFragment mMain; + private DNSTestFragment mDnsTest; + public static MainActivity getInstance() { return instance; } @@ -59,14 +60,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); - FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); - fab.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(new Intent(Daedalus.getInstance(), ServerTestActivity.class)); - } - }); - DrawerLayout drawer = (DrawerLayout) findViewById(R.id.main_drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); @@ -76,26 +69,21 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); - final Button but = (Button) findViewById(R.id.button_activate); - if (isServiceActivated()) { - but.setText(R.string.button_text_deactivate); - } else { - but.setText(R.string.button_text_activate); - } - but.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (isServiceActivated()) { - deactivateService(); - } else { - activateService(); - } - } - }); - ((TextView) navigationView.getHeaderView(0).findViewById(R.id.textView_nav_version)).setText(getString(R.string.nav_version) + " " + BuildConfig.VERSION_NAME); ((TextView) navigationView.getHeaderView(0).findViewById(R.id.textView_nav_git_commit)).setText(getString(R.string.nav_git_commit) + " " + BuildConfig.GIT_COMMIT); + FragmentManager fm = getFragmentManager(); + FragmentTransaction transaction = fm.beginTransaction(); + if (currentFragment == FRAGMENT_MAIN) { + mMain = new MainFragment(); + transaction.replace(R.id.id_content, mMain); + } + if (currentFragment == FRAGMENT_DNS_TEST) { + mDnsTest = new DNSTestFragment(); + transaction.replace(R.id.id_content, mDnsTest); + } + transaction.commit(); + updateUserInterface(getIntent()); } @@ -114,6 +102,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On super.onDestroy(); Log.d("DMainActivity", "onDestroy"); + mMain = null; + mDnsTest = null; instance = null; System.gc(); } @@ -130,141 +120,60 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On int launchAction = intent.getIntExtra(LAUNCH_ACTION, LAUNCH_ACTION_NONE); if (launchAction == LAUNCH_ACTION_ACTIVATE) { Daedalus.updateShortcut(this.getApplicationContext()); - activateService(); + mMain.activateService(); } else if (launchAction == LAUNCH_ACTION_DEACTIVATE) { - deactivateService(); + Daedalus.getInstance().deactivateService(); } else { - updateUserInterface(); Daedalus.updateShortcut(this.getApplicationContext()); } } - public boolean isAppOnForeground() { - // Returns a list of application processes that are running on the - // device - - ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); - String packageName = getApplicationContext().getPackageName(); - - List appProcesses = activityManager - .getRunningAppProcesses(); - if (appProcesses == null) - return false; - - for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { - // The name of the process that this object is associated with. - if (appProcess.processName.equals(packageName) - && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { - return true; - } - } - return false; - } - - private void updateUserInterface() { - Button but = (Button) findViewById(R.id.button_activate); - if (isServiceActivated()) { - but.setText(R.string.button_text_deactivate); - } else { - but.setText(R.string.button_text_activate); - } - - } - - @Override - protected void onRestart() { - super.onRestart(); - - updateUserInterface(); - } - - private void activateService() { - Intent intent = VpnService.prepare(this); - if (intent != null) { - startActivityForResult(intent, 0); - } else { - onActivityResult(0, RESULT_OK, null); - } - } - - - private void deactivateService() { - startService(getServiceIntent().setAction(DaedalusVpnService.ACTION_DEACTIVATE)); - stopService(getServiceIntent()); - } - - private boolean isServiceActivated() { - ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); - for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { - if (DaedalusVpnService.class.getName().equals(service.service.getClassName())) { - return true; - } - } - return false; - } - - private Intent getServiceIntent() { - return new Intent(getApplicationContext(), DaedalusVpnService.class); - } - - protected void onActivityResult(int request, int result, Intent data) { - if (result == RESULT_OK) { - DaedalusVpnService.primaryServer = DnsServer.getDnsServerAddressById(Daedalus.getPrefs().getString("primary_server", "0")); - DaedalusVpnService.secondaryServer = DnsServer.getDnsServerAddressById(Daedalus.getPrefs().getString("secondary_server", "1")); - - startService(getServiceIntent().setAction(DaedalusVpnService.ACTION_ACTIVATE)); - - - ((Button) findViewById(R.id.button_activate)).setText(R.string.button_text_deactivate); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.menu_main, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - - //noinspection SimplifiableIfStatement - if (id == R.id.action_settings) { - startActivity(new Intent(this, SettingsActivity.class)); - return true; - } - - if (id == R.id.action_about) { - startActivity(new Intent(this, AboutActivity.class)); - return true; - } - - return super.onOptionsItemSelected(item); - } - @Override public boolean onNavigationItemSelected(MenuItem item) { // Handle navigation view item clicks here. int id = item.getItemId(); - if (id == R.id.action_settings) { + if (id == R.id.nav_settings) { startActivity(new Intent(this, SettingsActivity.class)); } - if (id == R.id.action_about) { + if (id == R.id.nav_about) { startActivity(new Intent(this, AboutActivity.class)); } - if (id == R.id.action_check_update) { + if (id == R.id.nav_dns_test) { + if (mDnsTest == null) { + mDnsTest = new DNSTestFragment(); + } + FragmentManager fm = getFragmentManager(); + FragmentTransaction transaction = fm.beginTransaction(); + transaction.replace(R.id.id_content, mDnsTest); + transaction.commit(); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar.setTitle(R.string.action_dns_test); + currentFragment = FRAGMENT_DNS_TEST; + item.setChecked(true); + } + + if (id == R.id.nav_home) { + if (mMain == null) { + mMain = new MainFragment(); + } + FragmentManager fm = getFragmentManager(); + FragmentTransaction transaction = fm.beginTransaction(); + transaction.replace(R.id.id_content, mMain); + transaction.commit(); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar.setTitle(R.string.app_name); + currentFragment = FRAGMENT_MAIN; + item.setChecked(true); + } + + if (id == R.id.nav_check_update) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/iTXTech/Daedalus/releases"))); } - if (id == R.id.action_bug_report) { + if (id == R.id.nav_bug_report) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/iTXTech/Daedalus/issues"))); } diff --git a/app/src/main/java/org/itxtech/daedalus/activity/ServerTestActivity.java b/app/src/main/java/org/itxtech/daedalus/fragment/DNSTestFragment.java similarity index 84% rename from app/src/main/java/org/itxtech/daedalus/activity/ServerTestActivity.java rename to app/src/main/java/org/itxtech/daedalus/fragment/DNSTestFragment.java index 237b6b1..31fd026 100644 --- a/app/src/main/java/org/itxtech/daedalus/activity/ServerTestActivity.java +++ b/app/src/main/java/org/itxtech/daedalus/fragment/DNSTestFragment.java @@ -1,13 +1,15 @@ -package org.itxtech.daedalus.activity; +package org.itxtech.daedalus.fragment; +import android.app.Fragment; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.design.widget.Snackbar; -import android.support.v7.app.AppCompatActivity; import android.util.Log; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.*; import de.measite.minidns.DNSClient; @@ -35,7 +37,7 @@ import java.util.Set; * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. */ -public class ServerTestActivity extends AppCompatActivity { +public class DNSTestFragment extends Fragment { private static final int MSG_DISPLAY_STATUS = 0; private static final int MSG_TEST_DONE = 1; @@ -46,23 +48,20 @@ public class ServerTestActivity extends AppCompatActivity { private ServerTestHandler mHandler = null; @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_server_test); + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_dns_test, container, false); - final TextView textViewTestInfo = (TextView) findViewById(R.id.textView_test_info); + final TextView textViewTestInfo = (TextView) view.findViewById(R.id.textView_test_info); - final Spinner spinnerServerChoice = (Spinner) findViewById(R.id.spinner_server_choice); - ArrayAdapter spinnerArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, DnsServer.getDnsServerNames(this)); + final Spinner spinnerServerChoice = (Spinner) view.findViewById(R.id.spinner_server_choice); + ArrayAdapter spinnerArrayAdapter = new ArrayAdapter<>(Daedalus.getInstance(), android.R.layout.simple_list_item_1, DnsServer.getDnsServerNames(Daedalus.getInstance())); spinnerServerChoice.setAdapter(spinnerArrayAdapter); spinnerServerChoice.setSelection(Integer.valueOf(Daedalus.getPrefs().getString("primary_server", "0"))); - final AutoCompleteTextView textViewTestUrl = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView_test_url); - ArrayAdapter autoCompleteArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Daedalus.DEFAULT_TEST_DOMAINS); + final AutoCompleteTextView textViewTestUrl = (AutoCompleteTextView) view.findViewById(R.id.autoCompleteTextView_test_url); + ArrayAdapter autoCompleteArrayAdapter = new ArrayAdapter<>(Daedalus.getInstance(), android.R.layout.simple_list_item_1, Daedalus.DEFAULT_TEST_DOMAINS); textViewTestUrl.setAdapter(autoCompleteArrayAdapter); - final Context context = this; - mRunnable = new Runnable() { @Override public void run() { @@ -73,7 +72,7 @@ public class ServerTestActivity extends AppCompatActivity { } StringBuilder testText = new StringBuilder(); ArrayList dnsServers = new ArrayList() {{ - add(DnsServer.getDnsServerAddressByStringDescription(context, spinnerServerChoice.getSelectedItem().toString())); + add(DnsServer.getDnsServerAddressByStringDescription(Daedalus.getInstance(), spinnerServerChoice.getSelectedItem().toString())); String servers = Daedalus.getPrefs().getString("dns_test_servers", ""); if (!servers.equals("")) { for (String server : servers.split(",")) { @@ -127,7 +126,7 @@ public class ServerTestActivity extends AppCompatActivity { } }; - final Button startTestBut = (Button) findViewById(R.id.button_start_test); + final Button startTestBut = (Button) view.findViewById(R.id.button_start_test); startTestBut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -135,7 +134,7 @@ public class ServerTestActivity extends AppCompatActivity { .setAction("Action", null).show(); startTestBut.setVisibility(View.INVISIBLE); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager imm = (InputMethodManager) Daedalus.getInstance().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); textViewTestInfo.setText(""); @@ -150,10 +149,12 @@ public class ServerTestActivity extends AppCompatActivity { mHandler = new ServerTestHandler(); mHandler.setViews(startTestBut, textViewTestInfo); + + return view; } @Override - protected void onDestroy() { + public void onDestroy() { super.onDestroy(); stopThread(); diff --git a/app/src/main/java/org/itxtech/daedalus/fragment/MainFragment.java b/app/src/main/java/org/itxtech/daedalus/fragment/MainFragment.java new file mode 100644 index 0000000..26b6e16 --- /dev/null +++ b/app/src/main/java/org/itxtech/daedalus/fragment/MainFragment.java @@ -0,0 +1,105 @@ +package org.itxtech.daedalus.fragment; + +import android.app.Activity; +import android.app.Fragment; +import android.content.Intent; +import android.net.VpnService; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import org.itxtech.daedalus.Daedalus; +import org.itxtech.daedalus.R; +import org.itxtech.daedalus.service.DaedalusVpnService; +import org.itxtech.daedalus.util.DnsServer; + +/** + * Daedalus Project + * + * @author iTXTech + * @link https://itxtech.org + *

+ * 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, version 3. + */ +public class MainFragment extends Fragment { + + private View view = null; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + view = inflater.inflate(R.layout.fragment_main, container, false); + + final Button but = (Button) view.findViewById(R.id.button_activate); + if (Daedalus.getInstance().isServiceActivated()) { + but.setText(R.string.button_text_deactivate); + } else { + but.setText(R.string.button_text_activate); + } + but.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (Daedalus.getInstance().isServiceActivated()) { + Daedalus.getInstance().deactivateService(); + } else { + activateService(); + } + } + }); + + updateUserInterface(); + + return view; + } + + @Override + public void onDestroy() { + super.onDestroy(); + + view = null; + } + + public void activateService() { + Intent intent = VpnService.prepare(Daedalus.getInstance()); + if (intent != null) { + startActivityForResult(intent, 0); + } else { + onActivityResult(0, Activity.RESULT_OK, null); + } + } + + public void onActivityResult(int request, int result, Intent data) { + if (result == Activity.RESULT_OK) { + DaedalusVpnService.primaryServer = DnsServer.getDnsServerAddressById(Daedalus.getPrefs().getString("primary_server", "0")); + DaedalusVpnService.secondaryServer = DnsServer.getDnsServerAddressById(Daedalus.getPrefs().getString("secondary_server", "1")); + + Daedalus.getInstance().startService(Daedalus.getInstance().getServiceIntent().setAction(DaedalusVpnService.ACTION_ACTIVATE)); + + + ((Button) view.findViewById(R.id.button_activate)).setText(R.string.button_text_deactivate); + } + } + + @Override + public void onResume() { + super.onResume(); + updateUserInterface(); + } + + private void updateUserInterface() { + Button but = (Button) view.findViewById(R.id.button_activate); + if (Daedalus.getInstance().isServiceActivated()) { + but.setText(R.string.button_text_deactivate); + } else { + but.setText(R.string.button_text_activate); + } + + } +} diff --git a/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java b/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java index e7da598..ea19a33 100644 --- a/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java +++ b/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java @@ -168,7 +168,7 @@ public class DaedalusVpnService extends VpnService implements Runnable { } stopSelf(); - if (shouldRefresh && MainActivity.getInstance() != null && MainActivity.getInstance().isAppOnForeground()) { + if (shouldRefresh && MainActivity.getInstance() != null && Daedalus.getInstance().isAppOnForeground()) { MainActivity.getInstance().startActivity(new Intent(getApplicationContext(), MainActivity.class).putExtra(MainActivity.LAUNCH_ACTION, MainActivity.LAUNCH_ACTION_NONE)); } else if (shouldRefresh) { Daedalus.updateShortcut(getApplicationContext()); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 0db995e..48de343 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -14,6 +14,13 @@ android:layout_width="match_parent" android:layout_height="match_parent"/> + + - diff --git a/app/src/main/res/layout/activity_server_test.xml b/app/src/main/res/layout/activity_server_test.xml deleted file mode 100644 index 1597061..0000000 --- a/app/src/main/res/layout/activity_server_test.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - -