package com.amaze.filemanager.fragments;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.support.v7.widget.AppCompatCheckBox;
import android.support.v7.widget.AppCompatEditText;
import android.text.Html;
import android.text.InputType;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.amaze.filemanager.R;
import com.amaze.filemanager.activities.MainActivity;
import com.amaze.filemanager.services.ftpservice.FTPService;
import com.amaze.filemanager.utils.Utils;
import com.amaze.filemanager.utils.color.ColorUsage;
import com.amaze.filemanager.utils.theme.AppTheme;
import java.io.File;
import java.io.InputStream;
import java.util.Objects;
/**
* Created by yashwanthreddyg on 10-06-2016.
*/
public class FTPServerFragment extends Fragment {
private TextView statusText, username, password, port, sharedPath;
private AppCompatEditText usernameEditText, passwordEditText;
private TextInputLayout usernameTextInput, passwordTextInput;
private AppCompatCheckBox mAnonymousCheckBox, mSecureCheckBox;
private Button ftpBtn;
private MainActivity mainActivity;
private View rootView, startDividerView, statusDividerView;
private int skin_color, skinTwoColor, accentColor;
private Spanned spannedStatusNoConnection, spannedStatusConnected;
private Spanned spannedStatusSecure, spannedStatusNotRunning;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mainActivity = (MainActivity) getActivity();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_ftp, container, false);
statusText =(TextView) rootView.findViewById(R.id.text_view_ftp_status);
username = (TextView) rootView.findViewById(R.id.text_view_ftp_username);
password = (TextView) rootView.findViewById(R.id.text_view_ftp_password);
port = (TextView) rootView.findViewById(R.id.text_view_ftp_port);
sharedPath = (TextView) rootView.findViewById(R.id.text_view_ftp_path);
ftpBtn = (Button) rootView.findViewById(R.id.startStopButton);
startDividerView = rootView.findViewById(R.id.divider_ftp_start);
statusDividerView = rootView.findViewById(R.id.divider_ftp_status);
String statusHead = getResources().getString(R.string.ftp_status_title) + ": ";
skin_color = mainActivity.getColorPreference().getColor(ColorUsage.PRIMARY);
skinTwoColor = mainActivity.getColorPreference().getColor(ColorUsage.PRIMARY_TWO);
accentColor = mainActivity.getColorPreference().getColor(ColorUsage.ACCENT);
spannedStatusConnected = Html.fromHtml(statusHead + "<b> " +
"<font color='" + accentColor + "'>"
+ getResources().getString(R.string.ftp_status_running) + "</font></b>");
spannedStatusNoConnection = Html.fromHtml(statusHead + "<b> " +
"<font color='" + Utils.getColor(getContext(), android.R.color.holo_red_light) + "'>"
+ getResources().getString(R.string.ftp_status_no_connection) + "</font></b>");
spannedStatusNotRunning = Html.fromHtml(statusHead + "<b> " +
getResources().getString(R.string.ftp_status_not_running) + "</b>");
spannedStatusSecure = Html.fromHtml(statusHead + "<b> " +
"<font color='" + Utils.getColor(getContext(), android.R.color.holo_green_light) + "'>"
+ getResources().getString(R.string.ftp_status_secure_connection) + "</font></b>");
updateStatus();
//light theme
if (mainActivity.getAppTheme().equals(AppTheme.LIGHT)) {
startDividerView.setBackgroundColor(Utils.getColor(getContext(), R.color.divider));
statusDividerView.setBackgroundColor(Utils.getColor(getContext(), R.color.divider));
} else {
//dark
startDividerView.setBackgroundColor(Utils.getColor(getContext(), R.color.divider_dark_card));
statusDividerView.setBackgroundColor(Utils.getColor(getContext(), R.color.divider_dark_card));
}
ftpBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!FTPService.isRunning()) {
if (FTPService.isConnectedToWifi(getContext()))
startServer();
else {
// no wifi, we shouldn't be here in the first place, because of broadcast
// receiver, but just to be sure
statusText.setText(spannedStatusNoConnection);
}
} else {
stopServer();
}
}
});
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
mainActivity.setActionBarTitle(getResources().getString(R.string.ftp));
mainActivity.floatingActionButton.hideMenuButton(true);
mainActivity.buttonBarFrame.setVisibility(View.GONE);
mainActivity.supportInvalidateOptionsMenu();
mainActivity.updateViews(new ColorDrawable(MainActivity.currentTab==1 ?
skinTwoColor : skin_color));
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.choose_ftp_port:
int currentFtpPort = getDefaultPortFromPreferences();
new MaterialDialog.Builder(getActivity())
.input(getString(R.string.ftp_port_edit_menu_title), Integer.toString(currentFtpPort), true, new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
}
})
.inputType(InputType.TYPE_CLASS_NUMBER)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
EditText editText = dialog.getInputEditText();
if (editText != null) {
String name = editText.getText().toString();
int portNumber = Integer.parseInt(name);
if (portNumber < 1024) {
Toast.makeText(getActivity(), R.string.ftp_port_change_error_invalid, Toast.LENGTH_SHORT)
.show();
} else {
changeFTPServerPort(portNumber);
Toast.makeText(getActivity(), R.string.ftp_port_change_success, Toast.LENGTH_SHORT)
.show();
}
}
}
})
.positiveText(getResources().getString(R.string.change).toUpperCase())
.negativeText(R.string.cancel)
.build()
.show();
return true;
case R.id.ftp_path:
MaterialDialog.Builder dialogBuilder = new MaterialDialog.Builder(getActivity());
dialogBuilder.title(getString(R.string.ftp_path));
dialogBuilder.input(getString(R.string.ftp_path_hint),
getDefaultPathFromPreferences(),
false, new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
}
});
dialogBuilder.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
EditText editText = dialog.getInputEditText();
if (editText != null) {
String path = editText.getText().toString();
File pathFile = new File(path);
if (pathFile.exists() && pathFile.isDirectory()) {
changeFTPServerPath(pathFile.getPath());
Toast.makeText(getActivity(), R.string.ftp_path_change_success,
Toast.LENGTH_SHORT)
.show();
} else {
// try to get parent
File pathParentFile = new File(pathFile.getParent());
if (pathParentFile.exists() && pathParentFile.isDirectory()) {
changeFTPServerPath(pathParentFile.getPath());
Toast.makeText(getActivity(), R.string.ftp_path_change_success,
Toast.LENGTH_SHORT)
.show();
} else {
// don't have access, print error
Toast.makeText(getActivity(), R.string.ftp_path_change_error_invalid,
Toast.LENGTH_SHORT)
.show();
}
}
}
}
});
dialogBuilder.positiveText(getResources().getString(R.string.change).toUpperCase())
.negativeText(R.string.cancel)
.build()
.show();
return true;
case R.id.ftp_login:
MaterialDialog.Builder loginDialogBuilder = new MaterialDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View rootView = inflater.inflate(R.layout.dialog_ftp_login, null);
initLoginDialogViews(rootView);
loginDialogBuilder.customView(rootView, true);
loginDialogBuilder.title(getString(R.string.ftp_login));
loginDialogBuilder.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
if (mAnonymousCheckBox.isChecked()) {
// remove preferences
setFTPUsername("");
setFTPPassword("");
} else {
if (passwordEditText.getText().toString().equals("")) {
passwordTextInput.setError(getResources().getString(R.string.field_empty));
} else if (usernameEditText.getText().toString().equals("")) {
usernameTextInput.setError(getResources().getString(R.string.field_empty));
} else {
// password and username field not empty, let's set them to preferences
setFTPUsername(usernameEditText.getText().toString());
setFTPPassword(passwordEditText.getText().toString());
}
}
if (mSecureCheckBox.isChecked()) {
setSecurePreference(true);
} else setSecurePreference(false);
}
});
loginDialogBuilder.positiveText(getResources().getString(R.string.set).toUpperCase())
.negativeText(getResources().getString(R.string.cancel))
.build()
.show();
return true;
case R.id.ftp_timeout:
MaterialDialog.Builder timeoutBuilder = new MaterialDialog.Builder(getActivity());
timeoutBuilder.title(getResources().getString(R.string.ftp_timeout) + " (" +
getResources().getString(R.string.ftp_seconds) + ")");
timeoutBuilder.input(String.valueOf(FTPService.DEFAULT_TIMEOUT + " " +
getResources().getString(R.string.ftp_seconds)), String.valueOf(getFTPTimeout()),
true, new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
boolean isInputInteger;
try {
// try parsing for integer check
Integer.parseInt(input.toString());
isInputInteger = true;
} catch (NumberFormatException e) {
isInputInteger = false;
}
if (input.length()==0 || !isInputInteger)
setFTPTimeout(FTPService.DEFAULT_TIMEOUT);
else
setFTPTimeout(Integer.valueOf(input.toString()));
}
});
timeoutBuilder.positiveText(getResources().getString(R.string.set).toUpperCase())
.negativeText(getResources().getString(R.string.cancel))
.build()
.show();
return true;
}
return false;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
mainActivity.getMenuInflater().inflate(R.menu.ftp_server_menu, menu);
}
private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMan.getActiveNetworkInfo();
if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI) {
// connected to wifi
ftpBtn.setEnabled(true);
} else {
// wifi connection lost
stopServer();
statusText.setText(spannedStatusNoConnection);
ftpBtn.setEnabled(true);
ftpBtn.setEnabled(false);
ftpBtn.setText(getResources().getString(R.string.start_ftp).toUpperCase());
}
}
};
private BroadcastReceiver ftpReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Objects.equals(action, FTPService.ACTION_STARTED)) {
if (getSecurePreference()) {
statusText.setText(spannedStatusSecure);
} else {
statusText.setText(spannedStatusConnected);
}
ftpBtn.setText(getResources().getString(R.string.stop_ftp).toUpperCase());
} else if (Objects.equals(action, FTPService.ACTION_FAILEDTOSTART)) {
statusText.setText(spannedStatusNotRunning);
Toast.makeText(getContext(),
getResources().getString(R.string.unknown_error), Toast.LENGTH_LONG).show();
ftpBtn.setText(getResources().getString(R.string.start_ftp).toUpperCase());
} else if (Objects.equals(action, FTPService.ACTION_STOPPED)) {
statusText.setText(spannedStatusNotRunning);
ftpBtn.setText(getResources().getString(R.string.start_ftp).toUpperCase());
}
}
};
/**
* Sends a broadcast to start ftp server
*/
private void startServer() {
getContext().sendBroadcast(new Intent(FTPService.ACTION_START_FTPSERVER));
}
/**
* Sends a broadcast to stop ftp server
*/
private void stopServer() {
getContext().sendBroadcast(new Intent(FTPService.ACTION_STOP_FTPSERVER));
}
@Override
public void onResume() {
super.onResume();
IntentFilter wifiFilter = new IntentFilter();
wifiFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getContext().registerReceiver(mWifiReceiver, wifiFilter);
IntentFilter ftpFilter = new IntentFilter();
ftpFilter.addAction(FTPService.ACTION_STARTED);
ftpFilter.addAction(FTPService.ACTION_STOPPED);
ftpFilter.addAction(FTPService.ACTION_FAILEDTOSTART);
getContext().registerReceiver(ftpReceiver, ftpFilter);
}
@Override
public void onPause() {
super.onPause();
getContext().unregisterReceiver(mWifiReceiver);
getContext().unregisterReceiver(ftpReceiver);
}
/**
* Update UI widgets after change in shared preferences
*/
private void updateStatus() {
if (!FTPService.isRunning()) {
if (!FTPService.isConnectedToWifi(getContext())) {
statusText.setText(spannedStatusNoConnection);
ftpBtn.setEnabled(false);
} else {
statusText.setText(spannedStatusNotRunning);
ftpBtn.setEnabled(true);
}
ftpBtn.setText(getResources().getString(R.string.start_ftp).toUpperCase());
} else {
statusText.setText(spannedStatusConnected);
ftpBtn.setEnabled(true);
ftpBtn.setText(getResources().getString(R.string.stop_ftp).toUpperCase());
}
username.setText(getResources().getString(R.string.username) + ": " +
getUsernameFromPreferences());
password.setText(getResources().getString(R.string.password) + ": " +
getPasswordFromPreferences());
port.setText(getResources().getString(R.string.ftp_port) + ": " +
getDefaultPortFromPreferences());
sharedPath.setText(getResources().getString(R.string.ftp_path) + ": " +
getDefaultPathFromPreferences());
}
private void initLoginDialogViews(View loginDialogView) {
usernameEditText = (AppCompatEditText) loginDialogView.findViewById(R.id.edit_text_dialog_ftp_username);
passwordEditText = (AppCompatEditText) loginDialogView.findViewById(R.id.edit_text_dialog_ftp_password);
usernameTextInput = (TextInputLayout) loginDialogView.findViewById(R.id.text_input_dialog_ftp_username);
passwordTextInput = (TextInputLayout) loginDialogView.findViewById(R.id.text_input_dialog_ftp_password);
mAnonymousCheckBox = (AppCompatCheckBox) loginDialogView.findViewById(R.id.checkbox_ftp_anonymous);
mSecureCheckBox = (AppCompatCheckBox) loginDialogView.findViewById(R.id.checkbox_ftp_secure);
mAnonymousCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
usernameEditText.setEnabled(false);
passwordEditText.setEnabled(false);
} else {
usernameEditText.setEnabled(true);
passwordEditText.setEnabled(true);
}
}
});
// init dialog views as per preferences
if (getUsernameFromPreferences().equals(FTPService.DEFAULT_USERNAME)) {
mAnonymousCheckBox.setChecked(true);
} else {
usernameEditText.setText(getUsernameFromPreferences());
passwordEditText.setText(getPasswordFromPreferences());
}
if (getSecurePreference()) {
mSecureCheckBox.setChecked(true);
} else mSecureCheckBox.setChecked(false);
// check if we have a keystore
InputStream stream = getResources().openRawResource(R.raw.key);
if (stream == null) {
mSecureCheckBox.setEnabled(false);
mSecureCheckBox.setChecked(false);
setSecurePreference(false);
}
}
/**
* @return address at which server is running
*/
private String getFTPAddressString() {
return "ftp://" + FTPService.getLocalInetAddress(getContext()).getHostAddress() + ":" + FTPService.getPort();
}
private int getDefaultPortFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getInt(FTPService.PORT_PREFERENCE_KEY, FTPService.DEFAULT_PORT);
}
private String getUsernameFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getString(FTPService.KEY_PREFERENCE_USERNAME, FTPService.DEFAULT_USERNAME);
}
private String getPasswordFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getString(FTPService.KEY_PREFERENCE_PASSWORD, "");
}
private String getDefaultPathFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getString(FTPService.KEY_PREFERENCE_PATH, FTPService.DEFAULT_PATH);
}
private void changeFTPServerPort(int port) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit()
.putInt(FTPService.PORT_PREFERENCE_KEY, port)
.apply();
updateStatus();
}
private void changeFTPServerPath(String path) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putString(FTPService.KEY_PREFERENCE_PATH, path).apply();
updateStatus();
}
private void setFTPUsername(String username) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putString(FTPService.KEY_PREFERENCE_USERNAME, username).apply();
updateStatus();
}
private void setFTPPassword(String password) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putString(FTPService.KEY_PREFERENCE_PASSWORD, password).apply();
updateStatus();
}
/**
* Returns timeout from preferences
* @return timeout in seconds
*/
private int getFTPTimeout() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getInt(FTPService.KEY_PREFERENCE_TIMEOUT, FTPService.DEFAULT_TIMEOUT);
}
private void setFTPTimeout(int seconds) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putInt(FTPService.KEY_PREFERENCE_TIMEOUT, seconds).apply();
}
private boolean getSecurePreference() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getBoolean(FTPService.KEY_PREFERENCE_SECURE, FTPService.DEFAULT_SECURE);
}
private void setSecurePreference(boolean isSecureEnabled) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putBoolean(FTPService.KEY_PREFERENCE_SECURE, isSecureEnabled).apply();
}
}