Browse Source

Refs #27 send password to input

isundil 7 years ago
parent
commit
d5be2a029f

+ 40 - 9
app/src/main/java/info/knacki/pass/services/AccessibilityService.java

@@ -1,10 +1,15 @@
 package info.knacki.pass.services;
 
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
 import android.content.Intent;
 import android.graphics.PixelFormat;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
+import android.support.annotation.RequiresApi;
 import android.view.Gravity;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
@@ -13,11 +18,17 @@ import android.widget.Toast;
 
 import java.io.File;
 import java.util.Date;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import info.knacki.pass.R;
+import info.knacki.pass.io.FileInterfaceFactory;
+import info.knacki.pass.io.OnResponseListener;
+import info.knacki.pass.ui.passwordPicker.PasswordPickerFactory;
 
+@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
 public class AccessibilityService extends android.accessibilityservice.AccessibilityService {
+    private static final Logger log = Logger.getLogger(AccessibilityService.class.getName());
     private final static long CANCEL_DELAY_SEC = 10;
     private static AccessibilityService fInstance;
     private boolean fManagingEvent;
@@ -80,8 +91,9 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
                     @Override
                     public void OnPasswordClicked(File f) {
                         new Handler(getMainLooper()).post(() -> {
-                            CloseOpenWindow(openWindow);
-                            LoadFile(f, source);
+                            LoadFile(f, openWindow.getWindowToken(), source, () ->
+                                CloseOpenWindow(openWindow)
+                            );
                         });
                     }
 
@@ -115,10 +127,23 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
         }
     }
 
-    private void LoadFile(File f, AccessibilityNodeInfo source) {
+    private void LoadFile(File f, IBinder windowToken, AccessibilityNodeInfo source, Runnable done) {
         fManagingEvent = false;
-        Logger.getAnonymousLogger().severe("Loading " +f.getName());
-        //SendPassword(source, ""))
+        log.info("Loading " +f.getName());
+        FileInterfaceFactory.GetFileInterface(this, PasswordPickerFactory.GetPasswordPicker(this, windowToken), f).ReadFile(new OnResponseListener<String>() {
+            @Override
+            public void OnResponse(String result) {
+                done.run();
+                SendPassword(source, result);
+            }
+
+            @Override
+            public void OnError(String msg, Throwable e) {
+                done.run();
+                Toast.makeText(AccessibilityService.this, msg, Toast.LENGTH_LONG).show();
+                log.log(Level.SEVERE, msg, e);
+            }
+        });
     }
 
     private void SendPassword(AccessibilityNodeInfo accessibilityNode, String password) {
@@ -128,10 +153,10 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
             try {
                 accessibilityNode.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, passContent);
             } catch (Throwable e) {
-                LegacySendPassword(password);
+                LegacySendPassword(accessibilityNode, password);
             }
         } else {
-            LegacySendPassword(password);
+            LegacySendPassword(accessibilityNode, password);
         }
         fManagingEvent = false;
     }
@@ -142,8 +167,14 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
         }
     }
 
-    private void LegacySendPassword(String password) {
-        // FIXME
+    private void LegacySendPassword(AccessibilityNodeInfo accessibilityNode, String password) {
+        final ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+        final ClipData passClip = ClipData.newPlainText("password", password);
+        final ClipData prev = clipboard.getPrimaryClip();
+
+        clipboard.setPrimaryClip(passClip);
+        accessibilityNode.performAction(AccessibilityNodeInfo.ACTION_PASTE);
+        clipboard.setPrimaryClip(prev == null ? ClipData.newPlainText("", "") : prev);
     }
 
     @Override

+ 3 - 3
app/src/main/java/info/knacki/pass/services/InputService.java

@@ -123,7 +123,7 @@ public class InputService extends InputMethodService implements AccessibilityVie
     }
 
     protected void CreatePassword() {
-        new ServiceAlertPromptGenerator(fInputView).Generate(this)
+        new ServiceAlertPromptGenerator(fInputView.getWindowToken()).Generate(this)
                 .setCancelable(true)
                 .setView(new SimpleTextEditWithKeyboard(this))
                 .setPositiveButton(R.string.add, (dialogInterface, view) -> {
@@ -152,7 +152,7 @@ public class InputService extends InputMethodService implements AccessibilityVie
     protected void GeneratePassword(final File f) {
         final PasswordGeneratorWizard wiz = new PasswordGeneratorWizard(this);
 
-        new ServiceAlertPromptGenerator(fInputView).Generate(this)
+        new ServiceAlertPromptGenerator(fInputView.getWindowToken()).Generate(this)
                 .setCancelable(true)
                 .setView(wiz)
                 .setPositiveButton(R.string.add, (dialogInterface, view) -> {
@@ -191,7 +191,7 @@ public class InputService extends InputMethodService implements AccessibilityVie
 
     @Override
     public void OnPasswordClicked(File f) {
-        FileInterfaceFactory.GetFileInterface(this, PasswordPickerFactory.GetPasswordPicker(this, fInputView), f).ReadFile(new OnResponseListener<String>() {
+        FileInterfaceFactory.GetFileInterface(this, PasswordPickerFactory.GetPasswordPicker(this, fInputView.getWindowToken()), f).ReadFile(new OnResponseListener<String>() {
             @Override
             public void OnResponse(String passwordContent) {
                 new android.os.Handler(getMainLooper()).post(() -> sendPassword(passwordContent));

+ 1 - 1
app/src/main/java/info/knacki/pass/settings/ui/SettingsActivity.java

@@ -201,7 +201,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
         }
 
         private boolean IsAccessibilityEnabled() {
-            return AccessibilityService.IsRunning();
+            return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && AccessibilityService.IsRunning();
         }
 
         private boolean IsDrawOverEnabled() {

+ 5 - 5
app/src/main/java/info/knacki/pass/ui/alertPrompt/ServiceAlertPrompt.java

@@ -1,18 +1,18 @@
 package info.knacki.pass.ui.alertPrompt;
 
 import android.content.Context;
-import android.view.View;
+import android.os.IBinder;
 import android.view.Window;
 import android.view.WindowManager;
 
 import info.knacki.pass.R;
 
 public class ServiceAlertPrompt extends AlertPrompt {
-    protected final View fInputView;
+    protected final IBinder fWindowToken;
 
-    ServiceAlertPrompt(Context c, View inputView) {
+    ServiceAlertPrompt(Context c, IBinder windowToken) {
         super(c);
-        fInputView = inputView;
+        fWindowToken = windowToken;
     }
 
     @Override
@@ -20,7 +20,7 @@ public class ServiceAlertPrompt extends AlertPrompt {
         final Window window = fDialog.getWindow();
         if (window != null) {
             WindowManager.LayoutParams lay = window.getAttributes();
-            lay.token = fInputView.getWindowToken();
+            lay.token = fWindowToken;
             lay.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
             window.setAttributes(lay);
             window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

+ 5 - 5
app/src/main/java/info/knacki/pass/ui/alertPrompt/ServiceAlertPromptGenerator.java

@@ -1,17 +1,17 @@
 package info.knacki.pass.ui.alertPrompt;
 
 import android.content.Context;
-import android.view.View;
+import android.os.IBinder;
 
 public class ServiceAlertPromptGenerator extends AlertPromptGenerator {
-    private final View fInputView;
+    private final IBinder fWindowToken;
 
-    public ServiceAlertPromptGenerator(View inputView) {
-        fInputView = inputView;
+    public ServiceAlertPromptGenerator(IBinder windowToken) {
+        fWindowToken = windowToken;
     }
 
     @Override
     public AlertPrompt Generate(Context ctx) {
-        return new ServiceAlertPrompt(ctx, fInputView);
+        return new ServiceAlertPrompt(ctx, fWindowToken);
     }
 }

+ 3 - 3
app/src/main/java/info/knacki/pass/ui/passwordPicker/PasswordPickerFactory.java

@@ -3,7 +3,7 @@ package info.knacki.pass.ui.passwordPicker;
 import android.app.Service;
 import android.content.Context;
 import android.os.Build;
-import android.view.View;
+import android.os.IBinder;
 
 import info.knacki.pass.io.FileInterfaceFactory;
 import info.knacki.pass.settings.SettingsManager;
@@ -19,8 +19,8 @@ public class PasswordPickerFactory {
         return new PasswordPicker(ctx, generator);
     }
 
-    public static FileInterfaceFactory.PasswordGetter GetPasswordPicker(Service ctx, View v) {
-        final AlertPromptGenerator generator = new ServiceAlertPromptGenerator(v);
+    public static FileInterfaceFactory.PasswordGetter GetPasswordPicker(Service ctx, IBinder windowToken) {
+        final AlertPromptGenerator generator = new ServiceAlertPromptGenerator(windowToken);
 
         if (SettingsManager.IsFingerprintEnabled(ctx) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
             return new FingerprintPicker(ctx, generator);