这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 12 additions & 23 deletions app/src/main/java/com/termux/app/TermuxActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.view.ContextMenu;
Expand All @@ -21,7 +20,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.autofill.AutofillManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
Expand Down Expand Up @@ -181,7 +179,8 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo
private static final int CONTEXT_MENU_SELECT_URL_ID = 0;
private static final int CONTEXT_MENU_SHARE_TRANSCRIPT_ID = 1;
private static final int CONTEXT_MENU_SHARE_SELECTED_TEXT = 10;
private static final int CONTEXT_MENU_AUTOFILL_ID = 2;
private static final int CONTEXT_MENU_AUTOFILL_USERNAME = 11;
private static final int CONTEXT_MENU_AUTOFILL_PASSWORD = 2;
private static final int CONTEXT_MENU_RESET_TERMINAL_ID = 3;
private static final int CONTEXT_MENU_KILL_PROCESS_ID = 4;
private static final int CONTEXT_MENU_STYLING_ID = 5;
Expand Down Expand Up @@ -632,20 +631,16 @@ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuIn
TerminalSession currentSession = getCurrentSession();
if (currentSession == null) return;

boolean addAutoFillMenu = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AutofillManager autofillManager = getSystemService(AutofillManager.class);
if (autofillManager != null && autofillManager.isEnabled()) {
addAutoFillMenu = true;
}
}
boolean autoFillEnabled = mTerminalView.isAutoFillEnabled();

menu.add(Menu.NONE, CONTEXT_MENU_SELECT_URL_ID, Menu.NONE, R.string.action_select_url);
menu.add(Menu.NONE, CONTEXT_MENU_SHARE_TRANSCRIPT_ID, Menu.NONE, R.string.action_share_transcript);
if (!DataUtils.isNullOrEmpty(mTerminalView.getStoredSelectedText()))
menu.add(Menu.NONE, CONTEXT_MENU_SHARE_SELECTED_TEXT, Menu.NONE, R.string.action_share_selected_text);
if (addAutoFillMenu)
menu.add(Menu.NONE, CONTEXT_MENU_AUTOFILL_ID, Menu.NONE, R.string.action_autofill_password);
if (autoFillEnabled)
menu.add(Menu.NONE, CONTEXT_MENU_AUTOFILL_USERNAME, Menu.NONE, R.string.action_autofill_username);
if (autoFillEnabled)
menu.add(Menu.NONE, CONTEXT_MENU_AUTOFILL_PASSWORD, Menu.NONE, R.string.action_autofill_password);
menu.add(Menu.NONE, CONTEXT_MENU_RESET_TERMINAL_ID, Menu.NONE, R.string.action_reset_terminal);
menu.add(Menu.NONE, CONTEXT_MENU_KILL_PROCESS_ID, Menu.NONE, getResources().getString(R.string.action_kill_process, getCurrentSession().getPid())).setEnabled(currentSession.isRunning());
menu.add(Menu.NONE, CONTEXT_MENU_STYLING_ID, Menu.NONE, R.string.action_style_terminal);
Expand Down Expand Up @@ -676,8 +671,11 @@ public boolean onContextItemSelected(MenuItem item) {
case CONTEXT_MENU_SHARE_SELECTED_TEXT:
mTermuxTerminalViewClient.shareSelectedText();
return true;
case CONTEXT_MENU_AUTOFILL_ID:
requestAutoFill();
case CONTEXT_MENU_AUTOFILL_USERNAME:
mTerminalView.requestAutoFillUsername();
return true;
case CONTEXT_MENU_AUTOFILL_PASSWORD:
mTerminalView.requestAutoFillPassword();
return true;
case CONTEXT_MENU_RESET_TERMINAL_ID:
onResetTerminalSession(session);
Expand Down Expand Up @@ -760,15 +758,6 @@ private void toggleKeepScreenOn() {
}
}

private void requestAutoFill() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AutofillManager autofillManager = getSystemService(AutofillManager.class);
if (autofillManager != null && autofillManager.isEnabled()) {
autofillManager.requestAutofill(mTerminalView);
}
}
}



/**
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/res/layout/activity_termux.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
android:focusableInTouchMode="true"
android:scrollbarThumbVertical="@drawable/terminal_scroll_shape"
android:scrollbars="vertical"
android:importantForAutofill="no"
android:autofillHints="password"
tools:ignore="UnusedAttribute" />

<LinearLayout
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
<string name="title_share_selected_text">Terminal Text</string>
<string name="title_share_selected_text_with">Send selected text to:</string>

<string name="action_autofill_username">Autofill username</string>
<string name="action_autofill_password">Autofill password</string>

<string name="action_reset_terminal">Reset</string>
Expand Down
120 changes: 119 additions & 1 deletion terminal-view/src/main/java/com/termux/view/TerminalView.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityManager;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
Expand Down Expand Up @@ -85,6 +86,29 @@ public final class TerminalView extends View {
/** If non-zero, this is the last unicode code point received if that was a combining character. */
int mCombiningAccent;

/**
* The current AutoFill type returned for {@link View#getAutofillType()} by {@link #getAutofillType()}.
*
* The default is {@link #AUTOFILL_TYPE_NONE} so that AutoFill UI, like toolbar above keyboard
* is not shown automatically, like on Activity starts/View create. This value should be updated
* to required value, like {@link #AUTOFILL_TYPE_TEXT} before calling
* {@link AutofillManager#requestAutofill(View)} so that AutoFill UI shows. The updated value
* set will automatically be restored to {@link #AUTOFILL_TYPE_NONE} in
* {@link #autofill(AutofillValue)} so that AutoFill UI isn't shown anymore by calling
* {@link #resetAutoFill()}.
*/
@RequiresApi(api = Build.VERSION_CODES.O)
private int mAutoFillType = AUTOFILL_TYPE_NONE;

/**
* The current AutoFill hints returned for {@link View#getAutofillHints()} ()} by {@link #getAutofillHints()} ()}.
*
* The default is an empty `string[]`. This value should be updated to required value. The
* updated value set will automatically be restored an empty `string[]` in
* {@link #autofill(AutofillValue)} by calling {@link #resetAutoFill()}.
*/
private String[] mAutoFillHints = new String[0];

private final boolean mAccessibilityEnabled;

/** The {@link KeyEvent} is generated from a virtual keyboard, like manually with the {@link KeyEvent#KeyEvent(int, int)} constructor. */
Expand Down Expand Up @@ -609,6 +633,7 @@ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (TERMINAL_VIEW_KEY_LOGGING_ENABLED)
mClient.logInfo(LOG_TAG, "onKeyPreIme(keyCode=" + keyCode + ", event=" + event + ")");
if (keyCode == KeyEvent.KEYCODE_BACK) {
cancelRequestAutoFill();
if (isSelectingText()) {
stopTextSelectionMode();
return true;
Expand Down Expand Up @@ -1028,12 +1053,20 @@ public void autofill(AutofillValue value) {
if (value.isText()) {
mTermSession.write(value.getTextValue().toString());
}

resetAutoFill();
}

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public int getAutofillType() {
return AUTOFILL_TYPE_TEXT;
return mAutoFillType;
}

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public String[] getAutofillHints() {
return mAutoFillHints;
}

@RequiresApi(api = Build.VERSION_CODES.O)
Expand All @@ -1042,6 +1075,91 @@ public AutofillValue getAutofillValue() {
return AutofillValue.forText("");
}

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public int getImportantForAutofill() {
return IMPORTANT_FOR_AUTOFILL_NO;
}

@RequiresApi(api = Build.VERSION_CODES.O)
private synchronized void resetAutoFill() {
// Restore none type so that AutoFill UI isn't shown anymore.
mAutoFillType = AUTOFILL_TYPE_NONE;
mAutoFillHints = new String[0];
}

public AutofillManager getAutoFillManagerService() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return null;

try {
Context context = getContext();
if (context == null) return null;
return context.getSystemService(AutofillManager.class);
} catch (Exception e) {
mClient.logStackTraceWithMessage(LOG_TAG, "Failed to get AutofillManager service", e);
return null;
}
}

public boolean isAutoFillEnabled() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false;

try {
AutofillManager autofillManager = getAutoFillManagerService();
return autofillManager != null && autofillManager.isEnabled();
} catch (Exception e) {
mClient.logStackTraceWithMessage(LOG_TAG, "Failed to check if Autofill is enabled", e);
return false;
}
}

public synchronized void requestAutoFillUsername() {
requestAutoFill(
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? new String[]{View.AUTOFILL_HINT_USERNAME} :
null);
}

public synchronized void requestAutoFillPassword() {
requestAutoFill(
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? new String[]{View.AUTOFILL_HINT_PASSWORD} :
null);
}

public synchronized void requestAutoFill(String[] autoFillHints) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;
if (autoFillHints == null || autoFillHints.length < 1) return;

try {
AutofillManager autofillManager = getAutoFillManagerService();
if (autofillManager != null && autofillManager.isEnabled()) {
// Update type that will be returned by `getAutofillType()` so that AutoFill UI is shown.
mAutoFillType = AUTOFILL_TYPE_TEXT;
// Update hints that will be returned by `getAutofillHints()` for which to show AutoFill UI.
mAutoFillHints = autoFillHints;
autofillManager.requestAutofill(this);
}
} catch (Exception e) {
mClient.logStackTraceWithMessage(LOG_TAG, "Failed to request Autofill", e);
}
}

public synchronized void cancelRequestAutoFill() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;
if (mAutoFillType == AUTOFILL_TYPE_NONE) return;

try {
AutofillManager autofillManager = getAutoFillManagerService();
if (autofillManager != null && autofillManager.isEnabled()) {
resetAutoFill();
autofillManager.cancel();
}
} catch (Exception e) {
mClient.logStackTraceWithMessage(LOG_TAG, "Failed to cancel Autofill request", e);
}
}





/**
Expand Down