mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-29 04:22:22 -05:00
implemented AutoFill service in Java, integrated into main app
This commit is contained in:
parent
c0f2b68963
commit
3d2f6db36d
@ -84,6 +84,10 @@ namespace keepass2android
|
||||
AskAddTemplatesMessage,
|
||||
ReadOnlyReason_PreKitKat,
|
||||
ReadOnlyReason_ReadOnlyFlag,
|
||||
ReadOnlyReason_ReadOnlyKitKat
|
||||
ReadOnlyReason_ReadOnlyKitKat,
|
||||
ActivateAutoFillService_title,
|
||||
ActivateAutoFillService_message,
|
||||
ActivateAutoFillService_btnKeyboard,
|
||||
ActivateAutoFillService_btnAutoFill
|
||||
}
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
#Wed Jan 13 21:02:12 CET 2016
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -34,23 +34,11 @@
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file leaf-file-name="LatinKeyboardBaseView.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/LatinKeyboardBaseView.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="1234" column="25" selection-start-line="1234" selection-start-column="25" selection-end-line="1234" selection-end-column="25" />
|
||||
<folding>
|
||||
<element signature="method#LatinKeyboardBaseView#1;class#LatinKeyboardBaseView#0" expanded="false" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="KP2AKeyboard.java" pinned="false" current-in-tab="true">
|
||||
<file leaf-file-name="KP2AKeyboard.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/KP2AKeyboard.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="2465" column="13" selection-start-line="2465" selection-start-column="13" selection-end-line="2465" selection-end-column="13" />
|
||||
<caret line="2618" column="0" selection-start-line="2618" selection-start-column="0" selection-end-line="2618" selection-end-column="0" />
|
||||
<folding>
|
||||
<element signature="e#17350#17396#0" expanded="true" />
|
||||
<element signature="e#17428#17478#0" expanded="true" />
|
||||
@ -97,70 +85,108 @@
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="LocaleHelper.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/LocaleHelper.java">
|
||||
<file leaf-file-name="StringForTyping.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/StringForTyping.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="49" column="53" selection-start-line="49" selection-start-column="53" selection-end-line="49" selection-end-column="53" />
|
||||
<caret line="2" column="13" selection-start-line="2" selection-start-column="13" selection-end-line="2" selection-end-column="13" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="build.gradle" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="-4.76">
|
||||
<caret line="7" column="24" selection-start-line="7" selection-start-column="24" selection-end-line="7" selection-end-column="24" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="accserviceconfig.xml" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/accserviceconfig.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="0" column="38" selection-start-line="0" selection-start-column="38" selection-end-line="0" selection-end-column="38" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="strings.xml" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/values/strings.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="-7.56">
|
||||
<caret line="378" column="0" selection-start-line="378" selection-start-column="0" selection-end-line="378" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="strings_autofill.xml" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/values/strings_autofill.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="8" column="0" selection-start-line="8" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="AutoFillService.java" pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/autofill/AutoFillService.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.7568306">
|
||||
<caret line="104" column="5" selection-start-line="104" selection-start-column="5" selection-end-line="104" selection-end-column="5" />
|
||||
<folding>
|
||||
<element signature="imports" expanded="true" />
|
||||
<element signature="e#1549#1550#0" expanded="true" />
|
||||
<element signature="e#1585#1586#0" expanded="true" />
|
||||
<element signature="e#1660#1661#0" expanded="true" />
|
||||
<element signature="e#1712#1713#0" expanded="true" />
|
||||
<element signature="e#2880#2881#0" expanded="true" />
|
||||
<element signature="e#2913#2914#0" expanded="true" />
|
||||
<element signature="e#9594#9692#0" expanded="true" />
|
||||
<element signature="e#9727#9793#0" expanded="true" />
|
||||
<element signature="e#11813#11814#0" expanded="true" />
|
||||
<element signature="e#11867#11868#0" expanded="true" />
|
||||
<element signature="e#11925#11926#0" expanded="true" />
|
||||
<element signature="e#11979#11980#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="kbd_qwerty.xml" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/kbd_qwerty.xml">
|
||||
<file leaf-file-name="prefs.xml" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/prefs.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="476" column="38" selection-start-line="476" selection-start-column="38" selection-end-line="476" selection-end-column="38" />
|
||||
<caret line="60" column="46" selection-start-line="60" selection-start-column="46" selection-end-line="60" selection-end-column="46" />
|
||||
<folding>
|
||||
<element signature="e#5702#5728#0" expanded="true" />
|
||||
<element signature="e#6920#6946#0" expanded="true" />
|
||||
<element signature="e#8140#8166#0" expanded="true" />
|
||||
<element signature="e#9357#9383#0" expanded="true" />
|
||||
<element signature="e#10581#10607#0" expanded="true" />
|
||||
<element signature="e#12082#12108#0" expanded="true" />
|
||||
<element signature="e#13602#13628#0" expanded="true" />
|
||||
<element signature="e#15124#15150#0" expanded="true" />
|
||||
<element signature="e#16643#16669#0" expanded="true" />
|
||||
<element signature="e#2450#2474#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="kbd_qwerty_black.xml" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/kbd_qwerty_black.xml">
|
||||
<file leaf-file-name="KeyboardData.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/KeyboardData.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="146" column="46" selection-start-line="146" selection-start-column="35" selection-end-line="146" selection-end-column="46" />
|
||||
<state vertical-scroll-proportion="-12.24">
|
||||
<caret line="18" column="30" selection-start-line="18" selection-start-column="30" selection-end-line="18" selection-end-column="30" />
|
||||
<folding>
|
||||
<element signature="e#5666#5692#0" expanded="true" />
|
||||
<element signature="imports" expanded="true" />
|
||||
<element signature="e#362#363#0" expanded="true" />
|
||||
<element signature="e#404#405#0" expanded="true" />
|
||||
<element signature="e#438#439#0" expanded="true" />
|
||||
<element signature="e#479#480#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="kbd_qwerty.xml" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml-de/kbd_qwerty.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="147" column="38" selection-start-line="147" selection-start-column="38" selection-end-line="147" selection-end-column="38" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="KeyboardSwitcher.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/KeyboardSwitcher.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="591" column="0" selection-start-line="591" selection-start-column="0" selection-end-line="591" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="LatinIMESettings.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/LatinIMESettings.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
@ -171,35 +197,14 @@
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="LatinKeyboardView.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/LatinKeyboardView.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="36" column="23" selection-start-line="36" selection-start-column="23" selection-end-line="36" selection-end-column="23" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="LatinKeyboard.java" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/LatinKeyboard.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="397" column="24" selection-start-line="397" selection-start-column="24" selection-end-line="397" selection-end-column="24" />
|
||||
<folding>
|
||||
<element signature="e#15971#15972#0" expanded="true" />
|
||||
<element signature="e#16007#16008#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="resourceFile" />
|
||||
<option value="Class" />
|
||||
<option value="valueResourceFile" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@ -1228,7 +1233,7 @@
|
||||
</option>
|
||||
<option name="modificationStamps">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$" value="4358048248205" />
|
||||
<entry key="$PROJECT_DIR$" value="4359057111489" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="projectBuildClasspath">
|
||||
@ -1475,7 +1480,6 @@
|
||||
<option name="CHANGED_PATHS">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/build.gradle" />
|
||||
<option value="$PROJECT_DIR$/app/build.gradle" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/LatinKeyboardBaseView.java" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/LanguageSwitcher.java" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/Loc.java" />
|
||||
@ -1483,6 +1487,12 @@
|
||||
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/KeyboardSwitcher.java" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/LocaleHelper.java" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/KP2AKeyboard.java" />
|
||||
<option value="$PROJECT_DIR$/app/build.gradle" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/res/xml/accserviceconfig.xml" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/KeyboardData.java" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/autofill/AutoFillService.java" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/res/values/strings.xml" />
|
||||
<option value="$PROJECT_DIR$/app/src/main/res/values/strings_autofill.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@ -1558,96 +1568,6 @@
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="java" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="KP2ASoftkeyboard_AS" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="app" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="src" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="main" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="java" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="KP2ASoftkeyboard_AS" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="app" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="src" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="main" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="java" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="keepass2android" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="softkeyboard" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="java" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="KP2ASoftkeyboard_AS" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="app" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="src" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="main" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="java" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="keepass2android" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="kbbridge" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="Scope" />
|
||||
@ -1673,6 +1593,8 @@
|
||||
<property name="android.project.structure.proportion" value="0.15" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/../KP2ASoftKeyboard2/java" />
|
||||
<property name="FullScreen" value="false" />
|
||||
<property name="OverrideImplement.combined" value="true" />
|
||||
<property name="OverrideImplement.overriding.sorted" value="false" />
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration default="true" type="AndroidRunConfigurationType" factoryName="Android Application">
|
||||
@ -1843,34 +1765,43 @@
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TodoView">
|
||||
<todo-panel id="selected-file">
|
||||
<is-autoscroll-to-source value="true" />
|
||||
</todo-panel>
|
||||
<todo-panel id="all">
|
||||
<are-packages-shown value="true" />
|
||||
<is-autoscroll-to-source value="true" />
|
||||
</todo-panel>
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="-8" y="-8" width="1382" height="744" extended-state="6" />
|
||||
<editor active="true" />
|
||||
<editor active="false" />
|
||||
<layout>
|
||||
<window_info id="Palette	" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3270869" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Captures" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.32879046" sideWeight="0.5121029" order="7" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Gradle Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Build Variants" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.32879046" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Android" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.32879046" sideWeight="0.48789713" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Android" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32879046" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32879046" sideWeight="0.4969743" order="6" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Gradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.24886535" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.24886535" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24962178" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
|
||||
</layout>
|
||||
@ -2079,25 +2010,17 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="11" column="16" selection-start-line="11" selection-start-column="16" selection-end-line="11" selection-end-column="16" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/InputLanguageSelection.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="92" column="16" selection-start-line="92" selection-start-column="16" selection-end-line="92" selection-end-column="16" />
|
||||
<folding>
|
||||
<element signature="e#0#5655#0" expanded="true" />
|
||||
<element signature="imports" expanded="true" />
|
||||
<element signature="e#1509#1539#0" expanded="true" />
|
||||
<element signature="e#2941#2964#0" expanded="true" />
|
||||
<element signature="e#4545#4546#0" expanded="true" />
|
||||
<element signature="e#4577#4578#0" expanded="true" />
|
||||
<element signature="e#0#5655#0" expanded="false" />
|
||||
<element signature="imports" expanded="false" />
|
||||
<element signature="e#1509#1539#0" expanded="false" />
|
||||
<element signature="e#2941#2964#0" expanded="false" />
|
||||
<element signature="e#4545#4546#0" expanded="false" />
|
||||
<element signature="e#4577#4578#0" expanded="false" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
@ -2118,14 +2041,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/values/strings.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="-4.88">
|
||||
<caret line="187" column="34" selection-start-line="187" selection-start-column="18" selection-end-line="187" selection-end-column="34" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/LatinKeyboardView.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
@ -2139,8 +2054,8 @@
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="397" column="24" selection-start-line="397" selection-start-column="24" selection-end-line="397" selection-end-column="24" />
|
||||
<folding>
|
||||
<element signature="e#15971#15972#0" expanded="true" />
|
||||
<element signature="e#16007#16008#0" expanded="true" />
|
||||
<element signature="e#15971#15972#0" expanded="false" />
|
||||
<element signature="e#16007#16008#0" expanded="false" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
@ -2160,15 +2075,15 @@
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="476" column="38" selection-start-line="476" selection-start-column="38" selection-end-line="476" selection-end-column="38" />
|
||||
<folding>
|
||||
<element signature="e#5702#5728#0" expanded="true" />
|
||||
<element signature="e#6920#6946#0" expanded="true" />
|
||||
<element signature="e#8140#8166#0" expanded="true" />
|
||||
<element signature="e#9357#9383#0" expanded="true" />
|
||||
<element signature="e#10581#10607#0" expanded="true" />
|
||||
<element signature="e#12082#12108#0" expanded="true" />
|
||||
<element signature="e#13602#13628#0" expanded="true" />
|
||||
<element signature="e#15124#15150#0" expanded="true" />
|
||||
<element signature="e#16643#16669#0" expanded="true" />
|
||||
<element signature="e#5702#5728#0" expanded="false" />
|
||||
<element signature="e#6920#6946#0" expanded="false" />
|
||||
<element signature="e#8140#8166#0" expanded="false" />
|
||||
<element signature="e#9357#9383#0" expanded="false" />
|
||||
<element signature="e#10581#10607#0" expanded="false" />
|
||||
<element signature="e#12082#12108#0" expanded="false" />
|
||||
<element signature="e#13602#13628#0" expanded="false" />
|
||||
<element signature="e#15124#15150#0" expanded="false" />
|
||||
<element signature="e#16643#16669#0" expanded="false" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
@ -2178,7 +2093,7 @@
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="146" column="46" selection-start-line="146" selection-start-column="35" selection-end-line="146" selection-end-column="46" />
|
||||
<folding>
|
||||
<element signature="e#5666#5692#0" expanded="true" />
|
||||
<element signature="e#5666#5692#0" expanded="false" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
@ -2199,6 +2114,16 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/LocaleHelper.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="49" column="53" selection-start-line="49" selection-start-column="53" selection-end-line="49" selection-end-column="53" />
|
||||
<folding>
|
||||
<element signature="imports" expanded="false" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/LatinIMESettings.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
@ -2207,20 +2132,18 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/LocaleHelper.java">
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/StringForTyping.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="49" column="53" selection-start-line="49" selection-start-column="53" selection-end-line="49" selection-end-column="53" />
|
||||
<folding>
|
||||
<element signature="imports" expanded="true" />
|
||||
</folding>
|
||||
<caret line="2" column="13" selection-start-line="2" selection-start-column="13" selection-end-line="2" selection-end-column="13" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/softkeyboard/KP2AKeyboard.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="2465" column="13" selection-start-line="2465" selection-start-column="13" selection-end-line="2465" selection-end-column="13" />
|
||||
<caret line="2618" column="0" selection-start-line="2618" selection-start-column="0" selection-end-line="2618" selection-end-column="0" />
|
||||
<folding>
|
||||
<element signature="e#17350#17396#0" expanded="true" />
|
||||
<element signature="e#17428#17478#0" expanded="true" />
|
||||
@ -2266,5 +2189,83 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="-4.76">
|
||||
<caret line="7" column="24" selection-start-line="7" selection-start-column="24" selection-end-line="7" selection-end-column="24" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/kbbridge/KeyboardData.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="-12.24">
|
||||
<caret line="18" column="30" selection-start-line="18" selection-start-column="30" selection-end-line="18" selection-end-column="30" />
|
||||
<folding>
|
||||
<element signature="imports" expanded="true" />
|
||||
<element signature="e#362#363#0" expanded="true" />
|
||||
<element signature="e#404#405#0" expanded="true" />
|
||||
<element signature="e#438#439#0" expanded="true" />
|
||||
<element signature="e#479#480#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/accserviceconfig.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="0" column="38" selection-start-line="0" selection-start-column="38" selection-end-line="0" selection-end-column="38" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/prefs.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="60" column="46" selection-start-line="60" selection-start-column="46" selection-end-line="60" selection-end-column="46" />
|
||||
<folding>
|
||||
<element signature="e#2450#2474#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/values/strings.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="-7.56">
|
||||
<caret line="378" column="0" selection-start-line="378" selection-start-column="0" selection-end-line="378" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/res/values/strings_autofill.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0">
|
||||
<caret line="8" column="0" selection-start-line="8" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/autofill/AutoFillService.java">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.7568306">
|
||||
<caret line="104" column="5" selection-start-line="104" selection-start-column="5" selection-end-line="104" selection-end-column="5" />
|
||||
<folding>
|
||||
<element signature="imports" expanded="true" />
|
||||
<element signature="e#1549#1550#0" expanded="true" />
|
||||
<element signature="e#1585#1586#0" expanded="true" />
|
||||
<element signature="e#1660#1661#0" expanded="true" />
|
||||
<element signature="e#1712#1713#0" expanded="true" />
|
||||
<element signature="e#2880#2881#0" expanded="true" />
|
||||
<element signature="e#2913#2914#0" expanded="true" />
|
||||
<element signature="e#9594#9692#0" expanded="true" />
|
||||
<element signature="e#9727#9793#0" expanded="true" />
|
||||
<element signature="e#11813#11814#0" expanded="true" />
|
||||
<element signature="e#11867#11868#0" expanded="true" />
|
||||
<element signature="e#11925#11926#0" expanded="true" />
|
||||
<element signature="e#11979#11980#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
@ -5,7 +5,7 @@ android {
|
||||
buildToolsVersion "23.0.0"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 23
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,380 @@
|
||||
package keepass2android.autofill;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import keepass2android.kbbridge.KeyboardData;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Philipp on 25.01.2016.
|
||||
*/
|
||||
public class AutoFillService extends AccessibilityService {
|
||||
|
||||
|
||||
private static boolean _hasUsedData = false;
|
||||
private static String _lastSearchUrl;
|
||||
private static final String _logTag = "KP2AAF";
|
||||
private static boolean _isRunning;
|
||||
|
||||
private final int autoFillNotificationId = 798810;
|
||||
private final String androidAppPrefix = "androidapp://";
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
_isRunning = true;
|
||||
android.util.Log.d(_logTag, "OnCreate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
_isRunning = false;
|
||||
}
|
||||
|
||||
interface NodeCondition
|
||||
{
|
||||
boolean check(AccessibilityNodeInfo n);
|
||||
}
|
||||
|
||||
class WindowIdCondition implements NodeCondition
|
||||
{
|
||||
private int id;
|
||||
|
||||
public WindowIdCondition(int id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(AccessibilityNodeInfo n) {
|
||||
return n.getWindowId() == id;
|
||||
}
|
||||
}
|
||||
|
||||
class SystemUiCondition implements NodeCondition
|
||||
{
|
||||
@Override
|
||||
public boolean check(AccessibilityNodeInfo n) {
|
||||
return (n.getViewIdResourceName() != null) && (n.getViewIdResourceName().startsWith("com.android.systemui"));
|
||||
}
|
||||
}
|
||||
|
||||
private class PasswordFieldCondition implements NodeCondition {
|
||||
@Override
|
||||
public boolean check(AccessibilityNodeInfo n) {
|
||||
return n.isPassword() && (
|
||||
(n.getText() == null)
|
||||
|| ("".equals(n.getText())));
|
||||
}
|
||||
}
|
||||
|
||||
private class EditTextCondition implements NodeCondition {
|
||||
@Override
|
||||
public boolean check(AccessibilityNodeInfo n) {
|
||||
//it seems like n.Editable is not a good check as this is false for some fields which are actually editable, at least in tests with Chrome.
|
||||
return (n.getClassName() != null) && (n.getClassName().toString().toLowerCase().contains("edittext"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isAvailable()
|
||||
{
|
||||
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
|
||||
}
|
||||
|
||||
public static boolean isRunning()
|
||||
{
|
||||
return _isRunning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
android.util.Log.d(_logTag, "OnAccEvent");
|
||||
|
||||
try
|
||||
{
|
||||
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
|
||||
|| event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
|
||||
{
|
||||
android.util.Log.d(_logTag, "event: " + event.getEventType() + ", package = " + event.getPackageName());
|
||||
if ( "com.android.systemui".equals(event.getPackageName()) )
|
||||
{
|
||||
android.util.Log.d(_logTag, "return.");
|
||||
return; //avoid that the notification is cancelled when pulling down notif drawer
|
||||
}
|
||||
else
|
||||
{
|
||||
android.util.Log.d(_logTag, "no com.android.systemui");
|
||||
}
|
||||
|
||||
AccessibilityNodeInfo root = getRootInActiveWindow();
|
||||
int eventWindowId = event.getWindowId();
|
||||
if ((ExistsNodeOrChildren(root, new WindowIdCondition(eventWindowId)) && !ExistsNodeOrChildren(root, new SystemUiCondition())))
|
||||
{
|
||||
boolean cancelNotification = true;
|
||||
|
||||
String url = androidAppPrefix + root.getPackageName();
|
||||
|
||||
if ( "com.android.chrome".equals(root.getPackageName()) )
|
||||
{
|
||||
List<AccessibilityNodeInfo> urlFields = root.findAccessibilityNodeInfosByViewId("com.android.chrome:id/url_bar");
|
||||
url = urlFromAddressFields(urlFields, url);
|
||||
}
|
||||
else if ("com.android.browser".equals(root.getPackageName()))
|
||||
{
|
||||
List<AccessibilityNodeInfo> urlFields = root.findAccessibilityNodeInfosByViewId("com.android.browser:id/url");
|
||||
url = urlFromAddressFields(urlFields, url);
|
||||
}
|
||||
|
||||
if (ExistsNodeOrChildren(root, new PasswordFieldCondition()))
|
||||
{
|
||||
|
||||
if ((getLastReceivedCredentialsUser() != null) &&
|
||||
(Objects.equals(url, _lastSearchUrl)
|
||||
|| isSame(getCredentialsField("URL"), url)))
|
||||
{
|
||||
android.util.Log.d(_logTag, "Filling credentials for " + url);
|
||||
|
||||
List<AccessibilityNodeInfo> emptyPasswordFields = new ArrayList<>();
|
||||
GetNodeOrChildren(root, new PasswordFieldCondition(), emptyPasswordFields);
|
||||
|
||||
List<AccessibilityNodeInfo> allEditTexts = new ArrayList<>();
|
||||
GetNodeOrChildren(root, new EditTextCondition(), allEditTexts);
|
||||
|
||||
AccessibilityNodeInfo usernameEdit = null;
|
||||
for (int i=0;i<allEditTexts.size();i++)
|
||||
{
|
||||
if (allEditTexts.get(i).isPassword() == false)
|
||||
{
|
||||
usernameEdit = allEditTexts.get(i);
|
||||
android.util.Log.d(_logTag, "setting usernameEdit = " + usernameEdit.getText() + " ");
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
FillPassword(url, usernameEdit, emptyPasswordFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
android.util.Log.d (_logTag, "Notif for " + url );
|
||||
if (getLastReceivedCredentialsUser() != null)
|
||||
{
|
||||
android.util.Log.d (_logTag, getCredentialsField("URL"));
|
||||
android.util.Log.d (_logTag, url);
|
||||
}
|
||||
|
||||
AskFillPassword(url);
|
||||
cancelNotification = false;
|
||||
}
|
||||
|
||||
}
|
||||
if (cancelNotification)
|
||||
{
|
||||
((NotificationManager)getSystemService(NOTIFICATION_SERVICE)).cancel(autoFillNotificationId);
|
||||
android.util.Log.d (_logTag,"Cancel notif");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
android.util.Log.e(_logTag, e.toString());
|
||||
|
||||
Notification.Builder builder = new Notification.Builder(this);
|
||||
//TODO remove on release
|
||||
builder.setSmallIcon(keepass2android.softkeyboard.R.drawable.ic_notify_autofill)
|
||||
.setContentText(e.toString())
|
||||
.setContentTitle("error information")
|
||||
.setWhen(java.lang.System.currentTimeMillis());
|
||||
|
||||
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(autoFillNotificationId+1, builder.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void AskFillPassword(String url)
|
||||
{
|
||||
|
||||
Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(getApplicationContext().getPackageName());
|
||||
if (startKp2aIntent != null)
|
||||
{
|
||||
startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
String taskName = "SearchUrlTask";
|
||||
startKp2aIntent.putExtra("KP2A_APPTASK", taskName);
|
||||
startKp2aIntent.putExtra("UrlToSearch", url);
|
||||
}
|
||||
|
||||
|
||||
PendingIntent pending = PendingIntent.getActivity(this, 0, startKp2aIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
String targetName = url;
|
||||
|
||||
if (url.startsWith(androidAppPrefix))
|
||||
{
|
||||
String packageName = url.substring(androidAppPrefix.length());
|
||||
try
|
||||
{
|
||||
ApplicationInfo appInfo = getPackageManager().getApplicationInfo(packageName, 0);
|
||||
targetName = (String) (appInfo != null ? getPackageManager().getApplicationLabel(appInfo) : packageName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
android.util.Log.d(_logTag, e.toString());
|
||||
targetName = packageName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetName = getHost(url);
|
||||
}
|
||||
|
||||
|
||||
Notification.Builder builder = new Notification.Builder(this);
|
||||
//TODO icon
|
||||
//TODO plugin icon
|
||||
builder.setSmallIcon(keepass2android.softkeyboard.R.drawable.ic_notify_autofill)
|
||||
.setContentText(getString(keepass2android.softkeyboard.R.string.NotificationContentText, new Object[]{targetName}))
|
||||
.setContentTitle(getString(keepass2android.softkeyboard.R.string.NotificationTitle))
|
||||
.setWhen(java.lang.System.currentTimeMillis())
|
||||
.setVisibility(Notification.VISIBILITY_SECRET)
|
||||
.setContentIntent(pending);
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(autoFillNotificationId, builder.build());
|
||||
|
||||
}
|
||||
|
||||
private void FillPassword(String url, AccessibilityNodeInfo usernameEdit, List<AccessibilityNodeInfo> passwordFields)
|
||||
{
|
||||
if ((keepass2android.kbbridge.KeyboardData.hasData()) && (_hasUsedData == false))
|
||||
{
|
||||
fillDataInTextField(usernameEdit, getLastReceivedCredentialsUser());
|
||||
for (int i=0;i<passwordFields.size();i++)
|
||||
{
|
||||
fillDataInTextField(passwordFields.get(i), getLastReceivedCredentialsPassword());
|
||||
}
|
||||
_hasUsedData = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//LookupCredentialsActivity.LastReceivedCredentials = null;
|
||||
}
|
||||
|
||||
private void fillDataInTextField(AccessibilityNodeInfo edit, String value) {
|
||||
if (value == null)
|
||||
return;
|
||||
Bundle b = new Bundle();
|
||||
b.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, value);
|
||||
edit.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, b);
|
||||
}
|
||||
|
||||
|
||||
private boolean isSame(String url1, String url2) {
|
||||
if (url1.startsWith("androidapp://"))
|
||||
return url1.equals(url2);
|
||||
if (url1 == null)
|
||||
return (url2 == null);
|
||||
return getHost(url1).equals(getHost(url2));
|
||||
}
|
||||
|
||||
private String getHost(String url)
|
||||
{
|
||||
URI uri = null;
|
||||
try {
|
||||
uri = new URI(url);
|
||||
String domain = uri.getHost();
|
||||
return domain.startsWith("www.") ? domain.substring(4) : domain;
|
||||
} catch (URISyntaxException e) {
|
||||
android.util.Log.d(_logTag, "error parsing url: "+ url + e.toString());
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getLastReceivedCredentialsUser() {
|
||||
return getCredentialsField("UserName");
|
||||
}
|
||||
private String getLastReceivedCredentialsPassword() {
|
||||
return getCredentialsField("Password");
|
||||
}
|
||||
|
||||
private String getCredentialsField(String key) {
|
||||
for (int i=0;i<KeyboardData.availableFields.size();i++)
|
||||
{
|
||||
if (key.equals(KeyboardData.availableFields.get(i).key))
|
||||
{
|
||||
if (KeyboardData.availableFields.get(i).value != null)
|
||||
return KeyboardData.availableFields.get(i).value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void GetNodeOrChildren(AccessibilityNodeInfo n, NodeCondition condition, List<AccessibilityNodeInfo> result) {
|
||||
if (n != null)
|
||||
{
|
||||
if (condition.check(n))
|
||||
result.add(n);
|
||||
for (int i = 0; i < n.getChildCount(); i++)
|
||||
{
|
||||
GetNodeOrChildren(n.getChild(i), condition, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean ExistsNodeOrChildren(AccessibilityNodeInfo n, NodeCondition condition) {
|
||||
if (n == null) return false;
|
||||
if (condition.check(n))
|
||||
return true;
|
||||
for (int i = 0; i < n.getChildCount(); i++)
|
||||
{
|
||||
if (ExistsNodeOrChildren(n.getChild(i), condition))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String urlFromAddressFields(List<AccessibilityNodeInfo> urlFields, String url) {
|
||||
if (!urlFields.isEmpty())
|
||||
{
|
||||
AccessibilityNodeInfo addressField = urlFields.get(0);
|
||||
url = addressField.getText().toString();
|
||||
if (!url.contains("://"))
|
||||
url = "http://" + url;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterrupt() {
|
||||
|
||||
}
|
||||
|
||||
public static void NotifyNewData(String searchUrl)
|
||||
{
|
||||
_hasUsedData = false;
|
||||
_lastSearchUrl = searchUrl;
|
||||
android.util.Log.d(_logTag, "Notify new data: " + searchUrl);
|
||||
}
|
||||
|
||||
}
|
@ -16,6 +16,11 @@ public class KeyboardData
|
||||
return !TextUtils.isEmpty(entryId);
|
||||
}
|
||||
|
||||
public static boolean bla2()
|
||||
{
|
||||
return !TextUtils.isEmpty(entryId);
|
||||
}
|
||||
|
||||
public static void clear()
|
||||
{
|
||||
availableFields.clear();
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@ -376,4 +376,6 @@
|
||||
<!-- Title for Latin keyboard debug settings activity / dialog -->
|
||||
<string name="english_ime_debug_settings" translatable="false">Android keyboard Debug settings</string>
|
||||
<string name="prefs_debug_mode" translatable="false">Debug Mode</string>
|
||||
|
||||
|
||||
</resources>
|
||||
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="AutoFillServiceDescription">Monitors apps and websites for password fields. Offers to look up credentials from Keepass2Android and auto-fill them into the forms.</string>
|
||||
|
||||
<string name="LookupTitle">Look up credentials</string>
|
||||
<string name="ApplicationName">KP2A AutoFillPlugin</string>
|
||||
<string name="NotificationTitle">Keepass2Android AutoFill</string>
|
||||
<string name="NotificationContentText">AutoFill form for %1$s</string>
|
||||
|
||||
</resources>
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:description="@string/AutoFillServiceDescription"
|
||||
android:accessibilityEventTypes="typeAllMask"
|
||||
@ -7,4 +7,4 @@
|
||||
android:notificationTimeout="100"
|
||||
android:canRetrieveWindowContent="true"
|
||||
|
||||
/>
|
||||
/>
|
Binary file not shown.
@ -12,14 +12,14 @@ using Android.Views.Accessibility;
|
||||
using Android.Widget;
|
||||
using KeePassLib;
|
||||
|
||||
|
||||
/*
|
||||
namespace keepass2android.AutoFill
|
||||
{
|
||||
//<meta-data android:name="android.accessibilityservice" android:resource="@xml/serviceconfig" />
|
||||
[Service(Enabled =true, Permission= "android.permission.BIND_ACCESSIBILITY_SERVICE")]
|
||||
[IntentFilter(new[] { "android.accessibilityservice.AccessibilityService" })]
|
||||
[MetaData("android.accessibilityservice", Resource = "@xml/accserviceconfig")]
|
||||
public class Kp2aAccessibilityService : Android.AccessibilityServices.AccessibilityService
|
||||
public class AccessibilityService : Android.AccessibilityServices.AccessibilityService
|
||||
{
|
||||
private static bool _hasUsedData;
|
||||
const string _logTag = "KP2AAS";
|
||||
@ -53,12 +53,6 @@ namespace keepass2android.AutoFill
|
||||
{
|
||||
bool cancelNotification = true;
|
||||
|
||||
var allEditTexts = GetNodeOrChildren(root, IsEditText);
|
||||
|
||||
var usernameEdit = allEditTexts.TakeWhile(edit => (edit.Password == false)).LastOrDefault();
|
||||
|
||||
string searchString = androidAppPrefix + root.PackageName;
|
||||
|
||||
string url = androidAppPrefix + root.PackageName;
|
||||
|
||||
if (root.PackageName == "com.android.chrome")
|
||||
@ -73,14 +67,24 @@ namespace keepass2android.AutoFill
|
||||
UrlFromAddressField(ref url, addressField);
|
||||
}
|
||||
|
||||
List<AccessibilityNodeInfo> emptyPasswordFields = GetNodeOrChildren(root, IsPasswordField);
|
||||
if (emptyPasswordFields.Any())
|
||||
if (ExistsNodeOrChildren(root, IsPasswordField))
|
||||
{
|
||||
|
||||
if ((LastReceivedCredentialsUser != null) && IsSame(GetCredentialsField(PwDefs.UrlField), url))
|
||||
{
|
||||
Android.Util.Log.Debug ("KP2AAS", "Filling credentials for " + url);
|
||||
|
||||
List<AccessibilityNodeInfo> emptyPasswordFields = new List<AccessibilityNodeInfo>();
|
||||
GetNodeOrChildren(root, IsPasswordField, ref emptyPasswordFields);
|
||||
|
||||
List<AccessibilityNodeInfo> allEditTexts = new List<AccessibilityNodeInfo>();
|
||||
GetNodeOrChildren(root, IsEditText, ref allEditTexts);
|
||||
|
||||
var usernameEdit = allEditTexts.TakeWhile(edit => (edit.Password == false)).LastOrDefault();
|
||||
|
||||
FillPassword(url, usernameEdit, emptyPasswordFields);
|
||||
allEditTexts.Clear();
|
||||
emptyPasswordFields.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -91,7 +95,7 @@ namespace keepass2android.AutoFill
|
||||
Android.Util.Log.Debug ("KP2AAS", url);
|
||||
}
|
||||
|
||||
AskFillPassword(url, usernameEdit, emptyPasswordFields);
|
||||
AskFillPassword(url);
|
||||
cancelNotification = false;
|
||||
}
|
||||
|
||||
@ -105,10 +109,11 @@ namespace keepass2android.AutoFill
|
||||
|
||||
}
|
||||
GC.Collect();
|
||||
|
||||
Java.Lang.JavaSystem.Gc();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private bool IsSystemUi(AccessibilityNodeInfo n)
|
||||
{
|
||||
return (n.ViewIdResourceName != null) && (n.ViewIdResourceName.StartsWith("com.android.systemui"));
|
||||
@ -146,7 +151,12 @@ namespace keepass2android.AutoFill
|
||||
return (n.ClassName != null) && (n.ClassName.Contains("EditText"));
|
||||
}
|
||||
|
||||
private void AskFillPassword(string url, AccessibilityNodeInfo usernameEdit, List<AccessibilityNodeInfo> passwordFields)
|
||||
private static bool IsNonPasswordEditText(AccessibilityNodeInfo n)
|
||||
{
|
||||
return IsEditText(n) && n.Password == false;
|
||||
}
|
||||
|
||||
private void AskFillPassword(string url)
|
||||
{
|
||||
|
||||
Intent startKp2aIntent = PackageManager.GetLaunchIntentForPackage(ApplicationContext.PackageName);
|
||||
@ -243,6 +253,7 @@ namespace keepass2android.AutoFill
|
||||
|
||||
private bool ExistsNodeOrChildren(AccessibilityNodeInfo n, Func<AccessibilityNodeInfo, bool> p)
|
||||
{
|
||||
if (n == null) return false;
|
||||
if (p(n))
|
||||
return true;
|
||||
for (int i = 0; i < n.ChildCount; i++)
|
||||
@ -253,19 +264,17 @@ namespace keepass2android.AutoFill
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<AccessibilityNodeInfo> GetNodeOrChildren(AccessibilityNodeInfo n, Func<AccessibilityNodeInfo, bool> p)
|
||||
private void GetNodeOrChildren(AccessibilityNodeInfo n, Func<AccessibilityNodeInfo, bool> p, ref List<AccessibilityNodeInfo> result)
|
||||
{
|
||||
List<AccessibilityNodeInfo> result = new List<AccessibilityNodeInfo>();
|
||||
if (n != null)
|
||||
{
|
||||
if (p(n))
|
||||
result.Add(n);
|
||||
for (int i = 0; i < n.ChildCount; i++)
|
||||
{
|
||||
result.AddRange(GetNodeOrChildren(n.GetChild(i), p));
|
||||
GetNodeOrChildren(n.GetChild(i), p, ref result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void OnInterrupt()
|
||||
@ -283,4 +292,4 @@ namespace keepass2android.AutoFill
|
||||
_hasUsedData = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
56
src/keepass2android/ActivateAutoFillActivity.cs
Normal file
56
src/keepass2android/ActivateAutoFillActivity.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Preferences;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity(Label = AppNames.AppName, Theme = "@style/MyTheme_ActionBar")]
|
||||
public class ActivateAutoFillActivity : LifecycleDebugActivity
|
||||
{
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
new ActivityDesign(this).ApplyTheme();
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
App.Kp2a.AskYesNoCancel(UiStringKey.ActivateAutoFillService_title,
|
||||
UiStringKey.ActivateAutoFillService_message,
|
||||
UiStringKey.ActivateAutoFillService_btnKeyboard,
|
||||
UiStringKey.ActivateAutoFillService_btnAutoFill,
|
||||
delegate
|
||||
{
|
||||
//yes
|
||||
CopyToClipboardService.ActivateKeyboard(this);
|
||||
Finish();
|
||||
},
|
||||
delegate
|
||||
{
|
||||
//no
|
||||
Intent intent = new Intent(Android.Provider.Settings.ActionAccessibilitySettings);
|
||||
StartActivity(intent);
|
||||
prefs.Edit().PutBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), false).Commit();
|
||||
Toast.MakeText(this, Resource.String.ActivateAutoFillService_toast, ToastLength.Long).Show();
|
||||
Finish();
|
||||
},
|
||||
delegate
|
||||
{
|
||||
//cancel
|
||||
Finish();
|
||||
},
|
||||
(sender, args) => Finish() //dismiss
|
||||
,this);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -409,7 +409,7 @@ namespace keepass2android
|
||||
Intent showNotIntent = new Intent(this, typeof (CopyToClipboardService));
|
||||
showNotIntent.SetAction(Intents.ShowNotification);
|
||||
showNotIntent.PutExtra(KeyEntry, Entry.Uuid.ToHexString());
|
||||
|
||||
_appTask.PopulatePasswordAccessServiceIntent(showNotIntent);
|
||||
showNotIntent.PutExtra(KeyCloseAfterCreate, closeAfterCreate);
|
||||
|
||||
StartService(showNotIntent);
|
||||
|
@ -54,6 +54,13 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name="keepass2android.autofill.AutoFillService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<activity android:configChanges="orientation" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -101,4 +108,6 @@
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<!-- Samsung Pass permission -->
|
||||
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
|
||||
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
|
||||
|
||||
</manifest>
|
@ -33,6 +33,13 @@
|
||||
<category android:name="android.intent.category.OPENABLE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name="keepass2android.autofill.AutoFillService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service android:name="keepass2android.softkeyboard.KP2AKeyboard" android:permission="android.permission.BIND_INPUT_METHOD">
|
||||
<intent-filter>
|
||||
<action android:name="android.view.InputMethod" />
|
||||
@ -102,6 +109,8 @@
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
||||
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
|
||||
|
||||
<!-- Samsung Pass permission -->
|
||||
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
|
||||
</manifest>
|
@ -16,6 +16,12 @@
|
||||
<category android:name="android.intent.category.OPENABLE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name="keepass2android.autofill.AutoFillService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service android:name="keepass2android.softkeyboard.KP2AKeyboard" android:permission="android.permission.BIND_INPUT_METHOD">
|
||||
<intent-filter>
|
||||
<action android:name="android.view.InputMethod" />
|
||||
|
@ -354,7 +354,7 @@
|
||||
<string name="ShowSeparateNotifications_summary">Show separate notifications for copying username and password to clipboard and activating the keyboard.</string>
|
||||
|
||||
<string name="ShowKp2aKeyboardNotification_title">KP2A keyboard notification</string>
|
||||
<string name="ShowKp2aKeyboardNotification_summary">Make full entry accessible through the KP2A keyboard (recommended).</string>
|
||||
<string name="ShowKp2aKeyboardNotification_summary">Make full entry accessible through the KP2A keyboard and AutoFill service (recommended).</string>
|
||||
<string name="OpenKp2aKeyboardAutomatically_title">Switch keyboard</string>
|
||||
<string name="OpenKp2aKeyboardAutomatically_summary">Open keyboard selection dialog when entry is available through KP2A keyboard after search from the browser.</string>
|
||||
|
||||
@ -647,11 +647,11 @@
|
||||
<string name="ErrorReportAsk">Ask after error</string>
|
||||
<string name="ErrorReportPrefTitle">Send error reports</string>
|
||||
|
||||
<string name="LookupTitle">Look up credentials</string>
|
||||
<string name="ApplicationName">KP2A AutoFillPlugin</string>
|
||||
<string name="AutoFillServiceDescription">Monitors apps and websites for password fields. Offers to look up credentials from Keepass2Android and auto-fill them into the forms.</string>
|
||||
<string name="NotificationTitle">Keepass2Android AutoFill</string>
|
||||
<string name="NotificationContentText">AutoFill form for %1$s</string>
|
||||
<string name="ActivateAutoFillService_title">Activate AutoFill?</string>
|
||||
<string name="ActivateAutoFillService_message">Credentials can be transferred to other apps in several ways: You can copy values to clipboard, but please note that the clipboard is not secure in Android. The built-in keyboard gives full access to the selected entry but must be enabled each time you want to access the credentials. On Android 5 and later, Keepass2Android can enter username and password automatically using the AutoFill service.</string>
|
||||
<string name="ActivateAutoFillService_btnKeyboard">Use built-in keyboard</string>
|
||||
<string name="ActivateAutoFillService_btnAutoFill">Use AutoFill service</string>
|
||||
<string name="ActivateAutoFillService_toast">Please enable the Keepass2Android service.</string>
|
||||
|
||||
<string name="ChangeLog_0_9_8c">
|
||||
Version 0.9.8c\n
|
||||
|
@ -347,7 +347,7 @@ namespace keepass2android
|
||||
#endif
|
||||
}
|
||||
|
||||
class DismissListener: Java.Lang.Object, IDialogInterfaceOnDismissListener
|
||||
public class DismissListener: Java.Lang.Object, IDialogInterfaceOnDismissListener
|
||||
{
|
||||
private readonly Action _onDismiss;
|
||||
|
||||
|
@ -328,6 +328,17 @@ namespace keepass2android
|
||||
EventHandler<DialogClickEventArgs> noHandler,
|
||||
EventHandler<DialogClickEventArgs> cancelHandler,
|
||||
Context ctx)
|
||||
{
|
||||
AskYesNoCancel(titleKey, messageKey, yesString, noString, yesHandler, noHandler, cancelHandler, null, ctx);
|
||||
}
|
||||
|
||||
public void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey,
|
||||
UiStringKey yesString, UiStringKey noString,
|
||||
EventHandler<DialogClickEventArgs> yesHandler,
|
||||
EventHandler<DialogClickEventArgs> noHandler,
|
||||
EventHandler<DialogClickEventArgs> cancelHandler,
|
||||
EventHandler dismissHandler,
|
||||
Context ctx)
|
||||
{
|
||||
Handler handler = new Handler(Looper.MainLooper);
|
||||
handler.Post(() =>
|
||||
@ -353,7 +364,11 @@ namespace keepass2android
|
||||
cancelHandler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AlertDialog dialog = builder.Create();
|
||||
if (dismissHandler != null)
|
||||
dialog.SetOnDismissListener(new Util.DismissListener(() => dismissHandler(dialog, EventArgs.Empty)));
|
||||
dialog.Show();
|
||||
|
||||
if (yesText.Length + noText.Length + cancelText.Length >= 20)
|
||||
|
@ -327,6 +327,11 @@ namespace keepass2android
|
||||
{
|
||||
activity.StartNotificationsService(false);
|
||||
}
|
||||
|
||||
virtual public void PopulatePasswordAccessServiceIntent(Intent intent)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -393,7 +398,11 @@ namespace keepass2android
|
||||
//act.AppTask = new NullTask();
|
||||
}
|
||||
|
||||
|
||||
public override void PopulatePasswordAccessServiceIntent(Intent intent)
|
||||
{
|
||||
base.PopulatePasswordAccessServiceIntent(intent);
|
||||
intent.PutExtra(UrlToSearchKey, UrlToSearchFor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,6 +116,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ActivateAutoFillActivity.cs" />
|
||||
<Compile Include="addons\OtpKeyProv\EncodingUtil.cs" />
|
||||
<Compile Include="addons\OtpKeyProv\OathHotpKeyProv.cs" />
|
||||
<Compile Include="addons\OtpKeyProv\OtpAuxCachingFileStorage.cs" />
|
||||
@ -155,7 +156,7 @@
|
||||
<Compile Include="icons\DrawableFactory.cs" />
|
||||
<Compile Include="KeeChallenge.cs" />
|
||||
<Compile Include="FixedDrawerLayout.cs" />
|
||||
<Compile Include="Kp2aAccessibilityService.cs" />
|
||||
<Compile Include="AccessibilityService.cs" />
|
||||
<Compile Include="KpEntryTemplatedEdit.cs" />
|
||||
<Compile Include="MeasuringRelativeLayout.cs" />
|
||||
<Compile Include="NfcOtpActivity.cs" />
|
||||
@ -1671,14 +1672,6 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_fp_40px.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_notify_autofill.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\accserviceconfig.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="..\packages\Xamarin.Insights.1.11.3\build\MonoAndroid10\Xamarin.Insights.targets" Condition="Exists('..\packages\Xamarin.Insights.1.11.3\build\MonoAndroid10\Xamarin.Insights.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
@ -18,6 +18,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Android.AccessibilityServices;
|
||||
using Android.Support.V4.App;
|
||||
using Java.Util;
|
||||
|
||||
@ -27,10 +28,10 @@ using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Widget;
|
||||
using Android.Preferences;
|
||||
using Android.Views.Accessibility;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Utility;
|
||||
using Android.Views.InputMethods;
|
||||
using keepass2android.AutoFill;
|
||||
using KeePass.Util.Spr;
|
||||
|
||||
namespace keepass2android
|
||||
@ -278,6 +279,7 @@ namespace keepass2android
|
||||
if ((intent.Action == Intents.ShowNotification) || (intent.Action == Intents.UpdateKeyboard))
|
||||
{
|
||||
String uuidBytes = intent.GetStringExtra(EntryActivity.KeyEntry);
|
||||
String searchUrl = intent.GetStringExtra(SearchUrlTask.UrlToSearchKey);
|
||||
|
||||
PwUuid entryId = PwUuid.Zero;
|
||||
if (uuidBytes != null)
|
||||
@ -308,7 +310,7 @@ namespace keepass2android
|
||||
{
|
||||
//first time opening the entry -> bring up the notifications
|
||||
bool closeAfterCreate = intent.GetBooleanExtra(EntryActivity.KeyCloseAfterCreate, false);
|
||||
DisplayAccessNotifications(entry, closeAfterCreate);
|
||||
DisplayAccessNotifications(entry, closeAfterCreate, searchUrl);
|
||||
}
|
||||
else //UpdateKeyboard
|
||||
{
|
||||
@ -317,7 +319,7 @@ namespace keepass2android
|
||||
//update the keyboard data.
|
||||
//Check if keyboard is (still) available
|
||||
if (Keepass2android.Kbbridge.KeyboardData.EntryId == entry.Uuid.ToHexString())
|
||||
MakeAccessibleForKeyboard(entry);
|
||||
MakeAccessibleForKeyboard(entry, searchUrl);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -386,7 +388,7 @@ namespace keepass2android
|
||||
private const string ActionNotificationCancelled = "notification_cancelled";
|
||||
|
||||
|
||||
public void DisplayAccessNotifications(PwEntryOutput entry, bool closeAfterCreate)
|
||||
public void DisplayAccessNotifications(PwEntryOutput entry, bool closeAfterCreate, string searchUrl)
|
||||
{
|
||||
var hadKeyboardData = ClearNotifications();
|
||||
|
||||
@ -414,28 +416,22 @@ namespace keepass2android
|
||||
{
|
||||
|
||||
//keyboard
|
||||
hasKeyboardDataNow = MakeAccessibleForKeyboard(entry);
|
||||
hasKeyboardDataNow = MakeAccessibleForKeyboard(entry, searchUrl);
|
||||
if (hasKeyboardDataNow)
|
||||
{
|
||||
notBuilder.AddKeyboardAccess();
|
||||
if (prefs.GetBoolean("kp2a_switch_rooted", false))
|
||||
|
||||
if (Keepass2android.Autofill.AutoFillService.IsAvailable && (!Keepass2android.Autofill.AutoFillService.IsRunning))
|
||||
{
|
||||
//switch rooted
|
||||
bool onlySwitchOnSearch = prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false);
|
||||
if (closeAfterCreate || (!onlySwitchOnSearch))
|
||||
if (!prefs.GetBoolean("has_asked_autofillservice", false))
|
||||
{
|
||||
ActivateKp2aKeyboard();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if the app is about to be closed again (e.g. after searching for a URL and returning to the browser:
|
||||
// automatically bring up the Keyboard selection dialog
|
||||
if ((closeAfterCreate) && prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
|
||||
{
|
||||
ActivateKp2aKeyboard();
|
||||
var i = new Intent(this, typeof (ActivateAutoFillActivity));
|
||||
i.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
|
||||
StartActivity(i);
|
||||
prefs.Edit().PutBoolean("has_asked_autofillservice", true).Commit();
|
||||
}
|
||||
}
|
||||
else ActivateKeyboardIfAppropriate(closeAfterCreate, prefs);
|
||||
|
||||
}
|
||||
|
||||
@ -465,6 +461,31 @@ namespace keepass2android
|
||||
RegisterReceiver(_notificationDeletedBroadcastReceiver, deletefilter);
|
||||
}
|
||||
|
||||
public void ActivateKeyboardIfAppropriate(bool closeAfterCreate, ISharedPreferences prefs)
|
||||
{
|
||||
if (prefs.GetBoolean("kp2a_switch_rooted", false))
|
||||
{
|
||||
//switch rooted
|
||||
bool onlySwitchOnSearch = prefs.GetBoolean(
|
||||
GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false);
|
||||
if (closeAfterCreate || (!onlySwitchOnSearch))
|
||||
{
|
||||
ActivateKp2aKeyboard();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if the app is about to be closed again (e.g. after searching for a URL and returning to the browser:
|
||||
// automatically bring up the Keyboard selection dialog
|
||||
if ((closeAfterCreate) &&
|
||||
prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key),
|
||||
Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
|
||||
{
|
||||
ActivateKp2aKeyboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ClearNotifications()
|
||||
{
|
||||
// Notification Manager
|
||||
@ -479,7 +500,7 @@ namespace keepass2android
|
||||
return hadKeyboardData;
|
||||
}
|
||||
|
||||
bool MakeAccessibleForKeyboard(PwEntryOutput entry)
|
||||
bool MakeAccessibleForKeyboard(PwEntryOutput entry, string searchUrl)
|
||||
{
|
||||
#if EXCLUDE_KEYBOARD
|
||||
return false;
|
||||
@ -529,7 +550,7 @@ namespace keepass2android
|
||||
Keepass2android.Kbbridge.KeyboardData.EntryName = entry.OutputStrings.ReadSafe(PwDefs.TitleField);
|
||||
Keepass2android.Kbbridge.KeyboardData.EntryId = entry.Uuid.ToHexString();
|
||||
if (hasData)
|
||||
Kp2aAccessibilityService.NotifyNewData();
|
||||
Keepass2android.Autofill.AutoFillService.NotifyNewData(searchUrl);
|
||||
|
||||
return hasData;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user