diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2e4f4b16 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/src/keepass2android/todos.cs +/src/keepass2android/obj +/src/keepass2android/bin +/src/KeePassLib2Android/bin diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 00000000..95d2cc54 --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,5 @@ +Author of Keepass2Android: Philipp Crocoll +Author of KeePass (KP2A contains the KeePassLib): Dominik Reichl +Author of Keepassdroid (ported as base for UI): Brian Pellin + See https://github.com/bpellin/keepassdroid/blob/master/CONTRIBUTORS + for further Contributors of Keepassdroid. diff --git a/COPYING.gpl-2.0 b/COPYING.gpl-2.0 new file mode 100644 index 00000000..d511905c --- /dev/null +++ b/COPYING.gpl-2.0 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..5886ba1e --- /dev/null +++ b/LICENSE @@ -0,0 +1,132 @@ +Files under src/KeepassLib2Android: GPL-v2, Copyright Dominik Reichl (Modifications Copyright by Philipp Crocoll) + +--- + +Files under src/keepass2android* except under src/keepass2android/Resources/drawable*: + +Copyright Philipp Crocoll + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +--- + +Files ic00.png to ic61.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi + +TITLE: NUVOLA ICON THEME for KDE 3.x +AUTHOR: David Vignoni | ICON KING +SITE: http://www.icon-king.com +MAILING LIST: http://mail.icon-king.com/mailman/listinfo/nuvola_icon-king.com + +Copyright (c) 2003-2004 David Vignoni. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation, +version 2.1 of the License. +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. +You should have received a copy of the GNU Lesser General Public +License along with this library (see the the license.txt file); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#######**** NOTE THIS ADD-ON ****####### +The GNU Lesser General Public License or LGPL is written for software libraries +in the first place. The LGPL has to be considered valid for this artwork +library too. +Nuvola icon theme for KDE 3.x is a special kind of software library, it is an +artwork library, it's elements can be used in a Graphical User Interface, or +GUI. +Source code, for this library means: + - raster png image* . +The LGPL in some sections obliges you to make the files carry +notices. With images this is in some cases impossible or hardly usefull. +With this library a notice is placed at a prominent place in the directory +containing the elements. You may follow this practice. +The exception in section 6 of the GNU Lesser General Public License covers +the use of elements of this art library in a GUI. +dave [at] icon-king.com + +Date: 15 october 2004 +Version: 1.0 + +DESCRIPTION: + +Icon theme for KDE 3.x. +Icons where designed using Adobe Illustrator, and then exported to PNG format. +Icons shadows and minor corrections were done using Adobe Photoshop. +Kiconedit was used to correct some 16x16 and 22x22 icons. + +LICENSE + +Released under GNU Lesser General Public License (LGPL) +Look at the license.txt file. + +CONTACT + +David Vignoni +e-mail : david [at] icon-king.com +ICQ : 117761009 +http: http://www.icon-king.com + +--- + +Files ic62.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi + +Based on http://de.wikipedia.org/w/index.php?title=Datei:Tux.svg&filetimestamp=20090927073505 + +The copyright holder of this file allows anyone to use it for any purpose, +provided that the copyright holders Larry Ewing, Simon Budig and +Anja Gerwinski are mentioned. + +--- + +Files ic63.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi + +Based on http://en.wikipedia.org/wiki/File:ASF-logo.svg + +Apache logo +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may +obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. + +--- + +Files ic64.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi + +!!! Not included yet !!! + +--- + +Files ic65.png, ic67.png and ic68.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi + +Created by Tobias Selig and licensed under the terms of the GPLv2 or GPLv3. + +--- + +File ic66.png under under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi + +Based on http://commons.wikimedia.org/wiki/File:Dollar_symbol_gold.svg + +Author: Rugby471 + +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU Free Documentation License, Version 1.2 or any later +version published by the Free Software Foundation; with no Invariant Sections, +no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is +included in the section entitled "GNU Free Documentation License". diff --git a/src/KeePass.sln b/src/KeePass.sln new file mode 100644 index 00000000..435c9b7b --- /dev/null +++ b/src/KeePass.sln @@ -0,0 +1,104 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "keepass2android", "keepass2android\keepass2android.csproj", "{A6CF8A86-37C1-4197-80FE-519DE2C842F5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.Build.0 = Debug|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Win32.ActiveCfg = Debug|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Win32.Build.0 = Debug|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|x64.ActiveCfg = Debug|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|x64.Build.0 = Debug|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Any CPU.ActiveCfg = Release|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Any CPU.Build.0 = Release|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Win32.ActiveCfg = Release|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Win32.Build.0 = Release|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.ActiveCfg = Release|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.Build.0 = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.Build.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.ActiveCfg = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.Build.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.Build.0 = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.ActiveCfg = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.Build.0 = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.ActiveCfg = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = keepass2android\keepass2android.csproj + Policies = $0 + $0.DotNetNamingPolicy = $1 + $1.DirectoryNamespaceAssociation = None + $1.ResourceNamePolicy = FileFormatDefault + $0.TextStylePolicy = $2 + $2.FileWidth = 120 + $2.TabsToSpaces = False + $2.inheritsSet = VisualStudio + $2.inheritsScope = text/plain + $2.scope = text/x-csharp + $0.CSharpFormattingPolicy = $3 + $3.IndentSwitchBody = True + $3.AnonymousMethodBraceStyle = NextLine + $3.PropertyBraceStyle = NextLine + $3.PropertyGetBraceStyle = NextLine + $3.PropertySetBraceStyle = NextLine + $3.EventBraceStyle = NextLine + $3.EventAddBraceStyle = NextLine + $3.EventRemoveBraceStyle = NextLine + $3.StatementBraceStyle = NextLine + $3.ArrayInitializerBraceStyle = NextLine + $3.BeforeMethodDeclarationParentheses = False + $3.BeforeMethodCallParentheses = False + $3.BeforeConstructorDeclarationParentheses = False + $3.BeforeDelegateDeclarationParentheses = False + $3.NewParentheses = False + $3.inheritsSet = Mono + $3.inheritsScope = text/x-csharp + $3.scope = text/x-csharp + $0.TextStylePolicy = $4 + $4.FileWidth = 120 + $4.TabsToSpaces = False + $4.inheritsSet = VisualStudio + $4.inheritsScope = text/plain + $4.scope = text/plain + $0.TextStylePolicy = $5 + $5.inheritsSet = null + $5.scope = application/xml + $0.XmlFormattingPolicy = $6 + $6.inheritsSet = Mono + $6.inheritsScope = application/xml + $6.scope = application/xml + $0.StandardHeader = $7 + $7.Text = @/*\nThis file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.\n\n Keepass2Android is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 2 of the License, or\n (at your option) any later version.\n\n Keepass2Android is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with Keepass2Android. If not, see .\n */\n + $7.IncludeInNewFiles = True + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/KeePassLib2Android/Cryptography/CryptoRandom.cs b/src/KeePassLib2Android/Cryptography/CryptoRandom.cs index 1cd1523e..50660ced 100644 --- a/src/KeePassLib2Android/Cryptography/CryptoRandom.cs +++ b/src/KeePassLib2Android/Cryptography/CryptoRandom.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,7 +24,6 @@ using System.Security; using System.Security.Cryptography; using System.IO; using System.Diagnostics; -using System.Windows.Forms; using System.Drawing; using KeePassLib.Native; @@ -137,13 +138,6 @@ namespace KeePassLib.Cryptography pb = TimeUtil.PackTime(DateTime.Now); ms.Write(pb, 0, pb.Length); -#if !KeePassLibSD - Point pt = Cursor.Position; - pb = MemUtil.UInt32ToBytes((uint)pt.X); - ms.Write(pb, 0, pb.Length); - pb = MemUtil.UInt32ToBytes((uint)pt.Y); - ms.Write(pb, 0, pb.Length); -#endif pb = MemUtil.UInt32ToBytes((uint)rWeak.Next()); ms.Write(pb, 0, pb.Length); diff --git a/src/KeePassLib2Android/KeePassLib2Android.csproj b/src/KeePassLib2Android/KeePassLib2Android.csproj index 52c4dccc..714fb3fa 100644 --- a/src/KeePassLib2Android/KeePassLib2Android.csproj +++ b/src/KeePassLib2Android/KeePassLib2Android.csproj @@ -41,6 +41,8 @@ + + diff --git a/src/KeePassLib2Android/Keys/KcpKeyFile.cs b/src/KeePassLib2Android/Keys/KcpKeyFile.cs index 3a0a71a0..a02c701d 100644 --- a/src/KeePassLib2Android/Keys/KcpKeyFile.cs +++ b/src/KeePassLib2Android/Keys/KcpKeyFile.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -71,7 +73,7 @@ namespace KeePassLib.Keys private void Construct(IOConnectionInfo iocFile) { byte[] pbFileData = IOConnection.ReadFile(iocFile); - if(pbFileData == null) throw new FileNotFoundException(); + if(pbFileData == null) throw new Java.IO.FileNotFoundException(); byte[] pbKey = LoadXmlKeyFile(pbFileData); if(pbKey == null) pbKey = LoadKeyFile(pbFileData); diff --git a/src/KeePassLib2Android/Keys/KcpUserAccount.cs b/src/KeePassLib2Android/Keys/KcpUserAccount.cs index aefb02c9..b3b7da49 100644 --- a/src/KeePassLib2Android/Keys/KcpUserAccount.cs +++ b/src/KeePassLib2Android/Keys/KcpUserAccount.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -59,18 +61,7 @@ namespace KeePassLib.Keys /// public KcpUserAccount() { - // Test if ProtectedData is supported -- throws an exception - // when running on an old system (Windows 98 / ME). - byte[] pbDummyData = new byte[128]; - ProtectedData.Protect(pbDummyData, m_pbEntropy, - DataProtectionScope.CurrentUser); - - byte[] pbKey = LoadUserKey(false); - if(pbKey == null) pbKey = CreateUserKey(); - if(pbKey == null) throw new SecurityException(KLRes.UserAccountKeyError); - - m_pbKeyData = new ProtectedBinary(true, pbKey); - Array.Clear(pbKey, 0, pbKey.Length); + throw new NotSupportedException("DataProtection not supported on MonoForAndroid!"); } // public void Clear() @@ -100,13 +91,7 @@ namespace KeePassLib.Keys #if !KeePassLibSD try { - string strFilePath = GetUserKeyFilePath(false); - byte[] pbProtectedKey = File.ReadAllBytes(strFilePath); - - pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy, - DataProtectionScope.CurrentUser); - - Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length); + throw new NotSupportedException("DataProtection not supported on MonoForAndroid!"); } catch(Exception exLoad) { @@ -126,18 +111,7 @@ namespace KeePassLib.Keys #if !KeePassLibSD try { - string strFilePath = GetUserKeyFilePath(true); - - byte[] pbRandomKey = CryptoRandom.Instance.GetRandomBytes(64); - byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey, - m_pbEntropy, DataProtectionScope.CurrentUser); - - File.WriteAllBytes(strFilePath, pbProtectedKey); - - Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length); - Array.Clear(pbRandomKey, 0, pbRandomKey.Length); - - pbKey = LoadUserKey(true); + throw new NotSupportedException("DataProtection not supported on MonoForAndroid!"); } catch(Exception) { pbKey = null; } #endif diff --git a/src/KeePassLib2Android/Native/NativeLib.cs b/src/KeePassLib2Android/Native/NativeLib.cs index 26bf031b..06378d5b 100644 --- a/src/KeePassLib2Android/Native/NativeLib.cs +++ b/src/KeePassLib2Android/Native/NativeLib.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -90,13 +92,14 @@ namespace KeePassLib.Native m_platID = Environment.OSVersion.Platform; #if !KeePassLibSD - // Mono returns PlatformID.Unix on Mac OS X, workaround this + /*// Mono returns PlatformID.Unix on Mac OS X, workaround this + //fails on Anroid if(m_platID.Value == PlatformID.Unix) { if((RunConsoleApp("uname", null) ?? string.Empty).Trim().Equals( "Darwin", StrUtil.CaseIgnoreCmp)) m_platID = PlatformID.MacOSX; - } + }*/ #endif return m_platID.Value; diff --git a/src/KeePassLib2Android/PwCustomIcon.cs b/src/KeePassLib2Android/PwCustomIcon.cs index f32bc1a8..38cac720 100644 --- a/src/KeePassLib2Android/PwCustomIcon.cs +++ b/src/KeePassLib2Android/PwCustomIcon.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,8 +26,10 @@ using System.IO; using KeePassLib.Utility; + namespace KeePassLib { + /// /// Custom icon. PwCustomIcon objects are immutable. /// @@ -33,7 +37,7 @@ namespace KeePassLib { private PwUuid m_pwUuid; private byte[] m_pbImageDataPng; - private Image m_pCachedImage; + private Android.Graphics.Bitmap m_pCachedImage; public PwUuid Uuid { @@ -45,7 +49,7 @@ namespace KeePassLib get { return m_pbImageDataPng; } } - public Image Image + public Android.Graphics.Bitmap Image { get { return m_pCachedImage; } } diff --git a/src/KeePassLib2Android/PwDatabase.cs b/src/KeePassLib2Android/PwDatabase.cs index d3ef6570..925ab468 100644 --- a/src/KeePassLib2Android/PwDatabase.cs +++ b/src/KeePassLib2Android/PwDatabase.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1405,7 +1407,7 @@ namespace KeePassLib /// /// ID of the icon. /// Image data. - public Image GetCustomIcon(PwUuid pwIconId) + public Android.Graphics.Bitmap GetCustomIcon(PwUuid pwIconId) { int nIndex = GetCustomIconIndex(pwIconId); diff --git a/src/KeePassLib2Android/Resources/AboutResources.txt b/src/KeePassLib2Android/Resources/AboutResources.txt index 10f52d46..6dff7bcc 100644 --- a/src/KeePassLib2Android/Resources/AboutResources.txt +++ b/src/KeePassLib2Android/Resources/AboutResources.txt @@ -40,5 +40,5 @@ public class R { } You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main -to reference the layout/main.axml file, or R.strings.first_string to reference the first +to reference the layout/main.axml file, or R.Strings.first_string to reference the first string in the dictionary file values/strings.xml. diff --git a/src/KeePassLib2Android/Resources/Resource.designer.cs b/src/KeePassLib2Android/Resources/Resource.designer.cs index abaffe08..ee0b9514 100644 --- a/src/KeePassLib2Android/Resources/Resource.designer.cs +++ b/src/KeePassLib2Android/Resources/Resource.designer.cs @@ -1,3 +1,4 @@ +#pragma warning disable 1591 //------------------------------------------------------------------------------ // // Dieser Code wurde von einem Tool generiert. @@ -8,10 +9,13 @@ // //------------------------------------------------------------------------------ +[assembly: Android.Runtime.ResourceDesignerAttribute("KeePassLib2Android.Resource", IsApplication=false)] + namespace KeePassLib2Android { + [System.CodeDom.Compiler.GeneratedCodeAttribute("Novell.MonoDroid.Build.Tasks", "1.0.0.0")] public partial class Resource { @@ -27,7 +31,7 @@ namespace KeePassLib2Android { // aapt resource value: 0x7f020000 - public const int library_name = 2130837504; + public static int library_name = 2130837504; private String() { @@ -35,3 +39,4 @@ namespace KeePassLib2Android } } } +#pragma warning restore 1591 diff --git a/src/KeePassLib2Android/Security/ProtectedBinary.cs b/src/KeePassLib2Android/Security/ProtectedBinary.cs index b8ce4923..1a25fda4 100644 --- a/src/KeePassLib2Android/Security/ProtectedBinary.cs +++ b/src/KeePassLib2Android/Security/ProtectedBinary.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -73,16 +75,8 @@ namespace KeePassLib.Security static ProtectedBinary() { - try // Test whether ProtectedMemory is supported - { - byte[] pbDummy = new byte[PmBlockSize * 2]; - ProtectedMemory.Protect(pbDummy, MemoryProtectionScope.SameProcess); - m_bProtectionSupported = true; - } - catch(Exception) // Windows 98 / ME - { - m_bProtectionSupported = false; - } + //protection not supported on Android currently + m_bProtectionSupported = false; } /// @@ -143,7 +137,7 @@ namespace KeePassLib.Security // Data size must be > 0, otherwise 'Protect' throws if(m_bProtected && m_bProtectionSupported && (m_uDataLen > 0)) - ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess); + throw new NotSupportedException(); } /// @@ -164,9 +158,7 @@ namespace KeePassLib.Security { lock(m_objSync) { - ProtectedMemory.Unprotect(m_pbData, MemoryProtectionScope.SameProcess); - Array.Copy(m_pbData, pbReturn, (int)m_uDataLen); - ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess); + throw new NotSupportedException(); } } else Array.Copy(m_pbData, pbReturn, (int)m_uDataLen); diff --git a/src/KeePassLib2Android/Serialization/FileLock.cs b/src/KeePassLib2Android/Serialization/FileLock.cs index ac20e00d..a3030306 100644 --- a/src/KeePassLib2Android/Serialization/FileLock.cs +++ b/src/KeePassLib2Android/Serialization/FileLock.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -137,7 +139,7 @@ namespace KeePassLib.Serialization if(!v[0].StartsWith(LockFileHeader)) { Debug.Assert(false); return null; } return new LockFileInfo(v[1], v[2], v[3], v[4], v[5]); } - catch(FileNotFoundException) { } + catch(Java.IO.FileNotFoundException) { } catch(Exception) { Debug.Assert(false); } finally { if(s != null) s.Close(); } diff --git a/src/KeePassLib2Android/Serialization/FileTransactionEx.cs b/src/KeePassLib2Android/Serialization/FileTransactionEx.cs index 7e179963..254f99a8 100644 --- a/src/KeePassLib2Android/Serialization/FileTransactionEx.cs +++ b/src/KeePassLib2Android/Serialization/FileTransactionEx.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -92,7 +94,7 @@ namespace KeePassLib.Serialization bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path); #if !KeePassLibSD - FileSecurity bkSecurity = null; + bool bEfsEncrypted = false; #endif @@ -107,7 +109,7 @@ namespace KeePassLib.Serialization bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0); DateTime tCreation = File.GetCreationTime(m_iocBase.Path); - bkSecurity = File.GetAccessControl(m_iocBase.Path); + File.SetCreationTime(m_iocTemp.Path, tCreation); } @@ -131,8 +133,6 @@ namespace KeePassLib.Serialization catch(Exception) { Debug.Assert(false); } } - if(bkSecurity != null) - File.SetAccessControl(m_iocBase.Path, bkSecurity); } catch(Exception) { Debug.Assert(false); } } diff --git a/src/KeePassLib2Android/Serialization/HashedBlockStream.cs b/src/KeePassLib2Android/Serialization/HashedBlockStream.cs index 403b6dfd..098e6228 100644 --- a/src/KeePassLib2Android/Serialization/HashedBlockStream.cs +++ b/src/KeePassLib2Android/Serialization/HashedBlockStream.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,6 +34,44 @@ using KeePassLibSD; namespace KeePassLib.Serialization { + + [System.Serializable] + public class InvalidDataException: Exception + { + /// + /// Initializes a new instance of the class + /// + public InvalidDataException () + { + } + + /// + /// Initializes a new instance of the class + /// + /// A that describes the exception. + public InvalidDataException (string message) : base (message) + { + } + + /// + /// Initializes a new instance of the class + /// + /// A that describes the exception. + /// The exception that is the cause of the current exception. + public InvalidDataException (string message, Exception inner) : base (message, inner) + { + } + + /// + /// Initializes a new instance of the class + /// + /// The contextual information about the source or destination. + /// The object that holds the serialized object data. + protected InvalidDataException (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (info, context) + { + } + } + public sealed class HashedBlockStream : Stream { private const int m_nDefaultBufferSize = 1024 * 1024; // 1 MB diff --git a/src/KeePassLib2Android/Serialization/IOConnection.cs b/src/KeePassLib2Android/Serialization/IOConnection.cs index e115ff5b..90be2083 100644 --- a/src/KeePassLib2Android/Serialization/IOConnection.cs +++ b/src/KeePassLib2Android/Serialization/IOConnection.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -243,6 +245,41 @@ namespace KeePassLib.Serialization } #if !KeePassLibSD + + class UploadOnCloseMemoryStream: MemoryStream + { + System.Net.WebClient webClient; + string method; + Uri destinationFilePath; + + public UploadOnCloseMemoryStream(System.Net.WebClient _webClient, string _method, Uri _destinationFilePath) + { + this.webClient = _webClient; + this.method = _method; + this.destinationFilePath = _destinationFilePath; + } + + public UploadOnCloseMemoryStream(System.Net.WebClient _webClient, Uri _destinationFilePath) + { + this.webClient = _webClient; + this.method = null; + this.destinationFilePath = _destinationFilePath; + } + + public override void Close() + { + base.Close(); + if (method != null) + { + webClient.UploadData(destinationFilePath, method, this.ToArray()); + } else + { + webClient.UploadData(destinationFilePath, this.ToArray()); + } + + } + } + public static Stream OpenWrite(IOConnectionInfo ioc) { if(ioc == null) { Debug.Assert(false); return null; } @@ -256,9 +293,9 @@ namespace KeePassLib.Serialization if(NativeLib.IsUnix() && (uri.Scheme.Equals(Uri.UriSchemeHttp, StrUtil.CaseIgnoreCmp) || uri.Scheme.Equals(Uri.UriSchemeHttps, StrUtil.CaseIgnoreCmp))) - return CreateWebClient(ioc).OpenWrite(uri, WebRequestMethods.Http.Put); + return new UploadOnCloseMemoryStream(CreateWebClient(ioc), WebRequestMethods.Http.Put, uri); - return CreateWebClient(ioc).OpenWrite(uri); + return new UploadOnCloseMemoryStream(CreateWebClient(ioc), uri); } #else public static Stream OpenWrite(IOConnectionInfo ioc) @@ -296,7 +333,7 @@ namespace KeePassLib.Serialization try { Stream s = OpenRead(ioc); - if(s == null) throw new FileNotFoundException(); + if(s == null) throw new Java.IO.FileNotFoundException(); try { s.ReadByte(); } catch(Exception) { } diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Read.Streamed.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Read.Streamed.cs index 27b85c4e..c572f6ca 100644 --- a/src/KeePassLib2Android/Serialization/KdbxFile.Read.Streamed.cs +++ b/src/KeePassLib2Android/Serialization/KdbxFile.Read.Streamed.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,6 +45,49 @@ namespace KeePassLib.Serialization /// public sealed partial class KdbxFile { + private class ColorTranslator + { + public static Color FromHtml(String colorString) + { + Color color; + + if (colorString.StartsWith("#")) + { + colorString = colorString.Substring(1); + } + if (colorString.EndsWith(";")) + { + colorString = colorString.Substring(0, colorString.Length - 1); + } + + int red, green, blue; + switch (colorString.Length) + { + case 6: + red = int.Parse(colorString.Substring(0, 2), System.Globalization.NumberStyles.HexNumber); + green = int.Parse(colorString.Substring(2, 2), System.Globalization.NumberStyles.HexNumber); + blue = int.Parse(colorString.Substring(4, 2), System.Globalization.NumberStyles.HexNumber); + color = Color.FromArgb(red, green, blue); + break; + case 3: + red = int.Parse(colorString.Substring(0, 1), System.Globalization.NumberStyles.HexNumber); + green = int.Parse(colorString.Substring(1, 1), System.Globalization.NumberStyles.HexNumber); + blue = int.Parse(colorString.Substring(2, 1), System.Globalization.NumberStyles.HexNumber); + color = Color.FromArgb(red, green, blue); + break; + case 1: + red = green = blue = int.Parse(colorString.Substring(0, 1), System.Globalization.NumberStyles.HexNumber); + color = Color.FromArgb(red, green, blue); + break; + default: + throw new ArgumentException("Invalid color: " + colorString); + } + return color; + } + + } + + private enum KdbContext { Null, diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs index ada3a9ed..802feaf0 100644 --- a/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs +++ b/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,7 +29,6 @@ using System.Security; using System.Security.Cryptography; using System.Drawing; using System.Globalization; -using System.Drawing.Imaging; #if !KeePassLibSD using System.IO.Compression; diff --git a/src/KeePassLib2Android/Translation/KPControlCustomization.cs b/src/KeePassLib2Android/Translation/KPControlCustomization.cs index 1530f655..fcc4fb37 100644 --- a/src/KeePassLib2Android/Translation/KPControlCustomization.cs +++ b/src/KeePassLib2Android/Translation/KPControlCustomization.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +23,6 @@ using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; -using System.Windows.Forms; using System.Diagnostics; using System.Xml.Serialization; using System.Globalization; @@ -33,8 +34,12 @@ using KeePassLib.Utility; namespace KeePassLib.Translation { + public class Control + {} + public sealed class KpccLayout { + public enum LayoutParameterEx { X, Y, Width, Height @@ -113,7 +118,7 @@ namespace KeePassLib.Translation } #if !KeePassLibSD - internal void ApplyTo(Control c) + /*internal void ApplyTo(Control c) { Debug.Assert(c != null); if(c == null) return; @@ -181,7 +186,7 @@ namespace KeePassLib.Translation Debug.Assert(false); return null; - } + }*/ #endif public static string ToControlRelativeString(string strEncoded) @@ -268,7 +273,7 @@ namespace KeePassLib.Translation } #if !KeePassLibSD - private static readonly Type[] m_vTextControls = new Type[] { + /*private static readonly Type[] m_vTextControls = new Type[] { typeof(MenuStrip), typeof(PictureBox), typeof(ListView), typeof(TreeView), typeof(ToolStrip), typeof(WebBrowser), typeof(Panel), typeof(StatusStrip), typeof(ProgressBar), @@ -394,7 +399,7 @@ namespace KeePassLib.Translation // Currently only v1: is supported, see HashControl return (m_strHash == strHash); - } + }*/ #endif } } diff --git a/src/KeePassLib2Android/Translation/KPFormCustomization.cs b/src/KeePassLib2Android/Translation/KPFormCustomization.cs index 9c6a3442..de04b50b 100644 --- a/src/KeePassLib2Android/Translation/KPFormCustomization.cs +++ b/src/KeePassLib2Android/Translation/KPFormCustomization.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,13 +22,14 @@ using System; using System.Collections.Generic; using System.Text; -using System.Windows.Forms; using System.Xml.Serialization; using System.Diagnostics; using System.Reflection; namespace KeePassLib.Translation { + public class Form + {} public sealed class KPFormCustomization { private string m_strFQName = string.Empty; @@ -75,7 +78,7 @@ namespace KeePassLib.Translation } #if !KeePassLibSD - public void ApplyTo(Form form) + /*public void ApplyTo(Form form) { Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form"); @@ -100,7 +103,7 @@ namespace KeePassLib.Translation } foreach(Control cSub in c.Controls) ApplyToControl(cSub); - } + }*/ #endif } } diff --git a/src/KeePassLib2Android/Translation/KPStringTable.cs b/src/KeePassLib2Android/Translation/KPStringTable.cs index b5c676fb..f9896a50 100644 --- a/src/KeePassLib2Android/Translation/KPStringTable.cs +++ b/src/KeePassLib2Android/Translation/KPStringTable.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,11 +23,13 @@ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; -using System.Windows.Forms; + using System.Diagnostics; namespace KeePassLib.Translation { + public class ToolStripItemCollection + {} public sealed class KPStringTable { private string m_strName = string.Empty; @@ -67,7 +71,7 @@ namespace KeePassLib.Translation } #if !KeePassLibSD - public void ApplyTo(ToolStripItemCollection tsic) + /*public void ApplyTo(ToolStripItemCollection tsic) { if(tsic == null) throw new ArgumentNullException("tsic"); @@ -93,7 +97,7 @@ namespace KeePassLib.Translation if((tsmi != null) && (tsmi.DropDownItems != null)) this.ApplyTo(tsmi.DropDownItems); } - } + }*/ #endif } } diff --git a/src/KeePassLib2Android/Translation/KPTranslation.cs b/src/KeePassLib2Android/Translation/KPTranslation.cs index 2705325d..923057a3 100644 --- a/src/KeePassLib2Android/Translation/KPTranslation.cs +++ b/src/KeePassLib2Android/Translation/KPTranslation.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,7 +25,7 @@ using System.Text; using System.IO; using System.Xml; using System.Xml.Serialization; -using System.Windows.Forms; + using System.ComponentModel; using System.Drawing; using System.Diagnostics; @@ -154,7 +156,7 @@ namespace KeePassLib.Translation } #if !KeePassLibSD - public void ApplyTo(Form form) + /*public void ApplyTo(Form form) { if(form == null) throw new ArgumentNullException("form"); @@ -183,8 +185,8 @@ namespace KeePassLib.Translation try { RtlApplyToControls(form.Controls); } catch(Exception) { Debug.Assert(false); } } - } - + }*/ + /* private static void RtlApplyToControls(Control.ControlCollection cc) { foreach(Control c in cc) @@ -210,9 +212,9 @@ namespace KeePassLib.Translation if((c is GroupBox) || (c is Panel)) RtlMoveChildControls(c); } - } + }*/ - private static void RtlMoveChildControls(Control cParent) + /*private static void RtlMoveChildControls(Control cParent) { int nParentWidth = cParent.Size.Width; @@ -246,7 +248,7 @@ namespace KeePassLib.Translation } if(kpst != null) kpst.ApplyTo(tsic); - } + }*/ #endif } } diff --git a/src/KeePassLib2Android/Utility/GfxUtil.cs b/src/KeePassLib2Android/Utility/GfxUtil.cs index 2b487407..52a6f961 100644 --- a/src/KeePassLib2Android/Utility/GfxUtil.cs +++ b/src/KeePassLib2Android/Utility/GfxUtil.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,14 +24,15 @@ using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; -using System.Drawing.Imaging; + using System.Diagnostics; +using Android.Graphics; namespace KeePassLib.Utility { public static class GfxUtil { - public static Image LoadImage(byte[] pb) + public static Android.Graphics.Bitmap LoadImage(byte[] pb) { if(pb == null) throw new ArgumentNullException("pb"); @@ -37,59 +40,43 @@ namespace KeePassLib.Utility try { return LoadImagePriv(ms); } catch(Exception) { - Image imgIco = TryLoadIco(pb); + Android.Graphics.Bitmap imgIco = TryLoadIco(pb); if(imgIco != null) return imgIco; throw; } finally { ms.Close(); } } - private static Image LoadImagePriv(Stream s) + private static Android.Graphics.Bitmap LoadImagePriv(Stream s) { - // Image.FromStream wants the stream to be open during - // the whole lifetime of the image; as we can't guarantee - // this, we make a copy of the image - Image imgSrc = null; - try - { -#if !KeePassLibSD - imgSrc = Image.FromStream(s); - Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height, - PixelFormat.Format32bppArgb); + Android.Graphics.Bitmap img = null; + +#if !KeePassLibSD + + img = BitmapFactory.DecodeStream(s); - try - { - bmp.SetResolution(imgSrc.HorizontalResolution, - imgSrc.VerticalResolution); - Debug.Assert(bmp.Size == imgSrc.Size); - } - catch(Exception) { Debug.Assert(false); } #else imgSrc = new Bitmap(s); Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height); #endif - using(Graphics g = Graphics.FromImage(bmp)) - { - g.Clear(Color.Transparent); - g.DrawImage(imgSrc, 0, 0); - } - return bmp; - } - finally { if(imgSrc != null) imgSrc.Dispose(); } + return img; + } - private static Image TryLoadIco(byte[] pb) + private static Android.Graphics.Bitmap TryLoadIco(byte[] pb) { #if !KeePassLibSD + throw new NotImplementedException(); + /* MemoryStream ms = new MemoryStream(pb, false); try { return (new Icon(ms)).ToBitmap(); } catch(Exception) { } - finally { ms.Close(); } + finally { ms.Close(); }*/ #endif - return null; + //return null; } } } diff --git a/src/KeePassLib2Android/Utility/MessageService.cs b/src/KeePassLib2Android/Utility/MessageService.cs index 22ee8355..dac9d8fa 100644 --- a/src/KeePassLib2Android/Utility/MessageService.cs +++ b/src/KeePassLib2Android/Utility/MessageService.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +23,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Text; -using System.Windows.Forms; + using System.Diagnostics; using KeePassLib.Resources; @@ -29,17 +31,36 @@ using KeePassLib.Serialization; namespace KeePassLib.Utility { + public enum MessageBoxButtons + { + OK, OKCancel, AbortRetryIgnore, YesNoCancel, YesNo, RetryCancel + } + public enum MessageBoxIcon + { + Information, Warning, Error, Question + } + public enum MessageBoxDefaultButton + { + Button1, Button2, Button3 + } + + public enum DialogResult + { + Yes, No, Cancel, Retry, Abort + } + + public sealed class MessageServiceEventArgs : EventArgs { private string m_strTitle = string.Empty; private string m_strText = string.Empty; - private MessageBoxButtons m_msgButtons = MessageBoxButtons.OK; - private MessageBoxIcon m_msgIcon = MessageBoxIcon.None; + //private MessageBoxButtons m_msgButtons = MessageBoxButtons.OK; + //private MessageBoxIcon m_msgIcon = MessageBoxIcon.None; public string Title { get { return m_strTitle; } } public string Text { get { return m_strText; } } - public MessageBoxButtons Buttons { get { return m_msgButtons; } } - public MessageBoxIcon Icon { get { return m_msgIcon; } } + //public MessageBoxButtons Buttons { get { return m_msgButtons; } } + //public MessageBoxIcon Icon { get { return m_msgIcon; } } public MessageServiceEventArgs() { } @@ -48,8 +69,7 @@ namespace KeePassLib.Utility { m_strTitle = (strTitle ?? string.Empty); m_strText = (strText ?? string.Empty); - m_msgButtons = msgButtons; - m_msgIcon = msgIcon; + } } @@ -62,14 +82,12 @@ namespace KeePassLib.Utility private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Warning; private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Error; - private const MessageBoxOptions m_mboRtl = (MessageBoxOptions.RtlReading | - MessageBoxOptions.RightAlign); #else private const MessageBoxIcon m_mbiInfo = MessageBoxIcon.Asterisk; private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Exclamation; private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Hand; #endif - private const MessageBoxIcon m_mbiQuestion = MessageBoxIcon.Question; + //private const MessageBoxIcon m_mbiQuestion = MessageBoxIcon.Question; public static string NewLine { @@ -159,13 +177,13 @@ namespace KeePassLib.Utility } #if !KeePassLibSD - internal static Form GetTopForm() + /*internal static Form GetTopForm() { FormCollection fc = Application.OpenForms; if((fc == null) || (fc.Count == 0)) return null; return fc[fc.Count - 1]; - } + }*/ #endif private static DialogResult SafeShowMessageBox(string strText, string strTitle, @@ -174,7 +192,14 @@ namespace KeePassLib.Utility #if KeePassLibSD return MessageBox.Show(strText, strTitle, mb, mi, mdb); #else - IWin32Window wnd = null; + + if (mb == MessageBoxButtons.OK) + { + //Android.Widget.Toast toast = .. + } + //this might help: http://www.gregshackles.com/2011/04/using-background-threads-in-mono-for-android-applications/ + throw new NotImplementedException(); + /*IWin32Window wnd = null; try { Form f = GetTopForm(); @@ -203,11 +228,12 @@ namespace KeePassLib.Utility if(StrUtil.RightToLeft) return MessageBox.Show(strText, strTitle, mb, mi, mdb, m_mboRtl); return MessageBox.Show(strText, strTitle, mb, mi, mdb); + */ #endif } #if !KeePassLibSD - internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent, + /* internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent, string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb); @@ -218,7 +244,7 @@ namespace KeePassLib.Utility if(StrUtil.RightToLeft) return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb, m_mboRtl); return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb); - } + }*/ #endif public static void ShowInfo(params object[] vLines) @@ -284,8 +310,9 @@ namespace KeePassLib.Utility try { #if !KeePassLibSD - Clipboard.Clear(); - Clipboard.SetText(ObjectsToMessage(vLines, true)); + /* nicht benoetigt - hoffentlich :-) +Clipboard.Clear(); +Clipboard.SetText(ObjectsToMessage(vLines, true));*/ #else Clipboard.SetDataObject(ObjectsToMessage(vLines, true)); #endif @@ -312,10 +339,10 @@ namespace KeePassLib.Utility if(MessageService.MessageShowing != null) MessageService.MessageShowing(null, new MessageServiceEventArgs( - strTitleEx, strTextEx, mbb, m_mbiQuestion)); + strTitleEx, strTextEx, mbb, MessageBoxIcon.Question)); DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx, mbb, - m_mbiQuestion, MessageBoxDefaultButton.Button1); + MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); --m_uCurrentMessageCount; return dr; @@ -330,10 +357,10 @@ namespace KeePassLib.Utility if(MessageService.MessageShowing != null) MessageService.MessageShowing(null, new MessageServiceEventArgs( - strTitleEx, strTextEx, MessageBoxButtons.YesNo, m_mbiQuestion)); + strTitleEx, strTextEx, MessageBoxButtons.YesNo, MessageBoxIcon.Question)); DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx, - MessageBoxButtons.YesNo, m_mbiQuestion, bDefaultToYes ? + MessageBoxButtons.YesNo, MessageBoxIcon.Question, bDefaultToYes ? MessageBoxDefaultButton.Button1 : MessageBoxDefaultButton.Button2); --m_uCurrentMessageCount; diff --git a/src/KeePassLib2Android/Utility/StrUtil.cs b/src/KeePassLib2Android/Utility/StrUtil.cs index 94e590aa..10398c11 100644 --- a/src/KeePassLib2Android/Utility/StrUtil.cs +++ b/src/KeePassLib2Android/Utility/StrUtil.cs @@ -1,6 +1,8 @@ /* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl + + Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -990,15 +992,7 @@ namespace KeePassLib.Utility try { - byte[] pbPlain = StrUtil.Utf8.GetBytes(strPlainText); - byte[] pbEnc = ProtectedData.Protect(pbPlain, m_pbOptEnt, - DataProtectionScope.CurrentUser); - -#if !KeePassLibSD - return Convert.ToBase64String(pbEnc, Base64FormattingOptions.None); -#else - return Convert.ToBase64String(pbEnc); -#endif + throw new NotSupportedException(); } catch(Exception) { Debug.Assert(false); } @@ -1012,10 +1006,8 @@ namespace KeePassLib.Utility try { byte[] pbEnc = Convert.FromBase64String(strCipherText); - byte[] pbPlain = ProtectedData.Unprotect(pbEnc, m_pbOptEnt, - DataProtectionScope.CurrentUser); + throw new NotSupportedException(); - return StrUtil.Utf8.GetString(pbPlain, 0, pbPlain.Length); } catch(Exception) { Debug.Assert(false); } diff --git a/src/keepass2android/AboutDialog.cs b/src/keepass2android/AboutDialog.cs new file mode 100644 index 00000000..a61ab810 --- /dev/null +++ b/src/keepass2android/AboutDialog.cs @@ -0,0 +1,72 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.Content.PM; + +namespace keepass2android +{ + + public class AboutDialog : Dialog { + + public AboutDialog(Context context):base (context) { + } + + protected override void OnCreate(Bundle savedInstanceState) { + base.OnCreate(savedInstanceState); + SetContentView(Resource.Layout.about); + SetTitle(Resource.String.app_name); + + setVersion(); + + Button okButton = (Button) FindViewById(Resource.Id.about_button); + okButton.Click += (object sender, EventArgs e) => { + Dismiss(); + }; + } + + private void setVersion() { + Context ctx = Context; + + String version; + try { + PackageInfo packageInfo = ctx.PackageManager.GetPackageInfo(ctx.PackageName, 0); + version = packageInfo.VersionName; + + } catch (PackageManager.NameNotFoundException) { + version = ""; + } + + TextView tv = (TextView) FindViewById(Resource.Id.version); + tv.Text = version; + + } + + } + +} + diff --git a/src/keepass2android/AssemblyInfo.cs b/src/keepass2android/AssemblyInfo.cs new file mode 100644 index 00000000..53cf0e76 --- /dev/null +++ b/src/keepass2android/AssemblyInfo.cs @@ -0,0 +1,20 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ +using Android.App; + + + diff --git a/src/keepass2android/BitmapDrawableCompat.cs b/src/keepass2android/BitmapDrawableCompat.cs new file mode 100644 index 00000000..41269b79 --- /dev/null +++ b/src/keepass2android/BitmapDrawableCompat.cs @@ -0,0 +1,45 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.Graphics.Drawables; +using Android.Content.Res; +using Android.Graphics; + +namespace keepass2android +{ + + public class BitmapDrawableCompat { + + public static BitmapDrawable getBitmapDrawable(Resources res, Bitmap bitmap) { + return new BitmapDrawable(res, bitmap); + } + + } + +} + diff --git a/src/keepass2android/CancelDialog.cs b/src/keepass2android/CancelDialog.cs new file mode 100644 index 00000000..efacfc33 --- /dev/null +++ b/src/keepass2android/CancelDialog.cs @@ -0,0 +1,52 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + + public class CancelDialog : Dialog { + + private bool mCanceled = false; + + public CancelDialog(Context context): base(context) { + } + + public bool canceled() { + return mCanceled; + } + + + public override void Cancel() { + base.Cancel(); + mCanceled = true; + } + } + +} + diff --git a/src/keepass2android/Database.cs b/src/keepass2android/Database.cs new file mode 100644 index 00000000..b632a95a --- /dev/null +++ b/src/keepass2android/Database.cs @@ -0,0 +1,244 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +using KeePassLib; +using KeePassLib.Interfaces; +using KeePassLib.Serialization; + +namespace keepass2android +{ + + public class Database { + + + public Dictionary groups = new Dictionary(new PwUuidEqualityComparer()); + public Dictionary entries = new Dictionary(new PwUuidEqualityComparer()); + public HashSet dirty = new HashSet(new PwGroupEqualityFromIdComparer()); + public PwGroup root; + public PwDatabase pm; + public IOConnectionInfo mIoc; + public SearchDbHelper searchHelper; + + public DrawableFactory drawFactory = new DrawableFactory(); + + private bool loaded = false; + + + public bool Loaded { + get { return loaded;} + set { loaded = value; } + } + + public bool Open + { + get { return Loaded && (!Locked); } + } + + bool locked; + public bool Locked + { + get + { + return locked; + } + set + { + locked = value; + } + } + + + + public void LoadData (Context ctx, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status) + { + mIoc = iocInfo; + + KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase (); + + KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey (); + key.AddUserKey (new KeePassLib.Keys.KcpPassword (password)); + if (!String.IsNullOrEmpty (keyfile)) { + + try { key.AddUserKey(new KeePassLib.Keys.KcpKeyFile(keyfile)); } + catch(Exception) + { + throw new KeyFileException(); + } + } + + pwDatabase.Open(iocInfo, key, status); + + root = pwDatabase.RootGroup; + populateGlobals(root); + + + Loaded = true; + pm = pwDatabase; + searchHelper = new SearchDbHelper(ctx); + } + + bool quickUnlockEnabled = false; + public bool QuickUnlockEnabled + { + get + { + return quickUnlockEnabled; + } + set + { + quickUnlockEnabled = value; + } + } + + //KeyLength of QuickUnlock at time of loading the database. + //This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already. + public int QuickUnlockKeyLength + { + get; + set; + } + + public PwGroup SearchForText(String str) { + PwGroup group = searchHelper.searchForText(this, str); + + return group; + + } + + public PwGroup Search(SearchParameters searchParams) + { + return searchHelper.search(this, searchParams); + } + + + public PwGroup SearchForExactUrl(String url) { + PwGroup group = searchHelper.searchForExactUrl(this, url); + + return group; + + } + + public PwGroup SearchForHost(String url) { + PwGroup group = searchHelper.searchForHost(this, url); + + return group; + + } + + + public void SaveData(Context ctx) { + ISharedPreferences prefs = Android.Preferences.PreferenceManager.GetDefaultSharedPreferences(ctx); + pm.UseFileTransactions = prefs.GetBoolean(ctx.GetString(Resource.String.UseFileTransactions_key), true); + pm.Save(null); + + } + class SaveStatusLogger: IStatusLogger + { + #region IStatusLogger implementation + public void StartLogging (string strOperation, bool bWriteOperationToLog) + { + } + public void EndLogging () + { + } + public bool SetProgress (uint uPercent) + { + Android.Util.Log.Debug("DEBUG", "Progress: " + uPercent+"%"); + return true; + } + public bool SetText (string strNewText, LogStatusType lsType) + { + Android.Util.Log.Debug("DEBUG", strNewText); + return true; + } + public bool ContinueWork () + { + return true; + } + #endregion + } + + private void populateGlobals (PwGroup currentGroup) + { + + var childGroups = currentGroup.Groups; + var childEntries = currentGroup.Entries; + + foreach (PwEntry e in childEntries) { + entries [e.Uuid] = e; + } + foreach (PwGroup g in childGroups) { + groups[g.Uuid] = g; + populateGlobals(g); + } + } + + public void Clear() { + groups.Clear(); + entries.Clear(); + dirty.Clear(); + drawFactory.Clear(); + + root = null; + pm = null; + mIoc = null; + loaded = false; + locked = false; + } + + public void markAllGroupsAsDirty() { + foreach ( PwGroup group in groups.Values ) { + dirty.Add(group); + } + + + } + + + } + + /* + public void LoadData (Context mCtx, string mFileName, string mPass, string mKey, UpdateStatus mStatus) + { + KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase(); + KeePassLib.Serialization.IOConnectionInfo iocInfo = KeePassLib.Serialization.IOConnectionInfo.FromPath("/sdcard/keepass2androidtest.kdbx"); + KeePassLib.Serialization.IOConnectionInfo iocInfoSave = KeePassLib.Serialization.IOConnectionInfo.FromPath("/sdcard/keepass2androidtestSaved.kdbx"); + KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey(); + key.AddUserKey(new KeePassLib.Keys.KcpPassword("test")); + + pwDatabase.Open(iocInfo, key, new LogToButton(this)); + pwDatabase.RootGroup.AddGroup(new KeePassLib.PwGroup(true, true, "generatedFromKp2ANeu", KeePassLib.PwIcon.Folder), true); + pwDatabase.SaveAs(iocInfoSave,false,new LogToButton(this)); + pwDatabase.Close(); + //KeePassLib.Serialization.KdbxFile f = new KeePassLib.Serialization.KdbxFile(pwDatabase); + } +*/ + +} + diff --git a/src/keepass2android/EntryActivity.cs b/src/keepass2android/EntryActivity.cs new file mode 100644 index 00000000..201e1cb1 --- /dev/null +++ b/src/keepass2android/EntryActivity.cs @@ -0,0 +1,519 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib; +using Android.Text.Format; +using KeePassLib.Utility; +using Java.Util; +using Android.Preferences; +using Android.Text.Method; +using Android.Util; +using System.Globalization; +using Android.Content.PM; +using KeePassLib.Security; +using keepass2android.view; +using Android.Webkit; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")] + public class EntryActivity : LockCloseActivity { + public const String KEY_ENTRY = "entry"; + public const String KEY_REFRESH_POS = "refresh_pos"; + public const String KEY_CLOSE_AFTER_CREATE = "close_after_create"; + + public static void Launch(Activity act, PwEntry pw, int pos) { + Launch(act, pw, pos, false); + } + + public static void Launch(Activity act, PwEntry pw, int pos, bool closeAfterCreate) { + Intent i; + + i = new Intent(act, typeof(EntryActivity)); + + + i.PutExtra(KEY_ENTRY, pw.Uuid.ToHexString()); + i.PutExtra(KEY_REFRESH_POS, pos); + i.PutExtra(KEY_CLOSE_AFTER_CREATE, closeAfterCreate); + + act.StartActivityForResult(i,0); + } + + protected PwEntry mEntry; + + private bool mShowPassword; + private int mPos; + + + + protected void setEntryView() { + SetContentView(Resource.Layout.entry_view); + } + + protected void setupEditButtons() { + Button edit = (Button) FindViewById(Resource.Id.entry_edit); + edit.Click += (sender, e) => { + EntryEditActivity.Launch(this, mEntry); + }; + } + + protected override void OnCreate(Bundle savedInstanceState) + { + ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this); + mShowPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default)); + + base.OnCreate(savedInstanceState); + setEntryView(); + + Context appCtx = ApplicationContext; + + + Database db = App.getDB(); + // Likely the app has been killed exit the activity + if (! db.Loaded) + { + Finish(); + return; + } + + SetResult(KeePass.EXIT_NORMAL); + + Intent i = Intent; + PwUuid uuid = new PwUuid(MemUtil.HexStringToByteArray(i.GetStringExtra(KEY_ENTRY))); + mPos = i.GetIntExtra(KEY_REFRESH_POS, -1); + + bool closeAfterCreate = i.GetBooleanExtra(KEY_CLOSE_AFTER_CREATE, false); + + mEntry = db.entries [uuid]; + + + + // Refresh Menu contents in case onCreateMenuOptions was called before mEntry was set + ActivityCompat.invalidateOptionsMenu(this); + + // Update last access time. + mEntry.Touch(false); + + if (PwDefs.IsTanEntry(mEntry) && prefs.GetBoolean(GetString(Resource.String.TanExpiresOnUse_key), Resources.GetBoolean(Resource.Boolean.TanExpiresOnUse_default)) && ((mEntry.Expires == false) || mEntry.ExpiryTime > DateTime.Now)) + { + PwEntry backupEntry = mEntry.CloneDeep(); + mEntry.ExpiryTime = DateTime.Now; + mEntry.Expires = true; + mEntry.Touch(true); + requiresRefresh(); + Handler handler = new Handler(); + UpdateEntry update = new UpdateEntry(this, App.getDB(), backupEntry, mEntry, new AfterSave(handler)); + ProgressTask pt = new ProgressTask(this, update, Resource.String.saving_database); + pt.run(); + } + fillData(false); + + setupEditButtons(); + + Intent showNotIntent = new Intent(this, typeof(CopyToClipboardService)); + Intent.SetAction(Intents.SHOW_NOTIFICATION); + showNotIntent.PutExtra(KEY_ENTRY, mEntry.Uuid.ToHexString()); + + StartService(showNotIntent); + + Android.Util.Log.Debug("DEBUG", "Requesting copy to clipboard for Uuid=" + mEntry.Uuid.ToHexString()); + + /*foreach (PwUuid key in App.getDB().entries.Keys) + { + Android.Util.Log.Debug("DEBUG",key.ToHexString() + " -> " + App.getDB().entries[key].Uuid.ToHexString()); + }*/ + + if (closeAfterCreate) + { + Finish(); + } + } + + private class AfterSave : OnFinish { + + public AfterSave(Handler handler):base(handler) { + + } + + public override void run() { + + base.run(); + } + + }; + + + + private String getDateTime(System.DateTime dt) { + return dt.ToString ("g", CultureInfo.CurrentUICulture); + } + + String concatTags(List tags) + { + StringBuilder sb = new StringBuilder(); + foreach (string tag in tags) + { + sb.Append(tag); + sb.Append(", "); + } + if (tags.Count > 0) + sb.Remove(sb.Length-2,2); + return sb.ToString(); + } + + void populateExtraStrings(bool trimList) + { + ViewGroup extraGroup = (ViewGroup)FindViewById(Resource.Id.extra_strings); + if (trimList) + { + extraGroup.RemoveAllViews(); + } + bool hasExtraFields = false; + foreach (KeyValuePair pair in mEntry.Strings) + { + String key = pair.Key; + if (!PwDefs.IsStandardField(key)) + { + View view = new EntrySection(this, null, key, pair.Value.ReadString()); + extraGroup.AddView(view); + hasExtraFields = true; + } + } + FindViewById(Resource.Id.entry_extra_strings_label).Visibility = hasExtraFields ? ViewStates.Visible : ViewStates.Gone; + } + + string writeBinaryToFile(string key) + { + ProtectedBinary pb = mEntry.Binaries.Get(key); + System.Diagnostics.Debug.Assert(pb != null); if(pb == null) throw new ArgumentException(); + + ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this); + string binaryDirectory = prefs.GetString(GetString(Resource.String.BinaryDirectory_key),GetString(Resource.String.BinaryDirectory_default)); + + var targetFile = new Java.IO.File(binaryDirectory,key); + + Java.IO.File parent = targetFile.ParentFile; + + if (parent == null || (parent.Exists() && ! parent.IsDirectory)) + { + Toast.MakeText(this, + Resource.String.error_invalid_path, + ToastLength.Long).Show(); + return null; + } + + if (! parent.Exists()) + { + // Create parent dircetory + if (! parent.Mkdirs()) + { + Toast.MakeText(this, + Resource.String.error_could_not_create_parent, + ToastLength.Long).Show(); + return null; + + } + } + string filename = targetFile.AbsolutePath; + + byte[] pbData = pb.ReadData(); + try { System.IO.File.WriteAllBytes(filename, pbData); } + catch(Exception exWrite) + { + Toast.MakeText(this, GetString(Resource.String.SaveAttachment_Failed, new Java.Lang.Object[]{ filename}) + +exWrite.Message,ToastLength.Long).Show(); + return null; + } + finally + { + MemUtil.ZeroByteArray(pbData); + } + + return filename; + + } + + void openBinaryFile(string filename) + { + String theMIMEType = getMimeType(filename); + if (theMIMEType != null) + { + Intent theIntent = new Intent(Intent.ActionView); + theIntent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ExcludeFromRecents); + theIntent.SetDataAndType(Android.Net.Uri.FromFile(new Java.IO.File(filename)), theMIMEType); + try + { + StartActivity(theIntent); + } + catch (ActivityNotFoundException anfe) + { + //ignore + Toast.MakeText(this, "Couldn't open file", ToastLength.Short).Show(); + } + } + } + + void populateBinaries(bool trimList) + { + ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries); + if (trimList) + { + binariesGroup.RemoveAllViews(); + } + foreach (KeyValuePair pair in mEntry.Binaries) + { + String key = pair.Key; + Button binaryButton = new Button(this); + RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FillParent, RelativeLayout.LayoutParams.WrapContent); + binaryButton.Text = key; + binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuSave),null, null, null); + binaryButton.Click += (object sender, EventArgs e) => + { + Button btnSender = (Button)(sender); + string newFilename = writeBinaryToFile(btnSender.Text); + + if (newFilename != null) + { + Toast.MakeText(this, GetString(Resource.String.SaveAttachment_doneMessage, new Java.Lang.Object[]{newFilename}), ToastLength.Short).Show(); + openBinaryFile(newFilename); + } + + }; + binariesGroup.AddView(binaryButton,layoutParams); + + + } + FindViewById(Resource.Id.entry_binaries_label).Visibility = mEntry.Binaries.UCount > 0 ? ViewStates.Visible : ViewStates.Gone; + } + + // url = file path or whatever suitable URL you want. + public static String getMimeType(String url) + { + String type = null; + String extension = MimeTypeMap.GetFileExtensionFromUrl(url); + if (extension != null) { + MimeTypeMap mime = MimeTypeMap.Singleton; + type = mime.GetMimeTypeFromExtension(extension); + } + return type; + } + + protected void fillData(bool trimList) + { + ImageView iv = (ImageView)FindViewById(Resource.Id.entry_icon); + App.getDB().drawFactory.assignDrawableTo(iv, Resources, App.getDB().pm, mEntry.IconId, mEntry.CustomIconUuid); + + //populateText(Resource.Id.entry_title, mEntry.Strings.ReadSafe(PwDefs.TitleField)); + var button = ((Button)FindViewById(Resource.Id.entry_title)); + button.Text = mEntry.Strings.ReadSafe(PwDefs.TitleField); + button.Click += (object sender, EventArgs e) => { + Finish(); }; + + populateText(Resource.Id.entry_user_name, Resource.Id.entry_user_name_label, mEntry.Strings.ReadSafe(PwDefs.UserNameField)); + + populateText(Resource.Id.entry_url, Resource.Id.entry_url_label, mEntry.Strings.ReadSafe(PwDefs.UrlField)); + populateText(Resource.Id.entry_password, Resource.Id.entry_password_label, mEntry.Strings.ReadSafe(PwDefs.PasswordField)); + setPasswordStyle(); + + populateText(Resource.Id.entry_created, Resource.Id.entry_created_label, getDateTime(mEntry.CreationTime)); + populateText(Resource.Id.entry_modified, Resource.Id.entry_modified_label, getDateTime(mEntry.LastModificationTime)); + populateText(Resource.Id.entry_accessed, Resource.Id.entry_accessed_label, getDateTime(mEntry.LastAccessTime)); + + if (mEntry.Expires) + { + populateText(Resource.Id.entry_expires, Resource.Id.entry_expires_label, getDateTime(mEntry.ExpiryTime)); + } else + { + populateText(Resource.Id.entry_expires, Resource.Id.entry_expires_label, Resource.String.never); + } + populateText(Resource.Id.entry_comment, Resource.Id.entry_comment_label, mEntry.Strings.ReadSafe(PwDefs.NotesField)); + + populateText(Resource.Id.entry_tags, Resource.Id.entry_tags_label, concatTags(mEntry.Tags)); + + populateText(Resource.Id.entry_override_url, Resource.Id.entry_override_url_label, mEntry.OverrideUrl); + + populateExtraStrings(trimList); + + populateBinaries(trimList); + + + } + + private void populateText(int viewId, int headerViewId,int resId) { + View header = FindViewById(headerViewId); + TextView tv = (TextView)FindViewById(viewId); + + header.Visibility = tv.Visibility = ViewStates.Visible; + tv.SetText (resId); + } + + private void populateText(int viewId, int headerViewId, String text) + { + View header = FindViewById(headerViewId); + TextView tv = (TextView)FindViewById(viewId); + if (String.IsNullOrEmpty(text)) + { + header.Visibility = tv.Visibility = ViewStates.Gone; + } + else + { + header.Visibility = tv.Visibility = ViewStates.Visible; + tv.Text = text; + + } + } + + void requiresRefresh () + { + Intent ret = new Intent (); + ret.PutExtra (KEY_REFRESH_POS, mPos); + SetResult (KeePass.EXIT_REFRESH, ret); + } + + protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { + base.OnActivityResult(requestCode, resultCode, data); + if ( resultCode == KeePass.EXIT_REFRESH || resultCode == KeePass.EXIT_REFRESH_TITLE ) { + fillData(true); + if ( resultCode == KeePass.EXIT_REFRESH_TITLE ) { + requiresRefresh (); + } + } + } + + public override bool OnCreateOptionsMenu(IMenu menu) { + base.OnCreateOptionsMenu(menu); + + MenuInflater inflater = MenuInflater; + inflater.Inflate(Resource.Menu.entry, menu); + + IMenuItem togglePassword = menu.FindItem(Resource.Id.menu_toggle_pass); + if ( mShowPassword ) { + togglePassword.SetTitle(Resource.String.menu_hide_password); + } else { + togglePassword.SetTitle(Resource.String.show_password); + } + + IMenuItem gotoUrl = menu.FindItem(Resource.Id.menu_goto_url); + //Disabled IMenuItem copyUser = menu.FindItem(Resource.Id.menu_copy_user); + //Disabled IMenuItem copyPass = menu.FindItem(Resource.Id.menu_copy_pass); + + // In API >= 11 onCreateOptionsMenu may be called before onCreate completes + // so mEntry may not be set + if (mEntry == null) { + gotoUrl.SetVisible(false); + //Disabled copyUser.SetVisible(false); + //Disabled copyPass.SetVisible(false); + } + else { + String url = mEntry.Strings.ReadSafe (PwDefs.UrlField); + if (String.IsNullOrEmpty(url)) { + // disable button if url is not available + gotoUrl.SetVisible(false); + } + if ( String.IsNullOrEmpty(mEntry.Strings.ReadSafe(PwDefs.UserNameField ))) { + // disable button if username is not available + //Disabled copyUser.SetVisible(false); + } + if ( String.IsNullOrEmpty(mEntry.Strings.ReadSafe(PwDefs.PasswordField ))) { + // disable button if password is not available + //Disabled copyPass.SetVisible(false); + } + } + return true; + } + + private void setPasswordStyle() { + TextView password = (TextView) FindViewById(Resource.Id.entry_password); + + if ( mShowPassword ) { + password.TransformationMethod = null; + } else { + password.TransformationMethod = PasswordTransformationMethod.Instance; + } + } + + public override bool OnOptionsItemSelected(IMenuItem item) { + switch ( item.ItemId ) { + /*case Resource.Id.menu_donate: + try { + Util.gotoUrl(this, Resource.String.donate_url); + } catch (ActivityNotFoundException) { + Toast.MakeText(this, Resource.String.error_failed_to_launch_link, ToastLength.Long).Show(); + return false; + } + + return true;*/ + case Resource.Id.menu_toggle_pass: + if ( mShowPassword ) { + item.SetTitle(Resource.String.show_password); + mShowPassword = false; + } else { + item.SetTitle(Resource.String.menu_hide_password); + mShowPassword = true; + } + setPasswordStyle(); + + return true; + + case Resource.Id.menu_goto_url: + String url; + url = mEntry.Strings.ReadSafe (PwDefs.UserNameField); + + // Default http:// if no protocol specified + if ( ! url.Contains("://") ) { + url = "http://" + url; + } + + try { + Util.gotoUrl(this, url); + } catch (ActivityNotFoundException) { + Toast.MakeText(this, Resource.String.no_url_handler, ToastLength.Long).Show(); + } + return true; + /* TODO: required? + case Resource.Id.menu_copy_user: + timeoutCopyToClipboard(mEntry.Strings.ReadSafe (PwDefs.UserNameField)); + return true; + + case Resource.Id.menu_copy_pass: + timeoutCopyToClipboard(mEntry.Strings.ReadSafe (PwDefs.UserNameField)); + return true; + */ + case Resource.Id.menu_lock: + App.setShutdown(); + SetResult(KeePass.EXIT_LOCK); + Finish(); + return true; + } + + return base.OnOptionsItemSelected(item); + } + } + +} + diff --git a/src/keepass2android/EntryEditActivity.cs b/src/keepass2android/EntryEditActivity.cs new file mode 100644 index 00000000..4a738cf3 --- /dev/null +++ b/src/keepass2android/EntryEditActivity.cs @@ -0,0 +1,739 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.Preferences; +using KeePassLib.Utility; +using KeePassLib; +using Android.Text; +using KeePassLib.Security; +using Android.Content.PM; +using keepass2android.view; +using System.IO; +using System.Globalization; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")] + public class EntryEditActivity : LockCloseActivity { + public const String KEY_ENTRY = "entry"; + public const String KEY_PARENT = "parent"; + + public const int RESULT_OK_ICON_PICKER = (int)Result.FirstUser + 1000; + public const int RESULT_OK_PASSWORD_GENERATOR = RESULT_OK_ICON_PICKER + 1; + + private PwEntry mEntry, mEntryInDatabase; + private bool mShowPassword = false; + private bool mIsNew; + private PwIcon mSelectedIconID; + private PwUuid mSelectedCustomIconID = PwUuid.Zero; + private bool mSelectedIcon = false; + + public static void Launch(Activity act, PwEntry pw) { + Intent i = new Intent(act, typeof(EntryEditActivity)); + + i.PutExtra(KEY_ENTRY, pw.Uuid.ToHexString()); + + act.StartActivityForResult(i, 0); + } + + public static void Launch(Activity act, PwGroup pw) { + Intent i = new Intent(act, typeof(EntryEditActivity)); + + PwGroup parent = pw; + i.PutExtra(KEY_PARENT, parent.Uuid.ToHexString()); + + act.StartActivityForResult(i, 0); + } + + private ScrollView scroll; + + protected override void OnCreate(Bundle savedInstanceState) + { + ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this); + mShowPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default)); + + base.OnCreate(savedInstanceState); + SetContentView(Resource.Layout.entry_edit); + SetResult(KeePass.EXIT_NORMAL); + + // Likely the app has been killed exit the activity + Database db = App.getDB(); + if ( ! db.Open ) { + Finish(); + return; + } + + Intent i = Intent; + String uuidBytes = i.GetStringExtra(KEY_ENTRY); + + PwUuid entryId = PwUuid.Zero; + if (uuidBytes != null) + entryId = new KeePassLib.PwUuid(MemUtil.HexStringToByteArray(uuidBytes)); + + PwGroup parentGroup = null; + if ( entryId == PwUuid.Zero ) { + String groupId = i.GetStringExtra(KEY_PARENT); + + parentGroup = db.groups[new PwUuid(MemUtil.HexStringToByteArray(groupId))]; + + mEntryInDatabase = new PwEntry(true, true); + mEntryInDatabase.Strings.Set(PwDefs.UserNameField, new ProtectedString( + db.pm.MemoryProtection.ProtectUserName, db.pm.DefaultUserName)); + + /*KPDesktop + * ProtectedString psAutoGen; + PwGenerator.Generate(out psAutoGen, Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile, + null, Program.PwGeneratorPool); + psAutoGen = psAutoGen.WithProtection(pwDb.MemoryProtection.ProtectPassword); + pwe.Strings.Set(PwDefs.PasswordField, psAutoGen); + + int nExpireDays = Program.Config.Defaults.NewEntryExpiresInDays; + if(nExpireDays >= 0) + { + pwe.Expires = true; + pwe.ExpiryTime = DateTime.Now.AddDays(nExpireDays); + }*/ + + if((parentGroup.IconId != PwIcon.Folder) && (parentGroup.IconId != PwIcon.FolderOpen) && + (parentGroup.IconId != PwIcon.FolderPackage)) + { + mEntryInDatabase.IconId = parentGroup.IconId; // Inherit icon from group + } + mEntryInDatabase.CustomIconUuid = parentGroup.CustomIconUuid; + + /* + * KPDesktop + if(strDefaultSeq.Length == 0) + { + PwGroup pg = m_pwEntry.ParentGroup; + if(pg != null) + { + strDefaultSeq = pg.GetAutoTypeSequenceInherited(); + + if(strDefaultSeq.Length == 0) + { + if(PwDefs.IsTanEntry(m_pwEntry)) + strDefaultSeq = PwDefs.DefaultAutoTypeSequenceTan; + else + strDefaultSeq = PwDefs.DefaultAutoTypeSequence; + } + } + }*/ + mIsNew = true; + + } else { + + System.Diagnostics.Debug.Assert(entryId != null); + + mEntryInDatabase = db.entries[entryId]; + mIsNew = false; + + + } + + mEntry = mEntryInDatabase.CloneDeep(); + + fillData(); + View scrollView = FindViewById(Resource.Id.entry_scroll); + scrollView.ScrollBarStyle = ScrollbarStyles.InsideInset; + + ImageButton iconButton = (ImageButton) FindViewById(Resource.Id.icon_button); + iconButton.Click += (sender, evt) => { + IconPickerActivity.Launch(this); + }; + + + // Generate password button + Button generatePassword = (Button) FindViewById(Resource.Id.generate_button); + generatePassword.Click += (object sender, EventArgs e) => { + + GeneratePasswordActivity.Launch(this); + }; + + + + + // Save button + Button save = (Button) FindViewById(Resource.Id.entry_save); + save.Click += (object sender, EventArgs e) => + { + + EntryEditActivity act = this; + + if (!validateBeforeSaving()) + return; + + PwEntry initialEntry = mEntryInDatabase.CloneDeep(); + + PwEntry newEntry = mEntryInDatabase; + + //Clone history and re-assign: + newEntry.History = newEntry.History.CloneDeep(); + + //Based on KeePass Desktop + bool bCreateBackup = (!mIsNew); + if(bCreateBackup) newEntry.CreateBackup(null); + + if (mSelectedIcon == false) { + if (mIsNew) { + newEntry.IconId = PwIcon.Key; + } else { + // Keep previous icon, if no new one was selected + } + } + else { + newEntry.IconId = mSelectedIconID; + newEntry.CustomIconUuid = mSelectedCustomIconID; + } + /* KPDesktop + if(m_cbCustomForegroundColor.Checked) + newEntry.ForegroundColor = m_clrForeground; + else newEntry.ForegroundColor = Color.Empty; + if(m_cbCustomBackgroundColor.Checked) + newEntry.BackgroundColor = m_clrBackground; + else newEntry.BackgroundColor = Color.Empty; + + */ + + + newEntry.Strings.Set(PwDefs.TitleField, new ProtectedString(db.pm.MemoryProtection.ProtectTitle, + Util.getEditText(act, Resource.Id.entry_title))); + newEntry.Strings.Set(PwDefs.UserNameField, new ProtectedString(db.pm.MemoryProtection.ProtectUserName, + Util.getEditText(act, Resource.Id.entry_user_name))); + + String pass = Util.getEditText(act, Resource.Id.entry_password); + byte[] password = StrUtil.Utf8.GetBytes(pass); + newEntry.Strings.Set(PwDefs.PasswordField, new ProtectedString(db.pm.MemoryProtection.ProtectPassword, + password)); + MemUtil.ZeroByteArray(password); + + newEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(db.pm.MemoryProtection.ProtectUrl, + Util.getEditText(act, Resource.Id.entry_url))); + newEntry.Strings.Set(PwDefs.NotesField, new ProtectedString(db.pm.MemoryProtection.ProtectNotes, + Util.getEditText(act, Resource.Id.entry_comment))); + + // Delete all non standard strings + var keys = newEntry.Strings.GetKeys(); + foreach (String key in keys) + if (PwDefs.IsStandardField(key) == false) + newEntry.Strings.Remove(key); + + LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container); + + for (int index = 0; index < container.ChildCount; index++) { + View view = container.GetChildAt(index); + + TextView keyView = (TextView)view.FindViewById(Resource.Id.title); + String key = keyView.Text; + + TextView valueView = (TextView)view.FindViewById(Resource.Id.value); + String value = valueView.Text; + + CheckBox cb = (CheckBox)view.FindViewById(Resource.Id.protection); + bool protect = cb.Checked; + + newEntry.Strings.Set(key, new ProtectedString(protect, value)); + } + + newEntry.Binaries = mEntry.Binaries; + newEntry.Expires = mEntry.Expires; + if (newEntry.Expires) + { + newEntry.ExpiryTime = mEntry.ExpiryTime; + } + + newEntry.OverrideUrl = Util.getEditText(this,Resource.Id.entry_override_url); + + List vNewTags = StrUtil.StringToTags(Util.getEditText(this,Resource.Id.entry_tags)); + newEntry.Tags.Clear(); + foreach(string strTag in vNewTags) newEntry.AddTag(strTag); + + /*KPDesktop + + + m_atConfig.Enabled = m_cbAutoTypeEnabled.Checked; + m_atConfig.ObfuscationOptions = (m_cbAutoTypeObfuscation.Checked ? + AutoTypeObfuscationOptions.UseClipboard : + AutoTypeObfuscationOptions.None); + + SaveDefaultSeq(); + + newEntry.AutoType = m_atConfig; + */ + + + newEntry.Touch(true, false); // Touch *after* backup + + StrUtil.NormalizeNewLines(newEntry.Strings, true); + + bool bUndoBackup = false; + PwCompareOptions cmpOpt = (PwCompareOptions.NullEmptyEquivStd | + PwCompareOptions.IgnoreTimes); + if(bCreateBackup) cmpOpt |= PwCompareOptions.IgnoreLastBackup; + if(newEntry.EqualsEntry(initialEntry, cmpOpt, MemProtCmpMode.CustomOnly)) + { + // No modifications at all => restore last mod time and undo backup + newEntry.LastModificationTime = initialEntry.LastModificationTime; + bUndoBackup = bCreateBackup; + } + else if(bCreateBackup) + { + // If only history items have been modified (deleted) => undo + // backup, but without restoring the last mod time + PwCompareOptions cmpOptNH = (cmpOpt | PwCompareOptions.IgnoreHistory); + if(newEntry.EqualsEntry(initialEntry, cmpOptNH, MemProtCmpMode.CustomOnly)) + bUndoBackup = true; + } + if(bUndoBackup) newEntry.History.RemoveAt(newEntry.History.UCount - 1); + + newEntry.MaintainBackups(db.pm); + + + + //if ( newEntry.Strings.ReadSafe (PwDefs.TitleField).Equals(mEntry.Strings.ReadSafe (PwDefs.TitleField)) ) { + // SetResult(KeePass.EXIT_REFRESH); + //} else { + //it's safer to always update the title as we might add further information in the title like expiry etc. + SetResult(KeePass.EXIT_REFRESH_TITLE); + //} + + RunnableOnFinish task; + OnFinish onFinish = new AfterSave(new Handler(), act); + + if ( mIsNew ) { + task = AddEntry.getInstance(this, App.getDB(), newEntry, parentGroup, onFinish); + } else { + task = new UpdateEntry(this, App.getDB(), initialEntry, newEntry, onFinish); + } + ProgressTask pt = new ProgressTask(act, task, Resource.String.saving_database); + pt.run(); + }; + + + // Respect mask password setting + if (mShowPassword) { + EditText pass = (EditText) FindViewById(Resource.Id.entry_password); + EditText conf = (EditText) FindViewById(Resource.Id.entry_confpassword); + + pass.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword; + conf.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword; + } + + scroll = (ScrollView) FindViewById(Resource.Id.entry_scroll); + + Button addButton = (Button) FindViewById(Resource.Id.add_advanced); + addButton.Visibility = ViewStates.Visible; + addButton.Click += (object sender, EventArgs e) => + { + LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container); + + EntryEditSection ees = (EntryEditSection) LayoutInflater.Inflate(Resource.Layout.entry_edit_section, null); + ees.setData("", new ProtectedString(false, "")); + ees.getDeleteButton().Click += (senderEes, eEes) => deleteAdvancedString((View)senderEes); + container.AddView(ees); + + // Scroll bottom + scroll.Post(() => { + scroll.FullScroll(FocusSearchDirection.Down); + }); + + + }; + + ((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) => + { + mEntry.Expires = e.IsChecked; + if (e.IsChecked) + { + if (mEntry.ExpiryTime < DateTime.Now) + mEntry.ExpiryTime = DateTime.Now; + } + updateExpires(); + + }; + + } + + void addBinaryOrAsk(string filename) + { + string strItem = UrlUtil.GetFileName(filename); + + if(mEntry.Binaries.Get(strItem) != null) + { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.SetTitle(GetString(Resource.String.AskOverwriteBinary_title)); + + builder.SetMessage(GetString(Resource.String.AskOverwriteBinary)); + + builder.SetPositiveButton(GetString(Resource.String.AskOverwriteBinary_yes), new EventHandler((dlgSender, dlgEvt) => + { + addBinary(filename, true); + })); + + builder.SetNegativeButton(GetString(Resource.String.AskOverwriteBinary_no), new EventHandler((dlgSender, dlgEvt) => + { + addBinary(filename, false); + })); + + builder.SetNeutralButton(GetString(Android.Resource.String.Cancel), + new EventHandler((dlgSender, dlgEvt) => {})); + + Dialog dialog = builder.Create(); + dialog.Show(); + + + } else + addBinary(filename, true); + } + + void addBinary(string filename, bool overwrite) + { + string strItem = UrlUtil.GetFileName(filename); + + if (!overwrite) + { + string strFileName = UrlUtil.StripExtension(strItem); + string strExtension = "." + UrlUtil.GetExtension(strItem); + + int nTry = 0; + while(true) + { + string strNewName = strFileName + nTry.ToString() + strExtension; + if(mEntry.Binaries.Get(strNewName) == null) + { + strItem = strNewName; + break; + } + + ++nTry; + } + } + try + { + byte[] vBytes = File.ReadAllBytes(filename); + if(vBytes != null) + { + ProtectedBinary pb = new ProtectedBinary(false, vBytes); + mEntry.Binaries.Set(strItem, pb); + } + } + catch(Exception exAttach) + { + Toast.MakeText(this, GetString(Resource.String.AttachFailed)+" "+exAttach.Message, ToastLength.Long).Show(); + } + populateBinaries(); + } + + protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) + { + switch ((int)resultCode) + { + case RESULT_OK_ICON_PICKER: + mSelectedIconID = (PwIcon) data.Extras.GetInt(IconPickerActivity.KEY_ICON_ID); + mSelectedCustomIconID = PwUuid.Zero; + String customIconIdString = data.Extras.GetString(IconPickerActivity.KEY_CUSTOM_ICON_ID); + if (!String.IsNullOrEmpty(customIconIdString)) + mSelectedCustomIconID = new PwUuid(MemUtil.HexStringToByteArray(customIconIdString)); + mSelectedIcon = true; + ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button); + //TODO: custom image + currIconButton.SetImageResource(Icons.iconToResId(mSelectedIconID)); + break; + + case RESULT_OK_PASSWORD_GENERATOR: + String generatedPassword = data.GetStringExtra("keepass2android.password.generated_password"); + EditText password = (EditText) FindViewById(Resource.Id.entry_password); + EditText confPassword = (EditText) FindViewById(Resource.Id.entry_confpassword); + + password.Text = generatedPassword; + confPassword.Text = generatedPassword; + + break; + case (int)Result.Ok: + if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE) + { + String filename = data.DataString; + if (filename != null) { + if (filename.StartsWith("file://")) { + filename = filename.Substring(7); + } + + filename = Java.Net.URLDecoder.Decode(filename); + addBinaryOrAsk(filename); + } + } + + + break; + case (int)Result.Canceled: + break; + default: + break; + } + } + + void populateBinaries() + { + ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries); + binariesGroup.RemoveAllViews(); + RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FillParent, RelativeLayout.LayoutParams.WrapContent); + foreach (KeyValuePair pair in mEntry.Binaries) + { + String key = pair.Key; + Button binaryButton = new Button(this); + + binaryButton.Text = key; + binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuDelete),null, null, null); + binaryButton.Click += (object sender, EventArgs e) => + { + Button btnSender = (Button)(sender); + mEntry.Binaries.Remove(key); + populateBinaries(); + + }; + binariesGroup.AddView(binaryButton,layoutParams); + + + } + + Button addBinaryButton = new Button(this); + addBinaryButton.Text = GetString(Resource.String.add_binary); + addBinaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuAdd) , null, null, null); + addBinaryButton.Click += (object sender, EventArgs e) => + { + Util.showBrowseDialog("/mnt/sdcard", this); + }; + binariesGroup.AddView(addBinaryButton,layoutParams); + + FindViewById(Resource.Id.entry_binaries_label).Visibility = mEntry.Binaries.UCount > 0 ? ViewStates.Visible : ViewStates.Gone; + } + public override bool OnCreateOptionsMenu(IMenu menu) { + base.OnCreateOptionsMenu(menu); + + MenuInflater inflater = MenuInflater; + inflater.Inflate(Resource.Menu.entry_edit, menu); + + + IMenuItem togglePassword = menu.FindItem(Resource.Id.menu_toggle_pass); + if ( mShowPassword ) { + togglePassword.SetTitle(Resource.String.menu_hide_password); + } else { + togglePassword.SetTitle(Resource.String.show_password); + } + + return true; + } + + public override bool OnOptionsItemSelected(IMenuItem item) { + switch ( item.ItemId ) { + /*case Resource.Id.menu_donate: + try { + Util.gotoUrl(this, Resource.String.donate_url); + } catch (ActivityNotFoundException) { + Toast.MakeText(this, Resource.String.error_failed_to_launch_link, ToastLength.Long).Show(); + return false; + } + + return true;*/ + case Resource.Id.menu_toggle_pass: + if ( mShowPassword ) { + item.SetTitle(Resource.String.show_password); + mShowPassword = false; + } else { + item.SetTitle(Resource.String.menu_hide_password); + mShowPassword = true; + } + setPasswordStyle(); + return true; + case Resource.Id.menu_cancel_edit: + Finish(); + break; + } + + + + return base.OnOptionsItemSelected(item); + } + + private void setPasswordStyle() { + TextView password = (TextView) FindViewById(Resource.Id.entry_password); + TextView confpassword = (TextView) FindViewById(Resource.Id.entry_confpassword); + + if ( mShowPassword ) { + password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword; + confpassword.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword; + + } else { + password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword; + confpassword.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword; + } + } + + void updateExpires() + { + if (mEntry.Expires) + { + populateText(Resource.Id.entry_expires, getDateTime(mEntry.ExpiryTime)); + } + else + { + populateText(Resource.Id.entry_expires, GetString(Resource.String.never)); + } + ((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).Checked = mEntry.Expires; + ((EditText)FindViewById(Resource.Id.entry_expires)).Enabled = mEntry.Expires; + } + + private void fillData() { + ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button); + App.getDB().drawFactory.assignDrawableTo(currIconButton, Resources, App.getDB().pm, mEntry.IconId, mEntry.CustomIconUuid); + + populateText(Resource.Id.entry_title, mEntry.Strings.ReadSafe (PwDefs.TitleField)); + populateText(Resource.Id.entry_user_name, mEntry.Strings.ReadSafe (PwDefs.UserNameField)); + populateText(Resource.Id.entry_url, mEntry.Strings.ReadSafe (PwDefs.UrlField)); + + String password = mEntry.Strings.ReadSafe(PwDefs.PasswordField); + populateText(Resource.Id.entry_password, password); + populateText(Resource.Id.entry_confpassword, password); + setPasswordStyle(); + + populateText(Resource.Id.entry_comment, mEntry.Strings.ReadSafe (PwDefs.NotesField)); + + LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container); + + foreach (var pair in mEntry.Strings) + { + String key = pair.Key; + + if (!PwDefs.IsStandardField(key)) { + EntryEditSection ees = (EntryEditSection) LayoutInflater.Inflate(Resource.Layout.entry_edit_section, null); + ees.setData(key, pair.Value); + ees.getDeleteButton().Click += (sender, e) => deleteAdvancedString((View)sender); + container.AddView(ees); + } + } + + populateBinaries(); + + populateText(Resource.Id.entry_override_url, mEntry.OverrideUrl); + populateText(Resource.Id.entry_tags, StrUtil.TagsToString(mEntry.Tags, true)); + + updateExpires(); + } + private String getDateTime(System.DateTime dt) { + return dt.ToString ("g", CultureInfo.CurrentUICulture); + } + + + public void deleteAdvancedString(View view) { + EntryEditSection section = (EntryEditSection) view.Parent; + LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container); + + for (int i = 0; i < container.ChildCount; i++) { + EntryEditSection ees = (EntryEditSection) container.GetChildAt(i); + if (ees == section) { + container.RemoveViewAt(i); + container.Invalidate(); + break; + } + } + } + + + protected bool validateBeforeSaving() { + // Require title + String title = Util.getEditText(this, Resource.Id.entry_title); + if ( title.Length == 0 ) { + Toast.MakeText(this, Resource.String.error_title_required, ToastLength.Long).Show(); + return false; + } + + // Validate password + String pass = Util.getEditText(this, Resource.Id.entry_password); + String conf = Util.getEditText(this, Resource.Id.entry_confpassword); + if ( ! pass.Equals(conf) ) { + Toast.MakeText(this, Resource.String.error_pass_match, ToastLength.Long).Show(); + return false; + } + + // Validate expiry date + DateTime newExpiry = new DateTime(); + if ((mEntry.Expires) && (!DateTime.TryParse( Util.getEditText(this,Resource.Id.entry_expires), out newExpiry))) + { + Toast.MakeText(this, Resource.String.error_invalid_expiry_date, ToastLength.Long).Show(); + return false; + } + else + { + mEntry.ExpiryTime = newExpiry; + } + + + LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container); + for (int i = 0; i < container.ChildCount; i++) { + EntryEditSection ees = (EntryEditSection) container.GetChildAt(i); + + TextView keyView = (TextView) ees.FindViewById(Resource.Id.title); + string key = keyView.Text; + + if (String.IsNullOrEmpty(key)) { + Toast.MakeText(this, Resource.String.error_string_key, ToastLength.Long).Show(); + return false; + } + + } + + return true; + } + + + private void populateText(int viewId, String text) { + TextView tv = (TextView) FindViewById(viewId); + tv.Text = text; + } + + private class AfterSave : OnFinish { + Activity act; + public AfterSave(Handler handler, Activity act): base(handler) { + this.act = act; + } + + + public override void run() { + if ( mSuccess ) { + act.Finish(); + } else { + displayMessage(act); + } + } + + } + + } + +} + diff --git a/src/keepass2android/GeneratePasswordActivity.cs b/src/keepass2android/GeneratePasswordActivity.cs new file mode 100644 index 00000000..fb697d26 --- /dev/null +++ b/src/keepass2android/GeneratePasswordActivity.cs @@ -0,0 +1,130 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")] + public class GeneratePasswordActivity : LockCloseActivity { + private int[] BUTTON_IDS = new int[] {Resource.Id.btn_length6, Resource.Id.btn_length8, Resource.Id.btn_length12, Resource.Id.btn_length16}; + + public static void Launch(Activity act) { + Intent i = new Intent(act, typeof(GeneratePasswordActivity)); + + act.StartActivityForResult(i, 0); + } + + + protected override void OnCreate(Bundle savedInstanceState) { + base.OnCreate(savedInstanceState); + SetContentView(Resource.Layout.generate_password); + SetResult(KeePass.EXIT_NORMAL); + + foreach (int id in BUTTON_IDS) { + Button button = (Button) FindViewById(id); + button.Click += (object sender, EventArgs e) => + { + Button b = (Button) sender; + + EditText editText = (EditText) FindViewById(Resource.Id.length); + editText.Text = b.Text; + + }; + } + + Button genPassButton = (Button) FindViewById(Resource.Id.generate_password_button); + genPassButton.Click += (object sender, EventArgs e) => { + String password = generatePassword(); + + EditText txtPassword = (EditText) FindViewById(Resource.Id.password); + txtPassword.Text = password; + }; + + + + Button acceptButton = (Button) FindViewById(Resource.Id.accept_button); + acceptButton.Click += (object sender, EventArgs e) => { + EditText password = (EditText) FindViewById(Resource.Id.password); + + Intent intent = new Intent(); + intent.PutExtra("keepass2android.password.generated_password", password.Text); + + SetResult((Result)EntryEditActivity.RESULT_OK_PASSWORD_GENERATOR, intent); + + Finish(); + }; + + + Button cancelButton = (Button) FindViewById(Resource.Id.cancel_button); + cancelButton.Click += (object sender, EventArgs e) => + { + SetResult(Result.Canceled); + + Finish(); + }; + + + EditText txtPasswordToSet = (EditText) FindViewById(Resource.Id.password); + txtPasswordToSet.Text = generatePassword(); + + } + + public String generatePassword() { + String password = ""; + + try { + + int length; + if (!int.TryParse(((EditText) FindViewById(Resource.Id.length)).Text, out length)) + { + Toast.MakeText(this, Resource.String.error_wrong_length, ToastLength.Long).Show(); + return password; + } + + + PasswordGenerator generator = new PasswordGenerator(this); + + password = generator.generatePassword(length, + ((CheckBox) FindViewById(Resource.Id.cb_uppercase)).Checked, + ((CheckBox) FindViewById(Resource.Id.cb_lowercase)).Checked, + ((CheckBox) FindViewById(Resource.Id.cb_digits)).Checked, + ((CheckBox) FindViewById(Resource.Id.cb_minus)).Checked, + ((CheckBox) FindViewById(Resource.Id.cb_underline)).Checked, + ((CheckBox) FindViewById(Resource.Id.cb_space)).Checked, + ((CheckBox) FindViewById(Resource.Id.cb_specials)).Checked, + ((CheckBox) FindViewById(Resource.Id.cb_brackets)).Checked); + } catch (ArgumentException e) { + Toast.MakeText(this, e.Message, ToastLength.Long).Show(); + } + + return password; + } + } + +} + diff --git a/src/keepass2android/GroupActivity.cs b/src/keepass2android/GroupActivity.cs new file mode 100644 index 00000000..363f5513 --- /dev/null +++ b/src/keepass2android/GroupActivity.cs @@ -0,0 +1,195 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib; +using Android.Util; +using KeePassLib.Utility; +using keepass2android.view; +using Android.Content.PM; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden , Theme="@style/NoTitleBar")] + [MetaData("android.app.default_searchable",Value="keepass2android.search.SearchResults")] + public class GroupActivity : GroupBaseActivity { + + public const int UNINIT = -1; + + protected bool addGroupEnabled = false; + protected bool addEntryEnabled = false; + + private const String TAG = "Group Activity:"; + + public static void Launch(Activity act) { + Launch(act, null); + } + + public static void Launch (Activity act, PwGroup g) + { + Intent i; + + // Need to use PwDatabase since group may be null + PwDatabase db = App.getDB ().pm; + + if (db == null) { + // Reached if db is null + Log.Debug (TAG, "Tried to launch with null db"); + return; + } + + i = new Intent(act, typeof(GroupActivity)); + + if ( g != null ) { + i.PutExtra(KEY_ENTRY, g.Uuid.ToHexString()); + } + + act.StartActivityForResult(i,0); + } + + protected PwUuid retrieveGroupId(Intent i) + { + String uuid = i.GetStringExtra(KEY_ENTRY); + + if ( String.IsNullOrEmpty(uuid) ) { + return null; + } + return new PwUuid(MemUtil.HexStringToByteArray(uuid)); + } + + protected void setupButtons() + { + addGroupEnabled = true; + addEntryEnabled = !mGroup.Uuid.EqualsValue(App.getDB().root.Uuid); + } + + protected override void OnCreate (Bundle savedInstanceState) + { + base.OnCreate (savedInstanceState); + + if (IsFinishing) { + return; + } + + SetResult (KeePass.EXIT_NORMAL); + + Log.Warn (TAG, "Creating group view"); + Intent intent = Intent; + + PwUuid id = retrieveGroupId (intent); + + Database db = App.getDB (); + if (id == null) { + mGroup = db.root; + } else { + mGroup = db.groups[id]; + } + + Log.Warn (TAG, "Retrieved group"); + if (mGroup == null) { + Log.Warn (TAG, "Group was null"); + return; + } + + setupButtons (); + + if (addGroupEnabled && addEntryEnabled) { + SetContentView (new GroupAddEntryView (this)); + } else if (addGroupEnabled) { + SetContentView (new GroupRootView (this)); + } else if (addEntryEnabled) { + throw new Exception ("This mode is not supported."); + } else { + SetContentView (new GroupViewOnlyView (this)); + } + Log.Warn (TAG, "Set view"); + + if (addGroupEnabled) { + // Add Group button + Button addGroup = (Button)FindViewById (Resource.Id.add_group); + addGroup.Click += (object sender, EventArgs e) => { + GroupEditActivity.Launch (this, mGroup); + }; + } + + if (addEntryEnabled) { + // Add Entry button + Button addEntry = (Button)FindViewById (Resource.Id.add_entry); + addEntry.Click += (object sender, EventArgs e) => { + EntryEditActivity.Launch (this, mGroup); + + }; + } + + setGroupTitle(); + setGroupIcon(); + + ListAdapter = new PwGroupListAdapter(this, mGroup); + RegisterForContextMenu(ListView); + Log.Warn(TAG, "Finished creating group"); + + } + + public override void OnCreateContextMenu(IContextMenu menu, View v, + IContextMenuContextMenuInfo menuInfo) { + + AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) menuInfo; + ClickView cv = (ClickView) acmi.TargetView; + cv.OnCreateMenu(menu, menuInfo); + } + + + + public override bool OnContextItemSelected(IMenuItem item) { + Android.Widget.AdapterView.AdapterContextMenuInfo acmi = (Android.Widget.AdapterView.AdapterContextMenuInfo)item.MenuInfo; + ClickView cv = (ClickView) acmi.TargetView; + + return cv.OnContextItemSelected(item); + } + + protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) + { + switch (resultCode) + { + case Result.Ok: + String GroupName = data.Extras.GetString(GroupEditActivity.KEY_NAME); + int GroupIconID = data.Extras.GetInt(GroupEditActivity.KEY_ICON_ID); + GroupBaseActivity act = this; + Handler handler = new Handler(); + AddGroup task = AddGroup.getInstance(this, App.getDB(), GroupName, GroupIconID, mGroup, new RefreshTask(handler, this), false); + ProgressTask pt = new ProgressTask(act, task, Resource.String.saving_database); + pt.run(); + break; + + case Result.Canceled: + default: + break; + } + } + } +} + diff --git a/src/keepass2android/GroupBaseActivity.cs b/src/keepass2android/GroupBaseActivity.cs new file mode 100644 index 00000000..584f8b68 --- /dev/null +++ b/src/keepass2android/GroupBaseActivity.cs @@ -0,0 +1,295 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib; +using Android.Preferences; +using keepass2android.view; + +namespace keepass2android +{ + + public abstract class GroupBaseActivity : LockCloseListActivity { + public const String KEY_ENTRY = "entry"; + public const String KEY_MODE = "mode"; + + public virtual void LaunchActivityForEntry(KeePassLib.PwEntry pwEntry, int pos) + { + EntryActivity.Launch(this, pwEntry, pos, false); + } + public GroupBaseActivity () + { + + } + + public GroupBaseActivity (IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + + } + + private ISharedPreferences prefs; + + protected PwGroup mGroup; + + protected override void OnResume() { + base.OnResume(); + + refreshIfDirty(); + } + + public override bool OnSearchRequested() + { + StartActivityForResult(typeof(SearchActivity), 0); + return true; + } + + public void refreshIfDirty() { + Database db = App.getDB(); + if ( db.dirty.Contains(mGroup) ) { + db.dirty.Remove(mGroup); + BaseAdapter adapter = (BaseAdapter) ListAdapter; + adapter.NotifyDataSetChanged(); + + } + } + + protected override void OnListItemClick(ListView l, View v, int position, long id) { + base.OnListItemClick(l, v, position, id); + + Android.Widget.IListAdapter adapt = ListAdapter; + ClickView cv = (ClickView) adapt.GetView(position, null, null); + cv.OnClick(); + + } + + protected override void OnCreate(Bundle savedInstanceState) { + base.OnCreate(savedInstanceState); + + // Likely the app has been killed exit the activity + if ( ! App.getDB().Loaded ) { + Finish(); + return; + } + + prefs = PreferenceManager.GetDefaultSharedPreferences(this); + + SetContentView(new GroupViewOnlyView(this)); + SetResult(KeePass.EXIT_NORMAL); + + styleScrollBars(); + + } + + protected void styleScrollBars() { + ListView lv = ListView; + lv.ScrollBarStyle =ScrollbarStyles.InsideInset; + lv.TextFilterEnabled = true; + + } + + + protected void setGroupTitle() + { + Button tv = (Button)FindViewById(Resource.Id.group_name); + if (tv == null) + return; + + if (mGroup != null) + { + String name = mGroup.Name; + if (!String.IsNullOrEmpty(name)) + { + tv.Text = name; + } else + { + tv.Text = GetText(Resource.String.root); + } + + + } + + if ((mGroup != null) && (mGroup.IsVirtual == false) && (mGroup.ParentGroup != null)) + { + tv.Click += (object sender, EventArgs e) => + { + Finish(); + }; + } else + { + tv.SetCompoundDrawables(null, null, null, null); + tv.Clickable = false; + } + } + + + protected void setGroupIcon() { + if (mGroup != null) { + ImageView iv = (ImageView) FindViewById(Resource.Id.icon); + App.getDB().drawFactory.assignDrawableTo(iv, Resources, App.getDB().pm, mGroup.IconId, mGroup.CustomIconUuid); + } + } + + public override bool OnCreateOptionsMenu(IMenu menu) { + base.OnCreateOptionsMenu(menu); + + MenuInflater inflater = MenuInflater; + inflater.Inflate(Resource.Menu.group, menu); + + return true; + } + + private void setSortMenuText(IMenu menu) { + bool sortByName = prefs.GetBoolean(GetString(Resource.String.sort_key), Resources.GetBoolean(Resource.Boolean.sort_default)); + + int resId; + if ( sortByName ) { + resId = Resource.String.sort_db; + } else { + resId = Resource.String.sort_name; + } + + menu.FindItem(Resource.Id.menu_sort).SetTitle(resId); + + } + + public override bool OnPrepareOptionsMenu(IMenu menu) { + if ( ! base.OnPrepareOptionsMenu(menu) ) { + return false; + } + + setSortMenuText(menu); + + return true; + } + + public override bool OnOptionsItemSelected(IMenuItem item) { + switch ( item.ItemId ) { + /*case Resource.Id.menu_donate: + try { + Util.gotoUrl(this, Resource.String.donate_url); + } catch (ActivityNotFoundException) { + Toast.MakeText(this, Resource.String.error_failed_to_launch_link, ToastLength.Long).Show(); + return false; + } + + return true;*/ + case Resource.Id.menu_lock: + App.setShutdown(); + SetResult(KeePass.EXIT_LOCK); + Finish(); + return true; + + case Resource.Id.menu_search: + OnSearchRequested(); + return true; + + case Resource.Id.menu_app_settings: + AppSettingsActivity.Launch(this); + return true; + + case Resource.Id.menu_change_master_key: + setPassword(); + return true; + + case Resource.Id.menu_sort: + toggleSort(); + return true; + + } + + return base.OnOptionsItemSelected(item); + } + + private void toggleSort() { + // Toggle setting + String sortKey = GetString(Resource.String.sort_key); + bool sortByName = prefs.GetBoolean(sortKey, Resources.GetBoolean(Resource.Boolean.sort_default)); + ISharedPreferencesEditor editor = prefs.Edit(); + editor.PutBoolean(sortKey, ! sortByName); + EditorCompat.apply(editor); + + // Refresh menu titles + ActivityCompat.invalidateOptionsMenu(this); + + // Mark all groups as dirty now to refresh them on load + Database db = App.getDB(); + db.markAllGroupsAsDirty(); + // We'll manually refresh this group so we can remove it + db.dirty.Remove(mGroup); + + // Tell the adapter to refresh it's list + BaseAdapter adapter = (BaseAdapter) ListAdapter; + adapter.NotifyDataSetChanged(); + + } + + private void setPassword() { + SetPasswordDialog dialog = new SetPasswordDialog(this); + dialog.Show(); + } + + public class RefreshTask : OnFinish { + GroupBaseActivity act; + public RefreshTask(Handler handler, GroupBaseActivity act):base(handler) { + this.act = act; + } + + public override void run() { + if ( mSuccess) { + act.refreshIfDirty(); + } else { + displayMessage(act); + } + } + } + public class AfterDeleteGroup : OnFinish { + GroupBaseActivity act; + + public AfterDeleteGroup(Handler handler, GroupBaseActivity act):base(handler) { + this.act = act; + } + + + public override void run() { + if ( mSuccess) { + act.refreshIfDirty(); + } else { + mHandler.Post( () => { + Toast.MakeText(act, "Unrecoverable error: " + mMessage, ToastLength.Long).Show(); + }); + + App.setShutdown(); + act.Finish(); + } + } + + } + + } +} + diff --git a/src/keepass2android/GroupEditActivity.cs b/src/keepass2android/GroupEditActivity.cs new file mode 100644 index 00000000..1718f86a --- /dev/null +++ b/src/keepass2android/GroupEditActivity.cs @@ -0,0 +1,109 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", Theme="@style/Dialog")] + public class GroupEditActivity : LifecycleDebugActivity + { + public const String KEY_PARENT = "parent"; + public const String KEY_NAME = "name"; + public const String KEY_ICON_ID = "icon_id"; + + private int mSelectedIconID; + + public static void Launch(Activity act, PwGroup pw) + { + Intent i = new Intent(act, typeof(GroupEditActivity)); + + PwGroup parent = pw; + i.PutExtra(KEY_PARENT, parent.Uuid.ToHexString()); + + act.StartActivityForResult(i, 0); + } + + protected override void OnCreate (Bundle savedInstanceState) + { + base.OnCreate (savedInstanceState); + SetContentView (Resource.Layout.group_edit); + SetTitle (Resource.String.add_group_title); + + ImageButton iconButton = (ImageButton)FindViewById (Resource.Id.icon_button); + iconButton.Click += (object sender, EventArgs e) => + { + IconPickerActivity.Launch (this); + }; + mSelectedIconID = (int) PwIcon.FolderOpen; + iconButton.SetImageResource(Icons.iconToResId((PwIcon)mSelectedIconID)); + + Button okButton = (Button)FindViewById (Resource.Id.ok); + okButton.Click += (object sender, EventArgs e) => { + TextView nameField = (TextView)FindViewById (Resource.Id.group_name); + String name = nameField.Text; + + if (name.Length > 0) { + Intent intent = new Intent (); + + intent.PutExtra (KEY_NAME, name); + intent.PutExtra (KEY_ICON_ID, mSelectedIconID); + SetResult (Result.Ok, intent); + + Finish (); + } else { + Toast.MakeText (this, Resource.String.error_no_name, ToastLength.Long).Show (); + } + }; + + + Button cancel = (Button)FindViewById (Resource.Id.cancel); + cancel.Click += (object sender, EventArgs e) => { + Intent intent = new Intent (); + SetResult (Result.Canceled, intent); + + Finish (); + }; + } + + protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) + { + switch ((int)resultCode) + { + case EntryEditActivity.RESULT_OK_ICON_PICKER: + mSelectedIconID = data.Extras.GetInt(IconPickerActivity.KEY_ICON_ID); + ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button); + currIconButton.SetImageResource(Icons.iconToResId((PwIcon)mSelectedIconID)); + break; + default: + break; + } + } + } +} + diff --git a/src/keepass2android/IconPickerActivity.cs b/src/keepass2android/IconPickerActivity.cs new file mode 100644 index 00000000..7cf736a1 --- /dev/null +++ b/src/keepass2android/IconPickerActivity.cs @@ -0,0 +1,118 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")] + public class IconPickerActivity : LockCloseActivity + { + public const String KEY_ICON_ID = "icon_id"; + public const String KEY_CUSTOM_ICON_ID = "custom_icon_id"; + + public static void Launch(Activity act) + { + Intent i = new Intent(act, typeof(IconPickerActivity)); + act.StartActivityForResult(i, 0); + } + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + SetContentView(Resource.Layout.icon_picker); + + GridView currIconGridView = (GridView)FindViewById(Resource.Id.IconGridView); + currIconGridView.Adapter = new ImageAdapter(this, this); + + currIconGridView.ItemClick += (sender, e) => { + + Intent intent = new Intent(); + + intent.PutExtra(KEY_ICON_ID, e.Position); + SetResult((Result)EntryEditActivity.RESULT_OK_ICON_PICKER, intent); + + Finish(); + }; + } + + public class ImageAdapter : BaseAdapter + { + Context mContext; + + IconPickerActivity act; + + public ImageAdapter(Context c, IconPickerActivity act) + { + mContext = c; + this.act = act; + } + + public override int Count + { + get + { + /* Return number of KeePass icons */ + return Icons.count(); + } + } + + public override Java.Lang.Object GetItem(int position) + { + return null; + } + + public override long GetItemId(int position) + { + return 0; + } + + public override View GetView(int position, View convertView, ViewGroup parent) + { + View currView; + if(convertView == null) + { + LayoutInflater li = (LayoutInflater) act.GetSystemService(Context.LayoutInflaterService); + currView = li.Inflate(Resource.Layout.icon, null); + } + else + { + currView = convertView; + } + + TextView tv = (TextView) currView.FindViewById(Resource.Id.icon_text); + tv.Text = "" + position; + ImageView iv = (ImageView) currView.FindViewById(Resource.Id.icon_image); + iv.SetImageResource(Icons.iconToResId((KeePassLib.PwIcon)position)); + + return currView; + } + } + } + +} + diff --git a/src/keepass2android/KeePass.cs b/src/keepass2android/KeePass.cs new file mode 100644 index 00000000..c01704cb --- /dev/null +++ b/src/keepass2android/KeePass.cs @@ -0,0 +1,94 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ +using System; + +using Android.App; +using Android.Content; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.OS; + +using keepass2android.view; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", MainLauncher = true, Theme="@style/Base")] + [IntentFilter (new[]{Intent.ActionView}, + DataScheme="file", + DataMimeType="*/*", + DataHost="*", + DataPathPattern=".*\\.kdbx", //TODO http://stackoverflow.com/questions/3400072/pathpattern-to-match-file-extension-does-not-work-if-a-period-exists-elsewhere-i + //http://stackoverflow.com/questions/1733195/android-intent-filter-for-a-particular-file-extension + Categories=new[]{Intent.CategoryDefault, Intent.CategoryBrowsable})] + public class KeePass : LifecycleDebugActivity + { + public const Android.App.Result EXIT_NORMAL = Android.App.Result.FirstUser; + public const Android.App.Result EXIT_LOCK = Android.App.Result.FirstUser+1; + public const Android.App.Result EXIT_REFRESH = Android.App.Result.FirstUser+2; + public const Android.App.Result EXIT_REFRESH_TITLE = Android.App.Result.FirstUser+3; + public const Android.App.Result EXIT_FORCE_LOCK = Android.App.Result.FirstUser+4; + public const Android.App.Result EXIT_QUICK_UNLOCK = Android.App.Result.FirstUser+5; + public const Android.App.Result EXIT_CLOSE_AFTER_SEARCH = Android.App.Result.FirstUser+6; + public const Android.App.Result EXIT_CHANGE_DB = Android.App.Result.FirstUser+7; + public const Android.App.Result EXIT_FORCE_LOCK_AND_CHANGE_DB = Android.App.Result.FirstUser+8; + + protected override void OnCreate (Bundle bundle) + { + base.OnCreate (bundle); + Android.Util.Log.Debug("DEBUG","KeePass.OnCreate"); + } + + protected override void OnResume() + { + base.OnResume(); + Android.Util.Log.Debug("DEBUG","KeePass.OnResume"); + } + + + protected override void OnStart() { + base.OnStart(); + Android.Util.Log.Debug("DEBUG","KeePass.OnStart"); + startFileSelect(); + } + + private void startFileSelect() { + Intent intent = new Intent(this, typeof(FileSelectActivity)); + //TEST Intent intent = new Intent(this, typeof(EntryActivity)); + //Intent intent = new Intent(this, typeof(SearchActivity)); + //Intent intent = new Intent(this, typeof(QuickUnlock)); + + StartActivityForResult(intent, 0); + Finish(); + } + + + protected override void OnDestroy() { + Android.Util.Log.Debug("DEBUG","KeePass.OnDestry"+IsFinishing.ToString()); + base.OnDestroy(); + } + + + protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { + base.OnActivityResult(requestCode, resultCode, data); + + Finish(); + } + } +} + + diff --git a/src/keepass2android/KeyFileException.cs b/src/keepass2android/KeyFileException.cs new file mode 100644 index 00000000..fe8190f1 --- /dev/null +++ b/src/keepass2android/KeyFileException.cs @@ -0,0 +1,71 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + + [Serializable] + public class KeyFileException : Exception + { + /// + /// Initializes a new instance of the class + /// + public KeyFileException () + { + } + + /// + /// Initializes a new instance of the class + /// + /// A that describes the exception. + public KeyFileException (string message) : base (message) + { + } + + /// + /// Initializes a new instance of the class + /// + /// A that describes the exception. + /// The exception that is the cause of the current exception. + public KeyFileException (string message, Exception inner) : base (message, inner) + { + } + + /// + /// Initializes a new instance of the class + /// + /// The contextual information about the source or destination. + /// The object that holds the serialized object data. + protected KeyFileException (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (info, context) + { + } + } + +} + diff --git a/src/keepass2android/LifecycleDebugActivity.cs b/src/keepass2android/LifecycleDebugActivity.cs new file mode 100644 index 00000000..c6609bc5 --- /dev/null +++ b/src/keepass2android/LifecycleDebugActivity.cs @@ -0,0 +1,93 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + + public abstract class LifecycleDebugActivity : Activity + { + public LifecycleDebugActivity (IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + + } + + public LifecycleDebugActivity() + { + } + + + string className = null; + string ClassName + { + get { + if (className == null) + className = this.GetType().Name; + return className; + } + } + + protected override void OnResume() + { + base.OnResume(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnResume"); + } + + protected override void OnStart() + { + base.OnStart(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnStart"); + } + + protected override void OnCreate(Bundle bundle) + { + base.OnCreate(bundle); + Android.Util.Log.Debug("DEBUG",ClassName+".OnCreate"); + } + + protected override void OnDestroy() + { + base.OnDestroy(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnDestroy"+IsFinishing.ToString()); + } + + protected override void OnPause() + { + base.OnPause(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnPause"); + } + + protected override void OnStop() + { + base.OnStop(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnStop"); + } + } +} + diff --git a/src/keepass2android/LockCloseActivity.cs b/src/keepass2android/LockCloseActivity.cs new file mode 100644 index 00000000..09e3e57d --- /dev/null +++ b/src/keepass2android/LockCloseActivity.cs @@ -0,0 +1,53 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib.Serialization; + +namespace keepass2android +{ + public class LockCloseActivity : LockingActivity { + + IOConnectionInfo mIoc; + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + mIoc = App.getDB().mIoc; + } + + protected override void OnResume() { + base.OnResume(); + + TimeoutHelper.checkShutdown(this, mIoc); + } + + + } + +} + diff --git a/src/keepass2android/LockCloseListActivity.cs b/src/keepass2android/LockCloseListActivity.cs new file mode 100644 index 00000000..146e80ed --- /dev/null +++ b/src/keepass2android/LockCloseListActivity.cs @@ -0,0 +1,61 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib.Serialization; + +namespace keepass2android +{ + + public class LockCloseListActivity : LockingListActivity { + public LockCloseListActivity() + { + + } + + IOConnectionInfo mIoc; + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + mIoc = App.getDB().mIoc; + } + + public LockCloseListActivity (IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + + } + + protected override void OnResume() { + base.OnResume(); + + TimeoutHelper.checkShutdown(this, mIoc); + } + } +} + diff --git a/src/keepass2android/LockingActivity.cs b/src/keepass2android/LockingActivity.cs new file mode 100644 index 00000000..39fb9891 --- /dev/null +++ b/src/keepass2android/LockingActivity.cs @@ -0,0 +1,64 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + + public class LockingActivity : LifecycleDebugActivity { + + public LockingActivity (IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + + } + + public LockingActivity() + { + } + + protected override void OnPause() { + base.OnPause(); + + TimeoutHelper.pause(this); + } + + protected override void OnDestroy() + { + base.OnDestroy(); + GC.Collect(); + } + + protected override void OnResume() { + base.OnResume(); + + TimeoutHelper.resume(this); + } + } +} + diff --git a/src/keepass2android/LockingClosePreferenceActivity.cs b/src/keepass2android/LockingClosePreferenceActivity.cs new file mode 100644 index 00000000..e29bb651 --- /dev/null +++ b/src/keepass2android/LockingClosePreferenceActivity.cs @@ -0,0 +1,53 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib.Serialization; + +namespace keepass2android +{ + + public class LockingClosePreferenceActivity : LockingPreferenceActivity { + + + IOConnectionInfo mIoc; + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + mIoc = App.getDB().mIoc; + } + + protected override void OnResume() { + base.OnResume(); + + TimeoutHelper.checkShutdown(this, mIoc); + } + } + +} + diff --git a/src/keepass2android/LockingListActivity.cs b/src/keepass2android/LockingListActivity.cs new file mode 100644 index 00000000..f35850a5 --- /dev/null +++ b/src/keepass2android/LockingListActivity.cs @@ -0,0 +1,96 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + + public class LockingListActivity : ListActivity { + + + public LockingListActivity (IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + + } + public LockingListActivity () + { + } + + + string className = null; + string ClassName + { + get { + if (className == null) + className = this.GetType().Name; + return className; + } + } + + protected override void OnResume() + { + base.OnResume(); + TimeoutHelper.resume(this); + Android.Util.Log.Debug("DEBUG",ClassName+".OnResume"); + } + + protected override void OnStart() + { + base.OnStart(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnStart"); + } + + protected override void OnCreate(Bundle bundle) + { + base.OnCreate(bundle); + Android.Util.Log.Debug("DEBUG",ClassName+".OnCreate"); + } + + protected override void OnDestroy() + { + base.OnDestroy(); + GC.Collect(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnDestroy"+IsFinishing.ToString()); + } + + protected override void OnPause() + { + base.OnPause(); + TimeoutHelper.pause(this); + Android.Util.Log.Debug("DEBUG",ClassName+".OnPause"); + } + + protected override void OnStop() + { + base.OnStop(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnStop"); + } + } +} + diff --git a/src/keepass2android/LockingPreferenceActivity.cs b/src/keepass2android/LockingPreferenceActivity.cs new file mode 100644 index 00000000..f8719016 --- /dev/null +++ b/src/keepass2android/LockingPreferenceActivity.cs @@ -0,0 +1,97 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.Preferences; + +namespace keepass2android +{ + + public class LockingPreferenceActivity : PreferenceActivity { + + public LockingPreferenceActivity (IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + + } + public LockingPreferenceActivity () + { + } + + + string className = null; + string ClassName + { + get { + if (className == null) + className = this.GetType().Name; + return className; + } + } + + protected override void OnResume() + { + base.OnResume(); + TimeoutHelper.resume(this); + Android.Util.Log.Debug("DEBUG",ClassName+".OnResume"); + } + + protected override void OnStart() + { + base.OnStart(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnStart"); + } + + protected override void OnCreate(Bundle bundle) + { + base.OnCreate(bundle); + Android.Util.Log.Debug("DEBUG",ClassName+".OnCreate"); + } + + protected override void OnDestroy() + { + base.OnDestroy(); + GC.Collect(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnDestroy"+IsFinishing.ToString()); + } + + protected override void OnPause() + { + base.OnPause(); + TimeoutHelper.pause(this); + Android.Util.Log.Debug("DEBUG",ClassName+".OnPause"); + } + + protected override void OnStop() + { + base.OnStop(); + Android.Util.Log.Debug("DEBUG",ClassName+".OnStop"); + } + } + +} + diff --git a/src/keepass2android/PasswordActivity.cs b/src/keepass2android/PasswordActivity.cs new file mode 100644 index 00000000..06ea10e2 --- /dev/null +++ b/src/keepass2android/PasswordActivity.cs @@ -0,0 +1,570 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Java.Net; +using Android.Preferences; +using Java.IO; +using Android.Text; +using Android.Content.PM; +using Android.Text.Method; +using KeePassLib.Keys; +using KeePassLib.Serialization; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/Base")] + public class PasswordActivity : LockingActivity { + bool mShowPassword = false; + + public const String KEY_DEFAULT_FILENAME = "defaultFileName"; + + public const String KEY_FILENAME = "fileName"; + private const String KEY_KEYFILE = "keyFile"; + private const String KEY_SERVERUSERNAME = "serverCredUser"; + private const String KEY_SERVERPASSWORD = "serverCredPwd"; + private const String KEY_SERVERCREDMODE = "serverCredRememberMode"; + + private const String VIEW_INTENT = "android.intent.action.VIEW"; + + private IOConnectionInfo mIoConnection; + private String mKeyFile; + private bool mRememberKeyfile; + ISharedPreferences prefs; + + public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + + } + + public PasswordActivity() + { + + } + + + static void PutIoConnectionToIntent(IOConnectionInfo ioc, Android.Content.Intent i) + { + i.PutExtra(KEY_FILENAME, ioc.Path); + i.PutExtra(KEY_SERVERUSERNAME, ioc.UserName); + i.PutExtra(KEY_SERVERPASSWORD, ioc.Password); + i.PutExtra(KEY_SERVERCREDMODE, (int)ioc.CredSaveMode); + } + + public static void SetIoConnectionFromIntent(IOConnectionInfo ioc, Intent i) + { + ioc.Path = i.GetStringExtra(KEY_FILENAME); + ioc.UserName = i.GetStringExtra(KEY_SERVERUSERNAME) ?? ""; + ioc.Password = i.GetStringExtra(KEY_SERVERPASSWORD) ?? ""; + ioc.CredSaveMode = (IOCredSaveMode)i.GetIntExtra(KEY_SERVERCREDMODE, (int) IOCredSaveMode.NoSave); + } + + public static void Launch(Activity act, String fileName, String urlToSearchFor) { + Java.IO.File dbFile = new Java.IO.File(fileName); + if ( ! dbFile.Exists() ) { + throw new Java.IO.FileNotFoundException(); + } + + + Intent i = new Intent(act, typeof(PasswordActivity)); + i.PutExtra(KEY_FILENAME, fileName); + i.PutExtra(FileSelectActivity.UrlToSearch_key, urlToSearchFor); + act.StartActivityForResult(i, 0); + + } + + + public static void Launch(Activity act, String fileName) { + Launch(act, IOConnectionInfo.FromPath(fileName), null); + + } + + + public static void Launch(Activity act, IOConnectionInfo ioc, String urlToSearchFor) + { + if (ioc.IsLocalFile()) + { + Launch(act, ioc.Path, urlToSearchFor); + return; + } + + Intent i = new Intent(act, typeof(PasswordActivity)); + PutIoConnectionToIntent(ioc, i); + + i.PutExtra(FileSelectActivity.UrlToSearch_key, urlToSearchFor); + + act.StartActivityForResult(i, 0); + + } + + public void LaunchNextActivity() + { + + if (String.IsNullOrEmpty(mUrlToSearchFor)) + GroupActivity.Launch(this); + else + { + ShareUrlResults.Launch(this, mUrlToSearchFor); + } + } + + void unloadDatabase() + { + App.getDB().Clear(); + StopService(new Intent(this, typeof(QuickUnlockForegroundService))); + } + + void lockDatabase() + { + SetResult(KeePass.EXIT_LOCK); + setEditText(Resource.Id.password, ""); + if (App.getDB().QuickUnlockEnabled) + App.getDB().Locked = true; + else + { + unloadDatabase(); + } + } + + void lockAndClose() + { + lockDatabase(); + Finish(); + + } + + bool tryStartQuickUnlock() + { + if (!App.getDB().QuickUnlockEnabled) + return false; + + if (App.getDB().pm.MasterKey.ContainsType(typeof(KcpPassword)) == false) + return false; + KcpPassword kcpPassword = (KcpPassword)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpPassword)); + String password = kcpPassword.Password.ReadString(); + + if (password.Length == 0) + return false; + + App.getDB().Locked = true; + + Intent i = new Intent(this, typeof(QuickUnlock)); + PutIoConnectionToIntent(mIoConnection, i); + Android.Util.Log.Debug("DEBUG","Starting QuickUnlock"); + StartActivityForResult(i,0); + return true; + } + + public void StartQuickUnlockForegroundService() + { + if (App.getDB().QuickUnlockEnabled) + { + StartService(new Intent(this, typeof(QuickUnlockForegroundService))); + } + } + + bool startedWithActivityResult = false; + + protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) + { + base.OnActivityResult(requestCode, resultCode, data); + + startedWithActivityResult = true; + Android.Util.Log.Debug("DEBUG","PasswordActivity.OnActivityResult "+resultCode+"/"+requestCode); + + if (resultCode != KeePass.EXIT_CLOSE_AFTER_SEARCH) + { + //Stop service when app activity is left + StopService(new Intent(this, typeof(CopyToClipboardService))); + } + + //NOTE: original code from k eepassdroid used switch ((Android.App.Result)requestCode) { (but doesn't work here, although k eepassdroid works) + switch(resultCode) { + + case KeePass.EXIT_NORMAL: + if (!tryStartQuickUnlock()) + { + setEditText(Resource.Id.password, ""); + ; + } + break; + + case KeePass.EXIT_LOCK: + if (!tryStartQuickUnlock()) + { + lockAndClose(); + } + break; + case KeePass.EXIT_FORCE_LOCK: + setEditText(Resource.Id.password, ""); + unloadDatabase(); + break; + case KeePass.EXIT_FORCE_LOCK_AND_CHANGE_DB: + unloadDatabase(); + Finish(); + break; + case KeePass.EXIT_CHANGE_DB: + lockAndClose(); + break; + case KeePass.EXIT_CLOSE_AFTER_SEARCH: + SetResult(KeePass.EXIT_CLOSE_AFTER_SEARCH); + Finish(); + break; + case KeePass.EXIT_QUICK_UNLOCK: + App.getDB().Locked = false; + LaunchNextActivity(); + break; + + case Android.App.Result.Ok: + if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE) { + String filename = data.DataString; + if (filename != null) { + if (filename.StartsWith("file://")) { + filename = filename.Substring(7); + } + + filename = URLDecoder.Decode(filename); + + EditText fn = (EditText) FindViewById(Resource.Id.pass_keyfile); + fn.Text = filename; + } + } + break; + } + + } + + internal string mUrlToSearchFor; + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + + Intent i = Intent; + String action = i.Action; + + prefs = PreferenceManager.GetDefaultSharedPreferences(this); + mRememberKeyfile = prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default)); + + mIoConnection = new IOConnectionInfo(); + + if (action != null && action.Equals(VIEW_INTENT)) + { + mIoConnection.Path = i.DataString; + + if (! mIoConnection.Path.Substring(0, 7).Equals("file://")) + { + //TODO: this might no longer be required as we can handle http(s) and ftp as well (but we need server credentials therefore) + Toast.MakeText(this, Resource.String.error_can_not_handle_uri, ToastLength.Long).Show(); + Finish(); + return; + } + + mIoConnection.Path = URLDecoder.Decode(mIoConnection.Path.Substring(7, mIoConnection.Path.Length)); + + if (mIoConnection.Path.Length == 0) + { + // No file name + Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show(); + Finish(); + return; + } + + File dbFile = new File(mIoConnection.Path); + if (! dbFile.Exists()) + { + // File does not exist + Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show(); + Finish(); + return; + } + + mKeyFile = getKeyFile(mIoConnection.Path); + + } else + { + SetIoConnectionFromIntent(mIoConnection, i); + mKeyFile = i.GetStringExtra(KEY_KEYFILE); + if (mKeyFile == null || mKeyFile.Length == 0) + { + mKeyFile = getKeyFile(mIoConnection.Path); + } + } + + this.mUrlToSearchFor = i.GetStringExtra(FileSelectActivity.UrlToSearch_key); + + SetContentView(Resource.Layout.password); + populateView(); + + Button confirmButton = (Button)FindViewById(Resource.Id.pass_ok); + confirmButton.Click += (object sender, EventArgs e) => + { + String pass = GetEditText(Resource.Id.password); + String key = GetEditText(Resource.Id.pass_keyfile); + if (pass.Length == 0 && key.Length == 0) + { + errorMessage(Resource.String.error_nopass); + return; + } + + String fileName = GetEditText(Resource.Id.filename); + + + // Clear before we load + unloadDatabase(); + + // Clear the shutdown flag + App.clearShutdown(); + + CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock); + App.getDB().QuickUnlockEnabled = cbQuickUnlock.Checked; + App.getDB().QuickUnlockKeyLength = int.Parse(prefs.GetString(GetString(Resource.String.QuickUnlockLength_key), GetString(Resource.String.QuickUnlockLength_default))); + + Handler handler = new Handler(); + LoadDB task = new LoadDB(App.getDB(), this, mIoConnection, pass, key, new AfterLoad(handler, this)); + ProgressTask pt = new ProgressTask(this, task, Resource.String.loading_database); + pt.run(); + }; + + /*CheckBox checkBox = (CheckBox) FindViewById(Resource.Id.show_password); + // Show or hide password + checkBox.CheckedChange += delegate(object sender, CompoundButton.CheckedChangeEventArgs e) { + + TextView password = (TextView) FindViewById(Resource.Id.password); + if ( e.IsChecked ) { + password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword; + } else { + password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword; + } + }; + */ + ImageButton btnTogglePassword = (ImageButton)FindViewById(Resource.Id.toggle_password); + btnTogglePassword.Click += (object sender, EventArgs e) => { + mShowPassword = !mShowPassword; + TextView password = (TextView)FindViewById(Resource.Id.password); + if (mShowPassword) + { + password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword; + } else + { + password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword; + } + }; + + CheckBox defaultCheck = (CheckBox)FindViewById(Resource.Id.default_database); + ///Don't allow the current file to be the default if we don't have stored credentials + if ((mIoConnection.IsLocalFile() == false) && (mIoConnection.CredSaveMode != IOCredSaveMode.SaveCred)) + { + defaultCheck.Enabled = false; + } else + { + defaultCheck.Enabled = true; + } + defaultCheck.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) => + { + String newDefaultFileName; + + if (e.IsChecked) + { + newDefaultFileName = mIoConnection.Path; + } else + { + newDefaultFileName = ""; + } + + ISharedPreferencesEditor editor = prefs.Edit(); + editor.PutString(KEY_DEFAULT_FILENAME, newDefaultFileName); + EditorCompat.apply(editor); + }; + + ImageButton browse = (ImageButton)FindViewById(Resource.Id.browse_button); + browse.Click += (object sender, EventArgs evt) => + { + if (Interaction.isIntentAvailable(this, Intents.FILE_BROWSE)) + { + Intent intent = new Intent(Intents.FILE_BROWSE); + + if (!String.IsNullOrEmpty(mIoConnection.Path)) + { + File keyfile = new File(mIoConnection.Path); + File parent = keyfile.ParentFile; + if (parent != null) + { + intent.SetData(Android.Net.Uri.Parse("file://" + parent.AbsolutePath)); + } + } + + try + { + StartActivityForResult(intent, Intents.REQUEST_CODE_FILE_BROWSE); + } catch (ActivityNotFoundException) + { + BrowserDialog diag = new BrowserDialog(this); + diag.Show(); + } + } else + { + BrowserDialog diag = new BrowserDialog(this); + diag.Show(); + } + + }; + + retrieveSettings(); + + + } + + protected override void OnResume() { + base.OnResume(); + + // If the application was shutdown make sure to clear the password field, if it + // was saved in the instance state + if (App.isShutdown()) { + lockDatabase(); + } + + // Clear the shutdown flag + App.clearShutdown(); + + if (startedWithActivityResult) + return; + + if (App.getDB().Loaded && (App.getDB().mIoc != null) + && (mIoConnection != null) && (App.getDB().mIoc.GetDisplayName() == mIoConnection.GetDisplayName())) + { + if (App.getDB().Locked == false) + { + LaunchNextActivity(); + } + else + { + tryStartQuickUnlock(); + } + } + } + + private void retrieveSettings() { + String defaultFilename = prefs.GetString(KEY_DEFAULT_FILENAME, ""); + if (!String.IsNullOrEmpty(mIoConnection.Path) && mIoConnection.Path.Equals(defaultFilename)) { + CheckBox checkbox = (CheckBox) FindViewById(Resource.Id.default_database); + checkbox.Checked = true; + } + CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock); + cbQuickUnlock.Checked = prefs.GetBoolean(GetString(Resource.String.QuickUnlockDefaultEnabled_key), true); + } + + private String getKeyFile(String filename) { + if ( mRememberKeyfile ) { + FileDbHelper dbHelp = App.fileDbHelper; + + String keyfile = dbHelp.getFileByName(filename); + + return keyfile; + } else { + return ""; + } + } + + private void populateView() { + setEditText(Resource.Id.filename, mIoConnection.GetDisplayName()); + setEditText(Resource.Id.pass_keyfile, mKeyFile); + } + + /* + private void errorMessage(CharSequence text) + { + Toast.MakeText(this, text, ToastLength.Long).Show(); + } + */ + + private void errorMessage(int resId) + { + Toast.MakeText(this, resId, ToastLength.Long).Show(); + } + + private String GetEditText(int resId) { + return Util.getEditText(this, resId); + } + + private void setEditText(int resId, String str) { + TextView te = (TextView) FindViewById(resId); + //assert(te == null); + + if (te != null) { + te.Text = str; + } + } + + public override bool OnCreateOptionsMenu(IMenu menu) { + base.OnCreateOptionsMenu(menu); + + MenuInflater inflate = MenuInflater; + inflate.Inflate(Resource.Menu.password, menu); + + return true; + } + + public override bool OnOptionsItemSelected(IMenuItem item) { + switch ( item.ItemId ) { + case Resource.Id.menu_about: + AboutDialog dialog = new AboutDialog(this); + dialog.Show(); + return true; + + case Resource.Id.menu_app_settings: + AppSettingsActivity.Launch(this); + return true; + } + + return base.OnOptionsItemSelected(item); + } + + private class AfterLoad : OnFinish { + + + PasswordActivity act; + public AfterLoad(Handler handler, PasswordActivity act):base(handler) { + this.act = act; + } + + + public override void run() { + if ( mSuccess ) { + act.StartQuickUnlockForegroundService(); + act.LaunchNextActivity(); + } else { + displayMessage(act); + } + } + } + + } + +} + diff --git a/src/keepass2android/ProgressTask.cs b/src/keepass2android/ProgressTask.cs new file mode 100644 index 00000000..fb457978 --- /dev/null +++ b/src/keepass2android/ProgressTask.cs @@ -0,0 +1,87 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Java.Lang; + +namespace keepass2android +{ + public class ProgressTask { + private Context mCtx; + private Handler mHandler; + private RunnableOnFinish mTask; + private ProgressDialog mPd; + + public ProgressTask(Context ctx, RunnableOnFinish task, int messageId) { + mCtx = ctx; + mTask = task; + mHandler = new Handler(); + + // Show process dialog + mPd = new ProgressDialog(mCtx); + mPd.SetTitle(ctx.GetText(Resource.String.progress_title)); + mPd.SetMessage(ctx.GetText(messageId)); + + // Set code to run when this is finished + mTask.setStatus(new UpdateStatus(ctx, mHandler, mPd)); + mTask.mFinish = new AfterTask(task.mFinish, mHandler, mPd); + + } + + public void run() { + // Show process dialog + mPd.Show(); + + + // Start Thread to Run task + Thread t = new Thread(mTask.run); + t.Start(); + + } + + private class AfterTask : OnFinish { + + ProgressDialog mPd; + + public AfterTask (OnFinish finish, Handler handler, ProgressDialog pd): base(finish, handler) + { + mPd = pd; + } + + public override void run() { + base.run(); + + // Remove the progress dialog + mHandler.Post(delegate() {mPd.Dismiss();}); + + } + + } + + } +} + diff --git a/src/keepass2android/Properties/AndroidManifest.xml b/src/keepass2android/Properties/AndroidManifest.xml new file mode 100644 index 00000000..bc8c8174 --- /dev/null +++ b/src/keepass2android/Properties/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/keepass2android/Properties/AssemblyInfo.cs b/src/keepass2android/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..0fc76918 --- /dev/null +++ b/src/keepass2android/Properties/AssemblyInfo.cs @@ -0,0 +1,44 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ +using System.Reflection; +using System.Runtime.CompilerServices; +using Android.App; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("keepass2android")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Philipp Crocoll")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.0")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/src/keepass2android/PwGroupEqualityFromIdComparer.cs b/src/keepass2android/PwGroupEqualityFromIdComparer.cs new file mode 100644 index 00000000..6b86efc4 --- /dev/null +++ b/src/keepass2android/PwGroupEqualityFromIdComparer.cs @@ -0,0 +1,47 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib; + +namespace keepass2android +{ + class PwGroupEqualityFromIdComparer: IEqualityComparer + { + #region IEqualityComparer implementation + public bool Equals (PwGroup x, PwGroup y) + { + return x.Uuid.EqualsValue(y.Uuid); + } + public int GetHashCode (PwGroup obj) + { + return obj.Uuid.ToHexString().GetHashCode(); + } +#endregion + } +} + diff --git a/src/keepass2android/PwGroupListAdapter.cs b/src/keepass2android/PwGroupListAdapter.cs new file mode 100644 index 00000000..f0283fe0 --- /dev/null +++ b/src/keepass2android/PwGroupListAdapter.cs @@ -0,0 +1,158 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.Preferences; +using KeePassLib; +using keepass2android.view; + +namespace keepass2android +{ + + public class PwGroupListAdapter : BaseAdapter + { + + private GroupBaseActivity mAct; + private PwGroup mGroup; + private List groupsForViewing; + private List entriesForViewing; + + private ISharedPreferences prefs; + + public PwGroupListAdapter(GroupBaseActivity act, PwGroup group) { + mAct = act; + mGroup = group; + prefs = PreferenceManager.GetDefaultSharedPreferences(act); + + filterAndSort(); + + } + + + public override void NotifyDataSetChanged() { + base.NotifyDataSetChanged(); + + filterAndSort(); + } + + + public override void NotifyDataSetInvalidated() { + base.NotifyDataSetInvalidated(); + + filterAndSort(); + } + + private void filterAndSort() { + entriesForViewing = new List(); + + foreach (PwEntry entry in mGroup.Entries) + { + entriesForViewing.Add(entry); + } + + bool sortLists = prefs.GetBoolean(mAct.GetString(Resource.String.sort_key), mAct.Resources.GetBoolean(Resource.Boolean.sort_default)); + if ( sortLists ) + { + groupsForViewing = new List(mGroup.Groups); + groupsForViewing.Sort( (PwGroup x,PwGroup y) => { return String.Compare (x.Name, y.Name, true); }); + entriesForViewing.Sort( (PwEntry x, PwEntry y) => + { + String nameX = x.Strings.ReadSafe(PwDefs.TitleField); + String nameY = y.Strings.ReadSafe(PwDefs.TitleField); + if (nameX.ToLower() != nameY.ToLower()) + return String.Compare (nameX,nameY,true); + else + return x.CreationTime.CompareTo(y.CreationTime); + } + ); + } else { + groupsForViewing = new List(mGroup.Groups); + } + } + + public override int Count + { + get{ + + return groupsForViewing.Count + entriesForViewing.Count; + } + } + + public override Java.Lang.Object GetItem(int position) { + return position; + } + + public override long GetItemId(int position) { + return position; + } + + public override View GetView(int position, View convertView, ViewGroup parent) { + int size = groupsForViewing.Count; + + if ( position < size ) { + return createGroupView(position, convertView); + } else { + return createEntryView(position - size, convertView); + } + } + + private View createGroupView(int position, View convertView) { + PwGroup g = groupsForViewing[position]; + PwGroupView gv; + + if (convertView == null || !(convertView is PwGroupView)) { + + gv = PwGroupView.getInstance(mAct, g); + } + else { + gv = (PwGroupView) convertView; + gv.convertView(g); + + } + + return gv; + } + + private PwEntryView createEntryView(int position, View convertView) { + PwEntry entry = entriesForViewing[position]; + PwEntryView ev; + + if (convertView == null || !(convertView is PwEntryView)) { + ev = PwEntryView.getInstance(mAct, entry, position); + } + else { + ev = (PwEntryView) convertView; + ev.convertView(entry, position); + } + + return ev; + } + + } + +} + diff --git a/src/keepass2android/PwUuidEqualityComparer.cs b/src/keepass2android/PwUuidEqualityComparer.cs new file mode 100644 index 00000000..f769ff03 --- /dev/null +++ b/src/keepass2android/PwUuidEqualityComparer.cs @@ -0,0 +1,49 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +using KeePassLib; + +namespace keepass2android +{ + class PwUuidEqualityComparer: IEqualityComparer + { + #region IEqualityComparer implementation + public bool Equals (PwUuid x, PwUuid y) + { + return x.EqualsValue(y); + } + public int GetHashCode (PwUuid obj) + { + return obj.ToHexString().GetHashCode(); + } +#endregion + } + + +} diff --git a/src/keepass2android/QuickUnlock.cs b/src/keepass2android/QuickUnlock.cs new file mode 100644 index 00000000..46f45f4e --- /dev/null +++ b/src/keepass2android/QuickUnlock.cs @@ -0,0 +1,116 @@ +/* +This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. + + Keepass2Android is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Keepass2Android is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Keepass2Android. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.Content.PM; +using KeePassLib.Keys; +using Android.Preferences; +using Android.Views.InputMethods; +using KeePassLib.Serialization; + +namespace keepass2android +{ + [Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/Base")] + public class QuickUnlock : LifecycleDebugActivity + { + IOConnectionInfo mIoc; + + protected override void OnCreate(Bundle bundle) + { + base.OnCreate(bundle); + + Intent i = Intent; + mIoc = App.getDB().mIoc; + + if (mIoc == null) + { + Finish(); + return; + } + + + SetContentView(Resource.Layout.QuickUnlock); + + ((TextView)FindViewById(Resource.Id.qu_filename)).Text = mIoc.GetDisplayName(); + + + TextView txtLabel = (TextView)FindViewById(Resource.Id.QuickUnlock_label); + + ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this); + int quickUnlockLength = App.getDB().QuickUnlockKeyLength; + + txtLabel.Text = GetString(Resource.String.QuickUnlock_label, new Java.Lang.Object[]{quickUnlockLength}); + + EditText pwd= (EditText)FindViewById(Resource.Id.QuickUnlock_password); + pwd.SetEms(quickUnlockLength); + pwd.PostDelayed(() => { + InputMethodManager keyboard = (InputMethodManager)GetSystemService(Context.InputMethodService); + keyboard.ShowSoftInput(pwd, 0); + }, 50); + + SetResult(KeePass.EXIT_CHANGE_DB); + + Button btnUnlock = (Button)FindViewById(Resource.Id.QuickUnlock_button); + btnUnlock.Click += (object sender, EventArgs e) => + { + KcpPassword kcpPassword = (KcpPassword)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpPassword)); + String password = kcpPassword.Password.ReadString(); + String expectedPasswordPart = password.Substring(Math.Max(0,password.Length-quickUnlockLength),Math.Min(password.Length, quickUnlockLength)); + if (pwd.Text == expectedPasswordPart) + { + SetResult(KeePass.EXIT_QUICK_UNLOCK); + } + else + { + SetResult(KeePass.EXIT_FORCE_LOCK); + Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show(); + } + Finish(); + }; + + Button btnLock = (Button)FindViewById(Resource.Id.QuickUnlock_buttonLock); + btnLock.Click += (object sender, EventArgs e) => + { + SetResult(KeePass.EXIT_FORCE_LOCK_AND_CHANGE_DB); + Finish(); + }; + } + + + protected override void OnResume() + { + base.OnResume(); + + if ( ! App.getDB().Loaded ) { + SetResult(KeePass.EXIT_CHANGE_DB); + Finish(); + return; + } + } + } +} + diff --git a/src/keepass2android/Resources/AboutResources.txt b/src/keepass2android/Resources/AboutResources.txt new file mode 100644 index 00000000..6dff7bcc --- /dev/null +++ b/src/keepass2android/Resources/AboutResources.txt @@ -0,0 +1,44 @@ +Images, layout descriptions, binary blobs and string dictionaries can be included +in your application as resource files. Various Android APIs are designed to +operate on the resource IDs instead of dealing with images, strings or binary blobs +directly. + +For example, a sample Android app that contains a user interface layout (main.axml), +an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) +would keep its resources in the "Resources" directory of the application: + +Resources/ + drawable/ + icon.png + + layout/ + main.axml + + values/ + strings.xml + +In order to get the build system to recognize Android resources, set the build action to +"AndroidResource". The native Android APIs do not operate directly with filenames, but +instead operate on resource IDs. When you compile an Android application that uses resources, +the build system will package the resources for distribution and generate a class called "R" +(this is an Android convention) that contains the tokens for each one of the resources +included. For example, for the above Resources layout, this is what the R class would expose: + +public class R { + public class drawable { + public const int icon = 0x123; + } + + public class layout { + public const int main = 0x456; + } + + public class strings { + public const int first_string = 0xabc; + public const int second_string = 0xbcd; + } +} + +You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main +to reference the layout/main.axml file, or R.Strings.first_string to reference the first +string in the dictionary file values/strings.xml. diff --git a/src/keepass2android/Resources/Resource.designer.cs b/src/keepass2android/Resources/Resource.designer.cs new file mode 100644 index 00000000..bc06bdb7 --- /dev/null +++ b/src/keepass2android/Resources/Resource.designer.cs @@ -0,0 +1,1796 @@ +#pragma warning disable 1591 +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.296 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +[assembly: Android.Runtime.ResourceDesignerAttribute("keepass2android.Resource", IsApplication=true)] + +namespace keepass2android +{ + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Novell.MonoDroid.Build.Tasks", "1.0.0.0")] + public partial class Resource + { + + public static void UpdateIdValues() + { + KeePassLib2Android.Resource.String.library_name = keepass2android.Resource.String.library_name; + } + + public partial class Array + { + + // aapt resource value: 0x7f080002 + public const int clipboard_timeout_options = 2131230722; + + // aapt resource value: 0x7f080000 + public const int clipboard_timeout_values = 2131230720; + + // aapt resource value: 0x7f080004 + public const int cred_remember_modes = 2131230724; + + // aapt resource value: 0x7f080003 + public const int list_size_options = 2131230723; + + // aapt resource value: 0x7f080001 + public const int list_size_values = 2131230721; + + private Array() + { + } + } + + public partial class Attribute + { + + private Attribute() + { + } + } + + public partial class Boolean + { + + // aapt resource value: 0x7f070004 + public const int TanExpiresOnUse_default = 2131165188; + + // aapt resource value: 0x7f070001 + public const int keyfile_default = 2131165185; + + // aapt resource value: 0x7f070000 + public const int maskpass_default = 2131165184; + + // aapt resource value: 0x7f070003 + public const int omitbackup_default = 2131165187; + + // aapt resource value: 0x7f070002 + public const int sort_default = 2131165186; + + private Boolean() + { + } + } + + public partial class Color + { + + // aapt resource value: 0x7f050007 + public const int bg_gray = 2131034119; + + // aapt resource value: 0x7f050000 + public const int blue_highlight = 2131034112; + + // aapt resource value: 0x7f050005 + public const int emphasis = 2131034117; + + // aapt resource value: 0x7f050006 + public const int emphasis2 = 2131034118; + + // aapt resource value: 0x7f050001 + public const int group = 2131034113; + + // aapt resource value: 0x7f050004 + public const int group_header_button_pressed = 2131034116; + + // aapt resource value: 0x7f050002 + public const int icon_background = 2131034114; + + // aapt resource value: 0x7f050003 + public const int icon_text = 2131034115; + + private Color() + { + } + } + + public partial class Drawable + { + + // aapt resource value: 0x7f020000 + public const int BlueButton = 2130837504; + + // aapt resource value: 0x7f020001 + public const int btn_new_group = 2130837505; + + // aapt resource value: 0x7f020002 + public const int btn_new_group_dark = 2130837506; + + // aapt resource value: 0x7f020003 + public const int device_access_new_account = 2130837507; + + // aapt resource value: 0x7f020004 + public const int device_access_new_account_dark = 2130837508; + + // aapt resource value: 0x7f020005 + public const int EntryFieldHeaderBackground = 2130837509; + + // aapt resource value: 0x7f020006 + public const int extra_string_header = 2130837510; + + // aapt resource value: 0x7f020007 + public const int GreenButton = 2130837511; + + // aapt resource value: 0x7f020008 + public const int HeaderButtonBackground = 2130837512; + + // aapt resource value: 0x7f020009 + public const int ic00 = 2130837513; + + // aapt resource value: 0x7f02000a + public const int ic01 = 2130837514; + + // aapt resource value: 0x7f02000b + public const int ic02 = 2130837515; + + // aapt resource value: 0x7f02000c + public const int ic03 = 2130837516; + + // aapt resource value: 0x7f02000d + public const int ic04 = 2130837517; + + // aapt resource value: 0x7f02000e + public const int ic05 = 2130837518; + + // aapt resource value: 0x7f02000f + public const int ic06 = 2130837519; + + // aapt resource value: 0x7f020010 + public const int ic07 = 2130837520; + + // aapt resource value: 0x7f020011 + public const int ic08 = 2130837521; + + // aapt resource value: 0x7f020012 + public const int ic09 = 2130837522; + + // aapt resource value: 0x7f020013 + public const int ic10 = 2130837523; + + // aapt resource value: 0x7f020014 + public const int ic11 = 2130837524; + + // aapt resource value: 0x7f020015 + public const int ic12 = 2130837525; + + // aapt resource value: 0x7f020016 + public const int ic13 = 2130837526; + + // aapt resource value: 0x7f020017 + public const int ic14 = 2130837527; + + // aapt resource value: 0x7f020018 + public const int ic15 = 2130837528; + + // aapt resource value: 0x7f020019 + public const int ic16 = 2130837529; + + // aapt resource value: 0x7f02001a + public const int ic17 = 2130837530; + + // aapt resource value: 0x7f02001b + public const int ic18 = 2130837531; + + // aapt resource value: 0x7f02001c + public const int ic19 = 2130837532; + + // aapt resource value: 0x7f02001d + public const int ic20 = 2130837533; + + // aapt resource value: 0x7f02001e + public const int ic21 = 2130837534; + + // aapt resource value: 0x7f02001f + public const int ic22 = 2130837535; + + // aapt resource value: 0x7f020020 + public const int ic23 = 2130837536; + + // aapt resource value: 0x7f020021 + public const int ic24 = 2130837537; + + // aapt resource value: 0x7f020022 + public const int ic25 = 2130837538; + + // aapt resource value: 0x7f020023 + public const int ic26 = 2130837539; + + // aapt resource value: 0x7f020024 + public const int ic27 = 2130837540; + + // aapt resource value: 0x7f020025 + public const int ic28 = 2130837541; + + // aapt resource value: 0x7f020026 + public const int ic29 = 2130837542; + + // aapt resource value: 0x7f020027 + public const int ic30 = 2130837543; + + // aapt resource value: 0x7f020028 + public const int ic31 = 2130837544; + + // aapt resource value: 0x7f020029 + public const int ic32 = 2130837545; + + // aapt resource value: 0x7f02002a + public const int ic33 = 2130837546; + + // aapt resource value: 0x7f02002b + public const int ic34 = 2130837547; + + // aapt resource value: 0x7f02002c + public const int ic35 = 2130837548; + + // aapt resource value: 0x7f02002d + public const int ic36 = 2130837549; + + // aapt resource value: 0x7f02002e + public const int ic37 = 2130837550; + + // aapt resource value: 0x7f02002f + public const int ic38 = 2130837551; + + // aapt resource value: 0x7f020030 + public const int ic39 = 2130837552; + + // aapt resource value: 0x7f020031 + public const int ic40 = 2130837553; + + // aapt resource value: 0x7f020032 + public const int ic41 = 2130837554; + + // aapt resource value: 0x7f020033 + public const int ic42 = 2130837555; + + // aapt resource value: 0x7f020034 + public const int ic43 = 2130837556; + + // aapt resource value: 0x7f020035 + public const int ic44 = 2130837557; + + // aapt resource value: 0x7f020036 + public const int ic45 = 2130837558; + + // aapt resource value: 0x7f020037 + public const int ic46 = 2130837559; + + // aapt resource value: 0x7f020038 + public const int ic47 = 2130837560; + + // aapt resource value: 0x7f020039 + public const int ic48 = 2130837561; + + // aapt resource value: 0x7f02003a + public const int ic49 = 2130837562; + + // aapt resource value: 0x7f02003b + public const int ic50 = 2130837563; + + // aapt resource value: 0x7f02003c + public const int ic51 = 2130837564; + + // aapt resource value: 0x7f02003d + public const int ic52 = 2130837565; + + // aapt resource value: 0x7f02003e + public const int ic53 = 2130837566; + + // aapt resource value: 0x7f02003f + public const int ic54 = 2130837567; + + // aapt resource value: 0x7f020040 + public const int ic55 = 2130837568; + + // aapt resource value: 0x7f020041 + public const int ic56 = 2130837569; + + // aapt resource value: 0x7f020042 + public const int ic57 = 2130837570; + + // aapt resource value: 0x7f020043 + public const int ic58 = 2130837571; + + // aapt resource value: 0x7f020044 + public const int ic59 = 2130837572; + + // aapt resource value: 0x7f020045 + public const int ic60 = 2130837573; + + // aapt resource value: 0x7f020046 + public const int ic61 = 2130837574; + + // aapt resource value: 0x7f020047 + public const int ic62 = 2130837575; + + // aapt resource value: 0x7f020048 + public const int ic63 = 2130837576; + + // aapt resource value: 0x7f020049 + public const int ic64 = 2130837577; + + // aapt resource value: 0x7f02004a + public const int ic65 = 2130837578; + + // aapt resource value: 0x7f02004b + public const int ic66 = 2130837579; + + // aapt resource value: 0x7f02004c + public const int ic67 = 2130837580; + + // aapt resource value: 0x7f02004d + public const int ic68 = 2130837581; + + // aapt resource value: 0x7f02004e + public const int ic99_blank = 2130837582; + + // aapt resource value: 0x7f02004f + public const int ic_action_eye_open = 2130837583; + + // aapt resource value: 0x7f020050 + public const int ic_action_search = 2130837584; + + // aapt resource value: 0x7f020051 + public const int ic_launcher = 2130837585; + + // aapt resource value: 0x7f020052 + public const int ic_launcher_folder_small = 2130837586; + + // aapt resource value: 0x7f020053 + public const int ic_launcher_gray = 2130837587; + + // aapt resource value: 0x7f020054 + public const int ic_menu_view = 2130837588; + + // aapt resource value: 0x7f020055 + public const int navigation_accept = 2130837589; + + // aapt resource value: 0x7f020056 + public const int navigation_accept_dark = 2130837590; + + // aapt resource value: 0x7f020057 + public const int navigation_previous_item = 2130837591; + + // aapt resource value: 0x7f020058 + public const int navigation_previous_item_dark = 2130837592; + + // aapt resource value: 0x7f020059 + public const int notify = 2130837593; + + // aapt resource value: 0x7f02005a + public const int RedButton = 2130837594; + + // aapt resource value: 0x7f02005b + public const int section_header = 2130837595; + + // aapt resource value: 0x7f02005c + public const int YellowButton = 2130837596; + + private Drawable() + { + } + } + + public partial class Id + { + + // aapt resource value: 0x7f0b000a + public const int Credit = 2131427338; + + // aapt resource value: 0x7f0b0070 + public const int IconGridView = 2131427440; + + // aapt resource value: 0x7f0b007d + public const int QuickUnlock_button = 2131427453; + + // aapt resource value: 0x7f0b007e + public const int QuickUnlock_buttonLock = 2131427454; + + // aapt resource value: 0x7f0b007b + public const int QuickUnlock_label = 2131427451; + + // aapt resource value: 0x7f0b007c + public const int QuickUnlock_password = 2131427452; + + // aapt resource value: 0x7f0b0054 + public const int RelativeLayout = 2131427412; + + // aapt resource value: 0x7f0b0053 + public const int ScrollView = 2131427411; + + // aapt resource value: 0x7f0b0009 + public const int about_button = 2131427337; + + // aapt resource value: 0x7f0b0000 + public const int about_title = 2131427328; + + // aapt resource value: 0x7f0b0051 + public const int accept_button = 2131427409; + + // aapt resource value: 0x7f0b0024 + public const int add_advanced = 2131427364; + + // aapt resource value: 0x7f0b0067 + public const int add_entry = 2131427431; + + // aapt resource value: 0x7f0b0066 + public const int add_group = 2131427430; + + // aapt resource value: 0x7f0b0023 + public const int advanced_container = 2131427363; + + // aapt resource value: 0x7f0b0026 + public const int binaries = 2131427366; + + // aapt resource value: 0x7f0b0036 + public const int bottom_bar = 2131427382; + + // aapt resource value: 0x7f0b0050 + public const int bottom_layout = 2131427408; + + // aapt resource value: 0x7f0b0048 + public const int browse_button = 2131427400; + + // aapt resource value: 0x7f0b0059 + public const int btn_length12 = 2131427417; + + // aapt resource value: 0x7f0b0058 + public const int btn_length16 = 2131427416; + + // aapt resource value: 0x7f0b005b + public const int btn_length6 = 2131427419; + + // aapt resource value: 0x7f0b005a + public const int btn_length8 = 2131427418; + + // aapt resource value: 0x7f0b000e + public const int cancel = 2131427342; + + // aapt resource value: 0x7f0b0052 + public const int cancel_button = 2131427410; + + // aapt resource value: 0x7f0b008e + public const int cbCaseSensitive = 2131427470; + + // aapt resource value: 0x7f0b008f + public const int cbExcludeExpiredEntries = 2131427471; + + // aapt resource value: 0x7f0b0084 + public const int cbRegEx = 2131427460; + + // aapt resource value: 0x7f0b008d + public const int cbSearchInGroupName = 2131427469; + + // aapt resource value: 0x7f0b008a + public const int cbSearchInNotes = 2131427466; + + // aapt resource value: 0x7f0b008b + public const int cbSearchInOtherStrings = 2131427467; + + // aapt resource value: 0x7f0b0089 + public const int cbSearchInPassword = 2131427465; + + // aapt resource value: 0x7f0b008c + public const int cbSearchInTags = 2131427468; + + // aapt resource value: 0x7f0b0086 + public const int cbSearchInTitle = 2131427462; + + // aapt resource value: 0x7f0b0087 + public const int cbSearchInUrl = 2131427463; + + // aapt resource value: 0x7f0b0088 + public const int cbSearchInUsername = 2131427464; + + // aapt resource value: 0x7f0b0064 + public const int cb_brackets = 2131427428; + + // aapt resource value: 0x7f0b005f + public const int cb_digits = 2131427423; + + // aapt resource value: 0x7f0b005e + public const int cb_lowercase = 2131427422; + + // aapt resource value: 0x7f0b0060 + public const int cb_minus = 2131427424; + + // aapt resource value: 0x7f0b0062 + public const int cb_space = 2131427426; + + // aapt resource value: 0x7f0b0063 + public const int cb_specials = 2131427427; + + // aapt resource value: 0x7f0b0061 + public const int cb_underline = 2131427425; + + // aapt resource value: 0x7f0b005d + public const int cb_uppercase = 2131427421; + + // aapt resource value: 0x7f0b004b + public const int create = 2131427403; + + // aapt resource value: 0x7f0b0094 + public const int cred_password = 2131427476; + + // aapt resource value: 0x7f0b0095 + public const int cred_remember_mode = 2131427477; + + // aapt resource value: 0x7f0b0093 + public const int cred_username = 2131427475; + + // aapt resource value: 0x7f0b0078 + public const int default_database = 2131427448; + + // aapt resource value: 0x7f0b0030 + public const int delete = 2131427376; + + // aapt resource value: 0x7f0b0008 + public const int disclaimer = 2131427336; + + // aapt resource value: 0x7f0b0001 + public const int divider1 = 2131427329; + + // aapt resource value: 0x7f0b0004 + public const int divider2 = 2131427332; + + // aapt resource value: 0x7f0b0007 + public const int divider3 = 2131427335; + + // aapt resource value: 0x7f0b0032 + public const int divider_comment = 2131427378; + + // aapt resource value: 0x7f0b0079 + public const int enable_quickunlock = 2131427449; + + // aapt resource value: 0x7f0b0041 + public const int entry_accessed = 2131427393; + + // aapt resource value: 0x7f0b0040 + public const int entry_accessed_label = 2131427392; + + // aapt resource value: 0x7f0b0025 + public const int entry_binaries_label = 2131427365; + + // aapt resource value: 0x7f0b0021 + public const int entry_comment = 2131427361; + + // aapt resource value: 0x7f0b0020 + public const int entry_comment_label = 2131427360; + + // aapt resource value: 0x7f0b001f + public const int entry_confpassword = 2131427359; + + // aapt resource value: 0x7f0b001e + public const int entry_confpassword_label = 2131427358; + + // aapt resource value: 0x7f0b0039 + public const int entry_contents = 2131427385; + + // aapt resource value: 0x7f0b003d + public const int entry_created = 2131427389; + + // aapt resource value: 0x7f0b003c + public const int entry_created_label = 2131427388; + + // aapt resource value: 0x7f0b0038 + public const int entry_divider2 = 2131427384; + + // aapt resource value: 0x7f0b0037 + public const int entry_edit = 2131427383; + + // aapt resource value: 0x7f0b002d + public const int entry_expires = 2131427373; + + // aapt resource value: 0x7f0b002c + public const int entry_expires_checkbox = 2131427372; + + // aapt resource value: 0x7f0b002b + public const int entry_expires_label = 2131427371; + + // aapt resource value: 0x7f0b0022 + public const int entry_extra_strings_label = 2131427362; + + // aapt resource value: 0x7f0b0033 + public const int entry_icon = 2131427379; + + // aapt resource value: 0x7f0b003f + public const int entry_modified = 2131427391; + + // aapt resource value: 0x7f0b003e + public const int entry_modified_label = 2131427390; + + // aapt resource value: 0x7f0b002a + public const int entry_override_url = 2131427370; + + // aapt resource value: 0x7f0b0029 + public const int entry_override_url_label = 2131427369; + + // aapt resource value: 0x7f0b001d + public const int entry_password = 2131427357; + + // aapt resource value: 0x7f0b001b + public const int entry_password_label = 2131427355; + + // aapt resource value: 0x7f0b0012 + public const int entry_save = 2131427346; + + // aapt resource value: 0x7f0b0011 + public const int entry_save_header = 2131427345; + + // aapt resource value: 0x7f0b0013 + public const int entry_scroll = 2131427347; + + // aapt resource value: 0x7f0b003a + public const int entry_table = 2131427386; + + // aapt resource value: 0x7f0b0028 + public const int entry_tags = 2131427368; + + // aapt resource value: 0x7f0b0027 + public const int entry_tags_label = 2131427367; + + // aapt resource value: 0x7f0b0034 + public const int entry_text = 2131427380; + + // aapt resource value: 0x7f0b0016 + public const int entry_title = 2131427350; + + // aapt resource value: 0x7f0b0014 + public const int entry_title_label = 2131427348; + + // aapt resource value: 0x7f0b001a + public const int entry_url = 2131427354; + + // aapt resource value: 0x7f0b0019 + public const int entry_url_label = 2131427353; + + // aapt resource value: 0x7f0b0018 + public const int entry_user_name = 2131427352; + + // aapt resource value: 0x7f0b0017 + public const int entry_user_name_label = 2131427351; + + // aapt resource value: 0x7f0b003b + public const int extra_strings = 2131427387; + + // aapt resource value: 0x7f0b0006 + public const int feedback = 2131427334; + + // aapt resource value: 0x7f0b0042 + public const int file_filename = 2131427394; + + // aapt resource value: 0x7f0b0043 + public const int file_listtop = 2131427395; + + // aapt resource value: 0x7f0b0044 + public const int file_select = 2131427396; + + // aapt resource value: 0x7f0b0073 + public const int filename = 2131427443; + + // aapt resource value: 0x7f0b0045 + public const int filename_form = 2131427397; + + // aapt resource value: 0x7f0b0071 + public const int filename_label = 2131427441; + + // aapt resource value: 0x7f0b0072 + public const int filenamescroll = 2131427442; + + // aapt resource value: 0x7f0b004c + public const int fnv_cancel = 2131427404; + + // aapt resource value: 0x7f0b001c + public const int generate_button = 2131427356; + + // aapt resource value: 0x7f0b0056 + public const int generate_password_button = 2131427414; + + // aapt resource value: 0x7f0b0065 + public const int group_header = 2131427429; + + // aapt resource value: 0x7f0b006b + public const int group_icon = 2131427435; + + // aapt resource value: 0x7f0b006d + public const int group_label = 2131427437; + + // aapt resource value: 0x7f0b0068 + public const int group_name = 2131427432; + + // aapt resource value: 0x7f0b006c + public const int group_text = 2131427436; + + // aapt resource value: 0x7f0b0005 + public const int homepage = 2131427333; + + // aapt resource value: 0x7f0b006a + public const int icon = 2131427434; + + // aapt resource value: 0x7f0b0015 + public const int icon_button = 2131427349; + + // aapt resource value: 0x7f0b006e + public const int icon_image = 2131427438; + + // aapt resource value: 0x7f0b006f + public const int icon_text = 2131427439; + + // aapt resource value: 0x7f0b000c + public const int install_market = 2131427340; + + // aapt resource value: 0x7f0b000d + public const int install_web = 2131427341; + + // aapt resource value: 0x7f0b0047 + public const int label_open_by_filename = 2131427399; + + // aapt resource value: 0x7f0b0049 + public const int label_open_by_filename_details = 2131427401; + + // aapt resource value: 0x7f0b0046 + public const int label_warning = 2131427398; + + // aapt resource value: 0x7f0b005c + public const int length = 2131427420; + + // aapt resource value: 0x7f0b0057 + public const int length_label = 2131427415; + + // aapt resource value: 0x7f0b0083 + public const int linearLayout1 = 2131427459; + + // aapt resource value: 0x7f0b009b + public const int menu_about = 2131427483; + + // aapt resource value: 0x7f0b009a + public const int menu_app_settings = 2131427482; + + // aapt resource value: 0x7f0b0099 + public const int menu_cancel_edit = 2131427481; + + // aapt resource value: 0x7f0b009d + public const int menu_change_master_key = 2131427485; + + // aapt resource value: 0x7f0b0097 + public const int menu_goto_url = 2131427479; + + // aapt resource value: 0x7f0b0098 + public const int menu_lock = 2131427480; + + // aapt resource value: 0x7f0b009c + public const int menu_search = 2131427484; + + // aapt resource value: 0x7f0b009e + public const int menu_sort = 2131427486; + + // aapt resource value: 0x7f0b0096 + public const int menu_toggle_pass = 2131427478; + + // aapt resource value: 0x7f0b0069 + public const int ok = 2131427433; + + // aapt resource value: 0x7f0b004a + public const int open = 2131427402; + + // aapt resource value: 0x7f0b0091 + public const int pass_conf_password = 2131427473; + + // aapt resource value: 0x7f0b0076 + public const int pass_keyfile = 2131427446; + + // aapt resource value: 0x7f0b0077 + public const int pass_ok = 2131427447; + + // aapt resource value: 0x7f0b0090 + public const int pass_password = 2131427472; + + // aapt resource value: 0x7f0b0055 + public const int password = 2131427413; + + // aapt resource value: 0x7f0b0074 + public const int password_label = 2131427444; + + // aapt resource value: 0x7f0b002f + public const int protection = 2131427375; + + // aapt resource value: 0x7f0b007a + public const int qu_filename = 2131427450; + + // aapt resource value: 0x7f0b000f + public const int rounds = 2131427343; + + // aapt resource value: 0x7f0b0010 + public const int rounds_explaination = 2131427344; + + // aapt resource value: 0x7f0b0082 + public const int scrollView1 = 2131427458; + + // aapt resource value: 0x7f0b0081 + public const int searchEditText = 2131427457; + + // aapt resource value: 0x7f0b0080 + public const int search_button = 2131427456; + + // aapt resource value: 0x7f0b0085 + public const int search_in_label = 2131427461; + + // aapt resource value: 0x7f0b007f + public const int search_label = 2131427455; + + // aapt resource value: 0x7f0b004f + public const int start_create = 2131427407; + + // aapt resource value: 0x7f0b0092 + public const int start_create_import = 2131427474; + + // aapt resource value: 0x7f0b004d + public const int start_open_file = 2131427405; + + // aapt resource value: 0x7f0b004e + public const int start_open_url = 2131427406; + + // aapt resource value: 0x7f0b000b + public const int text = 2131427339; + + // aapt resource value: 0x7f0b002e + public const int title = 2131427374; + + // aapt resource value: 0x7f0b0035 + public const int title_block = 2131427381; + + // aapt resource value: 0x7f0b0075 + public const int toggle_password = 2131427445; + + // aapt resource value: 0x7f0b0031 + public const int value = 2131427377; + + // aapt resource value: 0x7f0b0003 + public const int version = 2131427331; + + // aapt resource value: 0x7f0b0002 + public const int version_title = 2131427330; + + private Id() + { + } + } + + public partial class Layout + { + + // aapt resource value: 0x7f030000 + public const int about = 2130903040; + + // aapt resource value: 0x7f030001 + public const int browser_install = 2130903041; + + // aapt resource value: 0x7f030002 + public const int database_settings = 2130903042; + + // aapt resource value: 0x7f030003 + public const int entry_edit = 2130903043; + + // aapt resource value: 0x7f030004 + public const int entry_edit_section = 2130903044; + + // aapt resource value: 0x7f030005 + public const int entry_list_entry = 2130903045; + + // aapt resource value: 0x7f030006 + public const int entry_section = 2130903046; + + // aapt resource value: 0x7f030007 + public const int entry_view = 2130903047; + + // aapt resource value: 0x7f030008 + public const int entry_view_contents = 2130903048; + + // aapt resource value: 0x7f030009 + public const int file_row = 2130903049; + + // aapt resource value: 0x7f03000a + public const int file_selection = 2130903050; + + // aapt resource value: 0x7f03000b + public const int file_selection_filename = 2130903051; + + // aapt resource value: 0x7f03000c + public const int file_selection_no_recent = 2130903052; + + // aapt resource value: 0x7f03000d + public const int generate_password = 2130903053; + + // aapt resource value: 0x7f03000e + public const int group_add_entry = 2130903054; + + // aapt resource value: 0x7f03000f + public const int group_edit = 2130903055; + + // aapt resource value: 0x7f030010 + public const int group_empty = 2130903056; + + // aapt resource value: 0x7f030011 + public const int group_header = 2130903057; + + // aapt resource value: 0x7f030012 + public const int group_list_entry = 2130903058; + + // aapt resource value: 0x7f030013 + public const int icon = 2130903059; + + // aapt resource value: 0x7f030014 + public const int icon_picker = 2130903060; + + // aapt resource value: 0x7f030015 + public const int password = 2130903061; + + // aapt resource value: 0x7f030016 + public const int QuickUnlock = 2130903062; + + // aapt resource value: 0x7f030017 + public const int search = 2130903063; + + // aapt resource value: 0x7f030018 + public const int set_password = 2130903064; + + // aapt resource value: 0x7f030019 + public const int StartScreenButtons = 2130903065; + + // aapt resource value: 0x7f03001a + public const int url_credentials = 2130903066; + + private Layout() + { + } + } + + public partial class Menu + { + + // aapt resource value: 0x7f0a0000 + public const int entry = 2131361792; + + // aapt resource value: 0x7f0a0001 + public const int entry_edit = 2131361793; + + // aapt resource value: 0x7f0a0002 + public const int fileselect = 2131361794; + + // aapt resource value: 0x7f0a0003 + public const int group = 2131361795; + + // aapt resource value: 0x7f0a0004 + public const int password = 2131361796; + + private Menu() + { + } + } + + public partial class String + { + + // aapt resource value: 0x7f06001e + public const int AboutText = 2131099678; + + // aapt resource value: 0x7f0600e7 + public const int AskOverwriteBinary = 2131099879; + + // aapt resource value: 0x7f0600ea + public const int AskOverwriteBinary_no = 2131099882; + + // aapt resource value: 0x7f0600e8 + public const int AskOverwriteBinary_title = 2131099880; + + // aapt resource value: 0x7f0600e9 + public const int AskOverwriteBinary_yes = 2131099881; + + // aapt resource value: 0x7f0600eb + public const int AttachFailed = 2131099883; + + // aapt resource value: 0x7f060016 + public const int BinaryDirectory_default = 2131099670; + + // aapt resource value: 0x7f060015 + public const int BinaryDirectory_key = 2131099669; + + // aapt resource value: 0x7f0600d9 + public const int BinaryDirectory_summary = 2131099865; + + // aapt resource value: 0x7f0600d8 + public const int BinaryDirectory_title = 2131099864; + + // aapt resource value: 0x7f060031 + public const int ClearClipboard = 2131099697; + + // aapt resource value: 0x7f06001f + public const int CreditsText = 2131099679; + + // aapt resource value: 0x7f060067 + public const int FileNotFound = 2131099751; + + // aapt resource value: 0x7f06007a + public const int InvalidPassword = 2131099770; + + // aapt resource value: 0x7f060084 + public const int MaskedPassword = 2131099780; + + // aapt resource value: 0x7f060017 + public const int QuickUnlockDefaultEnabled_key = 2131099671; + + // aapt resource value: 0x7f0600d3 + public const int QuickUnlockDefaultEnabled_summary = 2131099859; + + // aapt resource value: 0x7f0600d2 + public const int QuickUnlockDefaultEnabled_title = 2131099858; + + // aapt resource value: 0x7f0600d7 + public const int QuickUnlockLength_default = 2131099863; + + // aapt resource value: 0x7f060018 + public const int QuickUnlockLength_key = 2131099672; + + // aapt resource value: 0x7f0600d5 + public const int QuickUnlockLength_summary = 2131099861; + + // aapt resource value: 0x7f0600d4 + public const int QuickUnlockLength_title = 2131099860; + + // aapt resource value: 0x7f0600d0 + public const int QuickUnlock_button = 2131099856; + + // aapt resource value: 0x7f0600d6 + public const int QuickUnlock_fail = 2131099862; + + // aapt resource value: 0x7f0600cf + public const int QuickUnlock_label = 2131099855; + + // aapt resource value: 0x7f0600d1 + public const int QuickUnlock_lockButton = 2131099857; + + // aapt resource value: 0x7f0600ec + public const int RecycleBin = 2131099884; + + // aapt resource value: 0x7f0600db + public const int SaveAttachment_Failed = 2131099867; + + // aapt resource value: 0x7f0600da + public const int SaveAttachment_doneMessage = 2131099866; + + // aapt resource value: 0x7f060013 + public const int TanExpiresOnUse_key = 2131099667; + + // aapt resource value: 0x7f0600c1 + public const int TanExpiresOnUse_summary = 2131099841; + + // aapt resource value: 0x7f0600c0 + public const int TanExpiresOnUse_title = 2131099840; + + // aapt resource value: 0x7f060019 + public const int UseFileTransactions_key = 2131099673; + + // aapt resource value: 0x7f0600e6 + public const int UseFileTransactions_summary = 2131099878; + + // aapt resource value: 0x7f0600e5 + public const int UseFileTransactions_title = 2131099877; + + // aapt resource value: 0x7f06001c + public const int about_feedback = 2131099676; + + // aapt resource value: 0x7f06001d + public const int about_homepage = 2131099677; + + // aapt resource value: 0x7f0600ed + public const int about_twitter = 2131099885; + + // aapt resource value: 0x7f060020 + public const int accept = 2131099680; + + // aapt resource value: 0x7f0600e1 + public const int add_binary = 2131099873; + + // aapt resource value: 0x7f060021 + public const int add_entry = 2131099681; + + // aapt resource value: 0x7f0600e2 + public const int add_extra_string = 2131099874; + + // aapt resource value: 0x7f060022 + public const int add_group = 2131099682; + + // aapt resource value: 0x7f060023 + public const int add_group_title = 2131099683; + + // aapt resource value: 0x7f060024 + public const int algorithm = 2131099684; + + // aapt resource value: 0x7f060025 + public const int algorithm_colon = 2131099685; + + // aapt resource value: 0x7f060007 + public const int algorithm_key = 2131099655; + + // aapt resource value: 0x7f060008 + public const int app_key = 2131099656; + + // aapt resource value: 0x7f060026 + public const int app_name = 2131099686; + + // aapt resource value: 0x7f060029 + public const int app_timeout = 2131099689; + + // aapt resource value: 0x7f060009 + public const int app_timeout_key = 2131099657; + + // aapt resource value: 0x7f06002a + public const int app_timeout_summary = 2131099690; + + // aapt resource value: 0x7f06002b + public const int application = 2131099691; + + // aapt resource value: 0x7f06002c + public const int application_settings = 2131099692; + + // aapt resource value: 0x7f06002d + public const int brackets = 2131099693; + + // aapt resource value: 0x7f06002e + public const int browser_intall_text = 2131099694; + + // aapt resource value: 0x7f06002f + public const int building_search_idx = 2131099695; + + // aapt resource value: 0x7f060030 + public const int cancel = 2131099696; + + // aapt resource value: 0x7f0600c5 + public const int caseSensitive = 2131099845; + + // aapt resource value: 0x7f060032 + public const int clipboard_timeout = 2131099698; + + // aapt resource value: 0x7f06001a + public const int clipboard_timeout_default = 2131099674; + + // aapt resource value: 0x7f06000a + public const int clipboard_timeout_key = 2131099658; + + // aapt resource value: 0x7f060033 + public const int clipboard_timeout_summary = 2131099699; + + // aapt resource value: 0x7f060035 + public const int copy_password = 2131099701; + + // aapt resource value: 0x7f060034 + public const int copy_username = 2131099700; + + // aapt resource value: 0x7f060036 + public const int creating_db_key = 2131099702; + + // aapt resource value: 0x7f0600e4 + public const int credentials_dialog_title = 2131099876; + + // aapt resource value: 0x7f060037 + public const int current_group = 2131099703; + + // aapt resource value: 0x7f060038 + public const int current_group_root = 2131099704; + + // aapt resource value: 0x7f060039 + public const int database = 2131099705; + + // aapt resource value: 0x7f0600e3 + public const int database_loaded_quickunlock_enabled = 2131099875; + + // aapt resource value: 0x7f06000b + public const int db_key = 2131099659; + + // aapt resource value: 0x7f06003a + public const int decrypting_db = 2131099706; + + // aapt resource value: 0x7f06003b + public const int decrypting_entry = 2131099707; + + // aapt resource value: 0x7f06003c + public const int default_checkbox = 2131099708; + + // aapt resource value: 0x7f060000 + public const int default_file_path = 2131099648; + + // aapt resource value: 0x7f0600ac + public const int default_username = 2131099820; + + // aapt resource value: 0x7f060014 + public const int default_username_key = 2131099668; + + // aapt resource value: 0x7f0600ad + public const int default_username_summary = 2131099821; + + // aapt resource value: 0x7f06003d + public const int digits = 2131099709; + + // aapt resource value: 0x7f06003e + public const int disclaimer_formal = 2131099710; + + // aapt resource value: 0x7f060001 + public const int donate_url = 2131099649; + + // aapt resource value: 0x7f06003f + public const int ellipsis = 2131099711; + + // aapt resource value: 0x7f0600ce + public const int enable_quickunlock = 2131099854; + + // aapt resource value: 0x7f060040 + public const int enter_filename = 2131099712; + + // aapt resource value: 0x7f0600cc + public const int enter_filename_details_create = 2131099852; + + // aapt resource value: 0x7f0600cd + public const int enter_filename_details_create_import = 2131099853; + + // aapt resource value: 0x7f0600ca + public const int enter_filename_details_file = 2131099850; + + // aapt resource value: 0x7f0600cb + public const int enter_filename_details_url = 2131099851; + + // aapt resource value: 0x7f060041 + public const int entry_accessed = 2131099713; + + // aapt resource value: 0x7f060042 + public const int entry_and_or = 2131099714; + + // aapt resource value: 0x7f060052 + public const int entry_binaries = 2131099730; + + // aapt resource value: 0x7f060043 + public const int entry_cancel = 2131099715; + + // aapt resource value: 0x7f060044 + public const int entry_comment = 2131099716; + + // aapt resource value: 0x7f060047 + public const int entry_confpassword = 2131099719; + + // aapt resource value: 0x7f060048 + public const int entry_created = 2131099720; + + // aapt resource value: 0x7f060049 + public const int entry_expires = 2131099721; + + // aapt resource value: 0x7f060051 + public const int entry_extra_strings = 2131099729; + + // aapt resource value: 0x7f06004a + public const int entry_keyfile = 2131099722; + + // aapt resource value: 0x7f06004b + public const int entry_modified = 2131099723; + + // aapt resource value: 0x7f060046 + public const int entry_override_url = 2131099718; + + // aapt resource value: 0x7f06004c + public const int entry_password = 2131099724; + + // aapt resource value: 0x7f06004d + public const int entry_save = 2131099725; + + // aapt resource value: 0x7f060045 + public const int entry_tags = 2131099717; + + // aapt resource value: 0x7f06004e + public const int entry_title = 2131099726; + + // aapt resource value: 0x7f06004f + public const int entry_url = 2131099727; + + // aapt resource value: 0x7f060050 + public const int entry_user_name = 2131099728; + + // aapt resource value: 0x7f060053 + public const int error_arc4 = 2131099731; + + // aapt resource value: 0x7f060054 + public const int error_can_not_handle_uri = 2131099732; + + // aapt resource value: 0x7f060055 + public const int error_could_not_create_group = 2131099733; + + // aapt resource value: 0x7f060056 + public const int error_could_not_create_parent = 2131099734; + + // aapt resource value: 0x7f060057 + public const int error_database_exists = 2131099735; + + // aapt resource value: 0x7f060058 + public const int error_database_settings = 2131099736; + + // aapt resource value: 0x7f060059 + public const int error_failed_to_launch_link = 2131099737; + + // aapt resource value: 0x7f06005b + public const int error_file_not_create = 2131099739; + + // aapt resource value: 0x7f06005a + public const int error_filename_required = 2131099738; + + // aapt resource value: 0x7f06005c + public const int error_invalid_db = 2131099740; + + // aapt resource value: 0x7f0600dc + public const int error_invalid_expiry_date = 2131099868; + + // aapt resource value: 0x7f06005d + public const int error_invalid_path = 2131099741; + + // aapt resource value: 0x7f06005e + public const int error_no_name = 2131099742; + + // aapt resource value: 0x7f06005f + public const int error_nopass = 2131099743; + + // aapt resource value: 0x7f060060 + public const int error_out_of_memory = 2131099744; + + // aapt resource value: 0x7f060061 + public const int error_pass_gen_type = 2131099745; + + // aapt resource value: 0x7f060062 + public const int error_pass_match = 2131099746; + + // aapt resource value: 0x7f060063 + public const int error_rounds_not_number = 2131099747; + + // aapt resource value: 0x7f060064 + public const int error_rounds_too_large = 2131099748; + + // aapt resource value: 0x7f0600dd + public const int error_string_key = 2131099869; + + // aapt resource value: 0x7f060065 + public const int error_title_required = 2131099749; + + // aapt resource value: 0x7f060066 + public const int error_wrong_length = 2131099750; + + // aapt resource value: 0x7f0600c3 + public const int excludeExpiredEntries = 2131099843; + + // aapt resource value: 0x7f0600de + public const int field_name = 2131099870; + + // aapt resource value: 0x7f0600df + public const int field_value = 2131099871; + + // aapt resource value: 0x7f060068 + public const int file_browser = 2131099752; + + // aapt resource value: 0x7f060069 + public const int generate_password = 2131099753; + + // aapt resource value: 0x7f06006a + public const int group = 2131099754; + + // aapt resource value: 0x7f06006b + public const int hint_comment = 2131099755; + + // aapt resource value: 0x7f06006c + public const int hint_conf_pass = 2131099756; + + // aapt resource value: 0x7f06006d + public const int hint_generated_password = 2131099757; + + // aapt resource value: 0x7f06006e + public const int hint_group_name = 2131099758; + + // aapt resource value: 0x7f06006f + public const int hint_keyfile = 2131099759; + + // aapt resource value: 0x7f060070 + public const int hint_length = 2131099760; + + // aapt resource value: 0x7f060072 + public const int hint_login_pass = 2131099762; + + // aapt resource value: 0x7f060075 + public const int hint_override_url = 2131099765; + + // aapt resource value: 0x7f060071 + public const int hint_pass = 2131099761; + + // aapt resource value: 0x7f060076 + public const int hint_tags = 2131099766; + + // aapt resource value: 0x7f060073 + public const int hint_title = 2131099763; + + // aapt resource value: 0x7f060074 + public const int hint_url = 2131099764; + + // aapt resource value: 0x7f060077 + public const int hint_username = 2131099767; + + // aapt resource value: 0x7f060002 + public const int homepage = 2131099650; + + // aapt resource value: 0x7f060003 + public const int homepage_short = 2131099651; + + // aapt resource value: 0x7f060078 + public const int install_from_market = 2131099768; + + // aapt resource value: 0x7f060079 + public const int install_from_website = 2131099769; + + // aapt resource value: 0x7f06007b + public const int invalid_algorithm = 2131099771; + + // aapt resource value: 0x7f06007c + public const int invalid_db_sig = 2131099772; + + // aapt resource value: 0x7f060004 + public const int issues = 2131099652; + + // aapt resource value: 0x7f06007d + public const int keyfile_does_not_exist = 2131099773; + + // aapt resource value: 0x7f06007e + public const int keyfile_is_empty = 2131099774; + + // aapt resource value: 0x7f06000d + public const int keyfile_key = 2131099661; + + // aapt resource value: 0x7f0600c2 + public const int kp2a_findUrl = 2131099842; + + // aapt resource value: 0x7f06007f + public const int length = 2131099775; + + // aapt resource value: 0x7f060028 + public const int library_name = 2131099688; + + // aapt resource value: 0x7f06001b + public const int list_size_default = 2131099675; + + // aapt resource value: 0x7f060010 + public const int list_size_key = 2131099664; + + // aapt resource value: 0x7f060081 + public const int list_size_summary = 2131099777; + + // aapt resource value: 0x7f060080 + public const int list_size_title = 2131099776; + + // aapt resource value: 0x7f060082 + public const int loading_database = 2131099778; + + // aapt resource value: 0x7f060083 + public const int lowercase = 2131099779; + + // aapt resource value: 0x7f06000e + public const int maskpass_key = 2131099662; + + // aapt resource value: 0x7f060086 + public const int maskpass_summary = 2131099782; + + // aapt resource value: 0x7f060085 + public const int maskpass_title = 2131099781; + + // aapt resource value: 0x7f060087 + public const int menu_about = 2131099783; + + // aapt resource value: 0x7f06008c + public const int menu_app_settings = 2131099788; + + // aapt resource value: 0x7f060088 + public const int menu_change_key = 2131099784; + + // aapt resource value: 0x7f060089 + public const int menu_copy_pass = 2131099785; + + // aapt resource value: 0x7f06008a + public const int menu_copy_user = 2131099786; + + // aapt resource value: 0x7f06008b + public const int menu_create = 2131099787; + + // aapt resource value: 0x7f06008d + public const int menu_db_settings = 2131099789; + + // aapt resource value: 0x7f06008e + public const int menu_delete = 2131099790; + + // aapt resource value: 0x7f06008f + public const int menu_donate = 2131099791; + + // aapt resource value: 0x7f060090 + public const int menu_edit = 2131099792; + + // aapt resource value: 0x7f060091 + public const int menu_hide_password = 2131099793; + + // aapt resource value: 0x7f060092 + public const int menu_homepage = 2131099794; + + // aapt resource value: 0x7f060093 + public const int menu_lock = 2131099795; + + // aapt resource value: 0x7f060094 + public const int menu_open = 2131099796; + + // aapt resource value: 0x7f060095 + public const int menu_rename = 2131099797; + + // aapt resource value: 0x7f060096 + public const int menu_search = 2131099798; + + // aapt resource value: 0x7f060097 + public const int menu_url = 2131099799; + + // aapt resource value: 0x7f060098 + public const int minus = 2131099800; + + // aapt resource value: 0x7f060099 + public const int never = 2131099801; + + // aapt resource value: 0x7f06009a + public const int no_keys = 2131099802; + + // aapt resource value: 0x7f06009b + public const int no_results = 2131099803; + + // aapt resource value: 0x7f06009c + public const int no_url_handler = 2131099804; + + // aapt resource value: 0x7f060005 + public const int oi_filemanager_market = 2131099653; + + // aapt resource value: 0x7f060006 + public const int oi_filemanager_web = 2131099654; + + // aapt resource value: 0x7f06000f + public const int omitbackup_key = 2131099663; + + // aapt resource value: 0x7f06009f + public const int omitbackup_summary = 2131099807; + + // aapt resource value: 0x7f06009e + public const int omitbackup_title = 2131099806; + + // aapt resource value: 0x7f06009d + public const int open_recent = 2131099805; + + // aapt resource value: 0x7f0600a0 + public const int pass_filename = 2131099808; + + // aapt resource value: 0x7f0600a1 + public const int password_title = 2131099809; + + // aapt resource value: 0x7f0600a2 + public const int progress_create = 2131099810; + + // aapt resource value: 0x7f0600a3 + public const int progress_title = 2131099811; + + // aapt resource value: 0x7f0600e0 + public const int protection = 2131099872; + + // aapt resource value: 0x7f0600bf + public const int regular_expression = 2131099839; + + // aapt resource value: 0x7f0600a4 + public const int remember_keyfile_summary = 2131099812; + + // aapt resource value: 0x7f0600a5 + public const int remember_keyfile_title = 2131099813; + + // aapt resource value: 0x7f0600a6 + public const int remove_from_filelist = 2131099814; + + // aapt resource value: 0x7f0600a7 + public const int rijndael = 2131099815; + + // aapt resource value: 0x7f0600a8 + public const int root = 2131099816; + + // aapt resource value: 0x7f0600a9 + public const int rounds = 2131099817; + + // aapt resource value: 0x7f0600aa + public const int rounds_explaination = 2131099818; + + // aapt resource value: 0x7f0600ab + public const int rounds_hint = 2131099819; + + // aapt resource value: 0x7f06000c + public const int rounds_key = 2131099660; + + // aapt resource value: 0x7f0600ae + public const int saving_database = 2131099822; + + // aapt resource value: 0x7f0600b5 + public const int search_hint = 2131099829; + + // aapt resource value: 0x7f0600b7 + public const int search_in = 2131099831; + + // aapt resource value: 0x7f0600b0 + public const int search_label = 2131099824; + + // aapt resource value: 0x7f0600c4 + public const int search_options = 2131099844; + + // aapt resource value: 0x7f0600b6 + public const int search_results = 2131099830; + + // aapt resource value: 0x7f060027 + public const int short_app_name = 2131099687; + + // aapt resource value: 0x7f0600b1 + public const int show_password = 2131099825; + + // aapt resource value: 0x7f0600b3 + public const int sort_db = 2131099827; + + // aapt resource value: 0x7f060011 + public const int sort_key = 2131099665; + + // aapt resource value: 0x7f0600b2 + public const int sort_name = 2131099826; + + // aapt resource value: 0x7f0600af + public const int space = 2131099823; + + // aapt resource value: 0x7f0600b4 + public const int special = 2131099828; + + // aapt resource value: 0x7f0600c7 + public const int start_create = 2131099847; + + // aapt resource value: 0x7f0600c9 + public const int start_create_import = 2131099849; + + // aapt resource value: 0x7f0600c6 + public const int start_open_file = 2131099846; + + // aapt resource value: 0x7f0600c8 + public const int start_open_url = 2131099848; + + // aapt resource value: 0x7f060012 + public const int timeout_key = 2131099666; + + // aapt resource value: 0x7f0600b8 + public const int twofish = 2131099832; + + // aapt resource value: 0x7f0600b9 + public const int underline = 2131099833; + + // aapt resource value: 0x7f0600ba + public const int unsupported_db_version = 2131099834; + + // aapt resource value: 0x7f0600bb + public const int uppercase = 2131099835; + + // aapt resource value: 0x7f0600be + public const int version_label = 2131099838; + + // aapt resource value: 0x7f0600bc + public const int warning_read_only = 2131099836; + + // aapt resource value: 0x7f0600bd + public const int warning_unmounted = 2131099837; + + private String() + { + } + } + + public partial class Style + { + + // aapt resource value: 0x7f090011 + public const int Base = 2131296273; + + // aapt resource value: 0x7f090001 + public const int Dialog = 2131296257; + + // aapt resource value: 0x7f090006 + public const int ElementText = 2131296262; + + // aapt resource value: 0x7f090007 + public const int ElementTextLarge = 2131296263; + + // aapt resource value: 0x7f090005 + public const int ElementTextSmall = 2131296261; + + // aapt resource value: 0x7f09000e + public const int ElementTextTitle = 2131296270; + + // aapt resource value: 0x7f09000d + public const int EntryFieldHeader = 2131296269; + + // aapt resource value: 0x7f09000f + public const int EntryItem = 2131296271; + + // aapt resource value: 0x7f090010 + public const int ExtraFieldHeader = 2131296272; + + // aapt resource value: 0x7f09000a + public const int GroupAndEntryHeader = 2131296266; + + // aapt resource value: 0x7f090008 + public const int GroupLabel = 2131296264; + + // aapt resource value: 0x7f090003 + public const int GroupText = 2131296259; + + // aapt resource value: 0x7f090004 + public const int GroupTextLarge = 2131296260; + + // aapt resource value: 0x7f090002 + public const int GroupTextSmall = 2131296258; + + // aapt resource value: 0x7f090000 + public const int NoTitleBar = 2131296256; + + // aapt resource value: 0x7f090009 + public const int WhiteOnBlack = 2131296265; + + // aapt resource value: 0x7f09000b + public const int WhiteOnBlackSmall = 2131296267; + + // aapt resource value: 0x7f09000c + public const int WhiteOnDarkSmall = 2131296268; + + private Style() + { + } + } + + public partial class Xml + { + + // aapt resource value: 0x7f040000 + public const int preferences = 2130968576; + + // aapt resource value: 0x7f040001 + public const int searchable = 2130968577; + + private Xml() + { + } + } + } +} +#pragma warning restore 1591 diff --git a/src/keepass2android/Resources/drawable-hdpi/2_action_about.png b/src/keepass2android/Resources/drawable-hdpi/2_action_about.png new file mode 100644 index 00000000..8f39c428 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/2_action_about.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic00.png b/src/keepass2android/Resources/drawable-hdpi/ic00.png new file mode 100644 index 00000000..98d7607e Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic00.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic01.png b/src/keepass2android/Resources/drawable-hdpi/ic01.png new file mode 100644 index 00000000..b5f28c47 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic01.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic02.png b/src/keepass2android/Resources/drawable-hdpi/ic02.png new file mode 100644 index 00000000..b11a7b6a Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic02.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic03.png b/src/keepass2android/Resources/drawable-hdpi/ic03.png new file mode 100644 index 00000000..eb337b41 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic03.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic04.png b/src/keepass2android/Resources/drawable-hdpi/ic04.png new file mode 100644 index 00000000..ea9c78ed Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic04.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic05.png b/src/keepass2android/Resources/drawable-hdpi/ic05.png new file mode 100644 index 00000000..5eae5128 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic05.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic06.png b/src/keepass2android/Resources/drawable-hdpi/ic06.png new file mode 100644 index 00000000..ed1c867f Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic06.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic07.png b/src/keepass2android/Resources/drawable-hdpi/ic07.png new file mode 100644 index 00000000..36459cf4 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic07.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic08.png b/src/keepass2android/Resources/drawable-hdpi/ic08.png new file mode 100644 index 00000000..1bacbaae Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic08.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic09.png b/src/keepass2android/Resources/drawable-hdpi/ic09.png new file mode 100644 index 00000000..e21451fc Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic09.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic10.png b/src/keepass2android/Resources/drawable-hdpi/ic10.png new file mode 100644 index 00000000..75619bce Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic10.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic11.png b/src/keepass2android/Resources/drawable-hdpi/ic11.png new file mode 100644 index 00000000..68046fae Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic11.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic12.png b/src/keepass2android/Resources/drawable-hdpi/ic12.png new file mode 100644 index 00000000..67d7f50f Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic12.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic13.png b/src/keepass2android/Resources/drawable-hdpi/ic13.png new file mode 100644 index 00000000..99b3b7fc Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic13.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic14.png b/src/keepass2android/Resources/drawable-hdpi/ic14.png new file mode 100644 index 00000000..4a378789 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic14.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic15.png b/src/keepass2android/Resources/drawable-hdpi/ic15.png new file mode 100644 index 00000000..71aed183 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic15.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic16.png b/src/keepass2android/Resources/drawable-hdpi/ic16.png new file mode 100644 index 00000000..1fae5e7c Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic16.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic17.png b/src/keepass2android/Resources/drawable-hdpi/ic17.png new file mode 100644 index 00000000..1b0a5033 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic17.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic18.png b/src/keepass2android/Resources/drawable-hdpi/ic18.png new file mode 100644 index 00000000..6b9ab9e1 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic18.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic19.png b/src/keepass2android/Resources/drawable-hdpi/ic19.png new file mode 100644 index 00000000..79699c82 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic19.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic20.png b/src/keepass2android/Resources/drawable-hdpi/ic20.png new file mode 100644 index 00000000..0c17cd9a Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic20.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic21.png b/src/keepass2android/Resources/drawable-hdpi/ic21.png new file mode 100644 index 00000000..3aa37ad2 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic21.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic22.png b/src/keepass2android/Resources/drawable-hdpi/ic22.png new file mode 100644 index 00000000..884c362c Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic22.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic23.png b/src/keepass2android/Resources/drawable-hdpi/ic23.png new file mode 100644 index 00000000..ba4744f9 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic23.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic24.png b/src/keepass2android/Resources/drawable-hdpi/ic24.png new file mode 100644 index 00000000..4a2de8c7 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic24.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic25.png b/src/keepass2android/Resources/drawable-hdpi/ic25.png new file mode 100644 index 00000000..23365a12 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic25.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic26.png b/src/keepass2android/Resources/drawable-hdpi/ic26.png new file mode 100644 index 00000000..caee87ba Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic26.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic27.png b/src/keepass2android/Resources/drawable-hdpi/ic27.png new file mode 100644 index 00000000..20cd06b2 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic27.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic28.png b/src/keepass2android/Resources/drawable-hdpi/ic28.png new file mode 100644 index 00000000..004b077f Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic28.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic29.png b/src/keepass2android/Resources/drawable-hdpi/ic29.png new file mode 100644 index 00000000..3e2421f6 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic29.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic30.png b/src/keepass2android/Resources/drawable-hdpi/ic30.png new file mode 100644 index 00000000..aad1041b Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic30.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic31.png b/src/keepass2android/Resources/drawable-hdpi/ic31.png new file mode 100644 index 00000000..05e15987 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic31.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic32.png b/src/keepass2android/Resources/drawable-hdpi/ic32.png new file mode 100644 index 00000000..299e1372 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic32.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic33.png b/src/keepass2android/Resources/drawable-hdpi/ic33.png new file mode 100644 index 00000000..d741485f Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic33.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic34.png b/src/keepass2android/Resources/drawable-hdpi/ic34.png new file mode 100644 index 00000000..2bf463be Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic34.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic35.png b/src/keepass2android/Resources/drawable-hdpi/ic35.png new file mode 100644 index 00000000..f83e3dcc Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic35.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic36.png b/src/keepass2android/Resources/drawable-hdpi/ic36.png new file mode 100644 index 00000000..3393d26a Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic36.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic37.png b/src/keepass2android/Resources/drawable-hdpi/ic37.png new file mode 100644 index 00000000..3ba9bf29 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic37.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic38.png b/src/keepass2android/Resources/drawable-hdpi/ic38.png new file mode 100644 index 00000000..83d8e7ee Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic38.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic39.png b/src/keepass2android/Resources/drawable-hdpi/ic39.png new file mode 100644 index 00000000..7907787f Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic39.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic40.png b/src/keepass2android/Resources/drawable-hdpi/ic40.png new file mode 100644 index 00000000..56b68ee3 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic40.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic41.png b/src/keepass2android/Resources/drawable-hdpi/ic41.png new file mode 100644 index 00000000..9a352239 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic41.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic42.png b/src/keepass2android/Resources/drawable-hdpi/ic42.png new file mode 100644 index 00000000..ecd80726 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic42.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic43.png b/src/keepass2android/Resources/drawable-hdpi/ic43.png new file mode 100644 index 00000000..906608fb Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic43.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic44.png b/src/keepass2android/Resources/drawable-hdpi/ic44.png new file mode 100644 index 00000000..d0d7cba9 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic44.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic45.png b/src/keepass2android/Resources/drawable-hdpi/ic45.png new file mode 100644 index 00000000..6b4497d5 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic45.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic46.png b/src/keepass2android/Resources/drawable-hdpi/ic46.png new file mode 100644 index 00000000..079f8fc5 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic46.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic47.png b/src/keepass2android/Resources/drawable-hdpi/ic47.png new file mode 100644 index 00000000..c8a65a75 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic47.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic48.png b/src/keepass2android/Resources/drawable-hdpi/ic48.png new file mode 100644 index 00000000..31c8a7ed Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic48.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic49.png b/src/keepass2android/Resources/drawable-hdpi/ic49.png new file mode 100644 index 00000000..f7314b34 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic49.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic50.png b/src/keepass2android/Resources/drawable-hdpi/ic50.png new file mode 100644 index 00000000..bf10afc0 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic50.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic51.png b/src/keepass2android/Resources/drawable-hdpi/ic51.png new file mode 100644 index 00000000..c532f17e Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic51.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic52.png b/src/keepass2android/Resources/drawable-hdpi/ic52.png new file mode 100644 index 00000000..4d42a7e3 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic52.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic53.png b/src/keepass2android/Resources/drawable-hdpi/ic53.png new file mode 100644 index 00000000..3b7a6907 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic53.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic54.png b/src/keepass2android/Resources/drawable-hdpi/ic54.png new file mode 100644 index 00000000..3df00d2c Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic54.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic55.png b/src/keepass2android/Resources/drawable-hdpi/ic55.png new file mode 100644 index 00000000..bcc16814 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic55.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic56.png b/src/keepass2android/Resources/drawable-hdpi/ic56.png new file mode 100644 index 00000000..16f440dd Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic56.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic57.png b/src/keepass2android/Resources/drawable-hdpi/ic57.png new file mode 100644 index 00000000..c0f2b0f5 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic57.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic58.png b/src/keepass2android/Resources/drawable-hdpi/ic58.png new file mode 100644 index 00000000..108d62e8 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic58.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic59.png b/src/keepass2android/Resources/drawable-hdpi/ic59.png new file mode 100644 index 00000000..22a9248f Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic59.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic60.png b/src/keepass2android/Resources/drawable-hdpi/ic60.png new file mode 100644 index 00000000..74f8aea8 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic60.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic61.png b/src/keepass2android/Resources/drawable-hdpi/ic61.png new file mode 100644 index 00000000..e4e12439 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic61.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic62.png b/src/keepass2android/Resources/drawable-hdpi/ic62.png new file mode 100644 index 00000000..1038b740 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic62.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic63.png b/src/keepass2android/Resources/drawable-hdpi/ic63.png new file mode 100644 index 00000000..92298bfa Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic63.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic64.png b/src/keepass2android/Resources/drawable-hdpi/ic64.png new file mode 100644 index 00000000..f7f57386 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic64.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic65.png b/src/keepass2android/Resources/drawable-hdpi/ic65.png new file mode 100644 index 00000000..257c9d50 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic65.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic66.png b/src/keepass2android/Resources/drawable-hdpi/ic66.png new file mode 100644 index 00000000..6d9ed096 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic66.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic67.png b/src/keepass2android/Resources/drawable-hdpi/ic67.png new file mode 100644 index 00000000..054e5cae Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic67.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic68.png b/src/keepass2android/Resources/drawable-hdpi/ic68.png new file mode 100644 index 00000000..a5ac3110 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic68.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic99_blank.png b/src/keepass2android/Resources/drawable-hdpi/ic99_blank.png new file mode 100644 index 00000000..f7f57386 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic99_blank.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic_action_eye_open.png b/src/keepass2android/Resources/drawable-hdpi/ic_action_eye_open.png new file mode 100644 index 00000000..aa461c84 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic_action_eye_open.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic_action_search.png b/src/keepass2android/Resources/drawable-hdpi/ic_action_search.png new file mode 100644 index 00000000..e6b70451 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic_action_search.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/ic_launcher.png b/src/keepass2android/Resources/drawable-hdpi/ic_launcher.png new file mode 100644 index 00000000..4f8cc368 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/ic_launcher.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/navigation_accept.png b/src/keepass2android/Resources/drawable-hdpi/navigation_accept.png new file mode 100644 index 00000000..58bf9721 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/navigation_accept.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/navigation_accept_dark.png b/src/keepass2android/Resources/drawable-hdpi/navigation_accept_dark.png new file mode 100644 index 00000000..53cf6877 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/navigation_accept_dark.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/navigation_previous_item.png b/src/keepass2android/Resources/drawable-hdpi/navigation_previous_item.png new file mode 100644 index 00000000..23778ae9 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/navigation_previous_item.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/navigation_previous_item_dark.png b/src/keepass2android/Resources/drawable-hdpi/navigation_previous_item_dark.png new file mode 100644 index 00000000..64538ce8 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/navigation_previous_item_dark.png differ diff --git a/src/keepass2android/Resources/drawable-hdpi/notify.png b/src/keepass2android/Resources/drawable-hdpi/notify.png new file mode 100644 index 00000000..786c7f86 Binary files /dev/null and b/src/keepass2android/Resources/drawable-hdpi/notify.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic00.png b/src/keepass2android/Resources/drawable-ldpi/ic00.png new file mode 100644 index 00000000..2990c1f0 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic00.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic01.png b/src/keepass2android/Resources/drawable-ldpi/ic01.png new file mode 100644 index 00000000..f8bcf643 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic01.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic02.png b/src/keepass2android/Resources/drawable-ldpi/ic02.png new file mode 100644 index 00000000..b5286fe7 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic02.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic03.png b/src/keepass2android/Resources/drawable-ldpi/ic03.png new file mode 100644 index 00000000..f84a9c90 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic03.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic04.png b/src/keepass2android/Resources/drawable-ldpi/ic04.png new file mode 100644 index 00000000..42d2659c Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic04.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic05.png b/src/keepass2android/Resources/drawable-ldpi/ic05.png new file mode 100644 index 00000000..8860588a Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic05.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic06.png b/src/keepass2android/Resources/drawable-ldpi/ic06.png new file mode 100644 index 00000000..a3b23521 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic06.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic07.png b/src/keepass2android/Resources/drawable-ldpi/ic07.png new file mode 100644 index 00000000..cbfc7f84 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic07.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic08.png b/src/keepass2android/Resources/drawable-ldpi/ic08.png new file mode 100644 index 00000000..2225ad07 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic08.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic09.png b/src/keepass2android/Resources/drawable-ldpi/ic09.png new file mode 100644 index 00000000..2f2e222f Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic09.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic10.png b/src/keepass2android/Resources/drawable-ldpi/ic10.png new file mode 100644 index 00000000..6019830f Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic10.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic11.png b/src/keepass2android/Resources/drawable-ldpi/ic11.png new file mode 100644 index 00000000..67d970d9 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic11.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic12.png b/src/keepass2android/Resources/drawable-ldpi/ic12.png new file mode 100644 index 00000000..4f553d83 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic12.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic13.png b/src/keepass2android/Resources/drawable-ldpi/ic13.png new file mode 100644 index 00000000..8675e51f Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic13.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic14.png b/src/keepass2android/Resources/drawable-ldpi/ic14.png new file mode 100644 index 00000000..fc36b738 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic14.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic15.png b/src/keepass2android/Resources/drawable-ldpi/ic15.png new file mode 100644 index 00000000..330f4f0f Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic15.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic16.png b/src/keepass2android/Resources/drawable-ldpi/ic16.png new file mode 100644 index 00000000..43bbc36a Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic16.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic17.png b/src/keepass2android/Resources/drawable-ldpi/ic17.png new file mode 100644 index 00000000..f7e136c1 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic17.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic18.png b/src/keepass2android/Resources/drawable-ldpi/ic18.png new file mode 100644 index 00000000..fb409831 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic18.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic19.png b/src/keepass2android/Resources/drawable-ldpi/ic19.png new file mode 100644 index 00000000..683f7d41 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic19.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic20.png b/src/keepass2android/Resources/drawable-ldpi/ic20.png new file mode 100644 index 00000000..60ddc27f Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic20.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic21.png b/src/keepass2android/Resources/drawable-ldpi/ic21.png new file mode 100644 index 00000000..90fdd6b9 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic21.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic22.png b/src/keepass2android/Resources/drawable-ldpi/ic22.png new file mode 100644 index 00000000..28dc82ea Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic22.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic23.png b/src/keepass2android/Resources/drawable-ldpi/ic23.png new file mode 100644 index 00000000..6a4ee5f5 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic23.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic24.png b/src/keepass2android/Resources/drawable-ldpi/ic24.png new file mode 100644 index 00000000..ea7baaff Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic24.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic25.png b/src/keepass2android/Resources/drawable-ldpi/ic25.png new file mode 100644 index 00000000..404e8267 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic25.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic26.png b/src/keepass2android/Resources/drawable-ldpi/ic26.png new file mode 100644 index 00000000..0a767a78 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic26.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic27.png b/src/keepass2android/Resources/drawable-ldpi/ic27.png new file mode 100644 index 00000000..1e8c0c57 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic27.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic28.png b/src/keepass2android/Resources/drawable-ldpi/ic28.png new file mode 100644 index 00000000..127d638d Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic28.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic29.png b/src/keepass2android/Resources/drawable-ldpi/ic29.png new file mode 100644 index 00000000..f8d88334 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic29.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic30.png b/src/keepass2android/Resources/drawable-ldpi/ic30.png new file mode 100644 index 00000000..0a4f0e8f Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic30.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic31.png b/src/keepass2android/Resources/drawable-ldpi/ic31.png new file mode 100644 index 00000000..41f324f5 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic31.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic32.png b/src/keepass2android/Resources/drawable-ldpi/ic32.png new file mode 100644 index 00000000..5b3cf805 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic32.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic33.png b/src/keepass2android/Resources/drawable-ldpi/ic33.png new file mode 100644 index 00000000..5bc278bf Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic33.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic34.png b/src/keepass2android/Resources/drawable-ldpi/ic34.png new file mode 100644 index 00000000..6d845c5c Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic34.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic35.png b/src/keepass2android/Resources/drawable-ldpi/ic35.png new file mode 100644 index 00000000..5d5109c5 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic35.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic36.png b/src/keepass2android/Resources/drawable-ldpi/ic36.png new file mode 100644 index 00000000..5cce9624 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic36.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic37.png b/src/keepass2android/Resources/drawable-ldpi/ic37.png new file mode 100644 index 00000000..c4e3baf9 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic37.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic38.png b/src/keepass2android/Resources/drawable-ldpi/ic38.png new file mode 100644 index 00000000..44f634e2 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic38.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic39.png b/src/keepass2android/Resources/drawable-ldpi/ic39.png new file mode 100644 index 00000000..eb7743f1 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic39.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic40.png b/src/keepass2android/Resources/drawable-ldpi/ic40.png new file mode 100644 index 00000000..e42faa88 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic40.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic41.png b/src/keepass2android/Resources/drawable-ldpi/ic41.png new file mode 100644 index 00000000..47d0222b Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic41.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic42.png b/src/keepass2android/Resources/drawable-ldpi/ic42.png new file mode 100644 index 00000000..a24772ee Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic42.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic43.png b/src/keepass2android/Resources/drawable-ldpi/ic43.png new file mode 100644 index 00000000..5fcabceb Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic43.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic44.png b/src/keepass2android/Resources/drawable-ldpi/ic44.png new file mode 100644 index 00000000..bf57db20 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic44.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic45.png b/src/keepass2android/Resources/drawable-ldpi/ic45.png new file mode 100644 index 00000000..8bd34c45 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic45.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic46.png b/src/keepass2android/Resources/drawable-ldpi/ic46.png new file mode 100644 index 00000000..f26b6917 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic46.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic47.png b/src/keepass2android/Resources/drawable-ldpi/ic47.png new file mode 100644 index 00000000..06072478 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic47.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic48.png b/src/keepass2android/Resources/drawable-ldpi/ic48.png new file mode 100644 index 00000000..20df2445 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic48.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic49.png b/src/keepass2android/Resources/drawable-ldpi/ic49.png new file mode 100644 index 00000000..f51a8d8c Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic49.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic50.png b/src/keepass2android/Resources/drawable-ldpi/ic50.png new file mode 100644 index 00000000..a438d3d2 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic50.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic51.png b/src/keepass2android/Resources/drawable-ldpi/ic51.png new file mode 100644 index 00000000..1c85e52f Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic51.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic52.png b/src/keepass2android/Resources/drawable-ldpi/ic52.png new file mode 100644 index 00000000..875eccfd Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic52.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic53.png b/src/keepass2android/Resources/drawable-ldpi/ic53.png new file mode 100644 index 00000000..7d6473d7 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic53.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic54.png b/src/keepass2android/Resources/drawable-ldpi/ic54.png new file mode 100644 index 00000000..1cf164c8 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic54.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic55.png b/src/keepass2android/Resources/drawable-ldpi/ic55.png new file mode 100644 index 00000000..704acdb7 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic55.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic56.png b/src/keepass2android/Resources/drawable-ldpi/ic56.png new file mode 100644 index 00000000..ce6ab3cc Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic56.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic57.png b/src/keepass2android/Resources/drawable-ldpi/ic57.png new file mode 100644 index 00000000..59932cae Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic57.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic58.png b/src/keepass2android/Resources/drawable-ldpi/ic58.png new file mode 100644 index 00000000..4e594145 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic58.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic59.png b/src/keepass2android/Resources/drawable-ldpi/ic59.png new file mode 100644 index 00000000..c70b7af8 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic59.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic60.png b/src/keepass2android/Resources/drawable-ldpi/ic60.png new file mode 100644 index 00000000..13e358b6 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic60.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic61.png b/src/keepass2android/Resources/drawable-ldpi/ic61.png new file mode 100644 index 00000000..1ac441fb Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic61.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic62.png b/src/keepass2android/Resources/drawable-ldpi/ic62.png new file mode 100644 index 00000000..3c511460 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic62.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic63.png b/src/keepass2android/Resources/drawable-ldpi/ic63.png new file mode 100644 index 00000000..fff876c4 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic63.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic64.png b/src/keepass2android/Resources/drawable-ldpi/ic64.png new file mode 100644 index 00000000..5d8aa999 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic64.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic65.png b/src/keepass2android/Resources/drawable-ldpi/ic65.png new file mode 100644 index 00000000..d9e68cf7 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic65.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic66.png b/src/keepass2android/Resources/drawable-ldpi/ic66.png new file mode 100644 index 00000000..94f30cbb Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic66.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic67.png b/src/keepass2android/Resources/drawable-ldpi/ic67.png new file mode 100644 index 00000000..d8048d1a Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic67.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic68.png b/src/keepass2android/Resources/drawable-ldpi/ic68.png new file mode 100644 index 00000000..72536bce Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic68.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/ic99_blank.png b/src/keepass2android/Resources/drawable-ldpi/ic99_blank.png new file mode 100644 index 00000000..5d8aa999 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/ic99_blank.png differ diff --git a/src/keepass2android/Resources/drawable-ldpi/notify.png b/src/keepass2android/Resources/drawable-ldpi/notify.png new file mode 100644 index 00000000..524e0ee5 Binary files /dev/null and b/src/keepass2android/Resources/drawable-ldpi/notify.png differ diff --git a/src/keepass2android/Resources/drawable-mdpi/ic_action_eye_open.png b/src/keepass2android/Resources/drawable-mdpi/ic_action_eye_open.png new file mode 100644 index 00000000..a4e966f5 Binary files /dev/null and b/src/keepass2android/Resources/drawable-mdpi/ic_action_eye_open.png differ diff --git a/src/keepass2android/Resources/drawable-mdpi/ic_action_search.png b/src/keepass2android/Resources/drawable-mdpi/ic_action_search.png new file mode 100644 index 00000000..3aa64404 Binary files /dev/null and b/src/keepass2android/Resources/drawable-mdpi/ic_action_search.png differ diff --git a/src/keepass2android/Resources/drawable-mdpi/ic_launcher.png b/src/keepass2android/Resources/drawable-mdpi/ic_launcher.png new file mode 100644 index 00000000..f34f9b5b Binary files /dev/null and b/src/keepass2android/Resources/drawable-mdpi/ic_launcher.png differ diff --git a/src/keepass2android/Resources/drawable-mdpi/navigation_accept.png b/src/keepass2android/Resources/drawable-mdpi/navigation_accept.png new file mode 100644 index 00000000..cf5fab3a Binary files /dev/null and b/src/keepass2android/Resources/drawable-mdpi/navigation_accept.png differ diff --git a/src/keepass2android/Resources/drawable-mdpi/navigation_accept_dark.png b/src/keepass2android/Resources/drawable-mdpi/navigation_accept_dark.png new file mode 100644 index 00000000..35cda8e1 Binary files /dev/null and b/src/keepass2android/Resources/drawable-mdpi/navigation_accept_dark.png differ diff --git a/src/keepass2android/Resources/drawable-mdpi/navigation_previous_item.png b/src/keepass2android/Resources/drawable-mdpi/navigation_previous_item.png new file mode 100644 index 00000000..8d19e391 Binary files /dev/null and b/src/keepass2android/Resources/drawable-mdpi/navigation_previous_item.png differ diff --git a/src/keepass2android/Resources/drawable-mdpi/navigation_previous_item_dark.png b/src/keepass2android/Resources/drawable-mdpi/navigation_previous_item_dark.png new file mode 100644 index 00000000..b8b3e1ab Binary files /dev/null and b/src/keepass2android/Resources/drawable-mdpi/navigation_previous_item_dark.png differ diff --git a/src/keepass2android/Resources/drawable-v11/EntryFieldHeaderBackground.xml b/src/keepass2android/Resources/drawable-v11/EntryFieldHeaderBackground.xml new file mode 100644 index 00000000..508f0487 --- /dev/null +++ b/src/keepass2android/Resources/drawable-v11/EntryFieldHeaderBackground.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/keepass2android/Resources/drawable-xhdpi/2_action_about.png b/src/keepass2android/Resources/drawable-xhdpi/2_action_about.png new file mode 100644 index 00000000..2641f142 Binary files /dev/null and b/src/keepass2android/Resources/drawable-xhdpi/2_action_about.png differ diff --git a/src/keepass2android/Resources/drawable-xhdpi/ic_action_eye_open.png b/src/keepass2android/Resources/drawable-xhdpi/ic_action_eye_open.png new file mode 100644 index 00000000..3320a0e6 Binary files /dev/null and b/src/keepass2android/Resources/drawable-xhdpi/ic_action_eye_open.png differ diff --git a/src/keepass2android/Resources/drawable-xhdpi/ic_launcher.png b/src/keepass2android/Resources/drawable-xhdpi/ic_launcher.png new file mode 100644 index 00000000..03304a0e Binary files /dev/null and b/src/keepass2android/Resources/drawable-xhdpi/ic_launcher.png differ diff --git a/src/keepass2android/Resources/drawable-xhdpi/navigation_accept.png b/src/keepass2android/Resources/drawable-xhdpi/navigation_accept.png new file mode 100644 index 00000000..b8915716 Binary files /dev/null and b/src/keepass2android/Resources/drawable-xhdpi/navigation_accept.png differ diff --git a/src/keepass2android/Resources/drawable-xhdpi/navigation_accept_dark.png b/src/keepass2android/Resources/drawable-xhdpi/navigation_accept_dark.png new file mode 100644 index 00000000..b52dc370 Binary files /dev/null and b/src/keepass2android/Resources/drawable-xhdpi/navigation_accept_dark.png differ diff --git a/src/keepass2android/Resources/drawable-xhdpi/navigation_previous_item.png b/src/keepass2android/Resources/drawable-xhdpi/navigation_previous_item.png new file mode 100644 index 00000000..cf0b485f Binary files /dev/null and b/src/keepass2android/Resources/drawable-xhdpi/navigation_previous_item.png differ diff --git a/src/keepass2android/Resources/drawable-xhdpi/navigation_previous_item_dark.png b/src/keepass2android/Resources/drawable-xhdpi/navigation_previous_item_dark.png new file mode 100644 index 00000000..e97e910e Binary files /dev/null and b/src/keepass2android/Resources/drawable-xhdpi/navigation_previous_item_dark.png differ diff --git a/src/keepass2android/Resources/drawable-xxhdpi/ic_launcher.png b/src/keepass2android/Resources/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..479eb39b Binary files /dev/null and b/src/keepass2android/Resources/drawable-xxhdpi/ic_launcher.png differ diff --git a/src/keepass2android/Resources/drawable/2_action_about.png b/src/keepass2android/Resources/drawable/2_action_about.png new file mode 100644 index 00000000..8f39c428 Binary files /dev/null and b/src/keepass2android/Resources/drawable/2_action_about.png differ diff --git a/src/keepass2android/Resources/drawable/BlueButton.xml b/src/keepass2android/Resources/drawable/BlueButton.xml new file mode 100644 index 00000000..de790c7f --- /dev/null +++ b/src/keepass2android/Resources/drawable/BlueButton.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/keepass2android/Resources/drawable/EntryFieldHeaderBackground.xml b/src/keepass2android/Resources/drawable/EntryFieldHeaderBackground.xml new file mode 100644 index 00000000..058b5119 --- /dev/null +++ b/src/keepass2android/Resources/drawable/EntryFieldHeaderBackground.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/src/keepass2android/Resources/drawable/GreenButton.xml b/src/keepass2android/Resources/drawable/GreenButton.xml new file mode 100644 index 00000000..26143578 --- /dev/null +++ b/src/keepass2android/Resources/drawable/GreenButton.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/keepass2android/Resources/drawable/HeaderButtonBackground.xml b/src/keepass2android/Resources/drawable/HeaderButtonBackground.xml new file mode 100644 index 00000000..231b6355 --- /dev/null +++ b/src/keepass2android/Resources/drawable/HeaderButtonBackground.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/keepass2android/Resources/drawable/Icon.png b/src/keepass2android/Resources/drawable/Icon.png new file mode 100644 index 00000000..a07c69fa Binary files /dev/null and b/src/keepass2android/Resources/drawable/Icon.png differ diff --git a/src/keepass2android/Resources/drawable/RedButton.xml b/src/keepass2android/Resources/drawable/RedButton.xml new file mode 100644 index 00000000..216d100a --- /dev/null +++ b/src/keepass2android/Resources/drawable/RedButton.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/keepass2android/Resources/drawable/YellowButton.xml b/src/keepass2android/Resources/drawable/YellowButton.xml new file mode 100644 index 00000000..bad953c5 --- /dev/null +++ b/src/keepass2android/Resources/drawable/YellowButton.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/keepass2android/Resources/drawable/btn_new_group.png b/src/keepass2android/Resources/drawable/btn_new_group.png new file mode 100644 index 00000000..44ffbbd8 Binary files /dev/null and b/src/keepass2android/Resources/drawable/btn_new_group.png differ diff --git a/src/keepass2android/Resources/drawable/btn_new_group_dark.png b/src/keepass2android/Resources/drawable/btn_new_group_dark.png new file mode 100644 index 00000000..32ae9ebb Binary files /dev/null and b/src/keepass2android/Resources/drawable/btn_new_group_dark.png differ diff --git a/src/keepass2android/Resources/drawable/device_access_new_account.png b/src/keepass2android/Resources/drawable/device_access_new_account.png new file mode 100644 index 00000000..ca751c87 Binary files /dev/null and b/src/keepass2android/Resources/drawable/device_access_new_account.png differ diff --git a/src/keepass2android/Resources/drawable/device_access_new_account_dark.png b/src/keepass2android/Resources/drawable/device_access_new_account_dark.png new file mode 100644 index 00000000..27889219 Binary files /dev/null and b/src/keepass2android/Resources/drawable/device_access_new_account_dark.png differ diff --git a/src/keepass2android/Resources/drawable/extra_string_header.xml b/src/keepass2android/Resources/drawable/extra_string_header.xml new file mode 100644 index 00000000..5b7ab453 --- /dev/null +++ b/src/keepass2android/Resources/drawable/extra_string_header.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/src/keepass2android/Resources/drawable/ic00.png b/src/keepass2android/Resources/drawable/ic00.png new file mode 100644 index 00000000..b74e831f Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic00.png differ diff --git a/src/keepass2android/Resources/drawable/ic01.png b/src/keepass2android/Resources/drawable/ic01.png new file mode 100644 index 00000000..e164a9f3 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic01.png differ diff --git a/src/keepass2android/Resources/drawable/ic02.png b/src/keepass2android/Resources/drawable/ic02.png new file mode 100644 index 00000000..d5f6551d Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic02.png differ diff --git a/src/keepass2android/Resources/drawable/ic03.png b/src/keepass2android/Resources/drawable/ic03.png new file mode 100644 index 00000000..b3781e45 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic03.png differ diff --git a/src/keepass2android/Resources/drawable/ic04.png b/src/keepass2android/Resources/drawable/ic04.png new file mode 100644 index 00000000..def2ea10 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic04.png differ diff --git a/src/keepass2android/Resources/drawable/ic05.png b/src/keepass2android/Resources/drawable/ic05.png new file mode 100644 index 00000000..67118111 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic05.png differ diff --git a/src/keepass2android/Resources/drawable/ic06.png b/src/keepass2android/Resources/drawable/ic06.png new file mode 100644 index 00000000..57c1a1da Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic06.png differ diff --git a/src/keepass2android/Resources/drawable/ic07.png b/src/keepass2android/Resources/drawable/ic07.png new file mode 100644 index 00000000..89ef01ba Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic07.png differ diff --git a/src/keepass2android/Resources/drawable/ic08.png b/src/keepass2android/Resources/drawable/ic08.png new file mode 100644 index 00000000..cb5f8f0a Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic08.png differ diff --git a/src/keepass2android/Resources/drawable/ic09.png b/src/keepass2android/Resources/drawable/ic09.png new file mode 100644 index 00000000..b38168a2 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic09.png differ diff --git a/src/keepass2android/Resources/drawable/ic10.png b/src/keepass2android/Resources/drawable/ic10.png new file mode 100644 index 00000000..966610d9 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic10.png differ diff --git a/src/keepass2android/Resources/drawable/ic11.png b/src/keepass2android/Resources/drawable/ic11.png new file mode 100644 index 00000000..b41b44c3 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic11.png differ diff --git a/src/keepass2android/Resources/drawable/ic12.png b/src/keepass2android/Resources/drawable/ic12.png new file mode 100644 index 00000000..92ca07dc Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic12.png differ diff --git a/src/keepass2android/Resources/drawable/ic13.png b/src/keepass2android/Resources/drawable/ic13.png new file mode 100644 index 00000000..42b6ec07 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic13.png differ diff --git a/src/keepass2android/Resources/drawable/ic14.png b/src/keepass2android/Resources/drawable/ic14.png new file mode 100644 index 00000000..b7552c07 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic14.png differ diff --git a/src/keepass2android/Resources/drawable/ic15.png b/src/keepass2android/Resources/drawable/ic15.png new file mode 100644 index 00000000..974635d9 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic15.png differ diff --git a/src/keepass2android/Resources/drawable/ic16.png b/src/keepass2android/Resources/drawable/ic16.png new file mode 100644 index 00000000..47d4b36f Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic16.png differ diff --git a/src/keepass2android/Resources/drawable/ic17.png b/src/keepass2android/Resources/drawable/ic17.png new file mode 100644 index 00000000..209af79d Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic17.png differ diff --git a/src/keepass2android/Resources/drawable/ic18.png b/src/keepass2android/Resources/drawable/ic18.png new file mode 100644 index 00000000..30f1dfa0 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic18.png differ diff --git a/src/keepass2android/Resources/drawable/ic19.png b/src/keepass2android/Resources/drawable/ic19.png new file mode 100644 index 00000000..356a2e7b Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic19.png differ diff --git a/src/keepass2android/Resources/drawable/ic20.png b/src/keepass2android/Resources/drawable/ic20.png new file mode 100644 index 00000000..135fd11b Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic20.png differ diff --git a/src/keepass2android/Resources/drawable/ic21.png b/src/keepass2android/Resources/drawable/ic21.png new file mode 100644 index 00000000..d80fc95a Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic21.png differ diff --git a/src/keepass2android/Resources/drawable/ic22.png b/src/keepass2android/Resources/drawable/ic22.png new file mode 100644 index 00000000..788d0e7c Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic22.png differ diff --git a/src/keepass2android/Resources/drawable/ic23.png b/src/keepass2android/Resources/drawable/ic23.png new file mode 100644 index 00000000..6345beab Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic23.png differ diff --git a/src/keepass2android/Resources/drawable/ic24.png b/src/keepass2android/Resources/drawable/ic24.png new file mode 100644 index 00000000..6b77a056 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic24.png differ diff --git a/src/keepass2android/Resources/drawable/ic25.png b/src/keepass2android/Resources/drawable/ic25.png new file mode 100644 index 00000000..280423f3 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic25.png differ diff --git a/src/keepass2android/Resources/drawable/ic26.png b/src/keepass2android/Resources/drawable/ic26.png new file mode 100644 index 00000000..9e278996 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic26.png differ diff --git a/src/keepass2android/Resources/drawable/ic27.png b/src/keepass2android/Resources/drawable/ic27.png new file mode 100644 index 00000000..c71d9b7e Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic27.png differ diff --git a/src/keepass2android/Resources/drawable/ic28.png b/src/keepass2android/Resources/drawable/ic28.png new file mode 100644 index 00000000..3bea4d71 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic28.png differ diff --git a/src/keepass2android/Resources/drawable/ic29.png b/src/keepass2android/Resources/drawable/ic29.png new file mode 100644 index 00000000..a4ce18b9 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic29.png differ diff --git a/src/keepass2android/Resources/drawable/ic30.png b/src/keepass2android/Resources/drawable/ic30.png new file mode 100644 index 00000000..49dcd2ca Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic30.png differ diff --git a/src/keepass2android/Resources/drawable/ic31.png b/src/keepass2android/Resources/drawable/ic31.png new file mode 100644 index 00000000..a510ec65 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic31.png differ diff --git a/src/keepass2android/Resources/drawable/ic32.png b/src/keepass2android/Resources/drawable/ic32.png new file mode 100644 index 00000000..96b46fd2 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic32.png differ diff --git a/src/keepass2android/Resources/drawable/ic33.png b/src/keepass2android/Resources/drawable/ic33.png new file mode 100644 index 00000000..db5111a9 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic33.png differ diff --git a/src/keepass2android/Resources/drawable/ic34.png b/src/keepass2android/Resources/drawable/ic34.png new file mode 100644 index 00000000..feebf2bd Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic34.png differ diff --git a/src/keepass2android/Resources/drawable/ic35.png b/src/keepass2android/Resources/drawable/ic35.png new file mode 100644 index 00000000..629ad9aa Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic35.png differ diff --git a/src/keepass2android/Resources/drawable/ic36.png b/src/keepass2android/Resources/drawable/ic36.png new file mode 100644 index 00000000..8dc08855 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic36.png differ diff --git a/src/keepass2android/Resources/drawable/ic37.png b/src/keepass2android/Resources/drawable/ic37.png new file mode 100644 index 00000000..fef91068 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic37.png differ diff --git a/src/keepass2android/Resources/drawable/ic38.png b/src/keepass2android/Resources/drawable/ic38.png new file mode 100644 index 00000000..9b141689 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic38.png differ diff --git a/src/keepass2android/Resources/drawable/ic39.png b/src/keepass2android/Resources/drawable/ic39.png new file mode 100644 index 00000000..1f36acaa Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic39.png differ diff --git a/src/keepass2android/Resources/drawable/ic40.png b/src/keepass2android/Resources/drawable/ic40.png new file mode 100644 index 00000000..81d60885 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic40.png differ diff --git a/src/keepass2android/Resources/drawable/ic41.png b/src/keepass2android/Resources/drawable/ic41.png new file mode 100644 index 00000000..a02c56a4 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic41.png differ diff --git a/src/keepass2android/Resources/drawable/ic42.png b/src/keepass2android/Resources/drawable/ic42.png new file mode 100644 index 00000000..e0a295d0 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic42.png differ diff --git a/src/keepass2android/Resources/drawable/ic43.png b/src/keepass2android/Resources/drawable/ic43.png new file mode 100644 index 00000000..6170d86c Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic43.png differ diff --git a/src/keepass2android/Resources/drawable/ic44.png b/src/keepass2android/Resources/drawable/ic44.png new file mode 100644 index 00000000..0a9d2090 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic44.png differ diff --git a/src/keepass2android/Resources/drawable/ic45.png b/src/keepass2android/Resources/drawable/ic45.png new file mode 100644 index 00000000..2d5e260a Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic45.png differ diff --git a/src/keepass2android/Resources/drawable/ic46.png b/src/keepass2android/Resources/drawable/ic46.png new file mode 100644 index 00000000..d8197d61 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic46.png differ diff --git a/src/keepass2android/Resources/drawable/ic47.png b/src/keepass2android/Resources/drawable/ic47.png new file mode 100644 index 00000000..2aabd0a2 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic47.png differ diff --git a/src/keepass2android/Resources/drawable/ic48.png b/src/keepass2android/Resources/drawable/ic48.png new file mode 100644 index 00000000..bd433f4b Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic48.png differ diff --git a/src/keepass2android/Resources/drawable/ic49.png b/src/keepass2android/Resources/drawable/ic49.png new file mode 100644 index 00000000..376aa6ec Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic49.png differ diff --git a/src/keepass2android/Resources/drawable/ic50.png b/src/keepass2android/Resources/drawable/ic50.png new file mode 100644 index 00000000..174b86c3 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic50.png differ diff --git a/src/keepass2android/Resources/drawable/ic51.png b/src/keepass2android/Resources/drawable/ic51.png new file mode 100644 index 00000000..2b49969a Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic51.png differ diff --git a/src/keepass2android/Resources/drawable/ic52.png b/src/keepass2android/Resources/drawable/ic52.png new file mode 100644 index 00000000..36adbc8e Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic52.png differ diff --git a/src/keepass2android/Resources/drawable/ic53.png b/src/keepass2android/Resources/drawable/ic53.png new file mode 100644 index 00000000..592ce6f4 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic53.png differ diff --git a/src/keepass2android/Resources/drawable/ic54.png b/src/keepass2android/Resources/drawable/ic54.png new file mode 100644 index 00000000..2dfe90be Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic54.png differ diff --git a/src/keepass2android/Resources/drawable/ic55.png b/src/keepass2android/Resources/drawable/ic55.png new file mode 100644 index 00000000..69e55a1d Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic55.png differ diff --git a/src/keepass2android/Resources/drawable/ic56.png b/src/keepass2android/Resources/drawable/ic56.png new file mode 100644 index 00000000..fbedb011 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic56.png differ diff --git a/src/keepass2android/Resources/drawable/ic57.png b/src/keepass2android/Resources/drawable/ic57.png new file mode 100644 index 00000000..ed6d2e05 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic57.png differ diff --git a/src/keepass2android/Resources/drawable/ic58.png b/src/keepass2android/Resources/drawable/ic58.png new file mode 100644 index 00000000..91d7c5f6 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic58.png differ diff --git a/src/keepass2android/Resources/drawable/ic59.png b/src/keepass2android/Resources/drawable/ic59.png new file mode 100644 index 00000000..5cc4f6b5 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic59.png differ diff --git a/src/keepass2android/Resources/drawable/ic60.png b/src/keepass2android/Resources/drawable/ic60.png new file mode 100644 index 00000000..0094f836 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic60.png differ diff --git a/src/keepass2android/Resources/drawable/ic61.png b/src/keepass2android/Resources/drawable/ic61.png new file mode 100644 index 00000000..fcee6c9c Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic61.png differ diff --git a/src/keepass2android/Resources/drawable/ic62.png b/src/keepass2android/Resources/drawable/ic62.png new file mode 100644 index 00000000..8640421a Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic62.png differ diff --git a/src/keepass2android/Resources/drawable/ic63.png b/src/keepass2android/Resources/drawable/ic63.png new file mode 100644 index 00000000..e340fbea Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic63.png differ diff --git a/src/keepass2android/Resources/drawable/ic64.png b/src/keepass2android/Resources/drawable/ic64.png new file mode 100644 index 00000000..5dd1edf2 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic64.png differ diff --git a/src/keepass2android/Resources/drawable/ic65.png b/src/keepass2android/Resources/drawable/ic65.png new file mode 100644 index 00000000..4721b68f Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic65.png differ diff --git a/src/keepass2android/Resources/drawable/ic66.png b/src/keepass2android/Resources/drawable/ic66.png new file mode 100644 index 00000000..e2a83b94 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic66.png differ diff --git a/src/keepass2android/Resources/drawable/ic67.png b/src/keepass2android/Resources/drawable/ic67.png new file mode 100644 index 00000000..42691a0e Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic67.png differ diff --git a/src/keepass2android/Resources/drawable/ic68.png b/src/keepass2android/Resources/drawable/ic68.png new file mode 100644 index 00000000..69060470 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic68.png differ diff --git a/src/keepass2android/Resources/drawable/ic99_blank.png b/src/keepass2android/Resources/drawable/ic99_blank.png new file mode 100644 index 00000000..5dd1edf2 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic99_blank.png differ diff --git a/src/keepass2android/Resources/drawable/ic_action_eye_open.png b/src/keepass2android/Resources/drawable/ic_action_eye_open.png new file mode 100644 index 00000000..aa461c84 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic_action_eye_open.png differ diff --git a/src/keepass2android/Resources/drawable/ic_action_search.png b/src/keepass2android/Resources/drawable/ic_action_search.png new file mode 100644 index 00000000..3aa64404 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic_action_search.png differ diff --git a/src/keepass2android/Resources/drawable/ic_launcher.png b/src/keepass2android/Resources/drawable/ic_launcher.png new file mode 100644 index 00000000..f34f9b5b Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic_launcher.png differ diff --git a/src/keepass2android/Resources/drawable/ic_launcher_folder_small.png b/src/keepass2android/Resources/drawable/ic_launcher_folder_small.png new file mode 100644 index 00000000..5df8d60f Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic_launcher_folder_small.png differ diff --git a/src/keepass2android/Resources/drawable/ic_launcher_gray.png b/src/keepass2android/Resources/drawable/ic_launcher_gray.png new file mode 100644 index 00000000..4b9fe754 Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic_launcher_gray.png differ diff --git a/src/keepass2android/Resources/drawable/ic_menu_view.png b/src/keepass2android/Resources/drawable/ic_menu_view.png new file mode 100644 index 00000000..f13e199e Binary files /dev/null and b/src/keepass2android/Resources/drawable/ic_menu_view.png differ diff --git a/src/keepass2android/Resources/drawable/launcher.png b/src/keepass2android/Resources/drawable/launcher.png new file mode 100644 index 00000000..e52d5f33 Binary files /dev/null and b/src/keepass2android/Resources/drawable/launcher.png differ diff --git a/src/keepass2android/Resources/drawable/navigation_accept.png b/src/keepass2android/Resources/drawable/navigation_accept.png new file mode 100644 index 00000000..58bf9721 Binary files /dev/null and b/src/keepass2android/Resources/drawable/navigation_accept.png differ diff --git a/src/keepass2android/Resources/drawable/navigation_accept_dark.png b/src/keepass2android/Resources/drawable/navigation_accept_dark.png new file mode 100644 index 00000000..53cf6877 Binary files /dev/null and b/src/keepass2android/Resources/drawable/navigation_accept_dark.png differ diff --git a/src/keepass2android/Resources/drawable/navigation_previous_item.png b/src/keepass2android/Resources/drawable/navigation_previous_item.png new file mode 100644 index 00000000..8d19e391 Binary files /dev/null and b/src/keepass2android/Resources/drawable/navigation_previous_item.png differ diff --git a/src/keepass2android/Resources/drawable/navigation_previous_item_dark.png b/src/keepass2android/Resources/drawable/navigation_previous_item_dark.png new file mode 100644 index 00000000..64538ce8 Binary files /dev/null and b/src/keepass2android/Resources/drawable/navigation_previous_item_dark.png differ diff --git a/src/keepass2android/Resources/drawable/notify.png b/src/keepass2android/Resources/drawable/notify.png new file mode 100644 index 00000000..57439167 Binary files /dev/null and b/src/keepass2android/Resources/drawable/notify.png differ diff --git a/src/keepass2android/Resources/drawable/section_header.xml b/src/keepass2android/Resources/drawable/section_header.xml new file mode 100644 index 00000000..c08c173e --- /dev/null +++ b/src/keepass2android/Resources/drawable/section_header.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/src/keepass2android/Resources/layout-v11/entry_view_contents.xml b/src/keepass2android/Resources/layout-v11/entry_view_contents.xml new file mode 100644 index 00000000..93d283a6 --- /dev/null +++ b/src/keepass2android/Resources/layout-v11/entry_view_contents.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/keepass2android/Resources/layout/QuickUnlock.xml b/src/keepass2android/Resources/layout/QuickUnlock.xml new file mode 100644 index 00000000..4f96d020 --- /dev/null +++ b/src/keepass2android/Resources/layout/QuickUnlock.xml @@ -0,0 +1,70 @@ + + + + + + + + +