diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/home/HomeFragment.java b/app/src/main/java/de/jg_cody/Teraplex/ui/home/HomeFragment.java index 6dcd9a4..d6e6c96 100644 --- a/app/src/main/java/de/jg_cody/Teraplex/ui/home/HomeFragment.java +++ b/app/src/main/java/de/jg_cody/Teraplex/ui/home/HomeFragment.java @@ -1,5 +1,6 @@ package de.jg_cody.Teraplex.ui.home; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; @@ -10,8 +11,11 @@ import android.graphics.drawable.BitmapDrawable; import android.media.MediaPlayer; import android.os.Bundle; import android.os.Vibrator; +import android.text.method.HideReturnsTransformationMethod; +import android.text.method.PasswordTransformationMethod; import android.util.Base64; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -24,11 +28,16 @@ import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import com.jcraft.jsch.Channel; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Session; + import java.util.Objects; import de.jg_cody.Teraplex.MainActivity; import de.jg_cody.Teraplex.R; import de.jg_cody.Teraplex.SSH_connection; +import de.jg_cody.Teraplex.ui.terminal.Terminal; public class HomeFragment extends Fragment { @@ -37,18 +46,22 @@ public class HomeFragment extends Fragment { public static EditText ipInput; public static EditText userInput; public static EditText passwordInput; + boolean isPasswordVisible = false; Button reboot_Button; Button shutdown_Button; Button loginButton; Button logoutButton; + Terminal terminal; Button wlan_aus_Button; Button wlan_an_Button; Button kodian; Button kodiaus; + ImageView togglepassword; private HomeViewModel homeViewModel; + @SuppressLint("ClickableViewAccessibility") public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { SharedPreferences prefs = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE); @@ -80,13 +93,16 @@ public class HomeFragment extends Fragment { loginButton = (Button) root.findViewById(R.id.loginButton); reboot_Button = (Button) root.findViewById(R.id.reboot); shutdown_Button = (Button) root.findViewById(R.id.shutdown); + togglepassword = (ImageView) root.findViewById(R.id.togglepassword); SharedPreferences t = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE); if (user == null || ip == null) { loginButton.setVisibility(View.VISIBLE); + togglepassword.setVisibility(View.VISIBLE); reboot_Button.setVisibility(View.GONE); shutdown_Button.setVisibility(View.GONE); } else { loginButton.setVisibility(View.INVISIBLE); + togglepassword.setVisibility(View.INVISIBLE); ipInput.setVisibility(View.GONE); userInput.setVisibility(View.GONE); passwordInput.setVisibility(View.GONE); @@ -108,7 +124,7 @@ public class HomeFragment extends Fragment { // Specifying a listener allows you to take an action before dismissing the dialog. // The dialog is automatically dismissed when a dialog button is clicked. - .setPositiveButton(android.R.string.yes, null ) + .setPositiveButton(android.R.string.yes, null) .create(); Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round); mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id @@ -117,23 +133,64 @@ public class HomeFragment extends Fragment { user = userInput.getText().toString(); password = passwordInput.getText().toString(); ip = ipInput.getText().toString(); - SharedPreferences p = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE); - p.edit().putString("user", user).putString("password", password).putString("ip", ip).apply(); - Toast.makeText(getContext(), getString(R.string.login_saved), Toast.LENGTH_SHORT).show(); - if (user == null || ip == null) { - login_data.setText(""); - reboot_Button.setVisibility(View.GONE); - shutdown_Button.setVisibility(View.GONE); - } else { - login_data.setText(getString(R.string.sie_sind_als_angemeldet).replace("{IP}", ip).replace("{USERNAME}", user)); - logoutButton.setVisibility(View.VISIBLE); - loginButton.setVisibility(View.INVISIBLE); - ipInput.setVisibility(View.GONE); - userInput.setVisibility(View.GONE); - passwordInput.setVisibility(View.GONE); - reboot_Button.setVisibility(View.VISIBLE); - shutdown_Button.setVisibility(View.VISIBLE); - } + new Thread(new Runnable() { + @Override + public void run() { + try { + JSch jsch = new JSch(); + Session session; + session = jsch.getSession(user, ip, 22); + session.setPassword(password); + session.setUserInfo(new Terminal.MyUserInfo() { + @Override + public String getPassword() { + return super.getPassword(); + } + }); + session.setConfig("StrictHostKeyChecking", "no"); + System.out.println("CONNECT"); + session.connect(30000); + Channel channel = session.openChannel("shell"); + channel.connect(3 * 1000); + session.disconnect(); + System.out.println("DISCONNECT"); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(getContext(), "CONNECTED", Toast.LENGTH_SHORT).show(); + SharedPreferences p = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE); + p.edit().putString("user", user).putString("password", password).putString("ip", ip).apply(); + if (user == null || ip == null) { + login_data.setText(""); + reboot_Button.setVisibility(View.GONE); + shutdown_Button.setVisibility(View.GONE); + + } else { + login_data.setText(getString(R.string.sie_sind_als_angemeldet).replace("{IP}", ip).replace("{USERNAME}", user)); + logoutButton.setVisibility(View.VISIBLE); + loginButton.setVisibility(View.INVISIBLE); + togglepassword.setVisibility(View.INVISIBLE); + ipInput.setVisibility(View.GONE); + userInput.setVisibility(View.GONE); + passwordInput.setVisibility(View.GONE); + reboot_Button.setVisibility(View.VISIBLE); + shutdown_Button.setVisibility(View.VISIBLE); + } + } + }); + } catch (Exception e) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + e.printStackTrace(); + Toast.makeText(getContext(), "INVALID INPUT", Toast.LENGTH_SHORT).show(); + } + }); + + } + } + }).start(); + } } }); @@ -201,8 +258,6 @@ public class HomeFragment extends Fragment { mDialog.show(); - - } }); shutdown_Button = (Button) root.findViewById(R.id.shutdown); @@ -246,6 +301,27 @@ public class HomeFragment extends Fragment { } }); + + + if (togglepassword.getVisibility() == View.VISIBLE) { + togglepassword.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + if (isPasswordVisible == true) { + passwordInput.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); + isPasswordVisible = false; + } else { + passwordInput.setTransformationMethod(PasswordTransformationMethod.getInstance()); + isPasswordVisible = true; + } + return false; + } + }); + } + return root; + } + } + diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/terminal/Terminal.java b/app/src/main/java/de/jg_cody/Teraplex/ui/terminal/Terminal.java index 28d65b6..ed64436 100644 --- a/app/src/main/java/de/jg_cody/Teraplex/ui/terminal/Terminal.java +++ b/app/src/main/java/de/jg_cody/Teraplex/ui/terminal/Terminal.java @@ -34,7 +34,7 @@ public class Terminal { try { JSch jsch = new JSch(); - Session session = jsch.getSession(HomeFragment.user, HomeFragment.ip, 22); + session = jsch.getSession(HomeFragment.user, HomeFragment.ip, 22); session.setPassword(HomeFragment.password); session.setUserInfo(new MyUserInfo() { @@ -59,26 +59,30 @@ public class Terminal { channel.setOutputStream(Output); - - channel.connect(3 * 1000); } catch (Exception e) { e.printStackTrace(); } } - public String getTerminalOutput(){ - return new String(Output.toByteArray()).replaceAll("(\u001B\\[\\d+;\\d+m)+", "").replaceAll("\u2584", ""); + public String getTerminalOutput() { + return new String(Output.toByteArray()).replaceAll("\u001B\\[[;\\d]*m", ""); } - public void sendTerminalCommand(String terminalcommand){ + + public void sendTerminalCommand(String terminalcommand) { try { - Input.write((terminalcommand+"\n").getBytes()); + Input.write((terminalcommand + "\n").getBytes()); Input.flush(); } catch (IOException e) { e.printStackTrace(); } } + public void closeTerminal() { + session.disconnect(); + } + + public static abstract class MyUserInfo implements UserInfo, UIKeyboardInteractive { public String getPassword() { @@ -111,5 +115,6 @@ public class Terminal { boolean[] echo) { return null; } + } } \ No newline at end of file diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/terminal/TerminalFragment.java b/app/src/main/java/de/jg_cody/Teraplex/ui/terminal/TerminalFragment.java index 7395020..dcb82f5 100644 --- a/app/src/main/java/de/jg_cody/Teraplex/ui/terminal/TerminalFragment.java +++ b/app/src/main/java/de/jg_cody/Teraplex/ui/terminal/TerminalFragment.java @@ -7,6 +7,8 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.widget.Button; import android.widget.EditText; import android.widget.ScrollView; import android.widget.TextView; @@ -22,6 +24,7 @@ public class TerminalFragment extends Fragment { public static String command; + Button send_button; EditText terminal_edit_text; TextView terminal_textView; Terminal terminal; @@ -47,57 +50,83 @@ public class TerminalFragment extends Fragment { Toast.makeText(getContext(), ("test"), Toast.LENGTH_SHORT).show(); scrollView = (ScrollView) root.findViewById((R.id.scrollView)); terminal_edit_text = (EditText) root.findViewById(R.id.terminal_edit_text); - terminal_edit_text.setOnKeyListener(new View.OnKeyListener() { + send_button = (Button) root.findViewById(R.id.send_button); + send_button.setOnClickListener(new View.OnClickListener() { @Override - public boolean onKey(View view, int keyCode, KeyEvent keyEvent) { - if ((keyEvent.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { - terminal.sendTerminalCommand(terminal_edit_text.getText().toString()); + public void onClick(View view) { - - } else { - terminal_textView = (TextView) root.findViewById(R.id.terminal_textView); - new Thread() { - public void run() { - terminal = new Terminal(); - boolean isFragmentActive = true; - while (isFragmentActive) { - Fragment myFragment = (Fragment) requireActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_terminal); - if (myFragment == null) { - - isFragmentActive = false; - } - else if (myFragment.isVisible()) - { - isFragmentActive = false; - } - - try { - requireActivity().runOnUiThread(new Runnable() { - - @Override - public void run() { - boolean atBottom = scrollView.getChildAt(0).getBottom() <= (scrollView.getHeight() + scrollView.getScrollY()); - terminal_textView.setText(terminal.getTerminalOutput()); - System.out.println(atBottom); - - terminal_textView.invalidate(); - scrollView.invalidate(); - scrollView.fullScroll(View.FOCUS_DOWN); - - } - }); - Thread.sleep(250); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - }.start(); - } - return false; + if (terminal != null) { + terminal.sendTerminalCommand(terminal_edit_text.getText().toString()); + } } + }); + terminal_edit_text.setOnEditorActionListener(new EditText.OnEditorActionListener() { + @Override + public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) + { + boolean handled=false; + + // Some phones disregard the IME setting option in the xml, instead + // they send IME_ACTION_UNSPECIFIED so we need to catch that + if(EditorInfo.IME_ACTION_DONE==actionId || EditorInfo.IME_ACTION_UNSPECIFIED==actionId) + { + if (terminal != null) { + terminal.sendTerminalCommand(terminal_edit_text.getText().toString()); + Toast.makeText(getContext(), getString(R.string.login_saved), Toast.LENGTH_SHORT).show(); + } + + handled=true; + } + + return handled; + } + }); + terminal_textView = (TextView) root.findViewById(R.id.terminal_textView); + new Thread() { + public void run() { + terminal = new Terminal(); + requireActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(getContext(),"VERBUNDEN", Toast.LENGTH_SHORT).show(); + } + }); + boolean isFragmentActive = true; + while (isFragmentActive) { + Fragment myFragment = (Fragment) requireActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_terminal); + if (myFragment == null) { + + isFragmentActive = false; + } + else if (myFragment.isVisible()) + { + isFragmentActive = false; + } + + try { + requireActivity().runOnUiThread(new Runnable() { + + @Override + public void run() { + boolean atBottom = scrollView.getChildAt(0).getBottom() <= (scrollView.getHeight() + scrollView.getScrollY()); + terminal_textView.setText(terminal.getTerminalOutput()); + System.out.println(atBottom); + + terminal_textView.invalidate(); + scrollView.invalidate(); + scrollView.fullScroll(View.FOCUS_DOWN); + + } + }); + Thread.sleep(250); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }.start(); } @@ -107,6 +136,11 @@ public class TerminalFragment extends Fragment { @Override public void onDestroy() { + if (terminal != null) { + terminal.closeTerminal(); + } super.onDestroy(); } + + } \ No newline at end of file diff --git a/app/src/main/res/drawable/visibility_black_24dp.xml b/app/src/main/res/drawable/visibility_black_24dp.xml new file mode 100644 index 0000000..6fcd57a --- /dev/null +++ b/app/src/main/res/drawable/visibility_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 782394f..ec2ce15 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -159,7 +159,8 @@ app:layout_constraintEnd_toEndOf="@+id/text_home" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/text_home" - app:layout_constraintTop_toBottomOf="@+id/loginuserInput" /> + app:layout_constraintTop_toBottomOf="@+id/loginuserInput" + app:passwordToggleEnabled="true"/>