2727import android .text .Editable ;
2828import android .text .TextWatcher ;
2929import android .view .Menu ;
30- import android .view .View ;
31- import android .widget .LinearLayout ;
3230
3331import androidx .annotation .Nullable ;
3432import androidx .appcompat .widget .AppCompatEditText ;
3533import androidx .appcompat .widget .AppCompatImageButton ;
3634import androidx .appcompat .widget .AppCompatTextView ;
3735import androidx .appcompat .widget .PopupMenu ;
36+ import androidx .core .widget .NestedScrollView ;
3837
3938import com .smartpack .kernelmanager .R ;
39+ import com .smartpack .kernelmanager .utils .Utils ;
4040import com .smartpack .kernelmanager .utils .root .RootUtils ;
4141
42+ import java .util .ArrayList ;
43+ import java .util .ConcurrentModificationException ;
44+ import java .util .List ;
4245import java .util .Objects ;
4346
4447/**
4851public class TerminalActivity extends BaseActivity {
4952
5053 private AppCompatEditText mShellCommand ;
51- private AppCompatEditText mShellOutput ;
52- private AppCompatTextView mProgressMessage ;
53- private int i ;
54- private LinearLayout mProgressLayout ;
54+ private AppCompatTextView mClearAll , mShellOutput ;
55+ private boolean mRunning = false ;
56+ private CharSequence mHistory = null ;
5557 private static String whoAmI = RootUtils .runAndGetOutput ("whoami" );
56- private StringBuilder mLastCommand = new StringBuilder ();
58+ private List <String > mLastCommand = new ArrayList <>(), mResult = null ;
59+ private NestedScrollView mScrollView ;
5760
5861 @ SuppressLint ("SetTextI18n" )
5962 @ Override
6063 protected void onCreate (@ Nullable Bundle savedInstanceState ) {
6164 super .onCreate (savedInstanceState );
6265 setContentView (R .layout .activity_terminal );
6366
64- mProgressLayout = findViewById (R .id .progress_layout );
65- mProgressMessage = findViewById (R .id .progress_message );
6667 AppCompatImageButton mBack = findViewById (R .id .back_button );
6768 AppCompatImageButton mRecent = findViewById (R .id .recent_button );
6869 AppCompatImageButton mSave = findViewById (R .id .enter_button );
69- mBack .setOnClickListener (v -> onBackPressed ());
7070 mShellCommand = findViewById (R .id .shell_command );
7171 AppCompatTextView mShellCommandTitle = findViewById (R .id .shell_command_title );
7272 mShellOutput = findViewById (R .id .shell_output );
73+ mScrollView = findViewById (R .id .scroll_view );
74+
7375 mShellCommandTitle .setText (whoAmI );
76+
7477 mShellCommand .addTextChangedListener (new TextWatcher () {
7578 @ Override
7679 public void beforeTextChanged (CharSequence s , int start , int count , int after ) {
@@ -85,31 +88,63 @@ public void afterTextChanged(Editable s) {
8588 }
8689 }
8790 });
91+
92+ mBack .setOnClickListener (v -> onBackPressed ());
8893 mRecent .setOnClickListener (v -> {
89- String [] lines = mLastCommand .toString ().split ("," );
9094 PopupMenu popupMenu = new PopupMenu (this , mShellCommand );
9195 Menu menu = popupMenu .getMenu ();
9296 if (mLastCommand .toString ().isEmpty ()) {
9397 return ;
9498 }
95- for (i = 0 ; i < lines . length ; i ++) {
96- menu .add (Menu .NONE , i , Menu .NONE , lines [ i ] );
99+ for (String mCommand : mLastCommand ) {
100+ menu .add (Menu .NONE , Menu . NONE , Menu .NONE , mCommand );
97101 }
98102 popupMenu .setOnMenuItemClickListener (item -> {
99- for (i = 0 ; i < lines .length ; i ++) {
100- if (item .getItemId () == i ) {
101- mShellCommand .setText (lines [i ]);
102- }
103+ for (String mCommand : mLastCommand ) {
104+ mShellCommand .setText (mCommand );
103105 }
104106 return false ;
105107 });
106108 popupMenu .show ();
107109 });
108110 mSave .setOnClickListener (v -> runCommand ());
109- AppCompatTextView mClearAll = findViewById (R .id .clear_all );
111+ mClearAll = findViewById (R .id .clear_all );
110112 mClearAll .setOnClickListener (v -> {
111- clearAll ();
113+ if (mRunning ) {
114+ RootUtils .closeSU ();
115+ } else {
116+ clearAll ();
117+ }
112118 });
119+
120+ refreshStatus ();
121+ }
122+
123+ public void refreshStatus () {
124+ new Thread () {
125+ @ SuppressLint ("SetTextI18n" )
126+ @ Override
127+ public void run () {
128+ try {
129+ while (!isInterrupted ()) {
130+ Thread .sleep (100 );
131+ runOnUiThread (() -> {
132+ if (mRunning ) {
133+ mScrollView .fullScroll (NestedScrollView .FOCUS_DOWN );
134+ mClearAll .setText (R .string .cancel );
135+ try {
136+ mShellOutput .setText (Utils .getOutput (mResult ));
137+ } catch (ConcurrentModificationException | NullPointerException ignored ) {
138+ }
139+ } else {
140+ mShellOutput .setTextIsSelectable (true );
141+ mClearAll .setText (R .string .clear );
142+ }
143+ });
144+ }
145+ } catch (InterruptedException ignored ) {}
146+ }
147+ }.start ();
113148 }
114149
115150 @ SuppressLint ({"SetTextI18n" , "StaticFieldLeak" })
@@ -122,7 +157,7 @@ private void runCommand() {
122157 sb .append (" " ).append (s );
123158 }
124159 final String [] mCommand = {sb .toString ().replaceFirst (" " ,"" )};
125- mLastCommand .append (mCommand [0 ]). append ( "," );
160+ mLastCommand .add (mCommand [0 ]);
126161 if (mCommand [0 ].endsWith ("\n " )) {
127162 mCommand [0 ] = mCommand [0 ].replace ("\n " ,"" );
128163 }
@@ -135,33 +170,33 @@ private void runCommand() {
135170 mShellCommand .setText (null );
136171 } else {
137172 new AsyncTask <Void , Void , Void >() {
138- private String mResult ;
139173 @ Override
140174 protected void onPreExecute () {
141175 super .onPreExecute ();
142- mProgressMessage .setText (getString (R .string .executing ) + "..." );
143- mProgressMessage .setVisibility (View .VISIBLE );
144- mProgressLayout .setVisibility (View .VISIBLE );
176+ mShellOutput .setTextIsSelectable (false );
177+ mHistory = mShellOutput .getText ();
178+ mRunning = true ;
179+ mResult = new ArrayList <>();
145180 }
146181 @ SuppressLint ("WrongThread" )
147182 @ Override
148183 protected Void doInBackground (Void ... voids ) {
149184 if (mShellCommand .getText () != null && !mCommand [0 ].isEmpty ()) {
150- mResult = whoAmI + ": " + mCommand [0 ] + "\n " + RootUtils .runAndGetError (mCommand [0 ]);
151- if (mResult .equals (whoAmI + ": " + mCommand [0 ] + "\n " )) {
152- mResult = whoAmI + ": " + mCommand [0 ] + "\n " + mCommand [0 ];
185+ mResult .add (whoAmI + ": " + mCommand [0 ]);
186+ RootUtils .runAndGetLiveOutput (mCommand [0 ], mResult );
187+ if (Utils .getOutput (mResult ).equals (whoAmI + ": " + mCommand [0 ] + "\n " )) {
188+ mResult .add (whoAmI + ": " + mCommand [0 ] + "\n " + mCommand [0 ]);
153189 }
154190 }
155191 return null ;
156192 }
157193 @ Override
158194 protected void onPostExecute (Void aVoid ) {
159195 super .onPostExecute (aVoid );
160- mProgressMessage .setVisibility (View .GONE );
161- mProgressLayout .setVisibility (View .GONE );
162196 mShellCommand .setText (null );
163- mShellOutput .setText (mResult + "\n \n " + mShellOutput .getText ());
164- mShellOutput .setVisibility (View .VISIBLE );
197+ mShellOutput .setText (Utils .getOutput (mResult ) + "\n \n " + mHistory );
198+ mHistory = null ;
199+ mRunning = false ;
165200 }
166201 }.execute ();
167202 }
@@ -171,8 +206,13 @@ protected void onPostExecute(Void aVoid) {
171206
172207 private void clearAll () {
173208 mShellOutput .setText (null );
174- mShellOutput .setVisibility (View .GONE );
175209 mShellCommand .setText (null );
176210 }
177211
212+ @ Override
213+ public void onBackPressed () {
214+ if (mRunning ) return ;
215+ super .onBackPressed ();
216+ }
217+
178218}
0 commit comments