commit f3097e74507c0eb6a0bde63ae56227446423aebf Author: Johan Walles Date: Sat Jun 8 22:12:52 2019 +0200 Reboot in Go diff --git a/.whitesource b/.whitesource new file mode 100644 index 0000000..f056952 --- /dev/null +++ b/.whitesource @@ -0,0 +1,8 @@ +{ + "generalSettings": { + "shouldScanRepo": true + }, + "checkRunSettings": { + "vulnerableCheckRunConclusionLevel": "failure" + } +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0fab236 --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2013, johan.walles@gmail.com +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7e2e319 --- /dev/null +++ b/README.md @@ -0,0 +1,340 @@ +Moar is a pager. It's designed to just do the right thing without any +configuration: + +![Moar displaying its own test suite](http://walles.github.io/moar/images/moar.png) + +The intention is that Moar should work as a drop-in replacement for +[Less](http://www.greenwoodsoftware.com/less/). If you find that Moar +doesn't work that way, +[please report it](https://github.com/walles/moar/issues)! + +Doing the right thing includes: + +* **Syntax highlight** source code by default if + [GNU Source-highlight](http://www.gnu.org/software/src-highlite/) + is installed. +* **Search is incremental** / find-as-you-type just like in + [Chrome](http://www.google.com/chrome) or + [Emacs](http://www.gnu.org/software/emacs/) +* Search becomes case sensitive if you add any UPPER CASE characters + to your search terms, just like in Emacs +* [Regexp](http://en.wikipedia.org/wiki/Regular_expression#Basic_concepts) + search if your search string is a valid regexp +* Supports displaying ANSI color coded texts (like the output from + "git diff" for example) +* Supports UTF-8 input and output +* The position in the file is always shown + +Installing +---------- + +FIXME: Go install instructions + +... + +And now you can just invoke `moar` from the prompt! + +Setting Moar as Your Default Pager +---------------------------------- + +Set it as your default pager by adding... + +```bash +export PAGER=/usr/local/bin/moar +``` + +... to your `.bashrc`. + +Issues +------ + +Issues are tracked [here](https://github.com/walles/moar/issues), or +you can send questions to . + +Developing +---------- + +FIXME: Go build instructions + +FIXME: Go test instructions + +Making a new Release +-------------------- + +FIXME: Go release instructions + +TODO +---- +* Make search work cross color boundaries. Currently, if you have a syntax + highlighted line and search for something across a color change you won't get + any match. + +* Handle search hits to the right of the right screen edge. Searching + forwards should move first right, then to the left edge and + down. Searching backwards should move first left, then up and to the + right edge (if needed for showing search hits). + +* Auto generate the in-program help text to correctly correspond to + the actual key bindings. + * If you try to bind the same key to multiple actions, that must be caught by + the unit tests. + * If you try to bind to an action that doesn't exist, that must be caught by + the unit tests. + +* Read `source-highlight` output as a stream for startup performance reasons. + This must work when `source-highlight` fails as well, and when it succeeds on + an empty input file. + +* When skipping to the end, either while searching or when the user presses '>', + try finding the end of the file for at most two seconds, then show wherever we + are. Pressing '>' again or searching again should make another attempt until + we're actually done. + +* Redefine 'g' without any prefix to prompt for which line to go + to. This definition makes more sense to me than having to prefix 'g' + to jump. + +* Start at a certain line if run as "moar.rb file.txt:42" + +* Enable home / end using home / end keys. + +* Always print the name of the file being shown in the status field. + +* Support viewing multiple files by pushing them in reverse order on + the view stack. + +* Add search line editing + +* Try to find a newer Ruby version if needed for color support and + exec() with that instead if available. + +* Write "/ to search" somewhere in the status field + +* Incremental search using ^s and ^r like in Emacs + +* Gunzip input files with .gz extension before displaying them + +* Warn but don't hang if we get an incomplete UTF-8 sequence from + getch() in wide_getch(). Hanging won't be that much of a problem + assuming users will press more keys if nothing happens, thus + resolving the hang. + +* Enable up / down using the mouse wheel. + + +DONE +---- +* Enable exiting using q (restores screen) + +* Handle the terminal window getting resized. + +* Print info line in inverse video + +* Enable up / down using arrow keys. + +* Prevent pressing down past the last line of the file. + +* Enable out-of-file visualization with ~ like less. + +* Enable up / down using page-up and page-down keys. + +* Enable home / end using < and >. + +* Enable file input. + +* Enable continuous position display with everything we know (lines + visible, percentages, like less). + +* Enable stdin input. + +* Truncate lines that are longer than the screen width + +* Make sure we can print all the way into the rightmost column of the + screen when truncating too long lines. We should strip() lines + before we print them and manually move the cursor to the next line + after each. + +* Handle all kinds of line endings. + +* Handle files missing an ending newline. + +* Handle hitting BACKSPACE in the search field + +* Incremental search using / + +* Typing backspace in the line editor when it's empty should make the + line editor say "done". + +* Change out-of-file visualization to writing --- after the end of the + file and leaving the rest of the screen blank. + +* Scroll down if we have no search hits on the current screen + +* Wrap search if we have search hits above but not below + +* Find next using n + +* Highlight search hits using reverse video + +* Make sure we can properly render all lines of /etc/php.ini.default + without the bottom-of-the-screen prompt moving around. + +* Find previous using N + +* Indicate when we're wrapping the search while pressing n. + +* Indicate when we're wrapping the search while pressing N. + +* Highlight all matches while searching + +* Scroll down one line on RETURN + +* Print warnings to stderr after the run, for example if we aren't + using color support because of a too-old version of Ruby. + +* Make stdin input work even on newer (than 1.8) versions of + Ruby. Apparently + [this patch](http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/io.c?r1=7641&r2=7649&diff_format=h) + is the reason it doesn't + work. [Reported to the Ruby issue tracker](https://bugs.ruby-lang.org/issues/9067), + let's see how that goes. + +* Enable displaying colorized output from "git diff" + * Arrow down through the whole file, then arrow up again + * Page down through the whole file, then page up again + * Search highlighting + +* Use the same algorithm for highlighting as for determining which + lines match. + +* Make the search case sensitive only if it contains any capital + letters. + +* Do a regexp search if the search term is a valid regexp, otherwise + just use it as a substring. + +* Make the search case sensitive only if it contains any capital + letters, for both regexps and non-regexps. + +* If we print warnings at the end, also print an URL where they can be + reported. + +* If we crash with a stacktrace, print an URL where it can be reported + +* Enable sideways scrolling using arrow keys. + +* Warn about any unhandled keypresses during search. + +* Enable displaying a man page + * Arrow down through the whole file, then arrow up again + * Page down through the whole file, then page up again + * Search highlighting + +* Make sure we get the line length right even with unicode characters + present in the lines. Verify by looking at where the truncation + markers end up. + +* Make sure we can search for unicode characters + * Work around + [the issue with getch not returning unicode chars](https://bugs.ruby-lang.org/issues/9094) + + * Work around + [the issue with Regexp.quote() returning non-unicode strings](https://bugs.ruby-lang.org/issues/9096) + +* Warn but don't crash if we get an invalid UTF-8 sequence from + getch() in wide_getch(). + +* Make sure the LANG environment variable is printed if there are +warnings. + +* Make sure some kind of platform information is printed if there are +warnings. + +* Make sure the Ruby version is printed if there are warnings. + +* Startup exceptions should be caught through the same reporting + thingy as everything else. + +* We must not crash on getting binary data. Testcase: "moar.rb /bin/ls" + +* Fix handling of TAB characters in the input + +* Run rubocop as part of test.rb if installed and have the exit code + reflect any issues. + +* Make sure version information is printed if there are warnings. + +* Make it possible to install system-wide using "rake install". Don't + forget to fix the version number when doing this. + +* Enable --help for help + +* Enable --version for version information. + +* Report command line errors, think about different command line + requirements depending on whether we're piping input into moar.rb or + listing input files on the command line. + + Command line formats we want to support: + * moar.rb file.txt + * moar.rb < file.txt + + Command line formats we *don't* want to support: + * moar.rb file1.txt file2.txt + * moar.rb file1.txt < file2.txt + +* Enable 'h', '?' or F1 for help + +* Print something nice on file-not-found. + +* Test on Ubuntu + +* Test on Ruby 1.8.something. We did, and due to missing UTF-8 support + in Ruby 1.8 we just dropped support for it. Now we print an error + message if Ruby < 1.9 is detected. + +* Add info to the end of the --help output on how to set Moar to be +your default pager. + +* Add licensing information (BSD) + +* Enable source code highlighting by pre-filtering using GNU + Source-highlight. + +* Retain the search string when pressing / to search a second time. + +* Exit search mode and cancel the search on ESC. Because that's what I + feel like pressing. + +* Exit search mode and cancel the search on ^G. For compatibility with + Emacs. + +* Make sure searching for an upper case unicode character turns on + case sensitive search. + +* Doing moar.rb on an arbitrary binary (like /bin/ls) should put all + line-continuation markers at the rightmost column. This really + means our truncation code must work even with things like tabs and + various control characters. + +* Enable exiting using ^c (without restoring the screen). + +* Enable pass-through operation unless $stdout.isatty() + +* Accept numeric prefixes just like less. Implement for 'g', 'G' and + SPACE to begin with. + +* Exit search on pressing up / down / pageup / pagedown keys and + scroll. I attempted to do that spontaneously, so it's probably a + good idea. + +* Searching for something above us should wrap the search. + +* When pressing '/' to edit the search terms, find a hit and + re-highlight. + +* Make sure "git grep" output gets highlighted properly. + +* Lazy load big / slow streams + +* Add making binaries to the Making a new Release section above. diff --git a/sample-files/dos.txt b/sample-files/dos.txt new file mode 100644 index 0000000..50d0ceb --- /dev/null +++ b/sample-files/dos.txt @@ -0,0 +1,75 @@ + 1 #!/usr/bin/ruby + 2 + 3 require "curses" + 4 + 5 class Moar + 6 include Curses + 7 + 8 def initialize(file) + 9 @first_line = 0 + 10 @file = file + 11 @lines = IO.readlines(file) + 12 @last_key = 0 + 13 end + 14 + 15 def draw_screen() + 16 # @first_line must not be closer than lines-2 from the end + 17 max_first_line = @lines.size - (lines - 1) + 18 @first_line = [@first_line, max_first_line].min() + 19 + 20 # @first_line cannot be negative + 21 @first_line = [0, @first_line].max() + 22 + 23 clear() + 24 setpos(0, 0) + 25 + 26 attrset(A_NORMAL) + 27 last_line = @first_line + lines - 2 + 28 for line_number in @first_line..last_line do + 29 if line_number < @lines.size + 30 addstr(@lines[line_number]) + 31 else + 32 addstr("~\n") + 33 end + 34 end + 35 + 36 attrset(A_REVERSE) + 37 status = "Lines #{@first_line + 1}-" + 38 status += "#{[@lines.size, last_line].min()}" + 39 status += "/#{@lines.size}" + 40 addstr(status) + 41 + 42 refresh() + 43 end + 44 + 45 def run + 46 init_screen + 47 noecho + 48 stdscr.keypad(true) + 49 + 50 begin + 51 crmode + 52 while true + 53 draw_screen() + 54 + 55 key = getch() + 56 case key + 57 when ?q.ord + 58 break + 59 when Key::RESIZE + 60 draw_screen() + 61 when Key::DOWN + 62 @first_line += 1 + 63 when Key::UP + 64 @first_line -= 1 + 65 end + 66 + 67 @last_key = key + 68 end + 69 ensure + 70 close_screen + 71 end + 72 end + 73 end + 74 + 75 Moar.new(ARGV[0]).run() diff --git a/sample-files/gitdiff-color.txt b/sample-files/gitdiff-color.txt new file mode 100644 index 0000000..568f72e --- /dev/null +++ b/sample-files/gitdiff-color.txt @@ -0,0 +1,100 @@ +commit 0ccc858f87d70c302117db9034186754a4091f23 +Author: Johan Walles +Date: Thu Oct 24 20:45:40 2013 +0200 + + Prioritize the TODO file + +diff --git a/TODO.txt b/TODO.txt +index 52551e7..663ffd7 100644 +--- a/TODO.txt ++++ b/TODO.txt +@@ -1,36 +1,48 @@ + Moar is a pager. It's designed to be easy to use and just do the + right thing without any configuration. +  +-TODO (in some order): ++TODO (before using it myself) ++----------------------------- ++* Scroll down one line on RETURN +  +-* Write "/ to search" somewhere in the status field ++* Enable displaying ANSI-colored input ++ ++ ++TODO (before github) ++-------------------- +  ++TODO (before trying to get others to use it) ++-------------------------------------------- + * Do a regexp search if the search term is a valid regexp, otherwise + just use it as a substring. +  +-* Make the search case sensitive only if it contains any capital +- letters. This goes for both regexps and non-regexps. +- + * Make sure we can search for unicode characters +  +-* Make sure searching for an upper case unicode character turns on +- case sensitive search. +- + * Make sure we get the line length right even with unicode characters + present in the lines. Verify by looking at where the truncation + markers end up. +  +-* Scroll down one line on RETURN +- + * Enable sideways scrolling using arrow keys. +  + * Handle search hits to the right of the right screen edge +  +-* Interactive search using ^s and ^r like in Emacs ++* Enable 'h' or '?' for help +  +-* Highlight all matches while searching ++* Report command line errors, think about when to use $stdin for input ++ vs what commands we accept +  +-* Enable displaying ANSI-colored input ++ ++TODO (bonus) ++------------ ++* Make the search case sensitive only if it contains any capital ++ letters. This goes for both regexps and non-regexps. ++ ++* Make sure searching for an upper case unicode character turns on ++ case sensitive search. ++ ++* Write "/ to search" somewhere in the status field ++ ++* Interactive search using ^s and ^r like in Emacs +  + * Enable filtered input, start with zcat as a filter +  +@@ -47,11 +59,6 @@ TODO (in some order): +  + * Enable up / down using the mouse wheel. +  +-* Enable 'h' or '?' for help +- +-* Report command line errors, think about when to use $stdin for input +- vs what commands we accept +- + * Enable pass-through operation unless $stdout.isatty() +  + * Doing moar.rb on an arbitrary binary (like /bin/ls) should put all +@@ -60,7 +67,8 @@ TODO (in some order): + various control characters. +  +  +-DONE: ++DONE ++---- + * Enable exiting using q (restores screen) +  + * Handle the terminal window getting resized. +@@ -121,3 +129,5 @@ DONE: + * Indicate when we're wrapping the search while pressing n. +  + * Indicate when we're wrapping the search while pressing N. ++ ++* Highlight all matches while searching diff --git a/sample-files/hej.txt b/sample-files/hej.txt new file mode 100644 index 0000000..6fa8ac9 --- /dev/null +++ b/sample-files/hej.txt @@ -0,0 +1,197 @@ + +PRINTF(1) BSD General Commands Manual PRINTF(1) + +NNAAMMEE + pprriinnttff -- formatted output + +SSYYNNOOPPSSIISS + pprriinnttff _f_o_r_m_a_t [_a_r_g_u_m_e_n_t_s _._._.] + +DDEESSCCRRIIPPTTIIOONN + The pprriinnttff utility formats and prints its arguments, after the first, + under control of the _f_o_r_m_a_t. The _f_o_r_m_a_t is a character string which con- + tains three types of objects: plain characters, which are simply copied + to standard output, character escape sequences which are converted and + copied to the standard output, and format specifications, each of which + causes printing of the next successive _a_r_g_u_m_e_n_t. + + The _a_r_g_u_m_e_n_t_s after the first are treated as strings if the corresponding + format is either cc, bb or ss; otherwise it is evaluated as a C constant, + with the following extensions: + + ++oo A leading plus or minus sign is allowed. + ++oo If the leading character is a single or double quote, the value + is the ASCII code of the next character. + + The format string is reused as often as necessary to satisfy the + _a_r_g_u_m_e_n_t_s. Any extra format specifications are evaluated with zero or + the null string. + + Character escape sequences are in backslash notation as defined in the + ANSI X3.159-1989 (``ANSI C89''), with extensions. The characters and + their meanings are as follows: + + \\aa Write a character. + \\bb Write a character. + \\cc Ignore remaining characters in this string. + \\ff Write a character. + \\nn Write a character. + \\rr Write a character. + \\tt Write a character. + \\vv Write a character. + \\'' Write a character. + \\\\ Write a backslash character. + \\_n_u_m + \\00_n_u_m Write an 8-bit character whose ASCII value is the 1-, 2-, + or 3-digit octal number _n_u_m. + + Each format specification is introduced by the percent character (``%''). + The remainder of the format specification includes, in the following + order: + + Zero or more of the following flags: + + ## A `#' character specifying that the value should be + printed in an ``alternate form''. For cc, dd, and ss, for- + mats, this option has no effect. For the oo formats the + precision of the number is increased to force the first + character of the output string to a zero. For the xx (XX) + format, a non-zero result has the string 0x (0X) + prepended to it. For ee, EE, ff, gg, and GG, formats, the + result will always contain a decimal point, even if no + digits follow the point (normally, a decimal point only + appears in the results of those formats if a digit fol- + lows the decimal point). For gg and GG formats, trailing + zeros are not removed from the result as they would oth- + erwise be; + + -- A minus sign `-' which specifies _l_e_f_t _a_d_j_u_s_t_m_e_n_t of the + output in the indicated field; + + ++ A `+' character specifying that there should always be a + sign placed before the number when using signed formats. + + ` ' A space specifying that a blank should be left before a + positive number for a signed format. A `+' overrides a + space if both are used; + + 00 A zero `0' character indicating that zero-padding should + be used rather than blank-padding. A `-' overrides a `0' + if both are used; + + Field Width: + An optional digit string specifying a _f_i_e_l_d _w_i_d_t_h; if the output + string has fewer characters than the field width it will be + blank-padded on the left (or right, if the left-adjustment indi- + cator has been given) to make up the field width (note that a + leading zero is a flag, but an embedded zero is part of a field + width); + + Precision: + An optional period, `..', followed by an optional digit string + giving a _p_r_e_c_i_s_i_o_n which specifies the number of digits to appear + after the decimal point, for ee and ff formats, or the maximum num- + ber of characters to be printed from a string; if the digit + string is missing, the precision is treated as zero; + + Format: + A character which indicates the type of format to use (one of + ddiioouuxxXXffFFeeEEggGGaaAAccssbb). The uppercase formats differ from their low- + ercase counterparts only in that the output of the former is + entirely in uppercase. The floating-point format specifiers + (ffFFeeEEggGGaaAA) may be prefixed by an LL to request that additional + precision be used, if available. + + A field width or precision may be `**' instead of a digit string. In this + case an _a_r_g_u_m_e_n_t supplies the field width or precision. + + The format characters and their meanings are: + + ddiioouuXXxx The _a_r_g_u_m_e_n_t is printed as a signed decimal (d or i), + unsigned octal, unsigned decimal, or unsigned hexadecimal (X + or x), respectively. + + ffFF The _a_r_g_u_m_e_n_t is printed in the style `[-]ddd.ddd' where the + number of d's after the decimal point is equal to the preci- + sion specification for the argument. If the precision is + missing, 6 digits are given; if the precision is explicitly + 0, no digits and no decimal point are printed. The values + infinity and _N_a_N are printed as `inf' and `nan', respec- + tively. + + eeEE The _a_r_g_u_m_e_n_t is printed in the style ee `[-_d_._d_d_d+-_d_d]' where + there is one digit before the decimal point and the number + after is equal to the precision specification for the argu- + ment; when the precision is missing, 6 digits are produced. + The values infinity and _N_a_N are printed as `inf' and `nan', + respectively. + + ggGG The _a_r_g_u_m_e_n_t is printed in style ff (FF) or in style ee (EE) + whichever gives full precision in minimum space. + + aaAA The _a_r_g_u_m_e_n_t is printed in style `[-_h_._h_h_h+-p_d]' where there + is one digit before the hexadecimal point and the number + after is equal to the precision specification for the argu- + ment; when the precision is missing, enough digits are pro- + duced to convey the argument's exact double-precision float- + ing-point representation. The values infinity and _N_a_N are + printed as `inf' and `nan', respectively. + + cc The first character of _a_r_g_u_m_e_n_t is printed. + + ss Characters from the string _a_r_g_u_m_e_n_t are printed until the end + is reached or until the number of characters indicated by the + precision specification is reached; however if the precision + is 0 or missing, all characters in the string are printed. + + bb As for ss, but interpret character escapes in backslash nota- + tion in the string _a_r_g_u_m_e_n_t. + + %% Print a `%'; no argument is used. + + The decimal point character is defined in the program's locale (category + LC_NUMERIC). + + In no case does a non-existent or small field width cause truncation of a + field; padding takes place only if the specified field width exceeds the + actual width. + +EEXXIITT SSTTAATTUUSS + The pprriinnttff utility exits 0 on success, and >0 if an error occurs. + +CCOOMMPPAATTIIBBIILLIITTYY + The traditional BSD behavior of converting arguments of numeric formats + not beginning with a digit to the ASCII code of the first character is + not supported. + +SSEEEE AALLSSOO + echo(1), printf(3) + +SSTTAANNDDAARRDDSS + The pprriinnttff command is expected to be mostly compatible with the IEEE Std + 1003.2 (``POSIX.2'') specification. + +HHIISSTTOORRYY + The pprriinnttff command appeared in 4.3BSD-Reno. It is modeled after the + standard library function, printf(3). + +BBUUGGSS + Since the floating point numbers are translated from ASCII to floating- + point and then back again, floating-point precision may be lost. (By + default, the number is translated to an IEEE-754 double-precision value + before being printed. The LL modifier may produce additional precision, + depending on the hardware platform.) + + ANSI hexadecimal character constants were deliberately not provided. + + The escape sequence \000 is the string terminator. When present in the + argument for the bb format, the argument will be truncated at the \000 + character. + + Multibyte characters are not recognized in format strings (this is only a + problem if `%' can appear inside a multibyte character). + + Parsing of - arguments is also somewhat different from printf(3), where + unknown arguments are simply printed instead of being flagged as errors. + +BSD April 14, 2005 BSD diff --git a/sample-files/large-git-log-patch.txt b/sample-files/large-git-log-patch.txt new file mode 100644 index 0000000..71f8dbb --- /dev/null +++ b/sample-files/large-git-log-patch.txt @@ -0,0 +1,289477 @@ +commit 3a164ae699b2676a6648622fd4be2d427ca8e587 (HEAD -> master, origin/master, origin/HEAD) +Merge: dcfd089 cb95be3 +Author: Mathias Åhsberg +Date: Thu Mar 9 10:35:38 2017 +0100 + + Merge pull request #682 from walles/walles/unused + + Re-enable some Unused warnings + +commit cb95be3d87edc40f7bb4a7502d989803f33f500a (walles/walles/unused, walles/unused) +Author: Johan Walles +Date: Wed Mar 8 21:52:57 2017 +0100 + + Disable an unused Lint rule + +diff --git a/config/quality/lint/lint.xml b/config/quality/lint/lint.xml +index 71a7793..e8fe111 100644 +--- a/config/quality/lint/lint.xml ++++ b/config/quality/lint/lint.xml +@@ -20,7 +20,6 @@ +  +  +  +-  +  +  +  + +commit dcfd0893a07e7703aeb5fb61a9affb0b5f3f6c87 (walles/checks) +Merge: 0303e7d a20852c +Author: Mathias Åhsberg +Date: Wed Mar 8 21:52:00 2017 +0100 + + Merge pull request #681 from liato/feature/upgrade-build-tools + + Upgrade android build tools + +commit 11f299972fdd6154872c68aebc4947eb816d3551 +Author: Johan Walles +Date: Wed Mar 8 21:47:56 2017 +0100 + + Re-enable some Unused warnings + + Before Android Studio 2.3.0 having these enabled triggered internal + errors in Lint. Those errors have now been fixed and the checks can be + re-enabled. + +diff --git a/bankdroid-legacy/src/main/res/values-sv/strings.xml b/bankdroid-legacy/src/main/res/values-sv/strings.xml +index 36f71c5..e3f6dfa 100644 +--- a/bankdroid-legacy/src/main/res/values-sv/strings.xml ++++ b/bankdroid-legacy/src/main/res/values-sv/strings.xml +@@ -2,16 +2,12 @@ + Användarnamn + Lösenord + Kortnummer +- Kontonummer +- Kontrollkod + E-post + poäng + Kort ID + Saldo + ÅÅÅÅMMDDNNNN +  +- Nyckel +- + Bitcoin-adress + Ogiltig bitcoin-adress. + Allmän pension +@@ -24,7 +20,6 @@ + Inga konton funna + Ogiltigt användarnamn. + Ogiltigt kortnummer. +- Banken är för närvarande stängd. + Serverfel. Var god försök igen om en stund. + Kunde ej uppdatera transaktionsdata. Var vänlig försök igen senare. +  +diff --git a/bankdroid-legacy/src/main/res/values/strings.xml b/bankdroid-legacy/src/main/res/values/strings.xml +index a80426d..89167f4 100644 +--- a/bankdroid-legacy/src/main/res/values/strings.xml ++++ b/bankdroid-legacy/src/main/res/values/strings.xml +@@ -5,16 +5,12 @@ + Password + Extras + Card number +- Account number +- Control code + E-mail + points + Card ID + Balance + YYYYMMDDNNNN +  +- Key +- + Bitcoin address + Invalid bitcoin address. + Public pension +@@ -27,7 +23,6 @@ + No accounts found + Invalid username. + Invalid card number. +- The bank is currently closed. + Server error. Please try again later. + "There was a problem updating the transaction details. Please try again later." +  +diff --git a/config/quality/lint/lint.xml b/config/quality/lint/lint.xml +index c3565a5..71a7793 100644 +--- a/config/quality/lint/lint.xml ++++ b/config/quality/lint/lint.xml +@@ -47,8 +47,6 @@ +  +  +  +-  +-  +  +  +  + +commit a20852c17d74128d8071b7e6139115794d09cbe2 (origin/feature/upgrade-build-tools, feature/upgrade-build-tools) +Author: Mathias Åhsberg +Date: Thu Mar 2 21:40:58 2017 +0100 + + Fixes travis build + +diff --git a/.travis.yml b/.travis.yml +index 6c53f33..dadb73b 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -10,14 +10,14 @@ cache: +  + env: + matrix: +- - ANDROID_TARGET=android-24 ANDROID_ABI=armeabi-v7a ++ - ANDROID_TARGET=android-25 ANDROID_ABI=armeabi-v7a +  + android: + components: + - tools + - platform-tools +- - build-tools-24.0.3 +- - android-24 ++ - build-tools-25.0.1 ++ - android-25 + - extra-android-m2repository +  + script: ./gradlew assembleDebug check + +commit e6e1e4fdec9bf27aadef0d5c22d35a56c2253708 +Author: Mathias Åhsberg +Date: Thu Mar 2 21:33:49 2017 +0100 + + Upgrade android build tools + +diff --git a/app/build.gradle b/app/build.gradle +index 11832d8..f73b061 100644 +--- a/app/build.gradle ++++ b/app/build.gradle +@@ -38,14 +38,14 @@ ext { + } +  + android { +- compileSdkVersion 24 +- buildToolsVersion "24.0.3" ++ compileSdkVersion 25 ++ buildToolsVersion "25.0.1" +  + useLibrary 'org.apache.http.legacy' + defaultConfig { + applicationId "com.liato.bankdroid" + minSdkVersion 9 +- targetSdkVersion 24 ++ targetSdkVersion 25 + versionCode 224 + gitVersionCode + versionName gitVersionName + } +@@ -87,7 +87,7 @@ dependencies { + compile project(':bankdroid-core') + compile 'com.jakewharton:butterknife:6.1.0' + compile 'com.jakewharton.timber:timber:4.3.1' +- compile "com.android.support:appcompat-v7:24.2.1" ++ compile "com.android.support:appcompat-v7:25.2.0" + compile 'com.google.collections:google-collections:1.0' + compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') { + transitive = true; +diff --git a/app/src/main/java/com/liato/bankdroid/MainActivity.java b/app/src/main/java/com/liato/bankdroid/MainActivity.java +index 98c8a2b..78d7ff8 100644 +--- a/app/src/main/java/com/liato/bankdroid/MainActivity.java ++++ b/app/src/main/java/com/liato/bankdroid/MainActivity.java +@@ -59,7 +59,7 @@ public class MainActivity extends LockableActivity { +  + protected static boolean showHidden = false; +  +- private static Bank selectedBank = null; ++ private Bank selectedBank = null; +  + private static Account selectedAccount = null; +  +@@ -241,7 +241,7 @@ public class MainActivity extends LockableActivity { + final Button btnHide = (Button) root.findViewById(R.id.btnHide); + final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide); + final Button btnWWW = (Button) root.findViewById(R.id.btnWWW); +- if (selectedBank.getHideAccounts()) { ++ if (parent.selectedBank.getHideAccounts()) { + btnHide.setVisibility(View.GONE); + btnUnhide.setVisibility(View.VISIBLE); + btnUnhide.setOnClickListener(this); +@@ -250,7 +250,7 @@ public class MainActivity extends LockableActivity { + btnUnhide.setVisibility(View.GONE); + btnHide.setOnClickListener(this); + } +- if (selectedBank.isWebViewEnabled()) { ++ if (parent.selectedBank.isWebViewEnabled()) { + btnWWW.setOnClickListener(this); + } else { + btnWWW.setVisibility(View.GONE); +@@ -270,29 +270,29 @@ public class MainActivity extends LockableActivity { + case R.id.btnHide: + case R.id.btnUnhide: + this.dismiss(); +- selectedBank.toggleHideAccounts(); +- DBAdapter.save(selectedBank, context); ++ parent.selectedBank.toggleHideAccounts(); ++ DBAdapter.save(parent.selectedBank, context); + parent.refreshView(); + return; + case R.id.btnWWW: +- if (selectedBank != null && selectedBank.isWebViewEnabled()) { ++ if (parent.selectedBank != null && parent.selectedBank.isWebViewEnabled()) { + //Uri uri = Uri.parse(selectedBank.getURL()); + //Intent intent = new Intent(Intent.ACTION_VIEW, uri); + final Intent intent = new Intent(context, WebViewActivity.class); +- intent.putExtra("bankid", selectedBank.getDbId()); ++ intent.putExtra("bankid", parent.selectedBank.getDbId()); + context.startActivity(intent); + } + this.dismiss(); + return; + case R.id.btnEdit: + final Intent intent = new Intent(context, BankEditActivity.class); +- intent.putExtra("id", selectedBank.getDbId()); ++ intent.putExtra("id", parent.selectedBank.getDbId()); + context.startActivity(intent); + this.dismiss(); + return; + case R.id.btnRefresh: + this.dismiss(); +- new DataRetrieverTask(parent, selectedBank.getDbId()).execute(); ++ new DataRetrieverTask(parent, parent.selectedBank.getDbId()).execute(); + return; + case R.id.btnRemove: + this.dismiss(); +@@ -307,7 +307,7 @@ public class MainActivity extends LockableActivity { + public void onClick(final DialogInterface dialog, + final int id) { + final DBAdapter db = new DBAdapter(context); +- db.deleteBank(selectedBank.getDbId()); ++ db.deleteBank(parent.selectedBank.getDbId()); + dialog.cancel(); + parent.refreshView(); + } +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java +index 4d1ce55..80b12c7 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java +@@ -154,7 +154,7 @@ public class FieldBuilder { +  + @Override + public void validate(String value) throws IllegalArgumentException { +- if (isRequired()) { ++ if (required) { + if (value == null || value.trim().isEmpty()) { + throw new IllegalArgumentException(String.format("%s is required", getLabel())); + } +@@ -168,7 +168,7 @@ public class FieldBuilder { + if (!isLocale()) { + return null; + } +- String propertyKey = String.format("field.%s.%s", getReference(), key); ++ String propertyKey = String.format("field.%s.%s", reference, key); + return resourceBundle.containsKey(propertyKey) ? resourceBundle.getString(propertyKey) + : propertyKey; + } +diff --git a/bankdroid-legacy/build.gradle b/bankdroid-legacy/build.gradle +index 2cda778..e9b4290 100644 +--- a/bankdroid-legacy/build.gradle ++++ b/bankdroid-legacy/build.gradle +@@ -2,13 +2,13 @@ apply plugin: 'com.android.library' + apply from: '../config/quality/quality.gradle' +  + android { +- compileSdkVersion 24 +- buildToolsVersion "24.0.3" ++ compileSdkVersion 25 ++ buildToolsVersion "25.0.1" +  + useLibrary 'org.apache.http.legacy' + defaultConfig { + minSdkVersion 9 +- targetSdkVersion 24 ++ targetSdkVersion 25 + versionCode 1 + versionName "1.0" + } +@@ -27,7 +27,7 @@ android { + dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile project(':bankdroid-interface') +- compile 'com.android.support:appcompat-v7:24.2.1' ++ compile 'com.android.support:appcompat-v7:25.2.0' + compile 'com.jakewharton.timber:timber:4.3.1' + compile ('org.apache.commons:commons-io:1.3.2') {exclude module: 'commons-io'} + compile 'org.jsoup:jsoup:1.7.3' +diff --git a/build.gradle b/build.gradle +index 76cbdfb..bf6f81e 100644 +--- a/build.gradle ++++ b/build.gradle +@@ -5,7 +5,7 @@ buildscript { + jcenter() + } + dependencies { +- classpath 'com.android.tools.build:gradle:2.2.3' ++ classpath 'com.android.tools.build:gradle:2.3.0' +  + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files +@@ -30,5 +30,5 @@ subprojects { + } +  + task wrapper(type: Wrapper) { +- gradleVersion = '3.1' ++ gradleVersion = '3.3' + } +diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties +index 8893515..382630b 100644 +--- a/gradle/wrapper/gradle-wrapper.properties ++++ b/gradle/wrapper/gradle-wrapper.properties +@@ -1,6 +1,6 @@ +-#Thu Sep 29 21:09:55 CEST 2016 ++#Thu Mar 02 21:11:13 CET 2017 + distributionBase=GRADLE_USER_HOME + distributionPath=wrapper/dists + zipStoreBase=GRADLE_USER_HOME + zipStorePath=wrapper/dists +-distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip ++distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip + +commit 0303e7dbb40f21d278fa7aad7274430f4a871183 +Merge: 3c25a39 a08f401 +Author: Mathias Åhsberg +Date: Sat Feb 25 20:49:34 2017 +0100 + + Merge pull request #680 from liato/feature/remove-avanza + + Remove support for Avanza and Avanza mini + +commit a08f401c4d0b53cbbac74aaadd5527f847ccbee0 +Author: Mathias Åhsberg +Date: Wed Feb 22 22:18:58 2017 +0100 + + Remove support for Avanza and Avnza mini + +diff --git a/CHANGELOG b/CHANGELOG +index 6995d6b..53ddb44 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. +  + (Unreleased) + * Update certificates ++* Remove support for Avanza and Avanza Mini +  + v1.9.14 (2017-01-06) + * Updated certificates for First Card, Osuuspankki and Östgötatrafiken +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java +index f95ef32..2bdf551 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java +@@ -4,7 +4,6 @@ import com.liato.bankdroid.banking.banks.AkeliusInvest; + import com.liato.bankdroid.banking.banks.AkeliusSpar; + import com.liato.bankdroid.banking.banks.americanexpress.AmericanExpress; + import com.liato.bankdroid.banking.banks.AppeakPoker; +-import com.liato.bankdroid.banking.banks.AvanzaMini; + import com.liato.bankdroid.banking.banks.BetterGlobe; + import com.liato.bankdroid.banking.banks.Bioklubben; + import com.liato.bankdroid.banking.banks.BlekingeTrafiken; +@@ -36,7 +35,6 @@ import com.liato.bankdroid.banking.banks.TestBank; + import com.liato.bankdroid.banking.banks.TicketRikskortet; + import com.liato.bankdroid.banking.banks.Vasttrafik; + import com.liato.bankdroid.banking.banks.Zidisha; +-import com.liato.bankdroid.banking.banks.avanza.Avanza; + import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin; + import com.liato.bankdroid.banking.banks.coop.Coop; + import com.liato.bankdroid.banking.banks.ica.ICA; +@@ -71,10 +69,6 @@ public class LegacyBankFactory { + return new Coop(context); + case IBankTypes.ICA: + return new ICA(context); +- case IBankTypes.AVANZA: +- return new Avanza(context); +- case IBankTypes.AVANZAMINI: +- return new AvanzaMini(context); + case IBankTypes.OKQ8: + return new OKQ8(context); + case IBankTypes.FIRSTCARD: +@@ -157,8 +151,6 @@ public class LegacyBankFactory { + banks.add(new Lansforsakringar(context)); + banks.add(new Coop(context)); + banks.add(new ICA(context)); +- banks.add(new Avanza(context)); +- banks.add(new AvanzaMini(context)); + banks.add(new OKQ8(context)); + banks.add(new FirstCard(context)); + banks.add(new Payson(context)); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java +deleted file mode 100644 +index 5f7889b..0000000 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* +- * Copyright (C) 2014 Nullbyte  +- * +- * 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. +- */ +- +-package com.liato.bankdroid.banking.banks; +- +-import com.liato.bankdroid.banking.banks.avanza.Avanza; +-import com.liato.bankdroid.legacy.R; +-import com.liato.bankdroid.provider.IBankTypes; +- +-import android.content.Context; +- +-public class AvanzaMini extends Avanza { +- +- public AvanzaMini(Context context) { +- super(context, R.drawable.logo_avanzamini); +- url = "https://www.avanza.se/mini/hem/"; +- } +- +- @Override +- public int getBanktypeId() { +- return IBankTypes.AVANZAMINI; +- } +- +- @Override +- public String getName() { +- return "Avanza Mini"; +- } +-} +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java +deleted file mode 100644 +index 3d3aa64..0000000 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java ++++ /dev/null +@@ -1,213 +0,0 @@ +-/* +- * Copyright (C) 2014 Nullbyte  +- * +- * 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. +- */ +- +-package com.liato.bankdroid.banking.banks.avanza; +- +-import com.fasterxml.jackson.core.JsonParseException; +-import com.fasterxml.jackson.databind.ObjectMapper; +-import com.liato.bankdroid.Helpers; +-import com.liato.bankdroid.banking.Account; +-import com.liato.bankdroid.banking.Bank; +-import com.liato.bankdroid.banking.Transaction; +-import com.liato.bankdroid.banking.banks.avanza.model.AccountOverview; +-import com.liato.bankdroid.banking.banks.avanza.model.Position; +-import com.liato.bankdroid.banking.banks.avanza.model.PositionAggregation; +-import com.liato.bankdroid.banking.exceptions.BankChoiceException; +-import com.liato.bankdroid.banking.exceptions.BankException; +-import com.liato.bankdroid.banking.exceptions.LoginException; +-import com.liato.bankdroid.legacy.R; +-import com.liato.bankdroid.provider.IBankTypes; +-import com.liato.bankdroid.utils.StringUtils; +- +-import org.apache.http.HttpResponse; +-import org.apache.http.NameValuePair; +-import org.apache.http.message.BasicNameValuePair; +-import org.json.JSONException; +-import org.json.JSONObject; +- +-import android.content.Context; +-import android.support.annotation.DrawableRes; +-import android.util.Base64; +- +-import java.io.IOException; +-import java.math.BigDecimal; +-import java.util.ArrayList; +-import java.util.Date; +-import java.util.List; +- +-import eu.nullbyte.android.urllib.CertificateReader; +-import eu.nullbyte.android.urllib.Urllib; +- +-public class Avanza extends Bank { +- +- private static final String API_URL = "https://iphone.avanza.se/iphone-ws/"; +- +- protected Avanza(Context context, @DrawableRes int logoResource) { +- super(context, logoResource); +- url = "https://iphone.avanza.se"; +- } +- +- @Override +- public int getBanktypeId() { +- return IBankTypes.AVANZA; +- } +- +- @Override +- public String getName() { +- return "Avanza"; +- } +- +- public Avanza(Context context) { +- this(context, R.drawable.logo_avanza); +- } +- +- @Override +- protected LoginPackage preLogin() throws BankException, IOException { +- urlopen = new Urllib(context, +- CertificateReader.getCertificates(context, R.raw.cert_avanza)); +- urlopen.addHeader("Referer", url + "/start"); +- List postData = new ArrayList(); +- postData.add(new BasicNameValuePair("j_username", getUsername())); +- postData.add(new BasicNameValuePair("j_password", getPassword())); +- postData.add(new BasicNameValuePair("url", url + "/start")); +- String response = urlopen.open(url + "/ab/handlelogin", postData); +- String homeUrl = ""; +- try { +- JSONObject jsonResponse = new JSONObject(response); +- homeUrl = jsonResponse.getString("redirectUrl"); +- } catch (JSONException e) { +- throw new BankException( +- res.getText(R.string.unable_to_find).toString() + " login link.", e); +- } +- LoginPackage lp = new LoginPackage(urlopen, postData, "", url + homeUrl); +- lp.setIsLoggedIn(true); +- return lp; +- } +- +- public Urllib login() throws LoginException, BankException, IOException { +- urlopen = new Urllib(context, +- CertificateReader.getCertificates(context, R.raw.cert_avanza)); +- urlopen.addHeader("ctag", "1122334455"); +- urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString( +- StringUtils.getBytes(getUsername() + ":" + getPassword()), Base64.NO_WRAP)); +- balance = new BigDecimal(0); +- +- try { +- HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "account/overview/all", +- new ArrayList(), false); +- if (httpResponse.getStatusLine().getStatusCode() == 401) { +- throw new LoginException(context.getText( +- R.string.invalid_username_password).toString()); +- } +- ObjectMapper vObjectMapper = new ObjectMapper(); +- AccountOverview r = vObjectMapper.readValue(httpResponse.getEntity().getContent(), +- AccountOverview.class); +- for (com.liato.bankdroid.banking.banks.avanza.model.Account account : r.getAccounts()) { +- Account a = new Account(account.getAccountName(), +- new BigDecimal(account.getOwnCapital()), account.getAccountId()); +- if (!account.getCurrencyAccounts().isEmpty()) { +- a.setCurrency(account.getCurrencyAccounts().get(0).getCurrency()); +- } +- if (!account.getPositionAggregations().isEmpty()) { +- Date now = new Date(); +- ArrayList transactions = new ArrayList(); +- for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account +- .getCurrencyAccounts()) { +- transactions.add(new Transaction(Helpers.formatDate(now), +- "\u2014 " + currencyAccount.getCurrency() + " \u2014", +- BigDecimal.valueOf(currencyAccount.getBalance()), +- currencyAccount.getCurrency())); +- } +- for (PositionAggregation positionAgList : account.getPositionAggregations()) { +- if (positionAgList.getPositions().isEmpty()) { +- continue; +- } +- List positions = positionAgList.getPositions(); +- transactions.add(new Transaction(Helpers.formatDate(now), +- "\u2014 " + positionAgList.getInstrumentTypeName() + +- " " + positionAgList.getTotalProfitPercent() + "% \u2014", +- BigDecimal.valueOf(positionAgList.getTotalValue()), +- a.getCurrency())); +- for (Position p : positions) { +- Transaction t = new Transaction(Helpers.formatDate(now), +- p.getInstrumentName(), +- BigDecimal.valueOf(p.getProfit()), +- a.getCurrency()); +- transactions.add(t); +- } +- } +- a.setTransactions(transactions); +- } +- balance = balance.add(a.getBalance()); +- accounts.add(a); +- // Add subtypes for account as own account. +- if (!account.getPositionAggregations().isEmpty()) { +- Date now = new Date(); +- for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account +- .getCurrencyAccounts()) { +- Account b = new Account("\u2014 " + account.getAccountId() + ", " + +- currencyAccount.getCurrency(), +- new BigDecimal(currencyAccount.getBalance()), +- account.getAccountId() + currencyAccount.getCurrency(), +- Account.OTHER, +- currencyAccount.getCurrency()); +- b.setHidden(true); +- accounts.add(b); +- } +- for (PositionAggregation positionAgList : account.getPositionAggregations()) { +- if (positionAgList.getPositions().isEmpty()) { +- continue; +- } +- Account b = new Account("\u2014 " + account.getAccountId() + ", " + +- positionAgList.getInstrumentTypeName() + +- " " + positionAgList.getTotalProfitPercent() + "% ", +- new BigDecimal(positionAgList.getTotalValue()), +- account.getAccountId() + positionAgList.getInstrumentTypeName(), +- Account.OTHER, a.getCurrency()); +- b.setHidden(true); +- ArrayList transactions = new ArrayList(); +- for (Position p : positionAgList.getPositions()) { +- transactions.add(new Transaction(Helpers.formatDate(now), +- p.getInstrumentName(), +- BigDecimal.valueOf(p.getProfit()), +- a.getCurrency())); +- } +- b.setTransactions(transactions); +- accounts.add(b); +- } +- } +- } +- } catch (JsonParseException e) { +- throw new BankException(e.getMessage(), e); +- } +- return urlopen; +- } +- +- @Override +- public void update() throws BankException, LoginException, +- BankChoiceException, IOException { +- super.update(); +- if (getUsername().isEmpty() || getPassword().isEmpty()) { +- throw new LoginException(res.getText( +- R.string.invalid_username_password).toString()); +- } +- login(); +- if (accounts.isEmpty()) { +- throw new BankException(res.getText(R.string.no_accounts_found).toString()); +- } +- super.updateComplete(); +- } +-} +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java +deleted file mode 100644 +index 114b003..0000000 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java ++++ /dev/null +@@ -1,174 +0,0 @@ +-package com.liato.bankdroid.banking.banks.avanza.model; +- +-import com.fasterxml.jackson.annotation.JsonProperty; +- +-import java.io.Serializable; +-import java.util.Collections; +-import java.util.List; +- +-public class Account implements Serializable { +- +- private static final long serialVersionUID = -5718585872348469144L; +- +- @JsonProperty("balance") +- private double mBalance; +- +- @JsonProperty("totalProfit") +- private double mTotalProfit; +- +- @JsonProperty("accountName") +- private String mAccountName; +- +- @JsonProperty("totalAccruedInterest") +- private double mTotalAccruedInterest; +- +- @JsonProperty("adjustedForwardAmount") +- private double mAdjustedForwardAmount; +- +- @JsonProperty("unUsedCredit") +- private double mUnUsedCredit; +- +- @JsonProperty("superInterest") +- private double mSuperInterest; +- +- @JsonProperty("totalMarginRequirement") +- private double mTotalMarginRequirement; +- +- @JsonProperty("tradingPower") +- private double mTradingPower; +- +- @JsonProperty("resAmount") +- private double mResAmount; +- +- @JsonProperty("loanAmount") +- private double mLoanAmount; +- +- @JsonProperty("accountId") +- private String mAccountId; +- +- @JsonProperty("currencyAccounts") +- private List mCurrencyAccounts = Collections.emptyList(); +- +- @JsonProperty("creditLimit") +- private double mCreditLimit; +- +- @JsonProperty("totalProfitPercent") +- private double mTotalProfitPercent; +- +- @JsonProperty("ownCapital") +- private double mOwnCapital; +- +- @JsonProperty("totalValue") +- private double mTotalValue; +- +- @JsonProperty("interestAmount") +- private double mInterestAmount; +- +- @JsonProperty("secAmount") +- private double mSecAmount; +- +- @JsonProperty("positionAggregations") +- private List mPositionAggregations = Collections.emptyList(); +- +- +- @JsonProperty("balance") +- public double getBalance() { +- return mBalance; +- } +- +- @JsonProperty("totalProfit") +- public double getTotalProfit() { +- return mTotalProfit; +- } +- +- @JsonProperty("accountName") +- public String getAccountName() { +- return mAccountName; +- } +- +- @JsonProperty("totalAccruedInterest") +- public double getTotalAccruedInterest() { +- return mTotalAccruedInterest; +- } +- +- @JsonProperty("adjustedForwardAmount") +- public double getAdjustedForwardAmount() { +- return mAdjustedForwardAmount; +- } +- +- @JsonProperty("unUsedCredit") +- public double getUnUsedCredit() { +- return mUnUsedCredit; +- } +- +- @JsonProperty("superInterest") +- public double getSuperInterest() { +- return mSuperInterest; +- } +- +- @JsonProperty("totalMarginRequirement") +- public double getTotalMarginRequirement() { +- return mTotalMarginRequirement; +- } +- +- @JsonProperty("tradingPower") +- public double getTradingPower() { +- return mTradingPower; +- } +- +- @JsonProperty("resAmount") +- public double getResAmount() { +- return mResAmount; +- } +- +- @JsonProperty("loanAmount") +- public double getLoanAmount() { +- return mLoanAmount; +- } +- +- @JsonProperty("accountId") +- public String getAccountId() { +- return mAccountId; +- } +- +- @JsonProperty("currencyAccounts") +- public List getCurrencyAccounts() { +- return mCurrencyAccounts; +- } +- +- @JsonProperty("creditLimit") +- public double getCreditLimit() { +- return mCreditLimit; +- } +- +- @JsonProperty("totalProfitPercent") +- public double getTotalProfitPercent() { +- return mTotalProfitPercent; +- } +- +- @JsonProperty("ownCapital") +- public double getOwnCapital() { +- return mOwnCapital; +- } +- +- @JsonProperty("totalValue") +- public double getTotalValue() { +- return mTotalValue; +- } +- +- @JsonProperty("interestAmount") +- public double getInterestAmount() { +- return mInterestAmount; +- } +- +- @JsonProperty("secAmount") +- public double getSecAmount() { +- return mSecAmount; +- } +- +- @JsonProperty("positionAggregations") +- public List getPositionAggregations() { +- return mPositionAggregations; +- } +- +-} +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java +deleted file mode 100644 +index 19ac97f..0000000 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java ++++ /dev/null +@@ -1,30 +0,0 @@ +-package com.liato.bankdroid.banking.banks.avanza.model; +- +-import com.fasterxml.jackson.annotation.JsonProperty; +- +-import java.io.Serializable; +-import java.util.Collections; +-import java.util.List; +- +-public class AccountOverview implements Serializable { +- +- private static final long serialVersionUID = -5511775495529857976L; +- +- @JsonProperty("totalOwnCapital") +- private float mTotalOwnCapital; +- +- @JsonProperty("accounts") +- private List mAccounts = Collections.emptyList(); +- +- +- @JsonProperty("totalOwnCapital") +- public float getTotalOwnCapital() { +- return mTotalOwnCapital; +- } +- +- @JsonProperty("accounts") +- public List getAccounts() { +- return mAccounts; +- } +- +-} +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java +deleted file mode 100644 +index 76cf0b6..0000000 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java ++++ /dev/null +@@ -1,36 +0,0 @@ +-package com.liato.bankdroid.banking.banks.avanza.model; +- +-import com.fasterxml.jackson.annotation.JsonProperty; +- +-import java.io.Serializable; +- +-public class CurrencyAccount implements Serializable { +- +- private static final long serialVersionUID = 6004713686055778196L; +- +- @JsonProperty("currency") +- private String mCurrency; +- +- @JsonProperty("balance") +- private double mBalance; +- +- @JsonProperty("accountId") +- private String mAccountId; +- +- +- @JsonProperty("currency") +- public String getCurrency() { +- return mCurrency; +- } +- +- @JsonProperty("balance") +- public double getBalance() { +- return mBalance; +- } +- +- @JsonProperty("accountId") +- public String getAccountId() { +- return mAccountId; +- } +- +-} +\ No newline at end of file +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java +deleted file mode 100644 +index 0182251..0000000 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java ++++ /dev/null +@@ -1,124 +0,0 @@ +-package com.liato.bankdroid.banking.banks.avanza.model; +- +-import com.fasterxml.jackson.annotation.JsonProperty; +- +-import java.io.Serializable; +- +-public class Position implements Serializable { +- +- private static final long serialVersionUID = 4138023852221811457L; +- +- @JsonProperty("instrumentName") +- private String mInstrumentName; +- +- @JsonProperty("averageAcquiredPrice") +- private double mAverageAcquiredPrice; +- +- @JsonProperty("marketValue") +- private double mMarketValue; +- +- @JsonProperty("price") +- private double mPrice; +- +- @JsonProperty("profit") +- private double mProfit; +- +- @JsonProperty("modified") +- private long mModified; +- +- @JsonProperty("expiryDate") +- private long mExpiryDate; +- +- @JsonProperty("volume") +- private int mVolume; +- +- @JsonProperty("tradable") +- private boolean mTradable; +- +- @JsonProperty("orderbookId") +- private long mOrderbookId; +- +- @JsonProperty("profitPercent") +- private double mProfitPercent; +- +- @JsonProperty("type") +- private int mType; +- +- @JsonProperty("instrumentType") +- private String mInstrumentType; +- +- @JsonProperty("change") +- private double mChange; +- +- +- @JsonProperty("instrumentName") +- public String getInstrumentName() { +- return mInstrumentName; +- } +- +- @JsonProperty("averageAcquiredPrice") +- public double getAverageAcquiredPrice() { +- return mAverageAcquiredPrice; +- } +- +- @JsonProperty("marketValue") +- public double getMarketValue() { +- return mMarketValue; +- } +- +- @JsonProperty("price") +- public double getPrice() { +- return mPrice; +- } +- +- @JsonProperty("profit") +- public double getProfit() { +- return mProfit; +- } +- +- @JsonProperty("modified") +- public long getModified() { +- return mModified; +- } +- +- @JsonProperty("expiryDate") +- public long getExpiryDate() { +- return mExpiryDate; +- } +- +- @JsonProperty("volume") +- public int getVolume() { +- return mVolume; +- } +- +- @JsonProperty("tradable") +- public boolean getTradable() { +- return mTradable; +- } +- +- @JsonProperty("orderbookId") +- public long getOrderbookId() { +- return mOrderbookId; +- } +- +- @JsonProperty("profitPercent") +- public double getProfitPercent() { +- return mProfitPercent; +- } +- +- @JsonProperty("type") +- public int getType() { +- return mType; +- } +- +- @JsonProperty("instrumentType") +- public String getInstrumentType() { +- return mInstrumentType; +- } +- +- @JsonProperty("change") +- public double getChange() { +- return mChange; +- } +- +-} +\ No newline at end of file +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java +deleted file mode 100644 +index 3571eca..0000000 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java ++++ /dev/null +@@ -1,78 +0,0 @@ +-package com.liato.bankdroid.banking.banks.avanza.model; +- +-import com.fasterxml.jackson.annotation.JsonProperty; +- +-import java.io.Serializable; +-import java.util.Collections; +-import java.util.List; +- +-public class PositionAggregation implements Serializable { +- +- private static final long serialVersionUID = 5531947007427482418L; +- +- @JsonProperty("totalChange") +- private double mTotalChange; +- +- @JsonProperty("positions") +- private List mPositions = Collections.emptyList(); +- +- @JsonProperty("totalProfit") +- private double mTotalProfit; +- +- @JsonProperty("instrumentTypeName") +- private String mInstrumentTypeName; +- +- @JsonProperty("totalProfitPercent") +- private double mTotalProfitPercent; +- +- @JsonProperty("totalValue") +- private double mTotalValue; +- +- @JsonProperty("instrumentType") +- private int mInstrumentType; +- +- @JsonProperty("totalAverage") +- private double mTotalAverage; +- +- +- @JsonProperty("totalChange") +- public double getTotalChange() { +- return mTotalChange; +- } +- +- @JsonProperty("positions") +- public List getPositions() { +- return mPositions; +- } +- +- @JsonProperty("totalProfit") +- public double getTotalProfit() { +- return mTotalProfit; +- } +- +- @JsonProperty("instrumentTypeName") +- public String getInstrumentTypeName() { +- return mInstrumentTypeName; +- } +- +- @JsonProperty("totalProfitPercent") +- public double getTotalProfitPercent() { +- return mTotalProfitPercent; +- } +- +- @JsonProperty("totalValue") +- public double getTotalValue() { +- return mTotalValue; +- } +- +- @JsonProperty("instrumentType") +- public int getInstrumentType() { +- return mInstrumentType; +- } +- +- @JsonProperty("totalAverage") +- public double getTotalAverage() { +- return mTotalAverage; +- } +- +-} +\ No newline at end of file +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java +index 230dbd5..b72ba85 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java +@@ -27,8 +27,6 @@ public interface IBankTypes { + int LANSFORSAKRINGAR = 4; + int COOP = 6; + int ICA = 7; +- int AVANZA = 9; +- int AVANZAMINI = 11; + int OKQ8 = 12; + int FIRSTCARD = 14; + int PAYSON = 16; +diff --git a/bankdroid-legacy/src/main/res/drawable/logo_avanza.png b/bankdroid-legacy/src/main/res/drawable/logo_avanza.png +deleted file mode 100644 +index 1d5b836..0000000 +Binary files a/bankdroid-legacy/src/main/res/drawable/logo_avanza.png and /dev/null differ +diff --git a/bankdroid-legacy/src/main/res/drawable/logo_avanzamini.png b/bankdroid-legacy/src/main/res/drawable/logo_avanzamini.png +deleted file mode 100644 +index f19d914..0000000 +Binary files a/bankdroid-legacy/src/main/res/drawable/logo_avanzamini.png and /dev/null differ +diff --git a/bankdroid-legacy/src/main/res/raw/cert_avanza.pem b/bankdroid-legacy/src/main/res/raw/cert_avanza.pem +deleted file mode 100644 +index 0cea5a7..0000000 +--- a/bankdroid-legacy/src/main/res/raw/cert_avanza.pem ++++ /dev/null +@@ -1,29 +0,0 @@ +------BEGIN CERTIFICATE----- +-MIIEuzCCA6OgAwIBAgIQPw5F1jSoeVE1WSbiXJQYqDANBgkqhkiG9w0BAQsFADBB +-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMRswGQYDVQQDExJ0 +-aGF3dGUgU1NMIENBIC0gRzIwHhcNMTUwNTI5MDAwMDAwWhcNMTcwNTI4MjM1OTU5 +-WjB8MQswCQYDVQQGEwJTRTEYMBYGA1UECAwPU3RvY2tob2xtcyBsw6RuMRIwEAYD +-VQQHDAlTdG9ja2hvbG0xFzAVBgNVBAoMDkF2YW56YSBCYW5rIEFCMQswCQYDVQQL +-DAJJVDEZMBcGA1UEAwwQaXBob25lLmF2YW56YS5zZTCCASIwDQYJKoZIhvcNAQEB +-BQADggEPADCCAQoCggEBAMbCiEmYA1O3hIW4PR2v2KJ4A0pHKRjMSgvANXIRCc/I +-E8yHV/i0ZyCy3b94qIAJsZwLUi06si2vvIqLC4H9gUGaYL0EROHqM03BtgvZDe9D +-jk8dusJMxi1415SanHh+MuqwfNEB2yYvMJpBMZB+KciBcqX7DTdaC/l3bJrVBXOQ +-IbE0zZcz/TGg/R2gA2ZpDr3C5hUkfWvM+ic294TCF0ey6HRQYk9x0aASwOe5DWJM +-JMwrl33Jk4AnLKupC825JIM9rR7CvLrZ2vGXzLDQh+wz2/FY+yTuOTu+z2NrH5FY +-xwpqwSTk7r9mCh4Xy2lpqz3VVywMPf5T5LdzX9yY/VsCAwEAAaOCAXIwggFuMBsG +-A1UdEQQUMBKCEGlwaG9uZS5hdmFuemEuc2UwCQYDVR0TBAIwADBuBgNVHSAEZzBl +-MGMGBmeBDAECAjBZMCYGCCsGAQUFBwIBFhpodHRwczovL3d3dy50aGF3dGUuY29t +-L2NwczAvBggrBgEFBQcCAjAjDCFodHRwczovL3d3dy50aGF3dGUuY29tL3JlcG9z +-aXRvcnkwDgYDVR0PAQH/BAQDAgWgMB8GA1UdIwQYMBaAFMJPSFf80U+awF04fQ4F +-29kutVJgMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly90ai5zeW1jYi5jb20vdGou +-Y3JsMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBXBggrBgEFBQcBAQRL +-MEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly90ai5zeW1jZC5jb20wJgYIKwYBBQUHMAKG +-Gmh0dHA6Ly90ai5zeW1jYi5jb20vdGouY3J0MA0GCSqGSIb3DQEBCwUAA4IBAQAl +-Ojf5ZgrFjk6SJHpOWcwTbDf5OX8AnxBat8xvqxkoqAXHtkfC+B5vAbYqUT+JZE7O +-79roncesD8zzcT4L5iR+axHbB4fz7JNSbqISbYscDZA1bV69ciJs1XkvvvI3DUbB +-t3aVAa2ArnINI8IxxJVeQ8S416jgN6PlnDRMCGSFjOWC76Lc9M4wLmghW9lfeW+I +-knWQC+TGgu824yVYf6GlaAPpdwc+7M6bDc4TDsRzC/BKfMNGPdaBbrS8J5PKGGwd +-YJ2NYv4EGMhgR0u8ZT68X/B5RYfZZc0pQuiEEtv7MlPj4t+xbRKXm0HxneBblLxV +-fIBstELLSRgDEJNBmd8N +------END CERTIFICATE----- +-iphone.avanza.se:443 + +commit 3c25a3917ecdb1997b833ec259d3bdc42cb9d26b +Author: Mathias Åhsberg +Date: Wed Feb 22 22:07:48 2017 +0100 + + Update build tools to version 2.2.3 + +diff --git a/build.gradle b/build.gradle +index 43763d6..76cbdfb 100644 +--- a/build.gradle ++++ b/build.gradle +@@ -5,7 +5,7 @@ buildscript { + jcenter() + } + dependencies { +- classpath 'com.android.tools.build:gradle:2.2.2' ++ classpath 'com.android.tools.build:gradle:2.2.3' +  + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + +commit 31bf4e66992d3057c4cab3d711f99e666fc0883c +Author: Mathias Åhsberg +Date: Wed Feb 22 21:28:27 2017 +0100 + + Update certificates + +diff --git a/CHANGELOG b/CHANGELOG +index 1fbef9f..6995d6b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,5 +1,8 @@ + Please view this file on the master branch, on stable branches it's out of date. +  ++(Unreleased) ++* Update certificates ++ + v1.9.14 (2017-01-06) + * Updated certificates for First Card, Osuuspankki and Östgötatrafiken +  +diff --git a/bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem b/bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem +index 3057379..d4338ef 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem +@@ -1,52 +1,48 @@ + -----BEGIN CERTIFICATE----- +-MIIJGDCCCACgAwIBAgIQBcnDhS/kTPYwT7xQkKTIiTANBgkqhkiG9w0BAQsFADB1 ++MIIIYDCCB0igAwIBAgIQAaqnbsay6zOICUMaChU+CDANBgkqhkiG9w0BAQsFADB1 + MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 + d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk +-IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE2MTIwNjAwMDAwMFoXDTE4MTIxMTEy +-MDAwMFowggEXMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjETMBEGCysG ++IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE3MDEyNDAwMDAwMFoXDTE5MDEyOTEy ++MDAwMFowggEcMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjETMBEGCysG + AQQBgjc8AgEDEwJVUzEZMBcGCysGAQQBgjc8AgECEwhOZXcgWW9yazEPMA0GA1UE + BRMGMTg4MDU1MR4wHAYDVQQJExUzMTUxIFcuIEJlaHJlbmQgRHJpdmUxDjAMBgNV + BBETBTg1MDI3MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTEQMA4GA1UE +-BxMHUGhvZW5peDEhMB8GA1UEChMYQW1lcmljYW4gRXhwcmVzcyBDb21wYW55MQww +-CgYDVQQLEwNOR0kxIzAhBgNVBAMTGmdsb2JhbC5hbWVyaWNhbmV4cHJlc3MuY29t +-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArm1h2NyOnMpJE69RKSLN +-K3VXgzknpKXiWoW60+XnHvmCknUo1HSzKcWhUSYgDyGrziLs39QB3ygVKzkhp1Jm +-dCrCCLugcyowU5ILbIoGxehsbu/WsnJdW75sgo21QxmiT7lmhkfioruXbmFSHPk3 +-NmfhTTnzLLjrm4DTWhpM7QXbedyL5/r5U4usUAMTQrHffVQFI4A26lnv3uA0PeF5 +-17onx8ivwKTIXUTY64utgNI7qqF1zFwMtQioReXeoHGhF7a+KDMLNKT1fY2/1t8N +-NLsEcTcZl9hGhSSUx7zYDYyb6Syurz9U9IYGCP33LnMxU9wPSjuDe9FZZODawSKm +-wQIDAQABo4IE/jCCBPowHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8w +-HQYDVR0OBBYEFBqefDrKnrSSF++OIDOKR08xuuArMHsGA1UdEQR0MHKCGmdsb2Jh +-bC5hbWVyaWNhbmV4cHJlc3MuY29tgiluZ2lvcmlnaW4taXBjMS1nbG9iYWwuYW1l +-cmljYW5leHByZXNzLmNvbYIpbmdpb3JpZ2luLWlwYzItZ2xvYmFsLmFtZXJpY2Fu +-ZXhwcmVzcy5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB +-BggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2Vy +-dC5jb20vc2hhMi1ldi1zZXJ2ZXItZzEuY3JsMDSgMqAwhi5odHRwOi8vY3JsNC5k +-aWdpY2VydC5jb20vc2hhMi1ldi1zZXJ2ZXItZzEuY3JsMEsGA1UdIAREMEIwNwYJ +-YIZIAYb9bAIBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv +-bS9DUFMwBwYFZ4EMAQEwgYgGCCsGAQUFBwEBBHwwejAkBggrBgEFBQcwAYYYaHR0 +-cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsGAQUFBzAChkZodHRwOi8vY2FjZXJ0 +-cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyRXh0ZW5kZWRWYWxpZGF0aW9uU2Vy +-dmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggKtBgorBgEEAdZ5AgQCBIICnQSCApkC +-lwB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABWNTrpfsAAAQD +-AEYwRAIgFR/0U2pLZPoB4kVEeYMi9LqkYgFBM9hJf+A1uYT9354CIAqFZ17SAQ8V +-/H+tpdQY/zIl3lTnZBEFLST6E6t+xfe+AS8ArDua7X+pZ0dXFZ5tfVdWcvnZgQCU +-Hpve/+yhMTt1eC0AAAFY1OusCgAABAEBAD3psaSp1qs4oLVFAuHYX0ZwOf5x3TAl +-jyQbbLF1r5/mbIHzR6LkP5r7bfltTMtMmyc+u/771shPu6sAucM06nPkJF/VhvRM +-OlY6+nSTmVq4gW9a+EjcBefsRCRKa6d00rhSYTx1ZVIa87vSacHD5J+LMgcvTW6N +-YRW3d8zdbVUsbeir7dDx9Diu3aR1bmrjPpt4fEU/GOXOOdy7DFpp8wYN7zaGUhuh +-ThftdZIWhi0QEnZALodco2aZOTFgv2q1Uicf861+M6+QIlwg4zTQEF/rW+12Q5ob +-UivWtV7R9cu83ZenZ+UBeF4t61CF7aJUaoV1yDEkrSc80SYg2l4P9/cAdQBWFAaa +-L9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAVjU66aeAAAEAwBGMEQCICyv +-YtBEG+gUyhkDtf6MCY8LhmCQdPIEezWLlw7d6o/AAiAeuK4vWCe4ch/LCABsHh5x +-ODW/8QG5EjiXjbZ08PfPJAB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6 +-qP3LAAABWNTrqAkAAAQDAEcwRQIgEKsq+0O+H+50tY0s9A/2owkSY6diBkYTt2ZC +-+sNP8JYCIQDIchquB/qmN1UHn8n3DU0JJ8Zn8XqyVeTT6/kTAx7MCjANBgkqhkiG +-9w0BAQsFAAOCAQEAv5feWkUjogtKQgC5g2ORTcFgM+FjfXtHN7omZ2pjSXI2xVND +-VhTa0sbleHmB09vwY9v9orp68jxEvWM9FIpdRRiVmv4eJLGyBBaICxp9bePMK82R +-pMObMN9tBAMHd55rnllWE0rME9dB8WvoOkhY7A1BBVY5m86s0H3puOXStiJpAG1j +-JbSeJ4MoGpqbOryiOs/HcLIyHQOpNkykd2BuxxNW/qWQVFhPNvaVgeYy6lXunAVk +-CcNfyrTOKwj0D3JkXUzwYLxSRAEVHNjIxsJT5mJFnPuLd1Te2EDkNuoceYIA+OoE +-jTe/+O2Jm+Nw3PkYwmjtsc0EhaHp7HcPgHZPtQ== ++BxMHUGhvZW5peDEhMB8GA1UEChMYQW1lcmljYW4gRXhwcmVzcyBDb21wYW55MREw ++DwYDVQQLEwhDb25zdW1lcjEjMCEGA1UEAxMab25saW5lLmFtZXJpY2FuZXhwcmVz ++cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOe2+mom21AxhL ++BDJNgENfGvhF8z4mcTP5EnpvJno/7+46dPcy6otIEAx9mMbBM7eiYITO6ybPMldV ++epcg0WMoNrJ0xJlp+KwKIOxP+Vg16Rz7c07fDbTaCZfzR1qfdODD8hdGKDLuaT0D ++f142jNmYG0WibBaykN3E5kvmZ6EvnwwGvfEIfVD/4TOB0fFqexWWVDJRKNQH0wKc ++VCY9UIk3BoagWKzLxV5aU5lqCHf8PAJOZ6WEnomHuXYv7Pvg3XNaxxNYfesYms09 ++lEaxnLhqZIhhItfilllTX13n+vPFYTUsAJ6qnzAemJqzLsC4LAXQyz7D+TQ0nXAJ ++KJnoBYVRAgMBAAGjggRBMIIEPTAfBgNVHSMEGDAWgBQ901Cl1qCt7vNKYApl0yHU +++PjWDzAdBgNVHQ4EFgQUo25mMJ/p72Dun3+lrHE+72I9vSIwdwYDVR0RBHAwboIa ++b25saW5lLmFtZXJpY2FuZXhwcmVzcy5jb22CG3Jld2FyZHMuYW1lcmljYW5leHBy ++ZXNzLmNvbYIXcmV3YXJkcy5hZXhwLXN0YXRpYy5jb22CGmdsb2JhbC5hbWVyaWNh ++bmV4cHJlc3MuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD ++AQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNl ++cnQuY29tL3NoYTItZXYtc2VydmVyLWcxLmNybDA0oDKgMIYuaHR0cDovL2NybDQu ++ZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcxLmNybDBLBgNVHSAERDBCMDcG ++CWCGSAGG/WwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j ++b20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0 ++dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2Vy ++dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNl ++cnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIB9AYKKwYBBAHWeQIEAgSCAeQEggHg ++Ad4AdQCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAVnR4Z7LAAAE ++AwBGMEQCIGyUTKolX7fCjfAx0evgDlGtLmRqF/LFp3MCWl8BNY3PAiAlMUhh0X6F ++Dedm4odESahntfy8d/3WV02oBfcyPJypEwB2AFYUBpov18Ls0/XhvUSyPsdGdrm8 ++mRFcwO+UmFXWidDdAAABWdHhoB4AAAQDAEcwRQIgS1sYO973uUF1ck53HVNr0kIA ++kuYjUOau3K1tFllKz24CIQDYs45QOuiF91Cyr25jycnX8ppdfFjAOFmFZtC3pMkf ++OwB1AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABWdHhodwAAAQD ++AEYwRAIgCCu2KCYMQez7uGnoa3zMcg03Lj7+ubTmMe7WBBldQi4CIHg3clmsny5h ++erX47gKuoEbixn0vlUa2v3MyfIVgL0n1AHYAu9nfvB+KcbWTlCOXqpJ7RzhXlQqr ++UugakJZkNo4e0YUAAAFZ0eGf8QAABAMARzBFAiAi7IWcvkTTbpPkxqFPDffBGMH0 ++NuwWoRQHO5ljt0dlfgIhANFuzMU7pPpcvoKdnHNgfsbUp47XNlsJ92RQNyH/j3fQ ++MA0GCSqGSIb3DQEBCwUAA4IBAQBN1H5e5Mzl5+R7ed8LuQgPyNBMx853wCI+lKuy ++xUwGn/DJfNo+fvcywY12wFfsQAxxOTt8ecCs68JFYJlDgnzMumHBOVQf8Psb8OEN ++W3emi7z8lnbQusItvSzZiArbrGLbPICumVrJn+eodzenWn6DAJEQAl3LbXOn4FGP ++Kpijmf8hfb2I/UAwMISh4OiMcMHusoBHpekKxOTrCemLIbCKbV2sUV1o6PSN6SDq ++u7fX158B+qQxcEgn0fjAs8CVqs31lJjo/h1kb/53u2iqZFH3P2sbr0jQkVNiL2LW ++bdXhSyChR5z4w4lvj8HthWCs6kU+uzBHdtamdVkFU4d0dzi/ + -----END CERTIFICATE----- + global.americanexpress.com:443 +diff --git a/bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem b/bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem +index a01ed1e..e9de15f 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem +@@ -1,35 +1,37 @@ + -----BEGIN CERTIFICATE----- +-MIIF4TCCBMmgAwIBAgIQVPm9MeoE7SQFdlULvDppQjANBgkqhkiG9w0BAQsFADBE ++MIIGVjCCBT6gAwIBAgIQJ7c0DjE2rrf90ZxGr+exPTANBgkqhkiG9w0BAQsFADBE + MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU +-R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTYwMjAxMDAwMDAwWhcNMTcwMTMxMjM1 +-OTU5WjBqMQswCQYDVQQGEwJTRTEYMBYGA1UECAwPU1RPQ0tIT0xNUyBMw6ROMQ4w +-DAYDVQQHDAVTb2xuYTESMBAGA1UEChQJU0YgQmlvIEFCMQswCQYDVQQLDAJJVDEQ +-MA4GA1UEAxQHKi5zZi5zZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +-AKLUmrPm9g2Z12yVD9jnGgk3C2xrdOYqjfjFGOrU2SfTaI1L8POt2s9YspYcKkFG +-5EB7Iv3aIwL0TccsbWT1PaiVvT7hgU94n5fYjjHlMiVMdPpHunGj9KqO12/zz++e +-Qa8xITx5AW3S7CYHIBqxPIU43/6ukXcmsGe4ngbHxhl7nfWcgWT/qxUA7guWqxON +-KNaNOsw4KeJizxhURT52nf5+dJIZ9j/3x8vu+WC8kJ9LQzKdFuFOZ05/Ivwj+WcI +-SbOOaisxaQCdkFMDtTfWPBX9CjEvAEqYsthFj2trvxZYgvnN6zR7eRdAH2chgrh9 +-//ljApp85rzAVClGncBZKq0CAwEAAaOCAqcwggKjMBkGA1UdEQQSMBCCByouc2Yu +-c2WCBXNmLnNlMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQkMCIw +-IKAeoByGGmh0dHA6Ly9nbi5zeW1jYi5jb20vZ24uY3JsMIGdBgNVHSAEgZUwgZIw +-gY8GBmeBDAECAjCBhDA/BggrBgEFBQcCARYzaHR0cHM6Ly93d3cuZ2VvdHJ1c3Qu +-Y29tL3Jlc291cmNlcy9yZXBvc2l0b3J5L2xlZ2FsMEEGCCsGAQUFBwICMDUMM2h0 +-dHBzOi8vd3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeS9sZWdh +-bDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0jBBgwFoAU0m/3 +-lvSFP3I8MH0j2oV4m6N8WnwwVwYIKwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNo +-dHRwOi8vZ24uc3ltY2QuY29tMCYGCCsGAQUFBzAChhpodHRwOi8vZ24uc3ltY2Iu +-Y29tL2duLmNydDCCAQMGCisGAQQB1nkCBAIEgfQEgfEA7wB2AN3rHSt6DU+mIIuB +-rYFocH4ujp0B1VyIjT0RxM227L7MAAABUp0mwQkAAAQDAEcwRQIgequqjt1sy5zl +-gCK93rW9xs6YxLs1bCfp96HIYhZ49kACIQDhjtfaakCmfkQ9UDMBp7WpE1kA4PFl +-jNIZnsUqdf4meAB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAAB +-Up0mvTEAAAQDAEYwRAIgR0W9StBOqzQ85oWMWO6h/P4M+p77PJQrjgdyQlcePVUC +-IHRoUg4Ywdh9ookJITb8K9dn5MGikr7I6om9QwWNBb+6MA0GCSqGSIb3DQEBCwUA +-A4IBAQAlL/o5EhDh5lNkjJkxPzFnX4xuf2/PtyepQmlE9f0/o1ICgUgHDy2Vs2r/ +-yCWyjKSl+APsd0AOuKJtxXm9s+TtHDRAysODUVhSQYLjWOZoWrpQ3d0bDhDHhy8S +-3AaqoE65tRXbZHZ7sSB95XpKgPARwn918y1Oe6aTEE8JvSV/cXVyHbng5RB2ddJP +-OFXUmh+/uLgbPQ/V4wPipTbWLDgA+D7XuyQVzCNvhPD4A8w0oBi/HxjjYMdPByoK +-LjVEmYCdw91c/h6Avm9AUK92XGXkNdiML+hBEY2YJQZghH1yz98hbqfm0x5b43GI +-Lk4ymn/K6HZMbtsrXfcWX8N3UmO5 ++R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTYxMjE1MDAwMDAwWhcNMTgwMzE2MjM1 ++OTU5WjBkMQswCQYDVQQGEwJTRTESMBAGA1UECAwJU1RPQ0tIT0xNMQ4wDAYDVQQH ++DAVTb2xuYTESMBAGA1UECgwJU0YgQmlvIEFCMQswCQYDVQQLDAJJVDEQMA4GA1UE ++AwwHKi5zZi5zZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKLUmrPm ++9g2Z12yVD9jnGgk3C2xrdOYqjfjFGOrU2SfTaI1L8POt2s9YspYcKkFG5EB7Iv3a ++IwL0TccsbWT1PaiVvT7hgU94n5fYjjHlMiVMdPpHunGj9KqO12/zz++eQa8xITx5 ++AW3S7CYHIBqxPIU43/6ukXcmsGe4ngbHxhl7nfWcgWT/qxUA7guWqxONKNaNOsw4 ++KeJizxhURT52nf5+dJIZ9j/3x8vu+WC8kJ9LQzKdFuFOZ05/Ivwj+WcISbOOaisx ++aQCdkFMDtTfWPBX9CjEvAEqYsthFj2trvxZYgvnN6zR7eRdAH2chgrh9//ljApp8 ++5rzAVClGncBZKq0CAwEAAaOCAyIwggMeMBkGA1UdEQQSMBCCByouc2Yuc2WCBXNm ++LnNlMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQkMCIwIKAeoByG ++Gmh0dHA6Ly9nbi5zeW1jYi5jb20vZ24uY3JsMIGdBgNVHSAEgZUwgZIwgY8GBmeB ++DAECAjCBhDA/BggrBgEFBQcCARYzaHR0cHM6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl ++c291cmNlcy9yZXBvc2l0b3J5L2xlZ2FsMEEGCCsGAQUFBwICMDUMM2h0dHBzOi8v ++d3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeS9sZWdhbDAdBgNV ++HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0jBBgwFoAU0m/3lvSFP3I8 ++MH0j2oV4m6N8WnwwVwYIKwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNodHRwOi8v ++Z24uc3ltY2QuY29tMCYGCCsGAQUFBzAChhpodHRwOi8vZ24uc3ltY2IuY29tL2du ++LmNydDCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA3esdK3oNT6Ygi4GtgWhw ++fi6OnQHVXIiNPRHEzbbsvswAAAFZAd73PAAABAMARzBFAiEA2pXLVLlPgndL3HEz ++0c9DX2L2BJ86iWWr2hJvtMqN31ECIBR3r2mC1fxcm5fn3hdtWNl8GZmCzvRVL156 ++qtMwyVgNAHYA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFZAd73 ++gwAABAMARzBFAiAtaIC43JHp6fn0NSYUjwh+V+i45Rx4R/An+F+eX46c8AIhAK/x ++W4U0nreGDM7kYLg17Zf/IgdykcEWJUAo9C+pAeHYAHYAvHjh38X2PGhGSTNNoQ+h ++Xwl5aSAJwIG08/aRfz7ZuKUAAAFZAd74FQAABAMARzBFAiEApvwu6gDBg3h/04gQ ++Xo68xPtQhnhBK6KjDHy9+gRHj4wCIB6JlTJu/PB6mxn4EZJMJkmDjg1zul49LIKN ++lBSp8U0IMA0GCSqGSIb3DQEBCwUAA4IBAQCJuRpRxVPeK4iY19oPDdsXOkewpI1C ++Z/qM9gGyohgHSWpoTgOl3VpRXQxoyOHAjP09y9IfPcXE53tdUqRbXIyr2CLxbaMj ++Q8SkZl5li+XxYmCLSVBBeo9CZoPuztBI5i+KAki5tHtfOjynDyPmGs4UYH62c1A1 ++zvPjue4k2aP6Ea7PE5JzfFiWauoc529QNjE4s84YuM0eJBU8Qv2Bz2/YrjuRhkDx ++VyolwHaaiAUpKiQqVE0Dxbpb2SbAUL6gGqeD5XmAmevJdpBcO6C88BSuVEr4SR5a ++vOINhDQg/+E6MHckR2oHKtvIDY9jhp7UsP6idjWDakl4Yc2RGsq+PPIW + -----END CERTIFICATE----- + bioklubben.sf.se:443 +diff --git a/bankdroid-legacy/src/main/res/raw/cert_brummer.pem b/bankdroid-legacy/src/main/res/raw/cert_brummer.pem +index 57a3884..477acac 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_brummer.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_brummer.pem +@@ -1,43 +1,45 @@ + -----BEGIN CERTIFICATE----- +-MIIHXTCCBkWgAwIBAgIQDdd0lRu1ru2NPo7vkvNo8jANBgkqhkiG9w0BAQsFADB1 ++MIIH0jCCBrqgAwIBAgIQCRPnldXK9l40D0FXyRHdeDANBgkqhkiG9w0BAQsFADB1 + MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 + d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk +-IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE1MDIyNTAwMDAwMFoXDTE3MDMwMTEy +-MDAwMFowgdgxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB ++IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE3MDIwMTAwMDAwMFoXDTE5MDQwNDEy ++MDAwMFowgcsxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB + BAGCNzwCAQMTAlNFMRMwEQYDVQQFEwo1NTY2MjcyMTgyMRkwFwYDVQQJExBOb3Jy + bWFsbXN0b3JnIDE0MQ8wDQYDVQQREwYxMTEgNDYxCzAJBgNVBAYTAlNFMRIwEAYD +-VQQHEwlTdG9ja2hvbG0xHjAcBgNVBAoMFUJydW1tZXIgJiBQYXJ0bmVycyBBQjEL +-MAkGA1UECxMCSVQxEzARBgNVBAMTCmJydW1tZXIuc2UwggEiMA0GCSqGSIb3DQEB +-AQUAA4IBDwAwggEKAoIBAQCby3aJkkQeVq9mrntbSeHpvdRC3ZbUWJfMfCO6jDzZ +-rTKNa6krqeGBFOxOq8mIZBKdcSRqIp7NAoazPpSxWPi1RgMCOCLzQ84dHWPqEaDp +-4DYrhuQjM0A7jgXK/2vLLARCpUCSvN8IhP3PsduSOsmrAB/EqHZcdhsCtbffJKhE +-HSYYd3hv8idCmqXivHKUw6SSuKM01NYB5DWQ4O7NdUbZ/WU2hN2CK/lm0pCLm+ZU +-M6bo2Lb6QtyIjrCglRX5KkADN9xylVWJCgJyCW5bpecsbxf79m/gndzMGjuUTuaR +-n1TZtTV090P3lfR5Ml4BkzjkfePNPmyHJTalXgeqGOqBAgMBAAGjggODMIIDfzAf +-BgNVHSMEGDAWgBQ901Cl1qCt7vNKYApl0yHU+PjWDzAdBgNVHQ4EFgQU23vqNCiJ +-TVuQDBvFaTp8jThttkwwOAYDVR0RBDEwL4IKYnJ1bW1lci5zZYIOd3d3LmJydW1t +-ZXIuc2WCEW9ubGluZS5icnVtbWVyLnNlMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE +-FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDov +-L2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcxLmNybDA0oDKgMIYu +-aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcxLmNybDBC +-BgNVHSAEOzA5MDcGCWCGSAGG/WwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3 +-dy5kaWdpY2VydC5jb20vQ1BTMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGG +-GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2Nh +-Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlv +-blNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4E +-ggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAUvBVKCt +-AAAEAwBHMEUCIQD1EQomVM2Juf2/Fc84PgFtIcZzl+X5RNnnWE2o3jHKQgIgG1Hq +-34EWDsFfwbu642otUsq4zuJgAwgBWaEkG2mXmHgAdgBo9pj4H2SCvjqM7rkoHUz8 +-cVFdZ5PURNEKZ6y7T0/7xAAAAUvBVKBdAAAEAwBHMEUCIDpYzInLjWozqXvrwgbE +-193pSUL08wPC0sR6NFFSDP/eAiEAoZJraDVOtt+Ii4s7HZQB9jEdYfneKI+scvY8 +-ZtAe5rcAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAUvBVKI/ +-AAAEAwBHMEUCIQC9rtsHCafedt7mvkUvWxWZm+UYSWoDH6kc62gukOEAUQIgRbeF +-cxBLg9PA5D/zY27VtZsR/Hpf1pnR3gsRFzFDkBAwDQYJKoZIhvcNAQELBQADggEB +-AAXdbIn/XCTUhjUp0z6+6rvA6lwTptGbxUSoZbRv9XBP3yc7NpewKDmojTRZH1rF +-xYNrvCVAxNXlbmE3z+nRPydM2cTL9ijM140XhoCEp7eeppqlztGv039s3WNtAxar +-E8oLA8zI9nersr4r7aZWdwYTFZd5U2pwG30HVzM4qoFp3J6lmTQaMrO9qiCbfh+z +-obRiPEmDgdUJD7wy2cOIVyeST6nbO60BYS8jP1nW/t1ljq9CL0AxLUgSgWFps62O +-mS1MVeANDCE+htres7XH8DCAn+zQ+qX2Cow5eAluki9cl0m9IzLet2og4blKFyO9 +-U20t5htcdjfC2PmbN/Y6FxQ= ++VQQHEwlTdG9ja2hvbG0xHjAcBgNVBAoMFUJydW1tZXIgJiBQYXJ0bmVycyBBQjET ++MBEGA1UEAxMKYnJ1bW1lci5zZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ++ggEBALdYobK2du+PQct99KfEdqZ1LoCjJFs6YP0h91SBXtHZn7K6E3qkNW580DWM ++6R8DSXkcpjnjZygJCtApC3A9q/7ERoGtAAJa1la5jy7RFwg5r/D3cZVur+A7W+DX ++muegiHWQ8GfTPflGdllm3URfamHvAWgsZf8Se3pfusTY4ASsFrnOY/s+5Ip/lFHT ++WWF9bo3arY7zpK5aWKma5tDfDFHLF7uVp4XcAXNNDWd3pJlwMEOsrXQHG+GDN++D ++iJ5z1T6uvdBh7pd8YNGQ7/zbEcFeLYpuMA8KkRPrP+ujF7pjgDgyaoa3Rid8pSug ++xUpeCCjAUissK3iAGzei6jmK0DECAwEAAaOCBAUwggQBMB8GA1UdIwQYMBaAFD3T ++UKXWoK3u80pgCmXTIdT4+NYPMB0GA1UdDgQWBBRgAcs5Wlfij1QTyZJv/ht7klMU ++6jA4BgNVHREEMTAvggpicnVtbWVyLnNlgg53d3cuYnJ1bW1lci5zZYIRb25saW5l ++LmJydW1tZXIuc2UwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB ++BggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2Vy ++dC5jb20vc2hhMi1ldi1zZXJ2ZXItZzEuY3JsMDSgMqAwhi5odHRwOi8vY3JsNC5k ++aWdpY2VydC5jb20vc2hhMi1ldi1zZXJ2ZXItZzEuY3JsMEsGA1UdIAREMEIwNwYJ ++YIZIAYb9bAIBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv ++bS9DUFMwBwYFZ4EMAQEwgYgGCCsGAQUFBwEBBHwwejAkBggrBgEFBQcwAYYYaHR0 ++cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsGAQUFBzAChkZodHRwOi8vY2FjZXJ0 ++cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyRXh0ZW5kZWRWYWxpZGF0aW9uU2Vy ++dmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggH3BgorBgEEAdZ5AgQCBIIB5wSCAeMB ++4QB2AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABWfq1SfMAAAQD ++AEcwRQIhAO4WwezInv6io+B0UEpi73GMvYHOQM7F0GWZFK3UQCe8AiAslpzMJdcw ++Rj0mTM/bL/j/ywOpO6BCFIEW2pYspunW0AB3AFYUBpov18Ls0/XhvUSyPsdGdrm8 ++mRFcwO+UmFXWidDdAAABWfq1SGgAAAQDAEgwRgIhAMS0a56iGdE8z/NefoB2jIo4 ++ZDOyU2/4nG7PQqJGdhHKAiEA+lLD8gBDu/bQwJ1sjOXda58kYnIhdHBc4LsxdT51 ++GYYAdwDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAVn6tUfpAAAE ++AwBIMEYCIQCpDHuNS8fHcFuKolxzwYlPAm2bc+03MPdKuomoemb/kQIhAJAeZf1o ++M5PqrSA1OAJHIZXiLc0QNKPzYBG+LkaQIgd/AHUAu9nfvB+KcbWTlCOXqpJ7RzhX ++lQqrUugakJZkNo4e0YUAAAFZ+rVJ3QAABAMARjBEAiAfH0NqXD4oPCsjeHIMtXoE ++P0JtFgT2ttt1CzeAgj79fQIgI4bv4GxKzRcODXk8WX5lccQMk72iOhSns7hVBMqD ++tDswDQYJKoZIhvcNAQELBQADggEBABZOVNT14RPE/1LSPqz3h1WnxSOC3+YjYOle ++KeNeMjBnzSk56OzwMBCFDx+82fUy0Mg5Ocue4uSJsIkeH9+t0g7bLFRo2wO/+MF6 ++1VeCsGuB1PWH5aYFnLKOnUZgZh2gOk7Lv3XpmdIoRQx0SqKN29iehkjDxmM7lgKS ++mTkHw3ZOnbo5JKBHurGdmNMKcAgk3/Cg5sjaYGpMNacJBT2Uj4SYF07JScvJOi5U ++J9nw55LUapUbPLtN8sFnxX4GCKJD0nUiQGSqRpMZlmCIAjCyKNFB1kYkfqwULU8/ ++Hzn3KhA/seiw6RHEE6KH4ABCGcB+f+/wTWl9EpBBxaFQvsMmDTY= + -----END CERTIFICATE----- + www.brummer.se:443 +diff --git a/bankdroid-legacy/src/main/res/raw/cert_minpension.pem b/bankdroid-legacy/src/main/res/raw/cert_minpension.pem +index a9db360..46bf04b 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_minpension.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_minpension.pem +@@ -1,29 +1,46 @@ + -----BEGIN CERTIFICATE----- +-MIIEyjCCA7KgAwIBAgIQb/AHZMl0UKpzpPlDyW4CfTANBgkqhkiG9w0BAQsFADBB ++MIIH3TCCBsWgAwIBAgIQSxRugYizx9lBU/JAeD4aIzANBgkqhkiG9w0BAQsFADBB + MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMRswGQYDVQQDExJ0 +-aGF3dGUgU1NMIENBIC0gRzIwHhcNMTQxMTA0MDAwMDAwWhcNMTcwMTMxMjM1OTU5 +-WjCBhzELMAkGA1UEBhMCU0UxEjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJ +-U3RvY2tob2xtMSEwHwYDVQQKDBhNaW4gUGVuc2lvbiBpIFN2ZXJpZ2UgQUIxEzAR +-BgNVBAsMCk9wZXJhdGlvbnMxGDAWBgNVBAMMDyoubWlucGVuc2lvbi5zZTCCASIw +-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALVire6DFpjrGx69C4wZeC3IlWXS +-dXkGyHwEQQWdK+szlK2Wz5O9fVC7y00WCAyFEpUE7rmHb9v/ZWJtJEtoc+INeAIB +-fmpAWryfu8pkux7kz2KgWombA8WxSHOrwfpHf2Osbx0AYBVumCoHrARGa43wysYC +-U9nDTblwZThcktd8LSOtgHY/MoZgpjOURqB2miY6NvM7YQ6dIjXMeRQ3hfJBYON3 +-S0m2CmI5S8ovXkkE+WTzoIkBigSYu+gDdwJLPGAvKfrzy8dEI+NtvtfCSH22TxKH +-NcLRZTaTWEQeJN4037nx4Yahqlw1lKLcCiWw3KohnVmUTnIP0mJtVoyFpb0CAwEA +-AaOCAXUwggFxMBoGA1UdEQQTMBGCDyoubWlucGVuc2lvbi5zZTAJBgNVHRMEAjAA +-MHIGA1UdIARrMGkwZwYKYIZIAYb4RQEHNjBZMCYGCCsGAQUFBwIBFhpodHRwczov +-L3d3dy50aGF3dGUuY29tL2NwczAvBggrBgEFBQcCAjAjDCFodHRwczovL3d3dy50 +-aGF3dGUuY29tL3JlcG9zaXRvcnkwDgYDVR0PAQH/BAQDAgWgMB8GA1UdIwQYMBaA +-FMJPSFf80U+awF04fQ4F29kutVJgMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly90 +-ai5zeW1jYi5jb20vdGouY3JsMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD +-AjBXBggrBgEFBQcBAQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly90ai5zeW1jZC5j +-b20wJgYIKwYBBQUHMAKGGmh0dHA6Ly90ai5zeW1jYi5jb20vdGouY3J0MA0GCSqG +-SIb3DQEBCwUAA4IBAQA00XOwH0K4d9rlMqYm7fpsl74khsHCR8XKjheQoY9kevnT +-ClkekuiXDIYHjBIehZ9CV9J6fLlsVyRm7ppkLLwS1WUOw6/4RuX4uqVvu6387mnI +-kbHFbrLPu1puamM1ADYJS3DWrPE4aQGbQ9mvU9RPjvweGkgMKsgT3lvCUBXHyOZZ +-53JyzGtVgctEu5HBFkabtc194Vj0GQIgKbNBO4a3zqR6bvXRNuwf77OUkrFal3Nc +-gQigJu2fjgGwQZUb1cJSMjScfcpjiP2E41zqcncon76AAN6ZKfHmGayYX1LV3QTP +-Sg4ppKz/AHPCyN4SCh4pB4fVlr3XtldcQ2d1TTrN ++aGF3dGUgU1NMIENBIC0gRzIwHhcNMTYxMjA4MDAwMDAwWhcNMjAwMTMxMjM1OTU5 ++WjCBlTELMAkGA1UEBhMCU0UxEjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJ ++U3RvY2tob2xtMSEwHwYDVQQKDBhNaW4gUGVuc2lvbiBpIFN2ZXJpZ2UgQUIxITAf ++BgNVBAsMGE1pbiBQZW5zaW9uIGkgU3ZlcmlnZSBBQjEYMBYGA1UEAwwPKi5taW5w ++ZW5zaW9uLnNlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwpwIicRL ++TffXO9heGZoBxtyoRlq3QPq15RS75zdyr5tUNjyPFwqSny2UxWCSxIjEvYSyI7Iu ++UXzsu4MeePIgIdPHhZG+JaG0w8AS1ZFc1VAq/ULT0naHYVrE8xCQy4MDtFCxlDLN ++cSbsENZglVHIILoWhwh/xba6RrILk+tW5elQYM3TQxf3BT6xLvYYAkHGmWk95JFB ++MrL6uvTufs3bdwffUeYFwy1sXyiizbjr9F9MSx5u0FnelYrF7q39diJZKWTGAvK3 ++uEuAgKh4cpC80ixGr/zwGdsyvRBCoQB9w5gUWVEJSinLKoZjYS7zZyzyApzEf7fV ++HHPFXpuSzfL150sNf6ge4E4ZZhBPrRcDg7GU6ZjbonGgi7hARpKyU+fiPKXG908W ++P5cjmFomkz6rCVOeK0JEmVrxAlpAomTuTBMhEmjeqP19j3CGYauGHAAe8C6lERZ1 ++pvTXUS7+vioy1JYuEJVCWVE5DPp1yA6iBmuPG+DxvlapSJ1uD2cW4XhUflQjOwfA ++xBhhEhdY49XIH0iaa+ygfoKtkbPITxgYlk1EKu1yDgjPJ/DSO+4qQdsxwUL1PvfY ++MZZi7/MRyzQ7gX1MOlW1CG0m+UW6ZRLMdZ8WdNVN+gytVFoHZyWVp8Bt48GI+6DA ++OOvG2ohHVxlVpawlEJ5xd1ys2EwclVH4UM8CAwEAAaOCA3owggN2MCkGA1UdEQQi ++MCCCDyoubWlucGVuc2lvbi5zZYINbWlucGVuc2lvbi5zZTAJBgNVHRMEAjAAMG4G ++A1UdIARnMGUwYwYGZ4EMAQICMFkwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRo ++YXd0ZS5jb20vY3BzMC8GCCsGAQUFBwICMCMMIWh0dHBzOi8vd3d3LnRoYXd0ZS5j ++b20vcmVwb3NpdG9yeTAOBgNVHQ8BAf8EBAMCBaAwHwYDVR0jBBgwFoAUwk9IV/zR ++T5rAXTh9DgXb2S61UmAwKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3RqLnN5bWNi ++LmNvbS90ai5jcmwwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMFcGCCsG ++AQUFBwEBBEswSTAfBggrBgEFBQcwAYYTaHR0cDovL3RqLnN5bWNkLmNvbTAmBggr ++BgEFBQcwAoYaaHR0cDovL3RqLnN5bWNiLmNvbS90ai5jcnQwggH2BgorBgEEAdZ5 ++AgQCBIIB5gSCAeIB4AB2AN3rHSt6DU+mIIuBrYFocH4ujp0B1VyIjT0RxM227L7M ++AAABWN53LHkAAAQDAEcwRQIhANKbz22YATzbyv2DsuBOONOQlrSyfr7ZwkcrVQVx ++Ko/OAiBffkNpsiqNgvw3Mua5giyk7KRIZzmj/RuA6pIPs5d8nAB3AO5Lvbd1zmC6 ++4UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABWN53LMQAAAQDAEgwRgIhAKu7WS3z ++4RlEKvfBEEkXaU9ZsWfuWOERiBcgaXuGOI4HAiEAq34zpW7ww+W3Ka1gkn20RhyI ++tB4A8agZoRPO4S5SJx8AdgC8eOHfxfY8aEZJM02hD6FfCXlpIAnAgbTz9pF/Ptm4 ++pQAAAVjedy1wAAAEAwBHMEUCIH/iku72aTt3OjeL6QZepzX29fwae6AIEuW7Xdvu ++SkfKAiEAyQdE96NxQODnytn2FsMDLFbVHpjR/r9Ux3/eXc/2Q9QAdQCkuQmQtBhY ++FIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAVjedyyXAAAEAwBGMEQCIDz9ITBk ++5QE0Cokr1xotGVZbu7tzKmtEZVzEybbgb2KWAiBVgdBjh2mY4bIvjCDn0sOyeYiV ++8tOU0MHtw7IUoRcqjzANBgkqhkiG9w0BAQsFAAOCAQEAo6HA2EVB3j6KI56nKdUY ++sgKquCOylrAjPH3Ov9+E6Z71vCrpVBkB24oy3lhO6F3194HwQR8PsuMSBY35etm5 ++3E/Lg9GtvRydyKzO3IE3oP0JTKC2qjBS8GHhTZe+fCOlOUmBvTRV5efv0asSBr3f ++eplRu9iuJWXtlH4eTSLtJPI3d7Cy7rSe8pYcFItNAKP3cBt28Od3Q4i+6cFN5YNu ++xGq3V+6RIQLbjYtN8QOkmNZbCEFiLIT0aTKRzRS2Qsji62fQCGVrVTBFzOlenwLx ++Bcf6wJ+l96odQxruyF9Lf7FYkysSVsNcygIFglaI5RzcpuGH8k6fzciuN43lEhl+ ++zA== + -----END CERTIFICATE----- + www.minpension.se:443 + +commit f8153266dd485b441c979252c9372f4920e491f3 (tag: v1.9.14) +Author: Mathias Åhsberg +Date: Fri Jan 6 14:08:16 2017 +0100 + + Create release v1.9.14 + +diff --git a/CHANGELOG b/CHANGELOG +index 06dda56..1fbef9f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,6 +1,6 @@ + Please view this file on the master branch, on stable branches it's out of date. +  +-Not yet released ++v1.9.14 (2017-01-06) + * Updated certificates for First Card, Osuuspankki and Östgötatrafiken +  + v1.9.13 (2016-11-03) + +commit 3cf00343b0e0ee7fa6112e79946f10e937231322 +Author: Mathias Åhsberg +Date: Fri Jan 6 14:06:56 2017 +0100 + + Update certificates + +diff --git a/bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem b/bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem +index 516f2c0..3057379 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem +@@ -1,40 +1,52 @@ + -----BEGIN CERTIFICATE----- +-MIIG6jCCBdKgAwIBAgIQMMievVyROVhb96XpEOBsbDANBgkqhkiG9w0BAQsFADB3 +-MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd +-BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj +-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwMTE5MDAwMDAwWhcNMTcwMTE5 +-MjM1OTU5WjCCARQxEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIB +-AgwITmV3IFlvcmsxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMQ8wDQYD +-VQQFEwYxODgwNTUxCzAJBgNVBAYTAlVTMQ4wDAYDVQQRDAUxMDI4NTERMA8GA1UE +-CAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRkwFwYDVQQJDBAyMDAgVmVz +-ZXkgU3RyZWV0MSEwHwYDVQQKDBhBbWVyaWNhbiBFeHByZXNzIENvbXBhbnkxDDAK +-BgNVBAsMA05HSTEjMCEGA1UEAwwaZ2xvYmFsLmFtZXJpY2FuZXhwcmVzcy5jb20w +-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEDvtrbN7UhMqBifnGiFe1 +-SyY9H9gIk0jjJ64/Q5n4ix8ryijlduIAptwNPkLIW1F/gbqFHRFPGtk1vuH1KeAW +-ywaoOUxPFiyTipbwfnfRrL3IhJ5CDBAHRXnMuJAu4KcXzGjSW/GH1jg3x8b3g2S+ +-t7tIGawWhzvdgbb7IKLVWqjbwo3Q8k5zYjEj/7ZxpdL8LIR3tZIqP0stV7M8CtnI +-kEieNVq7aZZkr+PTmjrYOppfNZ+J/tn9dCCcw/6+t/Dv4kqRReKI95XpROXk0Snn +-9nG1cPszs16Q1SdaNsDBYPH/JWO8vhnpQXCqeYxHDEXz46jBsp3361V/zQmiI+9h +-AgMBAAGjggLRMIICzTB7BgNVHREEdDBygiluZ2lvcmlnaW4taXBjMS1nbG9iYWwu +-YW1lcmljYW5leHByZXNzLmNvbYIpbmdpb3JpZ2luLWlwYzItZ2xvYmFsLmFtZXJp +-Y2FuZXhwcmVzcy5jb22CGmdsb2JhbC5hbWVyaWNhbmV4cHJlc3MuY29tMAkGA1Ud +-EwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF +-BQcDAjBmBgNVHSAEXzBdMFsGC2CGSAGG+EUBBxcGMEwwIwYIKwYBBQUHAgEWF2h0 +-dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z +-eW1jYi5jb20vcnBhMB8GA1UdIwQYMBaAFAFZq+fdOgtZpmRj1s8gB1fVkedqMCsG +-A1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9zci5zeW1jYi5jb20vc3IuY3JsMFcGCCsG +-AQUFBwEBBEswSTAfBggrBgEFBQcwAYYTaHR0cDovL3NyLnN5bWNkLmNvbTAmBggr +-BgEFBQcwAoYaaHR0cDovL3NyLnN5bWNiLmNvbS9zci5jcnQwggEDBgorBgEEAdZ5 +-AgQCBIH0BIHxAO8AdQDd6x0reg1PpiCLga2BaHB+Lo6dAdVciI09EcTNtuy+zAAA +-AVJai34nAAAEAwBGMEQCICKhOESezeAvwC0y7eyyF+3Ed+j958sLKbS6L2oyxpUP +-AiBjb2mS1Ea8s55NkQWmAtbkofidSGs9WhnmN0/oLx3TlQB2AKS5CZC0GFgUh7sT +-osxncAo8NZgE+RvfuON3zQ7IDdwQAAABUlqLfmMAAAQDAEcwRQIgJizJc/otF/8Q +-BKsSunRYeq6a6p+GGPsxTCsE4htb7tkCIQDtSUJAfAMZ0sLPNnqamtpT0UI5nooF +-3zIjMKpP37LS8zANBgkqhkiG9w0BAQsFAAOCAQEAyWv9lGUhQV4XEXEoSNJTJcxX +-mIO/e/rYA3T3uwEE1g8rq7Bvmgo1phBTDcNuljMb/ksUy8+qKtzdT0tDSKIYV6Gu +-9N1WNd0aQrL2kpm63f19ZskMbTAMs8XZeK/DpJGQyCu+Y9prn/c/CZd/k6+2Mxoh +-IIqnswSmH/jcktObwGoeu6EVEeVdjgj/mnPLrhX3APSX6zK3qbFcxE7m2ubw+b8+ +-AnIUJYn77iVcKDMkqKsw70niitI0KLVvnX/EI7/gUp4B3ITY4aRSQSoJfghRdS0x +-2JijABwk8FpGAJ93NaikwniTN5q2nAAMV84S6fjYIIo7mjEk0qnZ1ngZTdRZhA== ++MIIJGDCCCACgAwIBAgIQBcnDhS/kTPYwT7xQkKTIiTANBgkqhkiG9w0BAQsFADB1 ++MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 ++d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk ++IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE2MTIwNjAwMDAwMFoXDTE4MTIxMTEy ++MDAwMFowggEXMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjETMBEGCysG ++AQQBgjc8AgEDEwJVUzEZMBcGCysGAQQBgjc8AgECEwhOZXcgWW9yazEPMA0GA1UE ++BRMGMTg4MDU1MR4wHAYDVQQJExUzMTUxIFcuIEJlaHJlbmQgRHJpdmUxDjAMBgNV ++BBETBTg1MDI3MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTEQMA4GA1UE ++BxMHUGhvZW5peDEhMB8GA1UEChMYQW1lcmljYW4gRXhwcmVzcyBDb21wYW55MQww ++CgYDVQQLEwNOR0kxIzAhBgNVBAMTGmdsb2JhbC5hbWVyaWNhbmV4cHJlc3MuY29t ++MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArm1h2NyOnMpJE69RKSLN ++K3VXgzknpKXiWoW60+XnHvmCknUo1HSzKcWhUSYgDyGrziLs39QB3ygVKzkhp1Jm ++dCrCCLugcyowU5ILbIoGxehsbu/WsnJdW75sgo21QxmiT7lmhkfioruXbmFSHPk3 ++NmfhTTnzLLjrm4DTWhpM7QXbedyL5/r5U4usUAMTQrHffVQFI4A26lnv3uA0PeF5 ++17onx8ivwKTIXUTY64utgNI7qqF1zFwMtQioReXeoHGhF7a+KDMLNKT1fY2/1t8N ++NLsEcTcZl9hGhSSUx7zYDYyb6Syurz9U9IYGCP33LnMxU9wPSjuDe9FZZODawSKm ++wQIDAQABo4IE/jCCBPowHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8w ++HQYDVR0OBBYEFBqefDrKnrSSF++OIDOKR08xuuArMHsGA1UdEQR0MHKCGmdsb2Jh ++bC5hbWVyaWNhbmV4cHJlc3MuY29tgiluZ2lvcmlnaW4taXBjMS1nbG9iYWwuYW1l ++cmljYW5leHByZXNzLmNvbYIpbmdpb3JpZ2luLWlwYzItZ2xvYmFsLmFtZXJpY2Fu ++ZXhwcmVzcy5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB ++BggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2Vy ++dC5jb20vc2hhMi1ldi1zZXJ2ZXItZzEuY3JsMDSgMqAwhi5odHRwOi8vY3JsNC5k ++aWdpY2VydC5jb20vc2hhMi1ldi1zZXJ2ZXItZzEuY3JsMEsGA1UdIAREMEIwNwYJ ++YIZIAYb9bAIBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv ++bS9DUFMwBwYFZ4EMAQEwgYgGCCsGAQUFBwEBBHwwejAkBggrBgEFBQcwAYYYaHR0 ++cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsGAQUFBzAChkZodHRwOi8vY2FjZXJ0 ++cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyRXh0ZW5kZWRWYWxpZGF0aW9uU2Vy ++dmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggKtBgorBgEEAdZ5AgQCBIICnQSCApkC ++lwB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABWNTrpfsAAAQD ++AEYwRAIgFR/0U2pLZPoB4kVEeYMi9LqkYgFBM9hJf+A1uYT9354CIAqFZ17SAQ8V ++/H+tpdQY/zIl3lTnZBEFLST6E6t+xfe+AS8ArDua7X+pZ0dXFZ5tfVdWcvnZgQCU ++Hpve/+yhMTt1eC0AAAFY1OusCgAABAEBAD3psaSp1qs4oLVFAuHYX0ZwOf5x3TAl ++jyQbbLF1r5/mbIHzR6LkP5r7bfltTMtMmyc+u/771shPu6sAucM06nPkJF/VhvRM ++OlY6+nSTmVq4gW9a+EjcBefsRCRKa6d00rhSYTx1ZVIa87vSacHD5J+LMgcvTW6N ++YRW3d8zdbVUsbeir7dDx9Diu3aR1bmrjPpt4fEU/GOXOOdy7DFpp8wYN7zaGUhuh ++ThftdZIWhi0QEnZALodco2aZOTFgv2q1Uicf861+M6+QIlwg4zTQEF/rW+12Q5ob ++UivWtV7R9cu83ZenZ+UBeF4t61CF7aJUaoV1yDEkrSc80SYg2l4P9/cAdQBWFAaa ++L9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAVjU66aeAAAEAwBGMEQCICyv ++YtBEG+gUyhkDtf6MCY8LhmCQdPIEezWLlw7d6o/AAiAeuK4vWCe4ch/LCABsHh5x ++ODW/8QG5EjiXjbZ08PfPJAB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6 ++qP3LAAABWNTrqAkAAAQDAEcwRQIgEKsq+0O+H+50tY0s9A/2owkSY6diBkYTt2ZC +++sNP8JYCIQDIchquB/qmN1UHn8n3DU0JJ8Zn8XqyVeTT6/kTAx7MCjANBgkqhkiG ++9w0BAQsFAAOCAQEAv5feWkUjogtKQgC5g2ORTcFgM+FjfXtHN7omZ2pjSXI2xVND ++VhTa0sbleHmB09vwY9v9orp68jxEvWM9FIpdRRiVmv4eJLGyBBaICxp9bePMK82R ++pMObMN9tBAMHd55rnllWE0rME9dB8WvoOkhY7A1BBVY5m86s0H3puOXStiJpAG1j ++JbSeJ4MoGpqbOryiOs/HcLIyHQOpNkykd2BuxxNW/qWQVFhPNvaVgeYy6lXunAVk ++CcNfyrTOKwj0D3JkXUzwYLxSRAEVHNjIxsJT5mJFnPuLd1Te2EDkNuoceYIA+OoE ++jTe/+O2Jm+Nw3PkYwmjtsc0EhaHp7HcPgHZPtQ== + -----END CERTIFICATE----- + global.americanexpress.com:443 +diff --git a/bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem b/bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem +index dab3079..240e7e3 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem +@@ -1,32 +1,38 @@ + -----BEGIN CERTIFICATE----- +-MIIFRzCCBC+gAwIBAgIQN6N70S/YZJ1IsI3RimJCNzANBgkqhkiG9w0BAQUFADCB +-vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug +-YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMt +-VmVyaVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMB4X +-DTE1MTExNzAwMDAwMFoXDTE2MTIzMTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIw +-EAYDVQQIEwlTdG9ja2hvbG0xEjAQBgNVBAcUCVN0b2NraG9sbTEXMBUGA1UEChQO +-Tm9yZGVhIEJhbmsgQUIxEjAQBgNVBAsUCVBsdXNnaXJvdDEhMB8GA1UEAxQYa29u +-dG91dGRyYWcucGx1c2dpcm90LnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +-CgKCAQEAt4V4w7RVKJ8ZNTZzhpe04u5MuknawqYN2q8OA2d23kvKor2YVIuTGvNz +-Jo098s+gqlqINUwAU7At4nn9z4+4JSJ4+tqK/xZVjLvzC9Y0enVXfvsmaOy9jp+o +-A5riJf5378ta+QHjLwU2m9kglEE7FiXJ7gNV8TaTpVTmKDvDCIrtG1pQPMNE4zAs +-EWtDSAjwe68Mkl2ZKbcqa+k+LfIy/Yyhi65RJVtRN9o99bq+ZrBoLZ6eFX4Tu9Tk +-zlMj5YN370Hz0tT7VuezEXLn70rJMPzxEfgwox/PYMccStviIc0++3tkgP3rAgjr +-tyCPL4lknsx+Ki8hgvIqz6T+jWB2HQIDAQABo4IBeDCCAXQwIwYDVR0RBBwwGoIY +-a29udG91dGRyYWcucGx1c2dpcm90LnNlMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQD +-AgWgMCgGA1UdJQQhMB8GCCsGAQUFBwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBMGEG +-A1UdIARaMFgwVgYGZ4EMAQICMEwwIwYIKwYBBQUHAgEWF2h0dHBzOi8vZC5zeW1j +-Yi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5zeW1jYi5jb20vcnBh +-MB8GA1UdIwQYMBaAFNebfNgioBX33a1fzimbWMO8RgC1MCsGA1UdHwQkMCIwIKAe +-oByGGmh0dHA6Ly9zZS5zeW1jYi5jb20vc2UuY3JsMFcGCCsGAQUFBwEBBEswSTAf +-BggrBgEFBQcwAYYTaHR0cDovL3NlLnN5bWNkLmNvbTAmBggrBgEFBQcwAoYaaHR0 +-cDovL3NlLnN5bWNiLmNvbS9zZS5jcnQwDQYJKoZIhvcNAQEFBQADggEBACqvFwm8 +-74fOxapTWBPS5SdSzIoyDTlsHPFbMFvyRxoK8fbres3K+pCo29q7wnYVLnxVh62L +-v3NJMCt1Z25bIFpNR3eCAGakJhEHc0ZS76Wl04pcsFbv64na8rFTNWL2hCJVWZDK +-tHv1zRQzC5fTe/XlseXKQ7zSPGZfo4Y5LHNWa3IpmQB3XPIEEinYGAXxWa7sN4SF +-4XUP5akudcIdP/Gqqj4H24gC4uq6FlAij+cKbcktxmmDYqhklkAKlqekcJX/iZIh +-Hm5AeElVAxdQyy+vC4pwPDZ8M+LSZD8cVmMgvEQpzprhRWQy+JYBwgcYCataFoff +-hA6n1bvE4ifRPUE= ++MIIGfjCCBWagAwIBAgIQbo/Txp+O1DUri0MJuySE2TANBgkqhkiG9w0BAQsFADB+ ++MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd ++BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVj ++IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MTAxNzAwMDAwMFoX ++DTE4MDEwMTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hv ++bG0xEjAQBgNVBAcMCVN0b2NraG9sbTEXMBUGA1UECgwOTm9yZGVhIEJhbmsgQUIx ++EjAQBgNVBAsMCVBsdXNnaXJvdDEhMB8GA1UEAwwYa29udG91dGRyYWcucGx1c2dp ++cm90LnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt4V4w7RVKJ8Z ++NTZzhpe04u5MuknawqYN2q8OA2d23kvKor2YVIuTGvNzJo098s+gqlqINUwAU7At ++4nn9z4+4JSJ4+tqK/xZVjLvzC9Y0enVXfvsmaOy9jp+oA5riJf5378ta+QHjLwU2 ++m9kglEE7FiXJ7gNV8TaTpVTmKDvDCIrtG1pQPMNE4zAsEWtDSAjwe68Mkl2ZKbcq ++a+k+LfIy/Yyhi65RJVtRN9o99bq+ZrBoLZ6eFX4Tu9TkzlMj5YN370Hz0tT7Vuez ++EXLn70rJMPzxEfgwox/PYMccStviIc0++3tkgP3rAgjrtyCPL4lknsx+Ki8hgvIq ++z6T+jWB2HQIDAQABo4IC7jCCAuowIwYDVR0RBBwwGoIYa29udG91dGRyYWcucGx1 ++c2dpcm90LnNlMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG ++CCsGAQUFBwMBBggrBgEFBQcDAjBhBgNVHSAEWjBYMFYGBmeBDAECAjBMMCMGCCsG ++AQUFBwIBFhdodHRwczovL2Quc3ltY2IuY29tL2NwczAlBggrBgEFBQcCAjAZDBdo ++dHRwczovL2Quc3ltY2IuY29tL3JwYTAfBgNVHSMEGDAWgBRfYM9hkFXfhEMUimAq ++svV69EMY7zArBgNVHR8EJDAiMCCgHqAchhpodHRwOi8vc3Muc3ltY2IuY29tL3Nz ++LmNybDBXBggrBgEFBQcBAQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zcy5zeW1j ++ZC5jb20wJgYIKwYBBQUHMAKGGmh0dHA6Ly9zcy5zeW1jYi5jb20vc3MuY3J0MIIB ++fQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdgDd6x0reg1PpiCLga2BaHB+Lo6dAdVc ++iI09EcTNtuy+zAAAAVfSdPmrAAAEAwBHMEUCIQDSRYkISpRrL2N/NzY1ngBn6KRP ++4sx65PoH0HSMPqlk5wIgIedk8JhBZweilNtXUjPNlaiu4NuDqBnJho3s+8f88IUA ++dgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAVfSdPnPAAAEAwBH ++MEUCIQCUTIT2u3vxVEPTD3Gpp1WD8qhnvTlbxojEI1dkOyZcggIgP7N2EnIFgD0n ++K2XhfHUyShXUbwjjhVz5+mlQxRTI58AAdQDuS723dc5guuFCaR+r4Z5mow9+X7By ++2IMAxHuJeqj9ywAAAVfSdPoNAAAEAwBGMEQCIBm+P4i7KuRUws/IppdxW0gAyzTj ++cCN3pyEYnu5A8Zm9AiAmJAwRz9Yd69pps3ulXTfLp4YZUHg63yv7lvJPwuqrczAN ++BgkqhkiG9w0BAQsFAAOCAQEABJ6GLvONcxtkEazxo4EBKDagkHkri5dmP9m6LSgD ++OljqxfuYyXX6d2I6ZkA9TdtFwdInPuCI9L5clHKE7i38SMSfTiLgiz6978jeYZso ++9PyHvs2rx6W8hn6wvCchIHt189ddBXF4BXAsL/KmaMjfDzm8ANNvVXqrUZ4ZKuvj ++UvFerDUmeJEPN88pIHmCLf0xCj2A1OSskFYLiPRuSPBycUU6m5eC7Blt2d9M6u1f ++BAi8cOyC6jv224QZl4QuuoxHzncJwP+DbbRkXovIzn4iFkY8SjbJLMGeM+hf/46X ++b7/H85qGm2J9Bge974C59pUB+NiDLZIhEK9SazvkSsDEiw== + -----END CERTIFICATE----- + kontoutdrag.plusgirot.se:443 + +commit 4583f2cfb0dc5eba0b93944b8c43d2d5a1b73713 +Merge: b3ca271 93a3464 +Author: Mathias Åhsberg +Date: Fri Jan 6 14:05:01 2017 +0100 + + Merge pull request #679 from robho/certificate_update + + Updated certificates for First Card, Osuuspankki and Östgötatrafiken + +commit 93a3464e2d3ab1d6cae747a44df3c807f4426a58 +Author: Robert Högberg +Date: Wed Dec 28 18:00:06 2016 +0100 + + Updated certificates for First Card, Osuuspankki and Östgötatrafiken + +diff --git a/CHANGELOG b/CHANGELOG +index 91dd35a..06dda56 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,5 +1,8 @@ + Please view this file on the master branch, on stable branches it's out of date. +  ++Not yet released ++* Updated certificates for First Card, Osuuspankki and Östgötatrafiken ++ + v1.9.13 (2016-11-03) + * Fixes Crashlytics logging issue +  +diff --git a/bankdroid-legacy/src/main/res/raw/cert_firstcard.pem b/bankdroid-legacy/src/main/res/raw/cert_firstcard.pem +index 179433a..75ced50 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_firstcard.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_firstcard.pem +@@ -1,9 +1,9 @@ + -----BEGIN CERTIFICATE----- +-MIIF/jCCBOagAwIBAgIQbq6gqE0Gd/rc9lIP11FmXjANBgkqhkiG9w0BAQsFADB+ ++MIIGdzCCBV+gAwIBAgIQFoz2cyoH3choP3fYGiPTlTANBgkqhkiG9w0BAQsFADB+ + MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd + BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVj +-IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MDYxNTAwMDAwMFoX +-DTE2MTIzMTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hv ++IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MTAxNDAwMDAwMFoX ++DTE4MDEwMTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hv + bG0xEjAQBgNVBAcMCVN0b2NraG9sbTEXMBUGA1UECgwOTm9yZGVhIEJhbmsgQUIx + GjAYBgNVBAsMEUlUIFJldGFpbCBCYW5raW5nMRkwFwYDVQQDDBB3d3cuZmlyc3Rj + YXJkLnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4dG7pvu0mER1 +@@ -12,25 +12,27 @@ fGHY/PWIfVTl0ixk3pbriKlay9paA/dTdFVKNOZzihPmjeh29bjoYkIRUPfpSfF3 + CDcKlWVyxH9/pR9RmcNtkm5NWDBZT26wGtyqzuwmyPunxQd6PyI9X2SUMZBMsZbd + /rE/1UEdRsgH1L0OmCe35OFIxoYVpNx7BbgVUSAJZc24Oi2AHrzKt5i7Wg2z2qqp + 6OPkZkJaH2y+lpztdSQAyFiyj1ai/V9CyW267uprA0vON/8zecFFvToIutFLZW9Z +-m0MOJzQUzwIDAQABo4ICbjCCAmowGwYDVR0RBBQwEoIQd3d3LmZpcnN0Y2FyZC5z ++m0MOJzQUzwIDAQABo4IC5zCCAuMwGwYDVR0RBBQwEoIQd3d3LmZpcnN0Y2FyZC5z + ZTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD + AQYIKwYBBQUHAwIwYQYDVR0gBFowWDBWBgZngQwBAgIwTDAjBggrBgEFBQcCARYX + aHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGQwXaHR0cHM6Ly9k + LnN5bWNiLmNvbS9ycGEwHwYDVR0jBBgwFoAUX2DPYZBV34RDFIpgKrL1evRDGO8w + KwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3NzLnN5bWNiLmNvbS9zcy5jcmwwVwYI + KwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNodHRwOi8vc3Muc3ltY2QuY29tMCYG +-CCsGAQUFBzAChhpodHRwOi8vc3Muc3ltY2IuY29tL3NzLmNydDCCAQUGCisGAQQB +-1nkCBAIEgfYEgfMA8QB2AN3rHSt6DU+mIIuBrYFocH4ujp0B1VyIjT0RxM227L7M +-AAABVVRwcbsAAAQDAEcwRQIhAM9elVj2e3BQwsGa7pXEVa5U1hPodisxEThcyD5B +-4sxVAiAqRSuOp2FaTDH4DO/K6/dwStGlk2Arvetyz/b7Ov+bxwB3AKS5CZC0GFgU +-h7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABVVRwcdcAAAQDAEgwRgIhAIxmtvOv +-FUbYUl7VnxSO4MnHaqlLbDCd0/xanWgaYw31AiEAzFm+NDhREk9r3z0MGMoG0Z7q +-lD7i6Zx5aBaH8zc8r2UwDQYJKoZIhvcNAQELBQADggEBAGkpiH0ggJGv5POZyxuj +-dumT4KiZl/4eqMjhv1DrWgS525ACi4aODDcmqSPMIu6Hvg3C8p4uaccL/7hPr5bF +-gvjWG7DCPKma2QyHMOMKkKowvojWLwhE+WcnZVO+o3C/Se5ua781gcSDiegnjaE5 +-XJpAuBir0gGXHcFosQ5OEVElQRu5uCR0Fs2w0zllg6wCGu28scMI+d2mLtsY9axN +-AfQUKmAxuqQXfNL3S+jKulpTUK2p4uu78jkHJGButha/aeO2w9Uyd9BDcQSko6BZ +-rI/0lkjmV5LjZprLuY237rfiVUjsezZ9H3lEo+H/HfqkKM+5Pt4zQUFdcqhJretf +-YE4= ++CCsGAQUFBzAChhpodHRwOi8vc3Muc3ltY2IuY29tL3NzLmNydDCCAX4GCisGAQQB ++1nkCBAIEggFuBIIBagFoAHYA3esdK3oNT6Ygi4GtgWhwfi6OnQHVXIiNPRHEzbbs ++vswAAAFXws6hjAAABAMARzBFAiBK8CEHPs9cixQPUkaXXB9K3Ud74tf1wmBaFPri ++UOEULQIhALTQaP9lQdrsAi4DKhs60g4yJNcIx3QjmJJh6a0b03W8AHYAaPaY+B9k ++gr46jO65KB1M/HFRXWeT1ETRCmesu09P+8QAAAFXws6hpwAABAMARzBFAiEAnkz+ ++Oc4HRUxm8RsDhGZ5b+PccYehX1BX3ur6v1g9DNUCID2eL8uVXm80F7FCchu+DG8b ++/URTy0sP6YuTjbC6yZZDAHYA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo ++/csAAAFXws6jggAABAMARzBFAiB2vLVVIqH7/J3SVY4T+ilynHdApDe9qsL3wU6U ++371GzwIhALmmDN5Y0d4WchYXECaRS3E5j/1qWCLffMm4w5eYVXB6MA0GCSqGSIb3 ++DQEBCwUAA4IBAQAXFhS0c69Z86ZfY1CAI+byoEmFvj41A1bb4GIyw2c7qyMISRu6 ++M6oYLGMBpj2OWZdCov+EfilRVtj/ThcuKuh9+VfZr2bloIsrymkXhmgE4orgfuVj ++lkMm+k3jRokTjQryJLAlIQ3UWf9tmn49cSF1culPi8WrYvbSi4DRfo1p3nWY7/RG ++wz0++oHsk5IK7hiGkXmvSWs/p1KJhoU0HViKci4ZcsPn9OEsDqZ9D2bmYLkhpSJG ++cgXx0qd5ledeOq4G9+mRTOudv2u9QJ24VxKycGoXy6ClWbKDt40CPQCBZ515OPRB ++0QnOSxH/5mBWvneOpWytZZ47OWWKPzalXlAK + -----END CERTIFICATE----- + www.firstcard.se:443 +diff --git a/bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem b/bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem +index 748e230..43f5e68 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem +@@ -1,33 +1,33 @@ + -----BEGIN CERTIFICATE----- +-MIIFiTCCBHGgAwIBAgIRAMMg/Cmbci6ISVbk/7dAE+MwDQYJKoZIhvcNAQEFBQAw ++MIIFfjCCBGagAwIBAgIRAKOKgCqyMq9biovKz3eHTo8wDQYJKoZIhvcNAQEFBQAw + gY4xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO + BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTQwMgYD +-VQQDEytDT01PRE8gRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQSAy +-MB4XDTE1MTIzMTAwMDAwMFoXDTE2MTIzMTIzNTk1OVowbDEhMB8GA1UECxMYRG9t +-YWluIENvbnRyb2wgVmFsaWRhdGVkMSEwHwYDVQQLExhQb3NpdGl2ZVNTTCBNdWx0 +-aS1Eb21haW4xJDAiBgNVBAMTG3NzbDMxMDkzOC5jbG91ZGZsYXJlc3NsLmNvbTCC +-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALYtvcavhTumH/f9oo0UxpP5 +-RFjDogfxBhfgwcWHbV9y1EUQEo4XeRze0xwHo7j+N+hmdo6+LwAZkHCUO4LXjDAX +-+s3pMGHUwcy47LcZKLd4DiTDx0ke2Qo6OUt7xNrexq2nPTRuul/9NdnHS1TroW/E +-+lN2hWvqREnF6Az8eARoS5+UBbHNFHfVsJSNVhjE8k6EAs8gFaw7bOTCk7a7ZE+K +-W2vDA/BmDx6zcEGn27bEBsvNZXLzX2PVtxYBcbShcSfEeeOO8jEN8ey5clYRnaz2 +-PoxeD7C5mMO1gcga+UMJzghz3+ACgWKezM1Uk75cls/XfkVL00mCe6p9XcCzKq8C +-AwEAAaOCAgEwggH9MB8GA1UdIwQYMBaAFGx3kOtsaJn2rmFG1WmlVeCFcjBLMB0G +-A1UdDgQWBBSjeVjzGrh4VXrOC1QBSDs0gJgbLjAOBgNVHQ8BAf8EBAMCBaAwDAYD +-VR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0g +-BEgwRjA6BgsrBgEEAbIxAQICBzArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3Vy +-ZS5jb21vZG8uY29tL0NQUzAIBgZngQwBAgEwUwYDVR0fBEwwSjBIoEagRIZCaHR0 +-cDovL2NybC5jb21vZG9jYTQuY29tL0NPTU9ET0RvbWFpblZhbGlkYXRpb25TZWN1 +-cmVTZXJ2ZXJDQTIuY3JsMIGFBggrBgEFBQcBAQR5MHcwTgYIKwYBBQUHMAKGQmh0 +-dHA6Ly9jcnQuY29tb2RvY2E0LmNvbS9DT01PRE9Eb21haW5WYWxpZGF0aW9uU2Vj +-dXJlU2VydmVyQ0EyLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AuY29tb2Rv +-Y2E0LmNvbTBQBgNVHREESTBHghtzc2wzMTA5MzguY2xvdWRmbGFyZXNzbC5jb22C +-FCoub3N0Z290YXRyYWZpa2VuLnNlghJvc3Rnb3RhdHJhZmlrZW4uc2UwDQYJKoZI +-hvcNAQEFBQADggEBAHTI4niIacYjr11856WPSJWY7haBqXDnDnZxuQu+tLm0zX3+ +-zFdmgiJBbEOfrTxzMW0sA7HlrjL4FPbMZCGirR17taXogn4wiyCXZ63I7hKB65Nm +-8pwHiqqOHx95d7AohDdrCfYL1rAyCP6BaBWh0JQFKu9m+ZQyOF6zog7IcMeOEHJi +-XuySpNVeT/DLvUbb4gWd6jaEcCp4zSZBqLLXXbIkkunJ3eTqXq8z5x+mOJpj1UV/ +-AwynkIWdAJxLaJma0Rdw0Ow89uknBWh1mBtQYaSBiltw/3bnTSGhScS00ZxZ85lL +-E1dVzW3GXPiOEh4LMGnnJERSVztgihJziES2RVE= ++VQQDEytDT01PRE8gRG9tYWluIFZhbGlkYXRpb24gTGVnYWN5IFNlcnZlciBDQSAy ++MB4XDTE2MTIxOTAwMDAwMFoXDTE3MTIxNzIzNTk1OVowazEhMB8GA1UECxMYRG9t ++YWluIENvbnRyb2wgVmFsaWRhdGVkMSAwHgYDVQQLExdMZWdhY3kgTXVsdGktRG9t ++YWluIFNTTDEkMCIGA1UEAxMbc3NsNTEzMjMxLmNsb3VkZmxhcmVzc2wuY29tMIIB ++IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoo5oiTWjySYRFPue9v7OFv27 ++95/KJcUZ50tTZx+Mu0XsM/vIeEifp2+/EMq13kr26xlY4mytJ8amhZlIC1gwh3/7 ++29RngE9u88UGJzhWKFmNu4yCtVZCoMkALaN4xIbVmlJVm6MWXFPDDYD2NVOA85TM ++H28ACxkU5uch9a02LktuV0Evq8Uqb+ldSqDKNz9mp1whTb8WOwqDFDxlRXu6U1pR ++g8YK1Wlc58hY8wgLnm5JwHnxYbHfAE5yiJMJ/d9HMxsKcooSMtP8WY42XJmcJ94B ++15WJgLtZq/J7s+nvaRJ+roncNhx9kpHvUAO1E3aSrI4rT6iz6H4Iep/3b51THwID ++AQABo4IB9zCCAfMwHwYDVR0jBBgwFoAUmY4ClcUeVSJ7h3CLXhwBwnbErugwHQYD ++VR0OBBYEFFd9xsH12GaSTSgdudw1HKZ905dqMA4GA1UdDwEB/wQEAwIFoDAMBgNV ++HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBFBgNVHSAE ++PjA8MDoGCysGAQQBsjEBAgIHMCswKQYIKwYBBQUHAgEWHWh0dHBzOi8vc2VjdXJl ++LmNvbW9kby5jb20vQ1BTMFMGA1UdHwRMMEowSKBGoESGQmh0dHA6Ly9jcmwuY29t ++b2RvY2E0LmNvbS9DT01PRE9Eb21haW5WYWxpZGF0aW9uTGVnYWN5U2VydmVyQ0Ey ++LmNybDCBhQYIKwYBBQUHAQEEeTB3ME4GCCsGAQUFBzAChkJodHRwOi8vY3J0LmNv ++bW9kb2NhNC5jb20vQ09NT0RPRG9tYWluVmFsaWRhdGlvbkxlZ2FjeVNlcnZlckNB ++Mi5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLmNvbW9kb2NhNC5jb20wUAYD ++VR0RBEkwR4Ibc3NsNTEzMjMxLmNsb3VkZmxhcmVzc2wuY29tghQqLm9zdGdvdGF0 ++cmFmaWtlbi5zZYISb3N0Z290YXRyYWZpa2VuLnNlMA0GCSqGSIb3DQEBBQUAA4IB ++AQBCyqq8Cl2smTKklqTNvjmJVz/HOOuHi/YplukWPv5Ztc6KrQ3m279ipdyQR4IK ++Q42iYhp7Z1/iw0WqCaDWHiibdJYKMaEWB6nr7BV2qvDnDdAgyTNcW4ZOLakfmy4y ++kGygPzt0cjlZMmSI8iTBPCD4cTkMtQ7EKn3kcRlZ5azBFqT5VXH9N3P183qz1sv6 ++iSg/pLR46dLy061+egeRoElS4Glggg0pAl1fv3duIGmYd3oREK3HRGHlCZ3dA0Hv ++cmJp6Qs2K1phPW3DC6EAVkDKyRUN3BiglOz3xu0eCdAVvnlUFveYcNnH8P2047x1 ++S8rFrPmWlg/+TVPw8kuNxYxG + -----END CERTIFICATE----- + www.ostgotatrafiken.se:443 +diff --git a/bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem b/bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem +index 49f5f1b..d3ad09e 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem +@@ -1,37 +1,37 @@ + -----BEGIN CERTIFICATE----- +-MIIGQjCCBSqgAwIBAgIQP5hSiLJfDuQhp1cXs/mT1DANBgkqhkiG9w0BAQsFADB3 ++MIIGSzCCBTOgAwIBAgIQQq4J10cEVtza7iMNxJPZGjANBgkqhkiG9w0BAQsFADB3 + MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd + BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj +-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUxMjExMDAwMDAwWhcNMTYxMjEx ++IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYxMTI4MDAwMDAwWhcNMTcxMjEx + MjM1OTU5WjCB0jETMBEGCysGAQQBgjc8AgEDEwJGSTEdMBsGA1UEDxMUUHJpdmF0 + ZSBPcmdhbml6YXRpb24xEjAQBgNVBAUTCTAyNDI1MjItMTELMAkGA1UEBhMCRkkx + DjAMBgNVBBEMBTAwNTEwMRAwDgYDVQQIDAdVdXNpbWFhMREwDwYDVQQHDAhIZWxz + aW5raTEaMBgGA1UECQwRVGVvbGxpc3V1c2thdHUgMUIxFjAUBgNVBAoMDU9QIE9z + dXVza3VudGExEjAQBgNVBAMMCXd3dy5vcC5maTCCASIwDQYJKoZIhvcNAQEBBQAD +-ggEPADCCAQoCggEBAOSj+joJzJTPu3fFhVs8Rr1spy+3yDfeZRVZpgPEqEywTIS5 +-4mK1AfmOFjRlv/PJjFXeK8DR/atABgZrcMZHDj3SsIDTvPzRSVZXcRo5FUXJJ1zE +-B7CIXjsxuCRDgbYVqiAl2NIufjooKQcqOB3lbAooLxOruHbG/Bu11h2X4NKEAyWH +-IohCfGTU/qEJBi/7MjRAf5G0j271j9yKxmaEQ4746Y+SW5rTi+HTREpTZgu2zDrN +-CE/znRIW6iUrqQAJQSB/lfjAk1MI6aho9LpgjtUixN3R+D+xF2XqdrrbaEby8KKn +-HmQWDbScoQacqSiU0N5G/wBOlmD+VmPHic8PIQMCAwEAAaOCAmwwggJoMBQGA1Ud ++ggEPADCCAQoCggEBAOtUH95ashzyEZYAvTzQ9EEijM7+styfIK/KZBJWUKM0+mod ++haod+cGvMT27IDm/EZt013X4RG8RbW74K54bdHdBkwFDOpVTRLL6ZGiGkz+C/Dd4 +++iPXJwKek0Bw+BicTwIayyvOIa3NlAGaJWUVG/R9MLZGu+Tx9/LtYStXQHOmBdsy ++jocNN+62OjFW/J11KW2jQTPeg/gZ7iE4S92U1jythHZp0/pSNYW2jCh8HAHj5F2d ++Se8VAkW5M7X7I30RVcb2tN4c2vdjSXsedwxlvPrZ+9SNpA+vHiTcH+PhVCeRfWnD ++vw96bSeS3XWSai+5dRxTiBHjkMT6VdA8HJLc2lkCAwEAAaOCAnUwggJxMBQGA1Ud + EQQNMAuCCXd3dy5vcC5maTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNV +-HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwZgYDVR0gBF8wXTBbBgtghkgBhvhF +-AQcXBjBMMCMGCCsGAQUFBwIBFhdodHRwczovL2Quc3ltY2IuY29tL2NwczAlBggr +-BgEFBQcCAjAZGhdodHRwczovL2Quc3ltY2IuY29tL3JwYTAfBgNVHSMEGDAWgBQB +-Wavn3ToLWaZkY9bPIAdX1ZHnajArBgNVHR8EJDAiMCCgHqAchhpodHRwOi8vc3Iu +-c3ltY2IuY29tL3NyLmNybDBXBggrBgEFBQcBAQRLMEkwHwYIKwYBBQUHMAGGE2h0 +-dHA6Ly9zci5zeW1jZC5jb20wJgYIKwYBBQUHMAKGGmh0dHA6Ly9zci5zeW1jYi5j +-b20vc3IuY3J0MIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHYA3esdK3oNT6Ygi4Gt +-gWhwfi6OnQHVXIiNPRHEzbbsvswAAAFRkUQSTAAABAMARzBFAiEAriTv2d2Ao6yZ +-Trh+sI47Wpwbc2U/dCEusw19L9Y3wHUCIEibTxmqb5yHSP3d9xc8bCVKA62mPoWa +-5jsNvNvp39N/AHcApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFR +-kUQSbAAABAMASDBGAiEAyxrljfrbJ7gbOM1Muaf32Qwr4KgzFO0Szbpv/MHaISIC +-IQCUh2c0pM8V1p/yWUZYmXhNRGhn1AkA3xVckr1is9H2vzANBgkqhkiG9w0BAQsF +-AAOCAQEAc1+J5Ex91zoB+0RJHzSFoPQ9TegFuyo0wO3M4278FYxwO2IDtcUspDvq +-J/ct2W04btWGur1EuG3Y6i87dhkFiIn2o9TbEmb7QvFBB/Ak3eSyi8Y7cqSPhpl4 +-o9m/7mBu6rfgJRdZCgKOE5xD/ND/dCLNzuOeYwXwvYOFv3k3yttU1I7hUVb2d46h +-9clPgOA8N27gKPp01rkTjfF65xpDlmX3xufMwFa9N4C9yJD1SeuZ0EDnjrYLTAp/ +-N5FLXTRm4wLIRzuvb3UoYMM7QLMxcnbXkGqT1SFKxbkupTVcQS5ZDfGNNLi1RTc2 +-/aCGL94jL5MWifVSVGvNLkogJSPiiA== ++HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwbwYDVR0gBGgwZjAHBgVngQwBATBb ++BgtghkgBhvhFAQcXBjBMMCMGCCsGAQUFBwIBFhdodHRwczovL2Quc3ltY2IuY29t ++L2NwczAlBggrBgEFBQcCAjAZDBdodHRwczovL2Quc3ltY2IuY29tL3JwYTAfBgNV ++HSMEGDAWgBQBWavn3ToLWaZkY9bPIAdX1ZHnajArBgNVHR8EJDAiMCCgHqAchhpo ++dHRwOi8vc3Iuc3ltY2IuY29tL3NyLmNybDBXBggrBgEFBQcBAQRLMEkwHwYIKwYB ++BQUHMAGGE2h0dHA6Ly9zci5zeW1jZC5jb20wJgYIKwYBBQUHMAKGGmh0dHA6Ly9z ++ci5zeW1jYi5jb20vc3IuY3J0MIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHcA3esd ++K3oNT6Ygi4GtgWhwfi6OnQHVXIiNPRHEzbbsvswAAAFYquWeNQAABAMASDBGAiEA ++m/vqbAbbDWYSuyDaeX/tL0Tgu6Yd9fTYsNS4sAPR3V8CIQDHEuKjK6b26BaEX3NM ++06N2iRP/Fc6jAG902C+DGoKf1AB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDE ++e4l6qP3LAAABWKrlnoQAAAQDAEcwRQIhAPfcqyFXMb4jVRim8DIE/ahDR2T6KaZ5 ++/Pk4oQIf0RkvAiBjbtXK8OxVk20vce9jgblMdYaANEuX1uZ/m91qCG0i3TANBgkq ++hkiG9w0BAQsFAAOCAQEASAe4g82eWmOp9ALiojwejKwQVV4LbT7vQ8smZGhptu1p ++r4zUppGqXRLpaJjudgLIgZsrHygbGTPJaqw8HR7PYjMt3fOozwH/W2dVHNhjPp09 ++IiBtERECYB9LXkbIC/Iqgn60OWgnaoh7mPjH6jgVGsG/KpDRyLQUx64nLIMFXqdV ++06xu/JcmEoe/5Tf30kcvVAB0I5T17FvzXoAQXUn2IgjYbPomC+Gg3YB80cz6/+NR ++GTBonUx/4aK3XhC5NyFYoR+U+rzEZOPwwLb8kdfg7ykSqz9OngKQl/lgpHsSmIqM ++cB1X7Qc6VtmqOTNuKPcPRlA7OV4N3DYNzhC2ePxoIw== + -----END CERTIFICATE----- + www.op.fi:443 + +commit b3ca27108f9677b0a172cdd155bf3bef1952d668 +Author: Mathias Åhsberg +Date: Mon Nov 28 17:12:45 2016 +0100 + + Update certs for Västtrafik and Ica + +diff --git a/bankdroid-legacy/src/main/res/raw/cert_ica.pem b/bankdroid-legacy/src/main/res/raw/cert_ica.pem +index 36cb10d..3df2bec 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_ica.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_ica.pem +@@ -1,31 +1,31 @@ + -----BEGIN CERTIFICATE----- +-MIIFKzCCBBOgAwIBAgISESHslX6V0aQ+7RZ1+hfIRWm5MA0GCSqGSIb3DQEBCwUA +-MGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTwwOgYD +-VQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gU0hB +-MjU2IC0gRzIwHhcNMTUxMTE4MDk0MTAyWhcNMTYxMTE4MDk0MTAyWjBpMQswCQYD +-VQQGEwJTRTEXMBUGA1UECBMOU3RvY2tob2xtcyBsYW4xDjAMBgNVBAcTBVNvbG5h +-MQswCQYDVQQLEwJJVDEPMA0GA1UEChMGSUNBIEFCMRMwEQYDVQQDEwphcGkuaWNh +-LnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtOXFdViq2xV7p32 +-XbxA27+emUxPKJ3xmhVGK6sMHGdyOSdaiyOWhUpmtl+FsgZ/svRbSMJyK9voSO+6 +-faXP62aaJP5cQIlm0repD9bbcyEZ0Mqe+I1Y5sOCMjwI50dGL+gHEEyB3bEcB1ID +-QRq14UvMT8JybLnOzs2xFkFDwPREzlqnEIt1MwNPudY/5/KHFOdwh937QCcW420l +-PkX3Caow4Sc8vEnsQmPzdrxQuZ2wT7gMMokYSby4eAyhT9QGPc4wZxd/jaOSSI4N +-1qrgCfmW0G4e9b9mI+FADK+yjwtdolT2eBlT7Zchg2NuQdtjUEeuCph4C7eCfLso +-05feywIDAQABo4IBzjCCAcowDgYDVR0PAQH/BAQDAgWgMEkGA1UdIARCMEAwPgYG +-Z4EMAQICMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29t +-L3JlcG9zaXRvcnkvMBUGA1UdEQQOMAyCCmFwaS5pY2Euc2UwCQYDVR0TBAIwADAd +-BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwSQYDVR0fBEIwQDA+oDygOoY4 +-aHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9ncy9nc29yZ2FuaXphdGlvbnZhbHNo +-YTJnMi5jcmwwgaAGCCsGAQUFBwEBBIGTMIGQME0GCCsGAQUFBzAChkFodHRwOi8v +-c2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9nc29yZ2FuaXphdGlvbnZhbHNo +-YTJnMnIxLmNydDA/BggrBgEFBQcwAYYzaHR0cDovL29jc3AyLmdsb2JhbHNpZ24u +-Y29tL2dzb3JnYW5pemF0aW9udmFsc2hhMmcyMB0GA1UdDgQWBBQTwufvdytHvYMM +-eHVL2qa4w7VzbjAfBgNVHSMEGDAWgBSW3mHxvRwWKVMcwMx9O4MAQOYafDANBgkq +-hkiG9w0BAQsFAAOCAQEAGHY6XgnAmrDR810WBns/S2q4cNxq5D/FkCHMbyo231ce +-9LXmbNQQsvmoDJuOivSN04e50DktGQAzk5xbZ0rnjrzFd9HnllWmSh3SPFmqNK9y +-IywGyVzU1UX2lHQ9etZRfnAfdKkajSeHdeBouYiYhgOKFhDkJGJk7qtRFX/PtClA +-dxioVa4kVsXNQ5H17SBQWDwGTRUeUXJUzuPcycvu+D41mdvOONBxKyJUoW0qy945 +-gVfwL0u/EW6jDPofNdvdLaysmGa6YAntqcMf+MUeZ92sbagdIKKiJuEXqzl6iYH+ +-Be2TKW8A9Zy/ke8Z3LCOsj6BVQIeAyMuZsIcvGGsEg== ++MIIFMjCCBBqgAwIBAgIMYiysILzIsNkk0aiAMA0GCSqGSIb3DQEBCwUAMGYxCzAJ ++BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTwwOgYDVQQDEzNH ++bG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gU0hBMjU2IC0g ++RzIwHhcNMTYxMTE1MDg0MTA2WhcNMTcxMTE2MDg0MTA2WjBpMQswCQYDVQQGEwJT ++RTEXMBUGA1UECBMOU3RvY2tob2xtcyBsYW4xDjAMBgNVBAcTBVNvbG5hMQswCQYD ++VQQLEwJJVDEPMA0GA1UEChMGSUNBIEFCMRMwEQYDVQQDEwphcGkuaWNhLnNlMIIB ++IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyUT84RTCZGqEcEe+8CNDDyve ++ayptEmLsnLo7SC0G/LWnvn5XhrOv9TQDhFiD1ayjwXvcbZjDzoLp5dN8M/r0c6NM ++6GSMo1F/mfwDmLJpp1Jx6FCL5CZ7+MYfzP0KaxGTLa9otbWy/Mfcxxx8ifvKI88h ++OjvJC+g3nz0wy1AJKDfYBgEraeFb5FtdhuuhUY78zHeXEXksZpiuh+x9DeEbHpPx ++vmRUDdZLOJVUwhGEa5kJyqMCqDEjwXX+gsfs+zIqIC6XW1kXRL53zF3Oroeat+qy ++vc/JtyI8tEuifrUIhqOipZVmGf2asw6isWpN/G1zoIIKTMRkJRMUssyLPZCqXwID ++AQABo4IB2zCCAdcwDgYDVR0PAQH/BAQDAgWgMIGgBggrBgEFBQcBAQSBkzCBkDBN ++BggrBgEFBQcwAoZBaHR0cDovL3NlY3VyZS5nbG9iYWxzaWduLmNvbS9jYWNlcnQv ++Z3Nvcmdhbml6YXRpb252YWxzaGEyZzJyMS5jcnQwPwYIKwYBBQUHMAGGM2h0dHA6 ++Ly9vY3NwMi5nbG9iYWxzaWduLmNvbS9nc29yZ2FuaXphdGlvbnZhbHNoYTJnMjBW ++BgNVHSAETzBNMEEGCSsGAQQBoDIBFDA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3 ++dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAIBgZngQwBAgIwCQYDVR0TBAIw ++ADBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2dz ++L2dzb3JnYW5pemF0aW9udmFsc2hhMmcyLmNybDAVBgNVHREEDjAMggphcGkuaWNh ++LnNlMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU8zEw ++//vJou9pN8JUZ+yxttNcLdIwHwYDVR0jBBgwFoAUlt5h8b0cFilTHMDMfTuDAEDm ++GnwwDQYJKoZIhvcNAQELBQADggEBAAU4C0JNq9AM2mYT3b8VXY6em77Y/AbXAze0 ++0TYeZgn2wtp9lSBmVUtyAqWFZIE9aKzDruRCaeRzla4zZPN5TDS8jm2KEuBp7xb3 ++4u3Fb7jSmOhyyMuqXzcjFVXp3Gde2GVYAgnDsaXBfJuk63aeUU1mg6kWOh+P7Vez ++84VLXofWNpdhspWXGkBc898GgLK7Ko+lJQ3LS5vn3ITTxlmD2t66jNib8R2aihwa ++XPUdPdTvFuyhT1i8CIuSZAXbZiQRtQh1ooh0lWGxYnL3zGQ29i0O5h44tq+gFOTB ++XP5rIJEjeETnTBZYVLKKjMP5+kUzD2+4o5jMz5ucz7Kzb2LcWYg= + -----END CERTIFICATE----- + api.ica.se:443 +diff --git a/bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem b/bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem +index ecc7ed3..1eb5a57 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem +@@ -1,30 +1,41 @@ + -----BEGIN CERTIFICATE----- +-MIIE8zCCA9ugAwIBAgIQUeTHmHB7Xr1CudcxMmVzpjANBgkqhkiG9w0BAQsFADBE ++MIIG8TCCBdmgAwIBAgIQLw3oiO5pfyS//nmbxVLjUDANBgkqhkiG9w0BAQsFADBE + MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU +-R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTQxMTEyMDAwMDAwWhcNMTYxMjExMjM1 +-OTU5WjBvMQswCQYDVQQGEwJTRTEPMA0GA1UECAwGU3dlZGVuMRAwDgYDVQQHDAdT +-S8OWVkRFMRYwFAYDVQQKDA1WYXN0dHJhZmlrIEFCMQswCQYDVQQLDAJJVDEYMBYG +-A1UEAwwPKi52YXN0dHJhZmlrLnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +-CgKCAQEApcU6TNs1zd1p0Y8ZwRagpav7ir4erVZwdjdocHXS5cTrTzgiwOeXlJRm +-d/708OFRfN6bQq+s1hnULqdwB9eWXUdOd3jZwJPuSupBnChJHrCQd9X81/hmvqUK +-nqvy9YBB2KZPSip4vj5C0r6gyL7FzqywHWmZ0KCyD+a0y3rj6jZHreMq2v6FpjLA +-8F55pegEI21PVVQ0HEWJV2K6ATnbEVw3/u1CqA5DuRj0zWJjYU+jQfTYsXVq/mA1 +-CntuNsAXVosrrolgbr+T4KqTmsDhXLAGeS/CGjQBgCNhHI9ljU8GkDH9k7N4mQDy +-J23Stxpsr9G2GmcZ3HEpApgpFz9EcwIDAQABo4IBtDCCAbAwKQYDVR0RBCIwIIIP +-Ki52YXN0dHJhZmlrLnNlgg12YXN0dHJhZmlrLnNlMAkGA1UdEwQCMAAwDgYDVR0P +-AQH/BAQDAgWgMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9nbi5zeW1jYi5jb20v +-Z24uY3JsMIGhBgNVHSAEgZkwgZYwgZMGCmCGSAGG+EUBBzYwgYQwPwYIKwYBBQUH +-AgEWM2h0dHBzOi8vd3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9y +-eS9sZWdhbDBBBggrBgEFBQcCAjA1DDNodHRwczovL3d3dy5nZW90cnVzdC5jb20v +-cmVzb3VyY2VzL3JlcG9zaXRvcnkvbGVnYWwwHQYDVR0lBBYwFAYIKwYBBQUHAwEG +-CCsGAQUFBwMCMB8GA1UdIwQYMBaAFNJv95b0hT9yPDB9I9qFeJujfFp8MFcGCCsG +-AQUFBwEBBEswSTAfBggrBgEFBQcwAYYTaHR0cDovL2duLnN5bWNkLmNvbTAmBggr +-BgEFBQcwAoYaaHR0cDovL2duLnN5bWNiLmNvbS9nbi5jcnQwDQYJKoZIhvcNAQEL +-BQADggEBANw8IArd3uMLPTObxzXxt/l+JsevXQoq2HKJeWerdW/yer8W8s5oNGmL +-gdFrBhtpxIDK/8x3bY9y1DjmlFjl1ZiQAW4yqSzFjDK9Fs3nM4SPjL0DnTTBIJ1h +-ZPhAof1l6iW+ft0h1/wqel8XMl2PeShsKSN3NQCYu7nuB20n+/no2KqmeFfzZzkU +-MFgcV0sNj019vVne3RizP93yrvAVILRZbU4EkiaBgf5y1GNyLWneRpRGennnbDMB +-oEOd427Js5wKuXAuLXyUOsfwTLB4gMD2RpIeiYnEhhN4n8nStDnbvsoq6tIYC4qz +-7lu66yWdSo3BXrk0mpe3BvNNjGY5R0U= ++R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTYxMTI0MDAwMDAwWhcNMjAwMTE2MjM1 ++OTU5WjB4MQswCQYDVQQGEwJTRTEYMBYGA1UECAwPVmFzdHJhIEdvdGFsYW5kMRAw ++DgYDVQQHDAdTS8OWVkRFMRYwFAYDVQQKDA1WYXN0dHJhZmlrIEFCMQswCQYDVQQL ++DAJJVDEYMBYGA1UEAwwPKi52YXN0dHJhZmlrLnNlMIIBIjANBgkqhkiG9w0BAQEF ++AAOCAQ8AMIIBCgKCAQEApcU6TNs1zd1p0Y8ZwRagpav7ir4erVZwdjdocHXS5cTr ++TzgiwOeXlJRmd/708OFRfN6bQq+s1hnULqdwB9eWXUdOd3jZwJPuSupBnChJHrCQ ++d9X81/hmvqUKnqvy9YBB2KZPSip4vj5C0r6gyL7FzqywHWmZ0KCyD+a0y3rj6jZH ++reMq2v6FpjLA8F55pegEI21PVVQ0HEWJV2K6ATnbEVw3/u1CqA5DuRj0zWJjYU+j ++QfTYsXVq/mA1CntuNsAXVosrrolgbr+T4KqTmsDhXLAGeS/CGjQBgCNhHI9ljU8G ++kDH9k7N4mQDyJ23Stxpsr9G2GmcZ3HEpApgpFz9EcwIDAQABo4IDqTCCA6UwKQYD ++VR0RBCIwIIIPKi52YXN0dHJhZmlrLnNlgg12YXN0dHJhZmlrLnNlMAkGA1UdEwQC ++MAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9nbi5z ++eW1jYi5jb20vZ24uY3JsMIGdBgNVHSAEgZUwgZIwgY8GBmeBDAECAjCBhDA/Bggr ++BgEFBQcCARYzaHR0cHM6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9yZXBv ++c2l0b3J5L2xlZ2FsMEEGCCsGAQUFBwICMDUMM2h0dHBzOi8vd3d3Lmdlb3RydXN0 ++LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeS9sZWdhbDAdBgNVHSUEFjAUBggrBgEF ++BQcDAQYIKwYBBQUHAwIwHwYDVR0jBBgwFoAU0m/3lvSFP3I8MH0j2oV4m6N8Wnww ++VwYIKwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNodHRwOi8vZ24uc3ltY2QuY29t ++MCYGCCsGAQUFBzAChhpodHRwOi8vZ24uc3ltY2IuY29tL2duLmNydDCCAfUGCisG ++AQQB1nkCBAIEggHlBIIB4QHfAHcA3esdK3oNT6Ygi4GtgWhwfi6OnQHVXIiNPRHE ++zbbsvswAAAFYljT1wAAABAMASDBGAiEAzUGB2nVUZmC/eiEOWFYaeOm61lHVgSzB ++YMfQ2chLCOsCIQC5yme+mKFeYJlsOcZGXviu4trgbFTwQ5/+dsGwX7cVAQB1AO5L ++vbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABWJY09gAAAAQDAEYwRAIg ++VPvLVocxnFGLTT1lhPN3Qgbr7ps5R48r6lYeaUWChMICIAcQD2cHWNx8RKHFPGE0 ++/moYHbD8rQTDDUBrMRLdGhcxAHUAvHjh38X2PGhGSTNNoQ+hXwl5aSAJwIG08/aR ++fz7ZuKUAAAFYljT2tgAABAMARjBEAiAgz+64cfRsaYoEKblmyo1rG+7g5fIvODu1 ++9klLI0EO+AIgDNce5RMtVyDiaMUKTvWqKh7Rn9F2/kdjyk8PPTNQCsUAdgCkuQmQ ++tBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAViWNPXfAAAEAwBHMEUCICHG ++6qRiiiTNKbZPNU55DKOpLn7mLsoD4MCxtyzuYz6TAiEA1kguSD4gB1Ov/zMdTytm ++yXZvRAo5PTmulMZX/v1XnDowDQYJKoZIhvcNAQELBQADggEBAFIyiOvLKy/sPqOp ++wYFyb/U6coPLGoCaqZG5XP5GC5wl1i2+y2U0GJ6270LHRQHtHxIkggYGiZUF2FE2 ++FjFwcSDvE1jiQF6Oub/VapNdRoBDG0OtBILF5rgS0k2lpMpk6Q7yKUJbARaUTbWX ++rMA/rcWwsOMCoYO3rS+KrefsZsOjt9UKPljbn/BrA+++FyK3TCwpli529+BCIkP8 ++fprgHJY/DbIXCU/PSBeIdyIq6YYyg5v1ZB0/uv5pFgQ6tpXhR1Fj8+ICuctmQ/8Y ++94rgEraoBiKpVL8EK8T5t7cHJLq53jT76eWHolLzQNr96NCrU9rGQaTKKF/SZ78M ++3WKfVac= + -----END CERTIFICATE----- + www.vasttrafik.se:443 + +commit ef07d475822680cb39898ad433fae1be5874d475 +Author: Johan Walles +Date: Wed Nov 9 20:17:38 2016 +0100 + + Blame Urllib problems on the callers + + For Crashlytics. + + The previous attempt at doing this failed, because it tried to modify + the *first* exception in the chain, but it turns out that it's the + *last* exception in the chain that Crashlytics looks at. + + So given an Exception... + " + java.lang.Exception: This is a test Exception + at not.bankdroid.at.all.ExceptionFactory.getException(ExceptionFactory.java:20) + at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:497) + at ... + " + ... we now report to Crashlytics: + " + java.lang.Exception: This is a test Exception + at not.bankdroid.at.all.ExceptionFactory.getException(ExceptionFactory.java:20) + at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:497) + at ... + Caused by: java.lang.Exception: This is a test Exception + at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:497) + at ... + ... 37 more + " + +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java +index 468b56e..91fe4d5 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java +@@ -1,6 +1,8 @@ + package com.liato.bankdroid.utils; +  ++import android.support.annotation.NonNull; + import android.support.annotation.Nullable; ++import android.support.annotation.VisibleForTesting; +  + import java.lang.reflect.InvocationTargetException; + import java.util.Arrays; +@@ -11,41 +13,109 @@ public class ExceptionUtils { + private static final String PREFIX = "com.liato.bankdroid."; +  + /** +- * Take an exception thrown and make it look like it came from Bankdroid. ++ * Modify an Exception to make it look like it was ultimately caused by Bankdroid. + *

 +- * Specifically, if Urllib.java, called by Bankdroid code, throws an exception, +- * rewrite the exception so that it appears as if it was thrown from the +- * Bankdroid method calling Urllib, but caused by the original Exception. ++ * The purpose is to make Crashlytics report Urllib exceptions as coming from whatever ++ * bank Urllib is trying to access. ++ *

 ++ * For example, this exception: ++ *


++     * java.lang.Exception: This is a test Exception
++     *     at not.bankdroid.at.all.ExceptionFactory.getException(ExceptionFactory.java:20)
++     *     at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
++     *     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
++     *     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
++     *     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
++     *     at java.lang.reflect.Method.invoke(Method.java:497)
++     *     at ...
++     * 
 ++ * ++ * Would be turned into this exception: ++ *

++     * java.lang.Exception: This is a test Exception
++     *     at not.bankdroid.at.all.ExceptionFactory.getException(ExceptionFactory.java:20)
++     *     at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
++     *     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
++     *     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
++     *     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
++     *     at java.lang.reflect.Method.invoke(Method.java:497)
++     *     at ...
++     * Caused by: java.lang.Exception: This is a test Exception
++     *     at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
++     *     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
++     *     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
++     *     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
++     *     at java.lang.reflect.Method.invoke(Method.java:497)
++     *     at ...
++     *     ... 37 more
++     * 
 + */ +- public static T bankdroidifyException(T exception) { ++ public static void blameBankdroid(Throwable exception) { ++ Throwable ultimateCause = getUltimateCause(exception); ++ if (ultimateCause == null) { ++ // Unable to find ultimate cause, never mind ++ return; ++ } ++ + StackTraceElement[] bankdroidifiedStacktrace = +- bankdroidifyStacktrace(exception.getStackTrace()); +- if (bankdroidifiedStacktrace.length == exception.getStackTrace().length) { +- // Unable to bankdroidify stacktrace, never mind +- return exception; ++ bankdroidifyStacktrace(ultimateCause.getStackTrace()); ++ if (bankdroidifiedStacktrace.length == 0) { ++ // No Bankdroid stack frames found, never mind ++ return; ++ } ++ if (bankdroidifiedStacktrace.length == ultimateCause.getStackTrace().length) { ++ // Bankdroid already to blame, never mind ++ return; + } +  +- T returnMe = createWrapperException(exception); +- if (returnMe == null) { ++ Throwable fakeCause = cloneException(ultimateCause); ++ if (fakeCause == null) { + Timber.w(new RuntimeException( +- "Unable to bankdroidify exception of class: " + exception.getClass())); +- return exception; ++ "Unable to bankdroidify exception of class: " + ultimateCause.getClass())); ++ return; + } +  +- returnMe.initCause(exception); ++ // Put the bankdroidified stack trace before the fakeCause's actual stack trace ++ fakeCause.setStackTrace(concatArrays(bankdroidifiedStacktrace, fakeCause.getStackTrace())); +  +- returnMe.setStackTrace(bankdroidifiedStacktrace); ++ ultimateCause.initCause(fakeCause); ++ } +  ++ @VisibleForTesting ++ static StackTraceElement[] concatArrays(StackTraceElement[] a, StackTraceElement[] b) { ++ StackTraceElement[] returnMe = new StackTraceElement[a.length + b.length]; ++ System.arraycopy(a, 0, returnMe, 0, a.length); ++ System.arraycopy(b, 0, returnMe, a.length, b.length); + return returnMe; + } +  ++ @VisibleForTesting ++ @Nullable ++ static Throwable getUltimateCause(Throwable t) { ++ int laps = 0; ++ Throwable ultimateCause = t; ++ while (ultimateCause.getCause() != null) { ++ ultimateCause = ultimateCause.getCause(); ++ if (laps++ > 10) { ++ return null; ++ } ++ } ++ return ultimateCause; ++ } ++ ++ /** ++ * Clone message and stacktrace but not the cause. ++ */ + @Nullable +- private static T createWrapperException(T wrapMe) { ++ @VisibleForTesting ++ static T cloneException(T wrapMe) { + Class newClass = wrapMe.getClass(); + while (newClass != null) { + try { +- return (T) newClass.getConstructor(String.class) +- .newInstance(wrapMe.getMessage()); ++ T returnMe = ++ (T) newClass.getConstructor(String.class).newInstance(wrapMe.getMessage()); ++ returnMe.setStackTrace(wrapMe.getStackTrace()); ++ return returnMe; + } catch (InvocationTargetException e) { + newClass = newClass.getSuperclass(); + } catch (NoSuchMethodException e) { +@@ -63,9 +133,12 @@ public class ExceptionUtils { + /** + * Remove all initial non-Bankdroid frames from a stack. + * +- * @return A copy of rawStack but with the initial non-Bankdroid frames removed ++ * @return A copy of rawStack but with the initial non-Bankdroid frames removed, or null ++ * if no sensible answer can be given. + */ +- private static StackTraceElement[] bankdroidifyStacktrace(final StackTraceElement[] rawStack) { ++ @VisibleForTesting ++ @NonNull ++ static StackTraceElement[] bankdroidifyStacktrace(final StackTraceElement[] rawStack) { + for (int i = 0; i < rawStack.length; i++) { + StackTraceElement stackTraceElement = rawStack[i]; + if (stackTraceElement.getClassName().startsWith(PREFIX)) { +@@ -74,6 +147,6 @@ public class ExceptionUtils { + } +  + // No Bankdroid stack frames found, never mind +- return rawStack; ++ return new StackTraceElement[0]; + } + } +diff --git a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java +index 36354b6..c064d9c 100644 +--- a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java ++++ b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java +@@ -149,7 +149,8 @@ public class Urllib { + try { + return this.open(url, new ArrayList()); + } catch (IOException e) { +- throw ExceptionUtils.bankdroidifyException(e); ++ ExceptionUtils.blameBankdroid(e); ++ throw e; + } + } +  +@@ -162,7 +163,8 @@ public class Urllib { + try { + return open(url, postData, false); + } catch (IOException e) { +- throw ExceptionUtils.bankdroidifyException(e); ++ ExceptionUtils.blameBankdroid(e); ++ throw e; + } + } +  +@@ -182,7 +184,8 @@ public class Urllib { + try { + return openAsHttpResponse(url, entity, forcePost); + } catch (IOException e) { +- throw ExceptionUtils.bankdroidifyException(e); ++ ExceptionUtils.blameBankdroid(e); ++ throw e; + } + } +  +@@ -200,7 +203,8 @@ public class Urllib { + return openAsHttpResponse(url, entity, HttpMethod.POST); + } + } catch (IOException e) { +- throw ExceptionUtils.bankdroidifyException(e); ++ ExceptionUtils.blameBankdroid(e); ++ throw e; + } + } +  +@@ -293,7 +297,8 @@ public class Urllib { + return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null, + forcePost); + } catch (IOException e) { +- throw ExceptionUtils.bankdroidifyException(e); ++ ExceptionUtils.blameBankdroid(e); ++ throw e; + } + } +  +diff --git a/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java b/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java +index df673c5..2b87a96 100644 +--- a/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java ++++ b/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java +@@ -3,85 +3,162 @@ package com.liato.bankdroid.utils; + import org.junit.Assert; + import org.junit.Test; +  ++import java.io.PrintWriter; ++import java.io.StringWriter; + import java.net.ConnectException; +  + import eu.nullbyte.android.urllib.Urllib; +-import not.bankdroid.at.all.ExceptionThrower; ++import not.bankdroid.at.all.ExceptionFactory; +  +-@SuppressWarnings("CallToPrintStackTrace") + public class ExceptionUtilsTest { + @Test +- @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.AvoidCatchingNPE", "PMD.SystemPrintln"}) +- public void testBankdroidifyException() throws Exception { +- Exception raw = null; +- try { +- //noinspection ConstantConditions +- new Urllib(null); +- Assert.fail("Exception expected"); +- } catch (NullPointerException e) { +- raw = e; ++ public void testBlameBankdroid() { ++ Exception e = ExceptionFactory.getException(); ++ String before = toStringWithStacktrace(e); ++ ExceptionUtils.blameBankdroid(e); ++ String after = toStringWithStacktrace(e); ++ String description = ++ String.format("\n---- Before ----\n%s---- After ----\n%s----", before, after); ++ ++ String[] afterLines = after.split("\n"); ++ int lastCausedByIndex = 0; ++ for (int i = 0; i < afterLines.length; i++) { ++ if (afterLines[i].startsWith("Caused by: ")) { ++ lastCausedByIndex = i; ++ } + } +  +- // Print stack traces, useful if the tests fail +- System.err.println("Before:"); +- raw.printStackTrace(); ++ Assert.assertNotEquals(description, 0, lastCausedByIndex); ++ Assert.assertTrue(description, ++ afterLines[lastCausedByIndex + 1].startsWith("\tat com.liato.bankdroid.")); ++ } +  +- System.err.println(); +- System.err.println("After:"); +- Exception bankdroidified = ExceptionUtils.bankdroidifyException(raw); +- bankdroidified.printStackTrace(); ++ /** ++ * Like {@link #testBlameBankdroid()} but with an Exception with a cause. ++ */ ++ @Test ++ public void testBlameBankdroidWithCause() { ++ Exception e = ExceptionFactory.getExceptionWithCause(); ++ String before = toStringWithStacktrace(e); ++ ExceptionUtils.blameBankdroid(e); ++ String after = toStringWithStacktrace(e); ++ String description = ++ String.format("\n---- Before ----\n%s---- After ----\n%s----", before, after); ++ ++ String[] afterLines = after.split("\n"); ++ int firstCausedByIndex = 0; ++ for (int i = 0; i < afterLines.length; i++) { ++ if (afterLines[i].startsWith("Caused by: ")) { ++ firstCausedByIndex = i; ++ break; ++ } ++ } ++ Assert.assertNotEquals(description, 0, firstCausedByIndex); ++ Assert.assertTrue(description, ++ afterLines[firstCausedByIndex + 1].startsWith("\tat not.bankdroid.at.all.")); ++ ++ int lastCausedByIndex = 0; ++ for (int i = 0; i < afterLines.length; i++) { ++ if (afterLines[i].startsWith("Caused by: ")) { ++ lastCausedByIndex = i; ++ } ++ } ++ Assert.assertNotEquals(description, 0, lastCausedByIndex); ++ Assert.assertTrue(description, ++ afterLines[lastCausedByIndex + 1].startsWith("\tat com.liato.bankdroid.")); ++ } +  +- Assert.assertFalse("Test setup: Top frame of initial exception shouldn't be in Bankdroid", +- raw.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid.")); ++ @Test ++ public void testBlameBankdroidAlreadyToBlame() { ++ // Creating it here we're already inside of Bankdroid code, blaming bankdroid should be a ++ // no-op ++ Exception e = new Exception(); +  +- Assert.assertTrue("Top frame of bankdroidified exception should be in Bankdroid", +- bankdroidified.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid.")); ++ String before = toStringWithStacktrace(e); +  +- // Verify that e is the cause of bankdroidified +- Assert.assertSame(raw, bankdroidified.getCause()); ++ ExceptionUtils.blameBankdroid(e); ++ String after = toStringWithStacktrace(e); +  +- // Verify that re-bankdroidifying is a no-op +- Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified)); ++ Assert.assertEquals(before, after); ++ } ++ ++ private String toStringWithStacktrace(Exception e) { ++ StringWriter stringWriter = new StringWriter(); ++ PrintWriter printWriter = new PrintWriter(stringWriter); ++ e.printStackTrace(printWriter); ++ printWriter.close(); ++ return stringWriter.toString(); + } +  +- /** +- * Test that we can wrap exceptions without (String) constructors. +- */ + @Test +- @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.SystemPrintln"}) +- public void testBankdroidifyWonkyException() { +- ExceptionThrower.WonkyException raw = null; +- try { +- ExceptionThrower.throwWonkyException(); +- Assert.fail("Exception expected"); +- } catch (ExceptionThrower.WonkyException e) { +- raw = e; +- } ++ public void testBankdroidifyStacktrace() { ++ StackTraceElement[] bankdroidified = new StackTraceElement[] { ++ new StackTraceElement("not.bankdroid.SomeClass", "someMethod", "SomeClass.java", 42), ++ new StackTraceElement("com.liato.bankdroid.SomeOtherClass", "someOtherMethod", "SomeOtherClass.java", 43), ++ }; ++ bankdroidified = ExceptionUtils.bankdroidifyStacktrace(bankdroidified); +  +- // Print stack traces, useful if the tests fail +- System.err.println("Before:"); +- raw.printStackTrace(); ++ StackTraceElement[] expected = new StackTraceElement[] { ++ new StackTraceElement("com.liato.bankdroid.SomeOtherClass", "someOtherMethod", "SomeOtherClass.java", 43), ++ }; +  +- // Since bankdroidify() won't be able to create a WonkyException, it +- // should fall back to creating something it extends +- ConnectException bankdroidified = ExceptionUtils.bankdroidifyException(raw); ++ Assert.assertArrayEquals(expected, bankdroidified); +  +- System.err.println(); +- System.err.println("After:"); +- bankdroidified.printStackTrace(); ++ // Test re-bankdroidification ++ Assert.assertArrayEquals(expected, ExceptionUtils.bankdroidifyStacktrace(bankdroidified)); ++ } +  +- Assert.assertFalse("Test setup: Top frame of initial exception shouldn't be in Bankdroid", +- raw.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid.")); ++ @Test ++ public void testCloneExceptionWonky() { ++ ExceptionFactory.WonkyException raw = ExceptionFactory.getWonkyException(); ++ ++ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") ++ ConnectException cloned = ExceptionUtils.cloneException(raw); ++ ++ assert cloned != null; ++ Assert.assertEquals(raw.getMessage(), cloned.getMessage()); ++ Assert.assertArrayEquals(raw.getStackTrace(), cloned.getStackTrace()); ++ Assert.assertEquals( ++ "Cloning an uninstantiable Exception should return an instance of its super class", ++ raw.getClass().getSuperclass(), cloned.getClass()); ++ } ++ ++ @Test ++ @SuppressWarnings({"PMD.AvoidCatchingNPE"}) ++ public void testCloneExceptionNPE() { ++ NullPointerException raw = null; ++ try { ++ //noinspection ConstantConditions ++ new Urllib(null); ++ Assert.fail("Exception expected"); ++ } catch (NullPointerException e) { ++ raw = e; ++ } +  +- Assert.assertTrue("Top frame of bankdroidified exception should be in Bankdroid", +- bankdroidified.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid.")); ++ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") ++ NullPointerException cloned = ExceptionUtils.cloneException(raw); +  +- Assert.assertEquals(raw.getMessage(), bankdroidified.getMessage()); ++ assert cloned != null; ++ Assert.assertEquals(raw.getMessage(), cloned.getMessage()); ++ Assert.assertArrayEquals(raw.getStackTrace(), cloned.getStackTrace()); ++ Assert.assertEquals(raw.getClass(), cloned.getClass()); ++ } +  +- // Verify that e is the cause of bankdroidified +- Assert.assertSame(raw, bankdroidified.getCause()); ++ @Test(timeout = 1000) ++ public void testGetUltimateCauseRecursive() { ++ Exception recursive = new Exception(); ++ Exception intermediate = new Exception(recursive); ++ recursive.initCause(intermediate); ++ Assert.assertNull(ExceptionUtils.getUltimateCause(recursive)); ++ } +  +- // Verify that re-bankdroidifying is a no-op +- Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified)); ++ @Test ++ public void testConcatArrays() { ++ StackTraceElement s1 = new StackTraceElement("a", "b", "c", 123); ++ StackTraceElement s2 = new StackTraceElement("d", "e", "f", 456); ++ StackTraceElement[] concatenated = ++ ExceptionUtils.concatArrays( ++ new StackTraceElement[]{s1}, new StackTraceElement[]{s2}); ++ Assert.assertArrayEquals(new StackTraceElement[]{ s1, s2 }, concatenated); + } + } +diff --git a/bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionFactory.java b/bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionFactory.java +new file mode 100644 +index 0000000..bc7d6fe +--- /dev/null ++++ b/bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionFactory.java +@@ -0,0 +1,26 @@ ++package not.bankdroid.at.all; ++ ++import java.net.ConnectException; ++ ++/** ++ * For the test in {@link com.liato.bankdroid.utils.ExceptionUtilsTest} ++ */ ++public class ExceptionFactory { ++ public static class WonkyException extends ConnectException { ++ public WonkyException(int wonky) { ++ super("Wonky: " + wonky); ++ } ++ } ++ ++ public static WonkyException getWonkyException() { ++ return new WonkyException(5); ++ } ++ ++ public static Exception getException() { ++ return new Exception("This is a test Exception"); ++ } ++ ++ public static Exception getExceptionWithCause() { ++ return new Exception("This Exception has a cause", getException()); ++ } ++} +diff --git a/config/quality/lint/lint.xml b/config/quality/lint/lint.xml +index 8195ce2..c3565a5 100644 +--- a/config/quality/lint/lint.xml ++++ b/config/quality/lint/lint.xml +@@ -1,8 +1,11 @@ +  +  +-  ++  +  +  ++  ++  ++ +  +  +  +diff --git a/tools/update-suppressions.sh b/tools/update-suppressions.sh +index 53ff534..1652568 100755 +--- a/tools/update-suppressions.sh ++++ b/tools/update-suppressions.sh +@@ -21,9 +21,12 @@ function set_lint_suppressions() { + cat > ${LINT_XML} << EOF +  +  +-  ++  +  +  ++  ++  ++ +  +  + EOF + +commit d64ede1abee89d557a5f4e0ea720a265b4256e05 +Author: Johan Walles +Date: Thu Nov 3 20:55:57 2016 +0100 + + Fix wrapping exceptions without String constructors + + Before this change, bankdroidifyException() failed if the exception + to wrap didn't come with a String constructor. + + Now it works, with tests and all! + +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java +index e61097b..468b56e 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java +@@ -1,5 +1,7 @@ + package com.liato.bankdroid.utils; +  ++import android.support.annotation.Nullable; ++ + import java.lang.reflect.InvocationTargetException; + import java.util.Arrays; +  +@@ -23,21 +25,10 @@ public class ExceptionUtils { + return exception; + } +  +- T returnMe; +- try { +- returnMe = (T)exception.getClass().getConstructor(String.class) +- .newInstance(exception.getMessage()); +- } catch (InstantiationException e) { +- Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass()); +- return exception; +- } catch (InvocationTargetException e) { +- Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass()); +- return exception; +- } catch (IllegalAccessException e) { +- Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass()); +- return exception; +- } catch (NoSuchMethodException e) { +- Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass()); ++ T returnMe = createWrapperException(exception); ++ if (returnMe == null) { ++ Timber.w(new RuntimeException( ++ "Unable to bankdroidify exception of class: " + exception.getClass())); + return exception; + } +  +@@ -48,6 +39,27 @@ public class ExceptionUtils { + return returnMe; + } +  ++ @Nullable ++ private static T createWrapperException(T wrapMe) { ++ Class newClass = wrapMe.getClass(); ++ while (newClass != null) { ++ try { ++ return (T) newClass.getConstructor(String.class) ++ .newInstance(wrapMe.getMessage()); ++ } catch (InvocationTargetException e) { ++ newClass = newClass.getSuperclass(); ++ } catch (NoSuchMethodException e) { ++ newClass = newClass.getSuperclass(); ++ } catch (InstantiationException e) { ++ newClass = newClass.getSuperclass(); ++ } catch (IllegalAccessException e) { ++ newClass = newClass.getSuperclass(); ++ } ++ } ++ ++ return null; ++ } ++ + /** + * Remove all initial non-Bankdroid frames from a stack. + * +diff --git a/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java b/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java +index 803dc5f..df673c5 100644 +--- a/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java ++++ b/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java +@@ -3,14 +3,19 @@ package com.liato.bankdroid.utils; + import org.junit.Assert; + import org.junit.Test; +  ++import java.net.ConnectException; ++ + import eu.nullbyte.android.urllib.Urllib; ++import not.bankdroid.at.all.ExceptionThrower; +  ++@SuppressWarnings("CallToPrintStackTrace") + public class ExceptionUtilsTest { + @Test +- @SuppressWarnings("PMD") // This is for the stack trace printing, we really want to do it here +- public void bankdroidifyException() throws Exception { ++ @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.AvoidCatchingNPE", "PMD.SystemPrintln"}) ++ public void testBankdroidifyException() throws Exception { + Exception raw = null; + try { ++ //noinspection ConstantConditions + new Urllib(null); + Assert.fail("Exception expected"); + } catch (NullPointerException e) { +@@ -38,4 +43,45 @@ public class ExceptionUtilsTest { + // Verify that re-bankdroidifying is a no-op + Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified)); + } ++ ++ /** ++ * Test that we can wrap exceptions without (String) constructors. ++ */ ++ @Test ++ @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.SystemPrintln"}) ++ public void testBankdroidifyWonkyException() { ++ ExceptionThrower.WonkyException raw = null; ++ try { ++ ExceptionThrower.throwWonkyException(); ++ Assert.fail("Exception expected"); ++ } catch (ExceptionThrower.WonkyException e) { ++ raw = e; ++ } ++ ++ // Print stack traces, useful if the tests fail ++ System.err.println("Before:"); ++ raw.printStackTrace(); ++ ++ // Since bankdroidify() won't be able to create a WonkyException, it ++ // should fall back to creating something it extends ++ ConnectException bankdroidified = ExceptionUtils.bankdroidifyException(raw); ++ ++ System.err.println(); ++ System.err.println("After:"); ++ bankdroidified.printStackTrace(); ++ ++ Assert.assertFalse("Test setup: Top frame of initial exception shouldn't be in Bankdroid", ++ raw.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid.")); ++ ++ Assert.assertTrue("Top frame of bankdroidified exception should be in Bankdroid", ++ bankdroidified.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid.")); ++ ++ Assert.assertEquals(raw.getMessage(), bankdroidified.getMessage()); ++ ++ // Verify that e is the cause of bankdroidified ++ Assert.assertSame(raw, bankdroidified.getCause()); ++ ++ // Verify that re-bankdroidifying is a no-op ++ Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified)); ++ } + } +diff --git a/bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionThrower.java b/bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionThrower.java +new file mode 100644 +index 0000000..1d21a09 +--- /dev/null ++++ b/bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionThrower.java +@@ -0,0 +1,18 @@ ++package not.bankdroid.at.all; ++ ++import java.net.ConnectException; ++ ++/** ++ * For the test in {@link com.liato.bankdroid.utils.ExceptionUtilsTest} ++ */ ++public class ExceptionThrower { ++ public static class WonkyException extends ConnectException { ++ public WonkyException(int wonky) { ++ super("Wonky: " + wonky); ++ } ++ } ++ ++ public static void throwWonkyException() throws WonkyException { ++ throw new WonkyException(5); ++ } ++} + +commit 04230928f02c083eafa9c631bb82c09f54ce8143 +Author: Johan Walles +Date: Fri Nov 4 11:26:49 2016 +0100 + + PMD: Enforce variable naming + + Inspired by a review for another change; these things are better found + by tooling. + + Non-final fields with NAMING_INDICATING_FINALITY have been turned into + final fields when possible. + + In Bank.java, refactored the API a bit so that bank names can be + constant. + +diff --git a/app/src/main/java/com/liato/bankdroid/BankEditActivity.java b/app/src/main/java/com/liato/bankdroid/BankEditActivity.java +index 835c64e..88c142e 100644 +--- a/app/src/main/java/com/liato/bankdroid/BankEditActivity.java ++++ b/app/src/main/java/com/liato/bankdroid/BankEditActivity.java +@@ -81,9 +81,9 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected + @InjectView(R.id.txtErrorDesc) + TextView mErrorDescription; +  +- private Bank SELECTED_BANK; ++ private Bank selectedBank; +  +- private long BANKID = -1; ++ private long bankId = -1; +  + @Override + public void onCreate(Bundle savedInstanceState) { +@@ -101,16 +101,16 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected +  + Bundle extras = getIntent().getExtras(); + if (extras != null) { +- BANKID = extras.getLong("id", -1); +- if (BANKID != -1) { +- Bank bank = BankFactory.bankFromDb(BANKID, this, false); ++ bankId = extras.getLong("id", -1); ++ if (bankId != -1) { ++ Bank bank = BankFactory.bankFromDb(bankId, this, false); + if (bank != null) { + mErrorDescription.setVisibility( + bank.isDisabled() ? View.VISIBLE : View.INVISIBLE); + mBankSpinner.setEnabled(false); + mBankSpinner.setSelection(adapter.getPosition(bank)); +- SELECTED_BANK = bank; +- createForm(SELECTED_BANK.getConnectionConfiguration(), ++ selectedBank = bank; ++ createForm(selectedBank.getConnectionConfiguration(), + DefaultConnectionConfiguration.fields() + ); + populateForm(bank); +@@ -125,10 +125,10 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected + if (!validate()) { + return; + } +- SELECTED_BANK.setProperties(getFormParameters(SELECTED_BANK.getConnectionConfiguration())); +- SELECTED_BANK.setCustomName(getFormParameter(DefaultConnectionConfiguration.NAME)); +- SELECTED_BANK.setDbid(BANKID); +- new DataRetrieverTask(this, SELECTED_BANK).execute(); ++ selectedBank.setProperties(getFormParameters(selectedBank.getConnectionConfiguration())); ++ selectedBank.setCustomName(getFormParameter(DefaultConnectionConfiguration.NAME)); ++ selectedBank.setDbid(bankId); ++ new DataRetrieverTask(this, selectedBank).execute(); + } +  + @OnClick(R.id.btnSettingsCancel) +@@ -139,10 +139,10 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected + @Override + public void onItemSelected(AdapterView parentView, View selectedItemView, int pos, long id) { + Bank selectedBank = (Bank) parentView.getItemAtPosition(pos); +- if (SELECTED_BANK == null || !SELECTED_BANK.equals(selectedBank)) { +- SELECTED_BANK = selectedBank; ++ if (this.selectedBank == null || !this.selectedBank.equals(selectedBank)) { ++ this.selectedBank = selectedBank; + mFormContainer.removeAllViewsInLayout(); +- createForm(SELECTED_BANK.getConnectionConfiguration(), ++ createForm(this.selectedBank.getConnectionConfiguration(), + DefaultConnectionConfiguration.fields() + ); + } +@@ -233,7 +233,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected +  + private boolean validate() { + boolean valid = true; +- Iterator fields = Iterators.concat(SELECTED_BANK.getConnectionConfiguration().iterator(), ++ Iterator fields = Iterators.concat(selectedBank.getConnectionConfiguration().iterator(), + DefaultConnectionConfiguration.fields().iterator()); + while (fields.hasNext()) { + Field field = fields.next(); +@@ -357,8 +357,8 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected + builder.setTitle(R.string.select_a_bank); + builder.setItems(items, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { +- SELECTED_BANK.setExtras(e.getBanks().get(item).getId()); +- new DataRetrieverTask(context, SELECTED_BANK).execute(); ++ selectedBank.setExtras(e.getBanks().get(item).getId()); ++ new DataRetrieverTask(context, selectedBank).execute(); + } + }); + } else { +diff --git a/app/src/main/java/com/liato/bankdroid/LockableActivity.java b/app/src/main/java/com/liato/bankdroid/LockableActivity.java +index 1b5720f..397b3e1 100644 +--- a/app/src/main/java/com/liato/bankdroid/LockableActivity.java ++++ b/app/src/main/java/com/liato/bankdroid/LockableActivity.java +@@ -40,7 +40,7 @@ import android.view.WindowManager; +  + public class LockableActivity extends ActionBarActivity { +  +- private static int PATTERNLOCK_UNLOCK = 42; ++ private static final int PATTERNLOCK_UNLOCK = 42; +  + protected boolean mSkipLockOnce = false; +  +diff --git a/app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java b/app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java +index ffa55f5..b690302 100644 +--- a/app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java ++++ b/app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java +@@ -31,7 +31,7 @@ import android.view.WindowManager; +  + public class LockablePreferenceActivity extends PreferenceActivity { +  +- private static int PATTERNLOCK_UNLOCK = 42; ++ private static final int PATTERNLOCK_UNLOCK = 42; +  + private SharedPreferences mPrefs; +  +diff --git a/app/src/main/java/com/liato/bankdroid/MainActivity.java b/app/src/main/java/com/liato/bankdroid/MainActivity.java +index 48acb74..98c8a2b 100644 +--- a/app/src/main/java/com/liato/bankdroid/MainActivity.java ++++ b/app/src/main/java/com/liato/bankdroid/MainActivity.java +@@ -59,9 +59,9 @@ public class MainActivity extends LockableActivity { +  + protected static boolean showHidden = false; +  +- private static Bank selected_bank = null; ++ private static Bank selectedBank = null; +  +- private static Account selected_account = null; ++ private static Account selectedAccount = null; +  + private final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override +@@ -91,14 +91,14 @@ public class MainActivity extends LockableActivity { + public boolean onItemLongClick(final AdapterView parent, final View view, + final int position, final long id) { + if (adapter.getItem(position) instanceof Account) { +- selected_account = (Account) adapter.getItem(position); ++ selectedAccount = (Account) adapter.getItem(position); + final PopupMenuAccount pmenu = new PopupMenuAccount(parent, view, MainActivity.this); + pmenu.showLikeQuickAction(0, 12); + return true; + } else if (adapter.getItem(position) instanceof Bank) { +- selected_bank = (Bank) adapter.getItem(position); +- selected_bank.toggleHideAccounts(); +- DBAdapter.save(selected_bank, MainActivity.this); ++ selectedBank = (Bank) adapter.getItem(position); ++ selectedBank.toggleHideAccounts(); ++ DBAdapter.save(selectedBank, MainActivity.this); + refreshView(); + return true; + } +@@ -110,7 +110,7 @@ public class MainActivity extends LockableActivity { + public void onItemClick(final AdapterView parent, final View view, + final int position, final long id) { + if (adapter.getItem(position) instanceof Bank) { +- selected_bank = (Bank) adapter.getItem(position); ++ selectedBank = (Bank) adapter.getItem(position); + final PopupMenuBank pmenu = new PopupMenuBank(parent, view, MainActivity.this); + pmenu.showLikeQuickAction(0, 12); + } else { +@@ -241,7 +241,7 @@ public class MainActivity extends LockableActivity { + final Button btnHide = (Button) root.findViewById(R.id.btnHide); + final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide); + final Button btnWWW = (Button) root.findViewById(R.id.btnWWW); +- if (selected_bank.getHideAccounts()) { ++ if (selectedBank.getHideAccounts()) { + btnHide.setVisibility(View.GONE); + btnUnhide.setVisibility(View.VISIBLE); + btnUnhide.setOnClickListener(this); +@@ -250,7 +250,7 @@ public class MainActivity extends LockableActivity { + btnUnhide.setVisibility(View.GONE); + btnHide.setOnClickListener(this); + } +- if (selected_bank.isWebViewEnabled()) { ++ if (selectedBank.isWebViewEnabled()) { + btnWWW.setOnClickListener(this); + } else { + btnWWW.setVisibility(View.GONE); +@@ -270,29 +270,29 @@ public class MainActivity extends LockableActivity { + case R.id.btnHide: + case R.id.btnUnhide: + this.dismiss(); +- selected_bank.toggleHideAccounts(); +- DBAdapter.save(selected_bank, context); ++ selectedBank.toggleHideAccounts(); ++ DBAdapter.save(selectedBank, context); + parent.refreshView(); + return; + case R.id.btnWWW: +- if (selected_bank != null && selected_bank.isWebViewEnabled()) { +- //Uri uri = Uri.parse(selected_bank.getURL()); ++ if (selectedBank != null && selectedBank.isWebViewEnabled()) { ++ //Uri uri = Uri.parse(selectedBank.getURL()); + //Intent intent = new Intent(Intent.ACTION_VIEW, uri); + final Intent intent = new Intent(context, WebViewActivity.class); +- intent.putExtra("bankid", selected_bank.getDbId()); ++ intent.putExtra("bankid", selectedBank.getDbId()); + context.startActivity(intent); + } + this.dismiss(); + return; + case R.id.btnEdit: + final Intent intent = new Intent(context, BankEditActivity.class); +- intent.putExtra("id", selected_bank.getDbId()); ++ intent.putExtra("id", selectedBank.getDbId()); + context.startActivity(intent); + this.dismiss(); + return; + case R.id.btnRefresh: + this.dismiss(); +- new DataRetrieverTask(parent, selected_bank.getDbId()).execute(); ++ new DataRetrieverTask(parent, selectedBank.getDbId()).execute(); + return; + case R.id.btnRemove: + this.dismiss(); +@@ -307,7 +307,7 @@ public class MainActivity extends LockableActivity { + public void onClick(final DialogInterface dialog, + final int id) { + final DBAdapter db = new DBAdapter(context); +- db.deleteBank(selected_bank.getDbId()); ++ db.deleteBank(selectedBank.getDbId()); + dialog.cancel(); + parent.refreshView(); + } +@@ -358,7 +358,7 @@ public class MainActivity extends LockableActivity { + .findViewById(R.id.btnDisableNotifications); + final Button btnEnableNotifications = (Button) root + .findViewById(R.id.btnEnableNotifications); +- if (selected_account.isHidden()) { ++ if (selectedAccount.isHidden()) { + btnHide.setVisibility(View.GONE); + btnUnhide.setVisibility(View.VISIBLE); + btnUnhide.setOnClickListener(this); +@@ -367,7 +367,7 @@ public class MainActivity extends LockableActivity { + btnUnhide.setVisibility(View.GONE); + btnHide.setOnClickListener(this); + } +- if (selected_account.isNotify()) { ++ if (selectedAccount.isNotify()) { + btnDisableNotifications.setVisibility(View.VISIBLE); + btnDisableNotifications.setOnClickListener(this); + btnEnableNotifications.setVisibility(View.GONE); +@@ -385,26 +385,26 @@ public class MainActivity extends LockableActivity { + switch (id) { + case R.id.btnHide: + this.dismiss(); +- selected_account.setHidden(true); +- DBAdapter.save(selected_account.getBank(), parent); ++ selectedAccount.setHidden(true); ++ DBAdapter.save(selectedAccount.getBank(), parent); + parent.refreshView(); + return; + case R.id.btnUnhide: + this.dismiss(); +- selected_account.setHidden(false); +- DBAdapter.save(selected_account.getBank(), parent); ++ selectedAccount.setHidden(false); ++ DBAdapter.save(selectedAccount.getBank(), parent); + parent.refreshView(); + return; + case R.id.btnEnableNotifications: + this.dismiss(); +- selected_account.setNotify(true); +- DBAdapter.save(selected_account.getBank(), parent); ++ selectedAccount.setNotify(true); ++ DBAdapter.save(selectedAccount.getBank(), parent); + parent.refreshView(); + return; + case R.id.btnDisableNotifications: + this.dismiss(); +- selected_account.setNotify(false); +- DBAdapter.save(selected_account.getBank(), parent); ++ selectedAccount.setNotify(false); ++ DBAdapter.save(selectedAccount.getBank(), parent); + parent.refreshView(); + return; +  +diff --git a/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java b/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java +index 7a82c5b..6af968b 100644 +--- a/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java ++++ b/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java +@@ -394,15 +394,15 @@ public class AutoRefreshService extends Service { + } + } catch (final BankException e) { + // Refresh widgets if an update fails +- Timber.e(e, "Could not update bank %s", bank.getShortName()); ++ Timber.e(e, "Could not update bank %s", bank.getName()); + } catch (final LoginException e) { +- Timber.d(e, "Invalid credentials for bank %s", bank.getShortName()); ++ Timber.d(e, "Invalid credentials for bank %s", bank.getName()); + refreshWidgets = true; + db.disableBank(bank.getDbId()); + } catch (BankChoiceException e) { + Timber.w(e, "BankChoiceException"); + } catch (Exception e) { +- Timber.e(e, "An unexpected error occurred while updating bank %s", bank.getShortName()); ++ Timber.e(e, "An unexpected error occurred while updating bank %s", bank.getName()); + } + } +  +diff --git a/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java b/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java +index fd0011c..e6dfd7f 100644 +--- a/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java ++++ b/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java +@@ -390,15 +390,15 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider { + } +  + } catch (BankException e) { +- Timber.e(e, "Could not update bank %s", bank.getShortName()); ++ Timber.e(e, "Could not update bank %s", bank.getName()); + } catch (LoginException e) { +- Timber.w(e, "Invalid credentials for bank %s", bank.getShortName()); ++ Timber.w(e, "Invalid credentials for bank %s", bank.getName()); + DBAdapter.disable(bank, context); + } catch (BankChoiceException e) { + Timber.w(e, "BankChoiceException"); + } catch (IOException e) { + if (NetworkUtils.isInternetAvailable()) { +- Timber.e(e, "Could not update bank %s", bank.getShortName()); ++ Timber.e(e, "Could not update bank %s", bank.getName()); + } + } + BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId); +diff --git a/app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java b/app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java +index 3e16654..0610ad7 100644 +--- a/app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java ++++ b/app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java +@@ -67,44 +67,44 @@ public class BankTransactionsProvider extends ContentProvider implements +  + private static final String TRANSACTIONS_TABLE = "transactions"; +  +- private final static UriMatcher uriMatcher; ++ private final static UriMatcher URI_MATCHER; +  +- private final static Map bankAccountProjectionMap; ++ private final static Map BANK_ACCOUNT_PROJECTION_MAP; +  +- private final static Map transProjectionMap; ++ private final static Map TRANS_PROJECTION_MAP; +  + static { +- uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); +- uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT + "/" + WILD_CARD, ++ URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); ++ URI_MATCHER.addURI(AUTHORITY, TRANSACTIONS_CAT + "/" + WILD_CARD, + TRANSACTIONS); +- uriMatcher.addURI(AUTHORITY, BANK_ACCOUNTS_CAT + "/" + WILD_CARD, ++ URI_MATCHER.addURI(AUTHORITY, BANK_ACCOUNTS_CAT + "/" + WILD_CARD, + BANK_ACCOUNTS); +  + // Projections are "Poor mans views" of the data. +- bankAccountProjectionMap = new HashMap(); ++ BANK_ACCOUNT_PROJECTION_MAP = new HashMap(); +  + // Must match bankAccountProjection in + // IBankTransactionsProvider#bankAccountProjection +- bankAccountProjectionMap.put(BANK_ID, BANK_ID); +- bankAccountProjectionMap.put(BANK_NAME, BANK_NAME); +- bankAccountProjectionMap.put(BANK_TYPE, BANK_TYPE); +- bankAccountProjectionMap.put(BANK_LAST_UPDATED, BANK_LAST_UPDATED); +- bankAccountProjectionMap.put(ACC_ID, ACC_ID); +- bankAccountProjectionMap.put(ACC_NAME, ACC_NAME); ++ BANK_ACCOUNT_PROJECTION_MAP.put(BANK_ID, BANK_ID); ++ BANK_ACCOUNT_PROJECTION_MAP.put(BANK_NAME, BANK_NAME); ++ BANK_ACCOUNT_PROJECTION_MAP.put(BANK_TYPE, BANK_TYPE); ++ BANK_ACCOUNT_PROJECTION_MAP.put(BANK_LAST_UPDATED, BANK_LAST_UPDATED); ++ BANK_ACCOUNT_PROJECTION_MAP.put(ACC_ID, ACC_ID); ++ BANK_ACCOUNT_PROJECTION_MAP.put(ACC_NAME, ACC_NAME); + // Table name has to be explicitly included here since Banks also have a column named balance. +- bankAccountProjectionMap.put(ACC_BALANCE, ACCOUNT_TABLE + "." + ACC_BALANCE); +- bankAccountProjectionMap.put(ACC_TYPE, ACC_TYPE); ++ BANK_ACCOUNT_PROJECTION_MAP.put(ACC_BALANCE, ACCOUNT_TABLE + "." + ACC_BALANCE); ++ BANK_ACCOUNT_PROJECTION_MAP.put(ACC_TYPE, ACC_TYPE); +  +- transProjectionMap = new HashMap(); ++ TRANS_PROJECTION_MAP = new HashMap(); +  + // Must match transactionProjection in + // IBankTransactionsProvider#transactionProjection +- transProjectionMap.put(TRANS_ID, TRANS_ID); +- transProjectionMap.put(TRANS_DATE, TRANS_DATE); +- transProjectionMap.put(TRANS_DESC, TRANS_DESC); +- transProjectionMap.put(TRANS_AMT, TRANS_AMT); +- transProjectionMap.put(TRANS_CUR, TRANS_CUR); +- transProjectionMap.put(TRANS_ACCNT, TRANS_ACCNT); ++ TRANS_PROJECTION_MAP.put(TRANS_ID, TRANS_ID); ++ TRANS_PROJECTION_MAP.put(TRANS_DATE, TRANS_DATE); ++ TRANS_PROJECTION_MAP.put(TRANS_DESC, TRANS_DESC); ++ TRANS_PROJECTION_MAP.put(TRANS_AMT, TRANS_AMT); ++ TRANS_PROJECTION_MAP.put(TRANS_CUR, TRANS_CUR); ++ TRANS_PROJECTION_MAP.put(TRANS_ACCNT, TRANS_ACCNT); + } +  + private DatabaseHelper dbHelper; +@@ -143,7 +143,7 @@ public class BankTransactionsProvider extends ContentProvider implements + public String getType(final Uri uri) { + Timber.d("Got URI: %s", uri.toString()); +  +- switch (uriMatcher.match(uri)) { ++ switch (URI_MATCHER.match(uri)) { + case BANK_ACCOUNTS: + return BANK_ACCOUNTS_MIME; + case TRANSACTIONS: +@@ -207,12 +207,12 @@ public class BankTransactionsProvider extends ContentProvider implements + if (BANK_ACCOUNTS_MIME.equals(getType(uri))) { + qb = new SQLiteQueryBuilder(); + qb.setTables(BANK_ACCOUNT_TABLES); +- qb.setProjectionMap(bankAccountProjectionMap); ++ qb.setProjectionMap(BANK_ACCOUNT_PROJECTION_MAP); + qb.setDistinct(true); + } else if (TRANSACTIONS_MIME.equals(getType(uri))) { + qb = new SQLiteQueryBuilder(); + qb.setTables(TRANSACTIONS_TABLE); +- qb.setProjectionMap(transProjectionMap); ++ qb.setProjectionMap(TRANS_PROJECTION_MAP); + } else { + throw new IllegalArgumentException("Unsupported URI: " + uri); + } +diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java +index 87a0c1d..8997f8f 100644 +--- a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java ++++ b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java +@@ -41,7 +41,7 @@ public class ColorPickerPreference + Preference.OnPreferenceClickListener, + ColorPickerDialog.OnColorChangedListener { +  +- private static final String androidns = "http://schemas.android.com/apk/res/android"; ++ private static final String ANDROID_NS = "http://schemas.android.com/apk/res/android"; +  + private ViewGroup parent; +  +@@ -137,7 +137,7 @@ public class ColorPickerPreference + mDensity = getContext().getResources().getDisplayMetrics().density; + setOnPreferenceClickListener(this); + if (attrs != null) { +- String defaultValue = attrs.getAttributeValue(androidns, "defaultValue"); ++ String defaultValue = attrs.getAttributeValue(ANDROID_NS, "defaultValue"); + if (defaultValue.startsWith("#")) { + try { + mDefaultValue = convertToColorInt(defaultValue); +@@ -146,7 +146,7 @@ public class ColorPickerPreference + mDefaultValue = convertToColorInt("#FF000000"); + } + } else { +- int resourceId = attrs.getAttributeResourceValue(androidns, "defaultValue", 0); ++ int resourceId = attrs.getAttributeResourceValue(ANDROID_NS, "defaultValue", 0); + if (resourceId != 0) { + mDefaultValue = context.getResources().getInteger(resourceId); + } +diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java +index 8ff79d3..13af48e 100644 +--- a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java ++++ b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java +@@ -64,29 +64,29 @@ public class ColorPickerView extends View { + /** + * The width in dp of the hue panel. + */ +- private float HUE_PANEL_WIDTH = 30f; ++ private float huePanelWidth = 30f; +  + /** + * The height in dp of the alpha panel + */ +- private float ALPHA_PANEL_HEIGHT = 20f; ++ private float alphaPanelHeight = 20f; +  + /** + * The distance in dp between the different + * color panels. + */ +- private float PANEL_SPACING = 10f; ++ private float panelSpacing = 10f; +  + /** + * The radius in dp of the color palette tracker circle. + */ +- private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f; ++ private float paletteCircleTrackerRadius = 5f; +  + /** + * The dp which the tracker of the hue or alpha panel + * will extend outside of its bounds. + */ +- private float RECTANGLE_TRACKER_OFFSET = 2f; ++ private float rectangleTrackerOffset = 2f; +  + private float mDensity = 1f; +  +@@ -172,11 +172,11 @@ public class ColorPickerView extends View { + setLayerType(View.LAYER_TYPE_SOFTWARE, null); + } + mDensity = getContext().getResources().getDisplayMetrics().density; +- PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity; +- RECTANGLE_TRACKER_OFFSET *= mDensity; +- HUE_PANEL_WIDTH *= mDensity; +- ALPHA_PANEL_HEIGHT *= mDensity; +- PANEL_SPACING = PANEL_SPACING * mDensity; ++ paletteCircleTrackerRadius *= mDensity; ++ rectangleTrackerOffset *= mDensity; ++ huePanelWidth *= mDensity; ++ alphaPanelHeight *= mDensity; ++ panelSpacing = panelSpacing * mDensity; +  + mDrawingOffset = calculateRequiredOffset(); +  +@@ -216,7 +216,7 @@ public class ColorPickerView extends View { + } +  + private float calculateRequiredOffset() { +- float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET); ++ float offset = Math.max(paletteCircleTrackerRadius, rectangleTrackerOffset); + offset = Math.max(offset, BORDER_WIDTH_PX * mDensity); +  + return offset * 1.5f; +@@ -274,11 +274,11 @@ public class ColorPickerView extends View { + Point p = satValToPoint(mSat, mVal); +  + mSatValTrackerPaint.setColor(0xff000000); +- canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, ++ canvas.drawCircle(p.x, p.y, paletteCircleTrackerRadius - 1f * mDensity, + mSatValTrackerPaint); +  + mSatValTrackerPaint.setColor(0xffdddddd); +- canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint); ++ canvas.drawCircle(p.x, p.y, paletteCircleTrackerRadius, mSatValTrackerPaint); +  + } +  +@@ -308,8 +308,8 @@ public class ColorPickerView extends View { + Point p = hueToPoint(mHue); +  + RectF r = new RectF(); +- r.left = rect.left - RECTANGLE_TRACKER_OFFSET; +- r.right = rect.right + RECTANGLE_TRACKER_OFFSET; ++ r.left = rect.left - rectangleTrackerOffset; ++ r.right = rect.right + rectangleTrackerOffset; + r.top = p.y - rectHeight; + r.bottom = p.y + rectHeight; +  +@@ -359,8 +359,8 @@ public class ColorPickerView extends View { + RectF r = new RectF(); + r.left = p.x - rectWidth; + r.right = p.x + rectWidth; +- r.top = rect.top - RECTANGLE_TRACKER_OFFSET; +- r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET; ++ r.top = rect.top - rectangleTrackerOffset; ++ r.bottom = rect.bottom + rectangleTrackerOffset; +  + canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint); +  +@@ -663,22 +663,22 @@ public class ColorPickerView extends View { +  + if (!mShowAlphaPanel) { +  +- height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH); ++ height = (int) (widthAllowed - panelSpacing - huePanelWidth); +  + //If calculated height (based on the width) is more than the allowed height. + if (height > heightAllowed || getTag().equals("landscape")) { + height = heightAllowed; +- width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH); ++ width = (int) (height + panelSpacing + huePanelWidth); + } else { + width = widthAllowed; + } + } else { +  +- width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH); ++ width = (int) (heightAllowed - alphaPanelHeight + huePanelWidth); +  + if (width > widthAllowed) { + width = widthAllowed; +- height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT); ++ height = (int) (widthAllowed - huePanelWidth + alphaPanelHeight); + } else { + height = heightAllowed; + } +@@ -709,10 +709,10 @@ public class ColorPickerView extends View { + int width = getPrefferedHeight(); +  + if (mShowAlphaPanel) { +- width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT); ++ width -= (panelSpacing + alphaPanelHeight); + } +  +- return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING); ++ return (int) (width + huePanelWidth + panelSpacing); +  + } +  +@@ -721,7 +721,7 @@ public class ColorPickerView extends View { + int height = (int) (200 * mDensity); +  + if (mShowAlphaPanel) { +- height += PANEL_SPACING + ALPHA_PANEL_HEIGHT; ++ height += panelSpacing + alphaPanelHeight; + } +  + return height; +@@ -748,7 +748,7 @@ public class ColorPickerView extends View { + float panelSide = dRect.height() - BORDER_WIDTH_PX * 2; +  + if (mShowAlphaPanel) { +- panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT; ++ panelSide -= panelSpacing + alphaPanelHeight; + } +  + float left = dRect.left + BORDER_WIDTH_PX; +@@ -762,10 +762,10 @@ public class ColorPickerView extends View { + private void setUpHueRect() { + final RectF dRect = mDrawingRect; +  +- float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX; ++ float left = dRect.right - huePanelWidth + BORDER_WIDTH_PX; + float top = dRect.top + BORDER_WIDTH_PX; +- float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING +- + ALPHA_PANEL_HEIGHT) : 0); ++ float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (panelSpacing ++ + alphaPanelHeight) : 0); + float right = dRect.right - BORDER_WIDTH_PX; +  + mHueRect = new RectF(left, top, right, bottom); +@@ -780,7 +780,7 @@ public class ColorPickerView extends View { + final RectF dRect = mDrawingRect; +  + float left = dRect.left + BORDER_WIDTH_PX; +- float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX; ++ float top = dRect.bottom - alphaPanelHeight + BORDER_WIDTH_PX; + float bottom = dRect.bottom - BORDER_WIDTH_PX; + float right = dRect.right - BORDER_WIDTH_PX; +  +diff --git a/app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java b/app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java +index b821497..5e3de22 100644 +--- a/app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java ++++ b/app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java +@@ -3,6 +3,7 @@ package com.liato.bankdroid.appwidget; + import com.liato.bankdroid.banking.Account; + import com.liato.bankdroid.banking.Bank; + import com.liato.bankdroid.db.DBAdapter; ++import com.liato.bankdroid.provider.IBankTypes; +  + import org.junit.Assert; + import org.junit.Test; +@@ -56,6 +57,16 @@ public class DataRetrieverTaskTest { + public BigDecimal getBalance() { + return getAccounts().get(0).getBalance(); + } ++ ++ @Override ++ public int getBanktypeId() { ++ return IBankTypes.TESTBANK; ++ } ++ ++ @Override ++ public String getName() { ++ return "Testbanken"; ++ } + } +  + private static class TestableDataRetrieverTask extends AutoRefreshService.DataRetrieverTask { +diff --git a/bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java b/bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java +index 3a47c5b..2fefbb9 100644 +--- a/bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java ++++ b/bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java +@@ -12,7 +12,7 @@ public class DefaultConnectionConfiguration { +  + public static final String NAME = "provider.configuration.name"; +  +- private final static List configuration = createConfiguration(); ++ private final static List CONFIGURATION = createConfiguration(); +  + private static List createConfiguration() { + List configuration = new ArrayList<>(); +@@ -24,6 +24,6 @@ public class DefaultConnectionConfiguration { + } +  + public static List fields() { +- return configuration; ++ return CONFIGURATION; + } + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java +index 2ea759a..7e53cf4 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java +@@ -38,7 +38,7 @@ import timber.log.Timber; + public class Helpers { + private static final StrikethroughSpan STRIKE_THROUGH_SPAN = new StrikethroughSpan(); +  +- private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", ++ private final static String[] CURRENCIES = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", + "AUD", + "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", + "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR", +@@ -62,7 +62,7 @@ public class Helpers { + "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "YER", + "ZAR", "ZMK", "ZWD"}; +  +- private final static String[][] symMappings = {{"$U", "UYU"}, {"$b", "BOB"}, {"BZ$", "BZD"}, ++ private final static String[][] SYM_MAPPINGS = {{"$U", "UYU"}, {"$b", "BOB"}, {"BZ$", "BZD"}, + {"C$", "NIO"}, {"J$", "JMD"}, {"NT$", "TWD"}, + {"R$", "BRL"}, {"RD$", "DOP"}, {"TT$", "TTD"}, + {"Z$", "ZWD"}, {"$", "USD"}, {"B/.", "PAB"}, +@@ -148,12 +148,12 @@ public class Helpers { +  + public static String parseCurrency(String text, String def) { + text = text != null ? text.toLowerCase() : ""; +- for (String currency : currencies) { ++ for (String currency : CURRENCIES) { + if (text.contains(currency)) { + return currency; + } + } +- for (String[] symCur : symMappings) { ++ for (String[] symCur : SYM_MAPPINGS) { + if (text.contains(symCur[0])) { + return symCur[1]; + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java +index 18a6a0c..b3f6e97 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java +@@ -54,14 +54,6 @@ public abstract class Bank implements Comparable, IBankTypes { + @DrawableRes + private final int logoResource; +  +- protected String TAG = "Bank"; +- +- protected String NAME = "Bank"; +- +- protected String NAME_SHORT = "bank"; +- +- protected int BANKTYPE_ID = 0; +- + /** + * URL for human-accessible web bank. + *

 +@@ -71,43 +63,43 @@ public abstract class Bank implements Comparable, IBankTypes { + * @see #isWebViewEnabled() + */ + @Nullable +- protected String URL; ++ protected String url; +  +- protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT; ++ protected int inputTypeUsername = InputType.TYPE_CLASS_TEXT; +  +- protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT ++ protected int inputTypePassword = InputType.TYPE_CLASS_TEXT + | InputType.TYPE_TEXT_VARIATION_PASSWORD; +  +- protected int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT; ++ private static final int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT; +  +- protected String INPUT_HINT_USERNAME = null; ++ protected String inputHintUsername = null; +  +- protected boolean INPUT_HIDDEN_USERNAME = false; ++ private static final boolean INPUT_HIDDEN_USERNAME = false; +  +- protected boolean INPUT_HIDDEN_PASSWORD = false; ++ protected boolean inputHiddenPassword = false; +  +- protected boolean INPUT_HIDDEN_EXTRAS = true; ++ private static final boolean INPUT_HIDDEN_EXTRAS = true; +  +- protected int INPUT_TITLETEXT_USERNAME = R.string.username; ++ protected int inputTitletextUsername = R.string.username; +  +- protected int INPUT_TITLETEXT_PASSWORD = R.string.password; ++ private final int INPUT_TITLETEXT_PASSWORD = R.string.password; +  +- protected int INPUT_TITLETEXT_EXTRAS = R.string.extras_field; ++ private final int INPUT_TITLETEXT_EXTRAS = R.string.extras_field; +  +- protected boolean STATIC_BALANCE = false; ++ protected boolean staticBalance = false; +  +- protected boolean BROKEN = false; ++ private static final boolean BROKEN = false; +  +- protected boolean DISPLAY_DECIMALS = true; ++ protected boolean displayDecimals = true; +  + /** + * Whether or not we support opening the web version of a bank. + *

 + * Lots of banks don't have this any more, but have apps instead. + * @see #isWebViewEnabled() +- * @see #URL ++ * @see #url + */ +- protected boolean WEB_VIEW_ENABLED = true; ++ protected boolean webViewEnabled = true; +  + protected Context context; +  +@@ -229,7 +221,7 @@ public abstract class Bank implements Comparable, IBankTypes { + } +  + public BigDecimal getBalance() { +- if (STATIC_BALANCE) { ++ if (staticBalance) { + return balance; + } else { + BigDecimal bal = new BigDecimal(0); +@@ -246,13 +238,9 @@ public abstract class Bank implements Comparable, IBankTypes { + } + } +  +- public int getBanktypeId() { +- return BANKTYPE_ID; +- } ++ public abstract int getBanktypeId(); +  +- public String getName() { +- return NAME; +- } ++ public abstract String getName(); +  + public String getDisplayName() { + if (customName != null && customName.length() > 0) { +@@ -278,10 +266,6 @@ public abstract class Bank implements Comparable, IBankTypes { + getProperties().put(LegacyProviderConfiguration.EXTRAS, extras); + } +  +- public String getShortName() { +- return NAME_SHORT; +- } +- + public void setData(BigDecimal balance, + boolean disabled, long dbid, String currency, String customName, + int hideAccounts) { +@@ -314,15 +298,15 @@ public abstract class Bank implements Comparable, IBankTypes { + } +  + public String getURL() { +- return URL; ++ return url; + } +  + public int getInputTypeUsername() { +- return INPUT_TYPE_USERNAME; ++ return inputTypeUsername; + } +  + public int getInputTypePassword() { +- return INPUT_TYPE_PASSWORD; ++ return inputTypePassword; + } +  + public int getInputTypeExtras() { +@@ -330,7 +314,7 @@ public abstract class Bank implements Comparable, IBankTypes { + } +  + public String getInputHintUsername() { +- return INPUT_HINT_USERNAME; ++ return inputHintUsername; + } +  + public boolean isInputUsernameHidden() { +@@ -338,7 +322,7 @@ public abstract class Bank implements Comparable, IBankTypes { + } +  + public boolean isInputPasswordHidden() { +- return INPUT_HIDDEN_PASSWORD; ++ return inputHiddenPassword; + } +  + public boolean isInputExtrasHidden() { +@@ -346,7 +330,7 @@ public abstract class Bank implements Comparable, IBankTypes { + } +  + public int getInputTitleUsername() { +- return INPUT_TITLETEXT_USERNAME; ++ return inputTitletextUsername; + } +  + public int getInputTitlePassword() { +@@ -361,11 +345,11 @@ public abstract class Bank implements Comparable, IBankTypes { + * Whether or not we support opening the web version of a bank. + *

 + * Lots of banks don't have this any more, but have apps instead. +- * @see #WEB_VIEW_ENABLED +- * @see #URL ++ * @see #webViewEnabled ++ * @see #url + */ + public boolean isWebViewEnabled() { +- return URL != null && WEB_VIEW_ENABLED; ++ return url != null && webViewEnabled; + } +  + public Map getProperties() { +@@ -455,7 +439,7 @@ public abstract class Bank implements Comparable, IBankTypes { + Timber.e(e, "Error getting session package"); + } + String html = String.format(preloader, +- String.format("function go(){window.location=\"%s\" }", this.URL), ++ String.format("function go(){window.location=\"%s\" }", this.url), + // Javascript function + "" // HTML + ); +@@ -467,7 +451,7 @@ public abstract class Bank implements Comparable, IBankTypes { + } +  + public boolean getDisplayDecimals() { +- return DISPLAY_DECIMALS; ++ return displayDecimals; + } +  + protected Context getContext() { +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java +index 1abfc23..61ce9dd 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java +@@ -58,10 +58,10 @@ public abstract class AbsIkanoPartner extends Bank { +  + public AbsIkanoPartner(Context context, @DrawableRes int logoResource) { + super(context, logoResource); +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.STATIC_BALANCE = true; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.staticBalance = true; + } +  + public AbsIkanoPartner(String username, String password, Context context, @DrawableRes int logoResource) +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java +index f84865b..848b842 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java +@@ -46,8 +46,6 @@ public class AkeliusInvest extends Bank { +  + private static final String NAME = "Akelius Invest"; +  +- private static final String NAME_SHORT = "akeliusinvest"; +- + private static final String URL = "https://online.akeliusinvest.com/"; +  + private static final int BANKTYPE_ID = IBankTypes.AKELIUSINVEST; +@@ -80,14 +78,11 @@ public class AkeliusInvest extends Bank { +  + public AkeliusInvest(Context context) { + super(context, R.drawable.logo_akeliusinvest); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.STATIC_BALANCE = STATIC_BALANCE; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.staticBalance = STATIC_BALANCE; + } +  + public AkeliusInvest(String username, String password, Context context) throws BankException, +@@ -138,6 +133,16 @@ public class AkeliusInvest extends Bank { + } +  + @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; ++ } ++ ++ @Override + public void update() throws BankException, LoginException, BankChoiceException, IOException { + super.update(); + if (getUsername().isEmpty() || getPassword().isEmpty()) { +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java +index 038f0fe..715515e 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java +@@ -47,8 +47,6 @@ public class AkeliusSpar extends Bank { +  + private static final String NAME = "Akelius Spar"; +  +- private static final String NAME_SHORT = "akeliusspar"; +- + private static final String URL = "https://www.online.akeliusspar.se/"; +  + private static final int BANKTYPE_ID = IBankTypes.AKELIUSSPAR; +@@ -81,14 +79,21 @@ public class AkeliusSpar extends Bank { +  + public AkeliusSpar(Context context) { + super(context, R.drawable.logo_akeliusspar); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.STATIC_BALANCE = STATIC_BALANCE; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.staticBalance = STATIC_BALANCE; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public AkeliusSpar(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java +index 4940fed..fd2e258 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java +@@ -42,8 +42,6 @@ public class AppeakPoker extends Bank { +  + private static final String NAME = "Appeak Poker"; +  +- private static final String NAME_SHORT = "appeakpoker"; +- + private static final String URL = "http://poker.appeak.se/"; +  + private static final int BANKTYPE_ID = Bank.APPEAKPOKER; +@@ -56,16 +54,23 @@ public class AppeakPoker extends Bank { +  + public AppeakPoker(Context context) { + super(context, R.drawable.logo_appeakpoker); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD; +- super.DISPLAY_DECIMALS = false; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHiddenPassword = INPUT_HIDDEN_PASSWORD; ++ super.displayDecimals = false; + currency = "chips"; + } +  ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; ++ } ++ + public AppeakPoker(String username, String password, Context context) throws BankException, + LoginException, BankChoiceException, IOException { + this(context); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java +index cc859ac..5f7889b 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java +@@ -26,9 +26,16 @@ public class AvanzaMini extends Avanza { +  + public AvanzaMini(Context context) { + super(context, R.drawable.logo_avanzamini); +- NAME = "Avanza Mini"; +- NAME_SHORT = "avanzamini"; +- URL = "https://www.avanza.se/mini/hem/"; +- BANKTYPE_ID = IBankTypes.AVANZAMINI; ++ url = "https://www.avanza.se/mini/hem/"; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return IBankTypes.AVANZAMINI; ++ } ++ ++ @Override ++ public String getName() { ++ return "Avanza Mini"; + } + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java +index eb46cac..536aafb 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java +@@ -44,8 +44,6 @@ public class BetterGlobe extends Bank { +  + private static final String NAME = "Better Globe"; +  +- private static final String NAME_SHORT = "betterglobe"; +- + private static final String URL = "http://betterglobe.com"; +  + private static final int BANKTYPE_ID = IBankTypes.BETTERGLOBE; +@@ -70,17 +68,24 @@ public class BetterGlobe extends Bank { +  + public BetterGlobe(Context context) { + super(context, R.drawable.logo_betterglobe); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.STATIC_BALANCE = STATIC_BALANCE; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.staticBalance = STATIC_BALANCE; + super.currency = "EUR"; + } +  ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; ++ } ++ + public BetterGlobe(String username, String password, Context context) throws BankException, + LoginException, BankChoiceException, IOException { + this(context); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java +index df9e368..55336d7 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java +@@ -46,8 +46,6 @@ public class Bioklubben extends Bank { +  + private static final String NAME = "Bioklubben"; +  +- private static final String NAME_SHORT = "bioklubben"; +- + private static final String URL = "https://bioklubben.sf.se/Start.aspx"; +  + private static final int BANKTYPE_ID = Bank.BIOKLUBBEN; +@@ -58,17 +56,24 @@ public class Bioklubben extends Bank { +  + public Bioklubben(Context context) { + super(context, R.drawable.logo_bioklubben); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.DISPLAY_DECIMALS = DISPLAY_DECIMALS; +- super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT ++ super.url = URL; ++ super.displayDecimals = DISPLAY_DECIMALS; ++ super.inputTypeUsername = InputType.TYPE_CLASS_TEXT + | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; +- super.INPUT_HINT_USERNAME = context.getString(R.string.email); ++ super.inputHintUsername = context.getString(R.string.email); + currency = context.getString(R.string.points); + } +  ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; ++ } ++ + public Bioklubben(String username, String password, Context context) throws BankException, + LoginException, BankChoiceException, IOException { + this(context); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java +index 62d977f..d2af51a 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java +@@ -42,8 +42,6 @@ public class BlekingeTrafiken extends Bank { +  + private static final String NAME = "Blekingetrafiken"; +  +- private static final String NAME_SHORT = "blekingetrafiken"; +- + private static final String URL = "https://www.blekingetrafiken.se"; +  + private static final int BANKTYPE_ID = IBankTypes.BLEKINGETRAFIKEN; +@@ -52,15 +50,21 @@ public class BlekingeTrafiken extends Bank { +  + public BlekingeTrafiken(Context context) { + super(context, R.drawable.logo_blekingetrafiken); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE; +- super.INPUT_HINT_USERNAME = "XXXXXXXXXX"; +- super.INPUT_TITLETEXT_USERNAME = R.string.card_number; +- super.INPUT_HIDDEN_PASSWORD = true; ++ super.url = URL; ++ super.inputTypeUsername = InputType.TYPE_CLASS_PHONE; ++ super.inputHintUsername = "XXXXXXXXXX"; ++ super.inputTitletextUsername = R.string.card_number; ++ super.inputHiddenPassword = true; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } +  ++ @Override ++ public String getName() { ++ return NAME; + } +  + public BlekingeTrafiken(String username, String password, Context context) +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java +index 60145b8..309ee6a 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java +@@ -63,11 +63,18 @@ public class Bredband2VoIP extends Bank { +  + public Bredband2VoIP(Context context) { + super(context, R.drawable.logo_bredband2voip); +- NAME = "Bredband2 VoIP"; +- NAME_SHORT = "bredband2voip"; +- BANKTYPE_ID = IBankTypes.BREDBAND2VOIP; +- super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE; +- super.INPUT_HINT_USERNAME = "19XXXXXX-XXXX"; ++ super.inputTypeUsername = InputType.TYPE_CLASS_PHONE; ++ super.inputHintUsername = "19XXXXXX-XXXX"; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return IBankTypes.BREDBAND2VOIP; ++ } ++ ++ @Override ++ public String getName() { ++ return "Bredband2 VoIP"; + } +  + public Bredband2VoIP(String username, String password, Context context) +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java +index 7c35408..c821869 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java +@@ -46,8 +46,6 @@ public class BrummerKF extends Bank { +  + private static final String NAME = "Brummer KF & Pension"; +  +- private static final String NAME_SHORT = "brummer_kf"; +- + private static final String URL = "https://www.brummer.se/"; +  + private static final int BANKTYPE_ID = IBankTypes.BRUMMER_KF; +@@ -78,14 +76,21 @@ public class BrummerKF extends Bank { +  + public BrummerKF(Context context) { + super(context, R.drawable.logo_brummer_kf); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.STATIC_BALANCE = STATIC_BALANCE; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.staticBalance = STATIC_BALANCE; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public BrummerKF(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java +index 3640850..1ba7084 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java +@@ -49,8 +49,6 @@ public class CSN extends Bank { +  + private static final String NAME = "CSN"; +  +- private static final String NAME_SHORT = "csn"; +- + private static final String URL = "https://www.csn.se/bas/inloggning/pinkod.do"; +  + private static final int BANKTYPE_ID = IBankTypes.CSN; +@@ -82,14 +80,21 @@ public class CSN extends Bank { +  + public CSN(Context context) { + super(context, R.drawable.logo_csn); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.STATIC_BALANCE = STATIC_BALANCE; ++ super.url = URL; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.staticBalance = STATIC_BALANCE; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public CSN(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java +index 5276b57..d59b8f2 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java +@@ -28,8 +28,6 @@ public class Chalmrest extends Bank { +  + private static final String NAME = "Chalmrest"; +  +- private static final String NAME_SHORT = "chalmrest"; +- + private static final int BANKTYPE_ID = IBankTypes.CHALMREST; +  + private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\""); +@@ -47,13 +45,20 @@ public class Chalmrest extends Bank { +  + public Chalmrest(Context context) { + super(context, R.drawable.logo_chalmrest); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.INPUT_TITLETEXT_USERNAME = R.string.card_number; +- super.INPUT_HINT_USERNAME = "XXXXXXXXXXXXXXXX"; +- super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER; +- super.INPUT_HIDDEN_PASSWORD = true; ++ super.inputTitletextUsername = R.string.card_number; ++ super.inputHintUsername = "XXXXXXXXXXXXXXXX"; ++ super.inputTypeUsername = InputType.TYPE_CLASS_NUMBER; ++ super.inputHiddenPassword = true; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Chalmrest(String username, String password, Context context) throws BankException, +@@ -110,30 +115,30 @@ public class Chalmrest extends Bank { + } + urlopen = login(); + response = urlopen.open("http://kortladdning3.chalmerskonferens.se/CardLoad_Order.aspx"); +- Matcher matcher; +- Matcher matcher_b; ++ Matcher accountMatcher; ++ Matcher balanceMatcher; +  +- matcher = reAccount.matcher(response); +- if (matcher.find()) { ++ accountMatcher = reAccount.matcher(response); ++ if (accountMatcher.find()) { + /* + * Capture groups: + * GROUP EXAMPLE DATA + * 1: Name Kalle Karlsson + */ +  +- matcher_b = reBalance.matcher(response); +- if (matcher_b.find()) { ++ balanceMatcher = reBalance.matcher(response); ++ if (balanceMatcher.find()) { + /* + * Capture groups: + * GROUP EXAMPLE DATA + * 1: Balance 118 kr + */ +  +- String balanceString = matcher_b.group(1).replaceAll("\\]*>", "") ++ String balanceString = balanceMatcher.group(1).replaceAll("\\]*>", "") + .replaceAll("\\<[^>]*>", "").trim(); +  +- accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), +- Helpers.parseBalance(balanceString), matcher.group(1))); ++ accounts.add(new Account(Html.fromHtml(accountMatcher.group(1)).toString().trim(), ++ Helpers.parseBalance(balanceString), accountMatcher.group(1))); + balance = balance.add(Helpers.parseBalance(balanceString)); + } + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java +index af8c51f..4f5e687 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java +@@ -49,8 +49,6 @@ public class DanskeBank extends Bank { +  + private static final String NAME = "DanskeBank"; +  +- private static final String NAME_SHORT = "danskebank"; +- + private static final String URL + = "https://mobil.danskebank.se/XI?WP=XAI&WO=Logon&WA=MBSELogon&gsSprog=SE&gsBrand=OEB"; +  +@@ -82,13 +80,20 @@ public class DanskeBank extends Bank { +  + public DanskeBank(Context context) { + super(context, R.drawable.logo_danskebank); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public DanskeBank(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java +index 729c222..0e2046d 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java +@@ -45,8 +45,6 @@ public class Everydaycard extends Bank { +  + private static final String NAME = "Everydaycard"; +  +- private static final String NAME_SHORT = "everydaycard"; +- + private static final String URL = "http://www.everydaycard.se/mobil/"; +  + private static final int BANKTYPE_ID = IBankTypes.EVERYDAYCARD; +@@ -67,12 +65,19 @@ public class Everydaycard extends Bank { +  + public Everydaycard(Context context) { + super(context, R.drawable.logo_everydaycard); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Everydaycard(String username, String password, Context context) +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java +index 90a513c..cb8b9a4 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java +@@ -46,8 +46,6 @@ public class FirstCard extends Bank { +  + private static final String NAME = "First Card"; +  +- private static final String NAME_SHORT = "firstcard"; +- + private static final String URL = "https://www.firstcard.se/login.jsp"; +  + private static final int BANKTYPE_ID = IBankTypes.FIRSTCARD; +@@ -68,12 +66,19 @@ public class FirstCard extends Bank { +  + public FirstCard(Context context) { + super(context, R.drawable.logo_firstcard); +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public FirstCard(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java +index 8d97593..688d147 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java +@@ -50,8 +50,6 @@ public class Hemkop extends Bank { +  + private static final String NAME = "Hemköp Kundkort"; +  +- private static final String NAME_SHORT = "hemkop"; +- + private static final String URL = "https://www.hemkop.se/Mina-sidor/Logga-in/"; +  + private static final int BANKTYPE_ID = IBankTypes.HEMKOP; +@@ -65,12 +63,19 @@ public class Hemkop extends Bank { + public Hemkop(Context context) { + super(context, R.drawable.logo_hemkop); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Hemkop(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java +index 0930038..3fed434 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java +@@ -45,8 +45,6 @@ public class Hors extends Bank { +  + private static final String NAME = "Hörs"; +  +- private static final String NAME_SHORT = "hors"; +- + private static final String URL = "http://www.dittkort.se/hors/"; +  + private static final int BANKTYPE_ID = IBankTypes.HORS; +@@ -58,15 +56,22 @@ public class Hors extends Bank { + public Hors(Context context) { + super(context, R.drawable.logo_hors); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.DISPLAY_DECIMALS = DISPLAY_DECIMALS; +- super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT ++ super.url = URL; ++ super.displayDecimals = DISPLAY_DECIMALS; ++ super.inputTypeUsername = InputType.TYPE_CLASS_TEXT + | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; +- super.INPUT_HINT_USERNAME = context.getString(R.string.card_id); +- super.INPUT_HIDDEN_PASSWORD = true; ++ super.inputHintUsername = context.getString(R.string.card_id); ++ super.inputHiddenPassword = true; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Hors(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java +index 3677f55..85255d6 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java +@@ -30,8 +30,6 @@ public class IKEA extends AbsIkanoPartner { +  + private static final String NAME = "IKEA HANDLA kort"; +  +- private static final String NAME_SHORT = "ikea"; +- + private static final String URL + = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1420"; +  +@@ -40,13 +38,20 @@ public class IKEA extends AbsIkanoPartner { + public IKEA(Context context) { + super(context, R.drawable.logo_ikea); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; ++ super.url = URL; + this.structId = "1420"; + } +  ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; ++ } ++ + public IKEA(String username, String password, Context context) throws BankException, + LoginException, BankChoiceException, IOException { + this(context); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java +index 9ea837a..b8de01c 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java +@@ -47,8 +47,6 @@ public class IkanoBank extends Bank { +  + private static final String NAME = "Ikano Bank"; +  +- private static final String NAME_SHORT = "ikanobank"; +- + private static final String URL = "https://secure.ikanobank.se/engines/page.aspx?structid=1895"; +  + private static final int BANKTYPE_ID = IBankTypes.IKANOBANK; +@@ -81,13 +79,20 @@ public class IkanoBank extends Bank { + public IkanoBank(Context context) { + super(context, R.drawable.logo_ikanobank); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public IkanoBank(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java +index fddf1bb..0b1d3ed 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java +@@ -48,8 +48,6 @@ public class Jojo extends Bank { +  + private static final String NAME = "Jojo Reskassa"; +  +- private static final String NAME_SHORT = "jojo"; +- + private static final String URL = "https://www.skanetrafiken.se"; +  + private static final int BANKTYPE_ID = IBankTypes.JOJO; +@@ -64,12 +62,19 @@ public class Jojo extends Bank { + public Jojo(Context context) { + super(context, R.drawable.logo_jojo); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TITLETEXT_USERNAME = R.string.email; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; ++ super.url = URL; ++ super.inputTitletextUsername = R.string.email; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Jojo(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java +index 1aeefd3..2fb50b7 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java +@@ -45,8 +45,6 @@ public class McDonalds extends Bank { +  + private static final String NAME = "McDonald's Presentkort"; +  +- private static final String NAME_SHORT = "mcdonalds"; +- + private static final String URL = "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm"; +  + private static final int BANKTYPE_ID = Bank.MCDONALDS; +@@ -67,13 +65,20 @@ public class McDonalds extends Bank { + public McDonalds(Context context) { + super(context, R.drawable.logo_mcdonalds); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD; +- super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHiddenPassword = INPUT_HIDDEN_PASSWORD; ++ super.inputTitletextUsername = INPUT_TITLETEXT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public McDonalds(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java +index 9b20da6..c383409 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java +@@ -32,8 +32,6 @@ public class Meniga extends Bank { +  + private static final String NAME = "Meniga"; +  +- private static final String NAME_SHORT = "meniga"; +- + private static final String URL = "https://www.meniga.is/"; +  + private static final int BANKTYPE_ID = IBankTypes.MENIGA; +@@ -53,15 +51,22 @@ public class Meniga extends Bank { + public Meniga(Context context) { + super(context, R.drawable.logo_meniga); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHintUsername = INPUT_HINT_USERNAME; + super.setCurrency("ISK"); + } +  ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; ++ } ++ + public Meniga(String username, String password, Context context) throws BankException, + LoginException, BankChoiceException, IOException { + this(context); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java +index b6f3cbb..ab68bfa 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java +@@ -48,13 +48,19 @@ public class MinPension extends Bank { +  + public MinPension(Context context) { + super(context, R.drawable.logo_minpension); +- TAG = "MinPension"; +- NAME = "Min Pension.se"; +- NAME_SHORT = "minpension"; +- BANKTYPE_ID = IBankTypes.MINPENSION; +- INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE; +- INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE | InputType.TYPE_TEXT_VARIATION_PASSWORD; +- INPUT_HINT_USERNAME = res.getText(R.string.pno).toString(); ++ inputTypeUsername = InputType.TYPE_CLASS_PHONE; ++ inputTypePassword = InputType.TYPE_CLASS_PHONE | InputType.TYPE_TEXT_VARIATION_PASSWORD; ++ inputHintUsername = res.getText(R.string.pno).toString(); ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return IBankTypes.MINPENSION; ++ } ++ ++ @Override ++ public String getName() { ++ return "Min Pension.se"; + } +  + public MinPension(String username, String password, Context context) +@@ -128,8 +134,8 @@ public class MinPension extends Bank { + super.updateComplete(); + } +  +- private Account updateAccount(String URL, String selector, String name) throws IOException { +- String response = urlopen.open(URL); ++ private Account updateAccount(String url, String selector, String name) throws IOException { ++ String response = urlopen.open(url); + Document dResponse = Jsoup.parse(response); + List transactions = new ArrayList<>(); + String institute = ""; +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java +index 7552aa9..8925dc6 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java +@@ -48,8 +48,6 @@ public class Nordnet extends Bank { +  + private static final String NAME = "Nordnet"; +  +- private static final String NAME_SHORT = "nordnet"; +- + private static final String URL = "https://www.nordnet.se/mux/login/startSE.html"; +  + private static final int BANKTYPE_ID = IBankTypes.NORDNET; +@@ -66,10 +64,17 @@ public class Nordnet extends Bank { + public Nordnet(Context context) { + super(context, R.drawable.logo_nordnet); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; ++ super.url = URL; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Nordnet(String username, String password, Context context) throws BankException, +@@ -128,32 +133,32 @@ public class Nordnet extends Bank { + throw new LoginException(res.getText(R.string.invalid_username_password).toString()); + } + urlopen = login(); +- Matcher matcher = reAccounts.matcher(response); +- Matcher matcher_b = reBalance.matcher(response); +- while (matcher.find()) { ++ Matcher accountMatcher = reAccounts.matcher(response); ++ Matcher balanceMatcher = reBalance.matcher(response); ++ while (accountMatcher.find()) { + /* + * Capture groups: + * GROUP EXAMPLE DATA + * 1: Account name and number Investeringssparkonto 1234567 | Sparkonto 1234 567890 1 + * + */ +- if (matcher_b.find()) { ++ if (balanceMatcher.find()) { + /* + * Capture groups: + * GROUP EXAMPLE DATA + * 1: Account balance 62 356 | 0 + * + */ +- Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), +- Helpers.parseBalance(matcher_b.group(1)), +- Html.fromHtml(matcher.group(1)).toString().trim().replaceAll(" ", "")); ++ Account account = new Account(Html.fromHtml(accountMatcher.group(1)).toString().trim(), ++ Helpers.parseBalance(balanceMatcher.group(1)), ++ Html.fromHtml(accountMatcher.group(1)).toString().trim().replaceAll(" ", "")); +  + // Saving accounts contain white space characters in the account number +- if (!matcher.group(1).trim().contains(" ")) { ++ if (!accountMatcher.group(1).trim().contains(" ")) { + account.setType(Account.FUNDS); + } + accounts.add(account); +- balance = balance.add(Helpers.parseBalance(matcher_b.group(1))); ++ balance = balance.add(Helpers.parseBalance(balanceMatcher.group(1))); + } + } +  +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java +index c7fa006..540abd3 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java +@@ -47,8 +47,6 @@ public class OKQ8 extends Bank { +  + private static final String NAME = "OKQ8 VISA"; +  +- private static final String NAME_SHORT = "okq8"; +- + private static final String URL + = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8"; +  +@@ -76,13 +74,20 @@ public class OKQ8 extends Bank { + public OKQ8(Context context) { + super(context, R.drawable.logo_okq8); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.STATIC_BALANCE = STATIC_BALANCE; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.staticBalance = STATIC_BALANCE; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public OKQ8(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java +index 8524e38..d017230 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java +@@ -43,8 +43,6 @@ public class Ostgotatrafiken extends Bank { +  + private static final String NAME = "Östgötatrafiken"; +  +- private static final String NAME_SHORT = "ogt"; +- + private static final int BANKTYPE_ID = IBankTypes.OSTGOTATRAFIKEN; +  + private Pattern reViewState = Pattern.compile( +@@ -68,10 +66,16 @@ public class Ostgotatrafiken extends Bank { +  + public Ostgotatrafiken(Context context) { + super(context, R.drawable.logo_ogt); ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Ostgotatrafiken(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java +index c597d44..f62b92a 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java +@@ -45,8 +45,6 @@ public class Osuuspankki extends Bank { +  + private static final String NAME = "Osuuspankki"; +  +- private static final String NAME_SHORT = "osuuspankki"; +- + private static final String URL = "https://www.op.fi/op?kielikoodi=sv"; +  + private static final int BANKTYPE_ID = IBankTypes.OSUUSPANKKI; +@@ -62,11 +60,17 @@ public class Osuuspankki extends Bank { +  + public Osuuspankki(Context context) { + super(context, R.drawable.logo_osuuspankki); ++ super.url = URL; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Osuuspankki(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java +index f90ae79..d98a263 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java +@@ -46,8 +46,6 @@ public class Payson extends Bank { +  + private static final String NAME = "Payson"; +  +- private static final String NAME_SHORT = "payson"; +- + private static final String URL = "https://www.payson.se/signin/"; +  + private static final int BANKTYPE_ID = IBankTypes.PAYSON; +@@ -66,11 +64,18 @@ public class Payson extends Bank { + public Payson(Context context) { + super(context, R.drawable.logo_payson); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Payson(String username, String password, Context context) throws BankChoiceException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java +index a4da2e4..8e1ee5b 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java +@@ -45,8 +45,6 @@ public class PlusGirot extends Bank { +  + private static final String NAME = "PlusGirot"; +  +- private static final String NAME_SHORT = "plusgirot"; +- + private static final String URL = "https://kontoutdrag.plusgirot.se/"; +  + private static final int BANKTYPE_ID = IBankTypes.PLUSGIROT; +@@ -63,11 +61,17 @@ public class PlusGirot extends Bank { +  + public PlusGirot(Context context) { + super(context, R.drawable.logo_plusgirot); ++ super.url = URL; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; ++ @Override ++ public String getName() { ++ return NAME; + } +  + public PlusGirot(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java +index 490046a..9990b50 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java +@@ -45,8 +45,6 @@ public class SevenDay extends Bank { +  + private static final String NAME = "SevenDay"; +  +- private static final String NAME_SHORT = "sevenday"; +- + private static final String URL = "https://www.sevenday.se/mina-sidor/mina-sidor.htm"; +  + private static final int BANKTYPE_ID = IBankTypes.SEVENDAY; +@@ -67,12 +65,19 @@ public class SevenDay extends Bank { + public SevenDay(Context context) { + super(context, R.drawable.logo_sevenday); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public SevenDay(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java +index 9aef3df..2a3566d 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java +@@ -32,8 +32,6 @@ public class SveaDirekt extends Bank { +  + private static final String NAME = "Svea Direkt"; +  +- private static final String NAME_SHORT = "sveadirekt"; +- + private static final String URL = "https://http://www.sveadirekt.com/sv/swe//"; +  + private static final int BANKTYPE_ID = IBankTypes.SVEADIREKT; +@@ -61,13 +59,20 @@ public class SveaDirekt extends Bank { + public SveaDirekt(Context context) { + super(context, R.drawable.logo_sveadirekt); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.URL = URL; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public SveaDirekt(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java +index 85d795c..b81cdc2 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java +@@ -45,8 +45,6 @@ public class SvenskaSpel extends Bank { +  + private static final String NAME = "Svenska Spel"; +  +- private static final String NAME_SHORT = "svenskaspel"; +- + private static final String URL = "https://api.www.svenskaspel.se/player/sessions"; +  + private static final int BANKTYPE_ID = Bank.SVENSKASPEL; +@@ -62,12 +60,19 @@ public class SvenskaSpel extends Bank { + public SvenskaSpel(Context context) { + super(context, R.drawable.logo_svenskaspel); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTitletextUsername = INPUT_TITLETEXT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public SvenskaSpel(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java +index 2ceec08..a3c3a5e 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java +@@ -43,8 +43,6 @@ public class TestBank extends Bank { +  + private static final String NAME = "Testbank"; +  +- private static final String NAME_SHORT = "testbank"; +- + private static final String URL = "http://www.nullbyte.eu/"; +  + private static final int BANKTYPE_ID = IBankTypes.TESTBANK; +@@ -70,13 +68,20 @@ public class TestBank extends Bank { + public TestBank(Context context) { + super(context, R.drawable.logo_bankdroid); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public TestBank(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java +index ed68966..2c370fa 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java +@@ -44,8 +44,6 @@ public class TicketRikskortet extends Bank { +  + private static final String NAME = "Ticket Rikskortet"; +  +- private static final String NAME_SHORT = "rikskortet"; +- + private static final String URL = "https://www.edenred.se/rikskuponger/mina-sidor/logga-in/"; +  + private static final String URL_OVERVIEW = "https://www.edenred.se/rikskuponger/mina-sidor/employee/start/"; +@@ -71,10 +69,17 @@ public class TicketRikskortet extends Bank { + public TicketRikskortet(Context context) { + super(context, R.drawable.logo_rikskortet); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; ++ super.url = URL; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public TicketRikskortet(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java +index 3c51255..0668464 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java +@@ -44,8 +44,6 @@ public class Vasttrafik extends Bank { +  + private static final String NAME = "Västtrafik"; +  +- private static final String NAME_SHORT = "vasttrafik"; +- + private static final String URL = "https://www.vasttrafik.se/mina-sidor/"; +  + private static final int BANKTYPE_ID = IBankTypes.VASTTRAFIK; +@@ -64,11 +62,17 @@ public class Vasttrafik extends Bank { +  + public Vasttrafik(Context context) { + super(context, R.drawable.logo_vasttrafik); ++ super.url = URL; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Vasttrafik(String username, String password, Context context) throws BankException, +@@ -127,11 +131,11 @@ public class Vasttrafik extends Bank { + } + urlopen = login(); + response = urlopen.open("https://www.vasttrafik.se/mina-sidor-inloggad/mina-kort/"); +- Matcher matcher; +- Matcher matcher_b; ++ Matcher accountMatcher; ++ Matcher balanceMatcher; +  +- matcher = reAccounts.matcher(response); +- while (matcher.find()) { ++ accountMatcher = reAccounts.matcher(response); ++ while (accountMatcher.find()) { + /* + * Capture groups: + * GROUP EXAMPLE DATA +@@ -139,12 +143,12 @@ public class Vasttrafik extends Bank { + * 2: Balance information + */ +  +- if ("".equals(matcher.group(1))) { ++ if ("".equals(accountMatcher.group(1))) { + continue; + } +  +- matcher_b = reBalance.matcher(matcher.group(2)); +- if (matcher_b.find()) { ++ balanceMatcher = reBalance.matcher(accountMatcher.group(2)); ++ if (balanceMatcher.find()) { + /* + * Capture groups: + * GROUP EXAMPLE DATA +@@ -152,11 +156,11 @@ public class Vasttrafik extends Bank { + * 2: Amount 592,80 kr + */ +  +- String balanceString = matcher_b.group(2).replaceAll("\\]*>", "") ++ String balanceString = balanceMatcher.group(2).replaceAll("\\]*>", "") + .replaceAll("\\<[^>]*>", "").trim(); +  +- accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), +- Helpers.parseBalance(balanceString), matcher.group(1))); ++ accounts.add(new Account(Html.fromHtml(accountMatcher.group(1)).toString().trim(), ++ Helpers.parseBalance(balanceString), accountMatcher.group(1))); + balance = balance.add(Helpers.parseBalance(balanceString)); + } + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java +index a7b13e1..ab4cef3 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java +@@ -44,8 +44,6 @@ public class Zidisha extends Bank { +  + private static final String NAME = "Zidisha"; +  +- private static final String NAME_SHORT = "zidisha"; +- + private static final String URL = "https://www.zidisha.org/"; +  + private static final int BANKTYPE_ID = IBankTypes.ZIDISHA; +@@ -70,17 +68,24 @@ public class Zidisha extends Bank { + public Zidisha(Context context) { + super(context, R.drawable.logo_zidisha); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; +- super.STATIC_BALANCE = STATIC_BALANCE; ++ super.url = URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ super.staticBalance = STATIC_BALANCE; + super.currency = "USD"; + } +  ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; ++ } ++ + public Zidisha(String username, String password, Context context) throws BankException, + LoginException, BankChoiceException, IOException { + this(context); +@@ -99,14 +104,14 @@ public class Zidisha extends Bank { + throw new BankException( + res.getText(R.string.unable_to_find).toString() + " user_guess."); + } +- String user_guess = mUserGuess.group(1); ++ String userGuess = mUserGuess.group(1); +  + List postData = new ArrayList(); + postData.add(new BasicNameValuePair("username", getUsername())); + postData.add(new BasicNameValuePair("password", getPassword())); + postData.add(new BasicNameValuePair("textpassword", getUsername())); + postData.add(new BasicNameValuePair("userlogin", "")); +- postData.add(new BasicNameValuePair("user_guess", user_guess)); ++ postData.add(new BasicNameValuePair("user_guess", userGuess)); + return new LoginPackage(urlopen, postData, response, "https://www.zidisha.org/process.php"); + } +  +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java +index 933ec1f..c853116 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java +@@ -52,12 +52,8 @@ import eu.nullbyte.android.urllib.Urllib; +  + public class AmericanExpress extends Bank { +  +- private static final String TAG = "AmericanExpress"; +- + private static final String NAME = "American Express"; +  +- private static final String NAME_SHORT = "americanexpress"; +- + private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS; +  + private static final ObjectMapper MAPPER = new ObjectMapper(); +@@ -67,11 +63,17 @@ public class AmericanExpress extends Bank { +  + public AmericanExpress(Context context) { + super(context, R.drawable.logo_americanexpress); +- super.TAG = TAG; +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.WEB_VIEW_ENABLED = false; ++ super.webViewEnabled = false; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public AmericanExpress(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java +index 1e6bf30..3d3aa64 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java +@@ -57,11 +57,17 @@ public class Avanza extends Bank { +  + protected Avanza(Context context, @DrawableRes int logoResource) { + super(context, logoResource); +- TAG = "Avanza"; +- NAME = "Avanza"; +- NAME_SHORT = "avanza"; +- URL = "https://iphone.avanza.se"; +- BANKTYPE_ID = IBankTypes.AVANZA; ++ url = "https://iphone.avanza.se"; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return IBankTypes.AVANZA; ++ } ++ ++ @Override ++ public String getName() { ++ return "Avanza"; + } +  + public Avanza(Context context) { +@@ -72,12 +78,12 @@ public class Avanza extends Bank { + protected LoginPackage preLogin() throws BankException, IOException { + urlopen = new Urllib(context, + CertificateReader.getCertificates(context, R.raw.cert_avanza)); +- urlopen.addHeader("Referer", URL + "/start"); ++ urlopen.addHeader("Referer", url + "/start"); + List postData = new ArrayList(); + postData.add(new BasicNameValuePair("j_username", getUsername())); + postData.add(new BasicNameValuePair("j_password", getPassword())); +- postData.add(new BasicNameValuePair("url", URL + "/start")); +- String response = urlopen.open(URL + "/ab/handlelogin", postData); ++ postData.add(new BasicNameValuePair("url", url + "/start")); ++ String response = urlopen.open(url + "/ab/handlelogin", postData); + String homeUrl = ""; + try { + JSONObject jsonResponse = new JSONObject(response); +@@ -86,7 +92,7 @@ public class Avanza extends Bank { + throw new BankException( + res.getText(R.string.unable_to_find).toString() + " login link.", e); + } +- LoginPackage lp = new LoginPackage(urlopen, postData, "", URL + homeUrl); ++ LoginPackage lp = new LoginPackage(urlopen, postData, "", url + homeUrl); + lp.setIsLoggedIn(true); + return lp; + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java +index c726896..9efdf1d 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java +@@ -40,8 +40,6 @@ public class Bitcoin extends Bank { +  + private static final String NAME = "Bitcoin"; +  +- private static final String NAME_SHORT = "bitcoin"; +- + private static final String URL = "http://blockchain.info"; +  + private static final int BANKTYPE_ID = IBankTypes.BITCOIN; +@@ -59,14 +57,21 @@ public class Bitcoin extends Bank { + public Bitcoin(Context context) { + super(context, R.drawable.logo_bitcoin); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.STATIC_BALANCE = STATIC_BALANCE; ++ super.url = URL; ++ super.staticBalance = STATIC_BALANCE; + super.currency = "BTC"; +- super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD; +- super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME; ++ super.inputHiddenPassword = INPUT_HIDDEN_PASSWORD; ++ super.inputTitletextUsername = INPUT_TITLETEXT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Bitcoin(String username, String password, Context context) +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java +index 1ac76d6..7c27950 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java +@@ -57,8 +57,6 @@ public class Coop extends Bank { +  + private static final String NAME = "Coop"; +  +- private static final String NAME_SHORT = "coop"; +- + private static final String URL = "https://www.coop.se/mina-sidor/oversikt/"; +  + private static final int BANKTYPE_ID = IBankTypes.COOP; +@@ -83,11 +81,18 @@ public class Coop extends Bank { + public Coop(Context context) { + super(context, R.drawable.logo_coop); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.STATIC_BALANCE = true; ++ super.url = URL; ++ super.staticBalance = true; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Coop(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java +index ffc18a5..ebdb705 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java +@@ -66,19 +66,25 @@ public class ICA extends Bank { +  + public ICA(Context context) { + super(context, R.drawable.logo_ica); +- TAG = "ICA"; +- NAME = "ICA"; +- NAME_SHORT = "ica"; +- URL = "http://mobil.ica.se/"; +- BANKTYPE_ID = IBankTypes.ICA; +- INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE; +- INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE; +- INPUT_HINT_USERNAME = "ÅÅMMDDXXXX"; ++ url = "http://mobil.ica.se/"; ++ inputTypeUsername = InputType.TYPE_CLASS_PHONE; ++ inputTypePassword = InputType.TYPE_CLASS_PHONE; ++ inputHintUsername = "ÅÅMMDDXXXX"; + mHeaders.put(AUTHENTICATION_TICKET_HEADER, null); + mHeaders.put(SESSION_TICKET_HEADER, null); + mHeaders.put(LOGOUT_KEY_HEADER, null); + } +  ++ @Override ++ public int getBanktypeId() { ++ return IBankTypes.ICA; ++ } ++ ++ @Override ++ public String getName() { ++ return "ICA"; ++ } ++ + public ICA(String username, String password, Context context) + throws BankException, LoginException, BankChoiceException, IOException { + this(context); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java +index b825abf..97e4b46 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java +@@ -64,8 +64,6 @@ public class Lansforsakringar extends Bank { +  + private static final String NAME = "Länsförsäkringar"; +  +- private static final String NAME_SHORT = "lansforsakringar"; +- + private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR; +  + private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE; +@@ -83,17 +81,24 @@ public class Lansforsakringar extends Bank { + public Lansforsakringar(Context context) { + super(context, R.drawable.logo_lansforsakringar); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; + mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false); + mObjectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + } +  ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; ++ } ++ + public Urllib login() throws LoginException, BankException, IOException { + urlopen = new Urllib(context, + CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar)); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java +index 24dbb7e..cf8dd19 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java +@@ -46,8 +46,6 @@ public class Nordea extends Bank { +  + private static final String NAME = "Nordea"; +  +- private static final String NAME_SHORT = "nordea"; +- + private static final String BASE_URL = "https://internetbanken.privat.nordea.se/nsp/"; +  + private static final String LOGIN_URL = BASE_URL + "login"; +@@ -210,13 +208,20 @@ public class Nordea extends Bank { + public Nordea(Context context) { + super(context, R.drawable.logo_nordea); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = BASE_URL; +- super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME; +- super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD; +- super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME; ++ super.url = BASE_URL; ++ super.inputTypeUsername = INPUT_TYPE_USERNAME; ++ super.inputTypePassword = INPUT_TYPE_PASSWORD; ++ super.inputHintUsername = INPUT_HINT_USERNAME; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Nordea(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java +index 1d58f40..9b08924 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java +@@ -40,8 +40,6 @@ public class Rikslunchen extends Bank { +  + private static final String NAME = "Rikslunchen"; +  +- private static final String NAME_SHORT = "rikslunchen"; +- + private static final String URL = "http://www.rikslunchen.se/index.html"; +  + private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN; +@@ -53,13 +51,20 @@ public class Rikslunchen extends Bank { + public Rikslunchen(Context context) { + super(context, R.drawable.logo_rikslunchen); +  +- super.NAME = NAME; +- super.NAME_SHORT = NAME_SHORT; +- super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; +- super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE; +- super.INPUT_TITLETEXT_USERNAME = R.string.card_id; +- super.INPUT_HIDDEN_PASSWORD = true; ++ super.url = URL; ++ super.inputTypeUsername = InputType.TYPE_CLASS_PHONE; ++ super.inputTitletextUsername = R.string.card_id; ++ super.inputHiddenPassword = true; ++ } ++ ++ @Override ++ public int getBanktypeId() { ++ return BANKTYPE_ID; ++ } ++ ++ @Override ++ public String getName() { ++ return NAME; + } +  + public Rikslunchen(String username, String password, Context context) throws BankException, +diff --git a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java +index 2636816..36354b6 100644 +--- a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java ++++ b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java +@@ -88,9 +88,9 @@ import timber.log.Timber; +  + public class Urllib { +  +- private static int MAX_RETRIES = 5; ++ private final static int MAX_RETRIES = 5; +  +- public static String DEFAULT_USER_AGENT ++ public final static String DEFAULT_USER_AGENT + = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17"; +  + private String userAgent = null; +diff --git a/config/quality/lint/lint.xml b/config/quality/lint/lint.xml +index f81c4ca..8195ce2 100644 +--- a/config/quality/lint/lint.xml ++++ b/config/quality/lint/lint.xml +@@ -30,7 +30,6 @@ +  +  +  +-  +  +  +  +diff --git a/config/quality/pmd/pmd-ruleset.xml b/config/quality/pmd/pmd-ruleset.xml +index 05b8f94..68eee4b 100644 +--- a/config/quality/pmd/pmd-ruleset.xml ++++ b/config/quality/pmd/pmd-ruleset.xml +@@ -113,7 +113,6 @@ +  +  +  +-  +  +  +  +@@ -139,6 +138,5 @@ +  +  +  +-  +  +  + +commit e1cbce765867ba88c0bf9c1931a4e47f34dacf44 +Author: Johan Walles +Date: Thu Nov 3 21:01:58 2016 +0100 + + If asked for an unknown bank, log the id + + So instead of getting in Crashlytics... + BankType id not found. + ... we now get... + BankType id not found: 1234 + + This way it will be easier to understand why we get these exceptions and + how they should be handled (or not). + +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java +index d2a8b11..f95ef32 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java +@@ -144,7 +144,7 @@ public class LegacyBankFactory { + case IBankTypes.HORS: + return new Hors(context); + default: +- throw new BankException("BankType id not found."); ++ throw new BankException("BankType id not found: " + id); + } + } +  + +commit de72b761b9a9a84ea49fb4036e942b24ca49cd5e +Author: Johan Walles +Date: Thu Nov 3 21:21:31 2016 +0100 + + Don't lose the stacks when re-throwing exceptions + +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java +index 4f2d1ae..f90ae79 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java +@@ -108,7 +108,7 @@ public class Payson extends Bank { + userInfo = new JSONObject( + urlopen.open("https://www.payson.se/myaccount/user/getuserinfo")); + } catch (JSONException e) { +- throw new LoginException(res.getText(R.string.invalid_username_password).toString()); ++ throw new LoginException(res.getText(R.string.invalid_username_password).toString(), e); + } + return urlopen; + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java +index e0ee2d8..1e6bf30 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java +@@ -84,7 +84,7 @@ public class Avanza extends Bank { + homeUrl = jsonResponse.getString("redirectUrl"); + } catch (JSONException e) { + throw new BankException( +- res.getText(R.string.unable_to_find).toString() + " login link."); ++ res.getText(R.string.unable_to_find).toString() + " login link.", e); + } + LoginPackage lp = new LoginPackage(urlopen, postData, "", URL + homeUrl); + lp.setIsLoggedIn(true); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java +index 0f789ff..c726896 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java +@@ -96,7 +96,7 @@ public class Bitcoin extends Bank { + setCurrency("BTC"); + } catch (JsonParseException e) { + throw new BankException(res.getText( +- R.string.invalid_bitcoin_address).toString()); ++ R.string.invalid_bitcoin_address).toString(), e); + } +  + return urlopen; +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java +index 7e8fe82..b825abf 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java +@@ -115,7 +115,7 @@ public class Lansforsakringar extends Bank { + objectAsJson(new LoginRequest(getUsername(), getPassword())), LoginResponse.class); + urlopen.addHeader("Utoken", lr.getTicket()); + } catch (Exception e) { +- throw new LoginException(res.getText(R.string.invalid_username_password).toString()); ++ throw new LoginException(res.getText(R.string.invalid_username_password).toString(), e); + } + return urlopen; + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java +index 65446a9..67895b3 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java +@@ -23,4 +23,8 @@ public class LoginException extends Exception { + public LoginException(String message) { + super(message); + } ++ ++ public LoginException(String message, Exception cause) { ++ super(message, cause); ++ } + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java +index f85b8f2..6656ba3 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java +@@ -13,7 +13,7 @@ public class StringUtils { + try { + return string.getBytes(CHARSET); + } catch (UnsupportedEncodingException e) { +- throw new RuntimeException("Internal error"); ++ throw new RuntimeException("Internal error", e); + } + } +  +@@ -21,7 +21,7 @@ public class StringUtils { + try { + return new String(bytes, CHARSET); + } catch (UnsupportedEncodingException e) { +- throw new RuntimeException("Internal error"); ++ throw new RuntimeException("Internal error", e); + } + } + } +diff --git a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java +index 616084c..bbae0ee 100644 +--- a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java ++++ b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java +@@ -86,7 +86,7 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory { + context.init(keyManagers, new TrustManager[]{mTrustManager}, null); + return context; + } catch (Exception e) { +- throw new IOException(e.getMessage()); ++ throw new IOException(e.getMessage(), e); + } + } +  +diff --git a/config/quality/pmd/pmd-ruleset.xml b/config/quality/pmd/pmd-ruleset.xml +index 288976e..05b8f94 100644 +--- a/config/quality/pmd/pmd-ruleset.xml ++++ b/config/quality/pmd/pmd-ruleset.xml +@@ -104,7 +104,6 @@ +  +  +  +-  +  +  +  + +commit 35a0c501384bd9bd99f998d48fd5e2cd1b32fa5e (tag: v1.9.13) +Author: Mathias Åhsberg +Date: Thu Nov 3 20:32:14 2016 +0100 + + Creates release v1.9.13 + +diff --git a/CHANGELOG b/CHANGELOG +index f2f5b8d..91dd35a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,5 +1,8 @@ + Please view this file on the master branch, on stable branches it's out of date. +  ++v1.9.13 (2016-11-03) ++* Fixes Crashlytics logging issue ++ + v1.9.12 (2016-11-02) + * Bioklubben: Use https. It's secure and http page no longer exists. + * Östgötatrafiken: Adapt to new login page (Facebook login not supported) + +commit 709cf1fa638b955646f76775592a433b0e4ad707 +Author: Johan Walles +Date: Thu Nov 3 07:30:07 2016 +0100 + + Log correct bank names to Crashlytics + +diff --git a/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java b/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java +index bea4936..e5c019d 100644 +--- a/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java ++++ b/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java +@@ -56,7 +56,7 @@ public class LoggingUtils { + } +  + logCustom(new CustomEvent("Disabled Bank"). +- putCustomAttribute("Name", bank.getDisplayName())); ++ putCustomAttribute("Name", bank.getName())); + } +  + public static void logBankUpdate(Bank bank, boolean withTransactions) { +@@ -65,7 +65,7 @@ public class LoggingUtils { + } +  + logCustom(new CustomEvent("Bank Updated"). +- putCustomAttribute("Name", bank.getDisplayName()). ++ putCustomAttribute("Name", bank.getName()). + putCustomAttribute("With Transactions", Boolean.toString(withTransactions))); +  + boolean hasTransactions = false; +@@ -76,7 +76,7 @@ public class LoggingUtils { + } + if (withTransactions && !hasTransactions) { + logCustom(new CustomEvent("Bank Without Transactions"). +- putCustomAttribute("Name", bank.getDisplayName())); ++ putCustomAttribute("Name", bank.getName())); + } + } +  + +commit c60033a4f1f18446e0c298147764af052f90e0a6 (tag: v1.9.12) +Author: Mathias Åhsberg +Date: Wed Nov 2 22:25:10 2016 +0100 + + Create release v1.9.12 + +diff --git a/CHANGELOG b/CHANGELOG +index 5ebd411..f2f5b8d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,8 +1,9 @@ + Please view this file on the master branch, on stable branches it's out of date. +  +-Not yet released ++v1.9.12 (2016-11-02) + * Bioklubben: Use https. It's secure and http page no longer exists. + * Östgötatrafiken: Adapt to new login page (Facebook login not supported) ++* Removes broken encryption +  + v1.9.11 (2016-10-26) + * Warn about disabled banks in the transactions list + +commit 1e50923e7b4092101945b4f73b27e82d1cff69f0 +Author: Mathias Åhsberg +Date: Wed Nov 2 22:21:59 2016 +0100 + + Update certificates + +diff --git a/bankdroid-legacy/src/main/res/raw/cert_danskebank.pem b/bankdroid-legacy/src/main/res/raw/cert_danskebank.pem +index 328a9ec..8a9fe0a 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_danskebank.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_danskebank.pem +@@ -1,31 +1,32 @@ + -----BEGIN CERTIFICATE----- +-MIIFOTCCBCGgAwIBAgISESGZp5e2NeqwsdyPhd1B3uLdMA0GCSqGSIb3DQEBCwUA +-MGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTwwOgYD +-VQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gU0hB +-MjU2IC0gRzIwHhcNMTUwNDE0MTMxNzAzWhcNMTYxMTA4MTI1NDQzWjBjMQswCQYD +-VQQGEwJESzELMAkGA1UECBMCREsxEzARBgNVBAcTCkNvcGVuaGFnZW4xGDAWBgNV +-BAoTD0RhbnNrZSBCYW5rIEEvUzEYMBYGA1UEAxQPKi5kYW5za2ViYW5rLnNlMIIB +-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtoh4WuhtiJKh/585noJRB+nx +-9DgSK4+oE4zpYX5kihpbqVf/UgUvfl73MDMcbFM4300q2CKh+O1dDRMcPNNdNTHN +-PRtnNAoBlHrRU1OtfLJGYfQ5I8zWbip1CbY8DfSnNoav4JhgV3Jwryq+WpVk6Nww +-YsfuJbyWrWJe2bIwydGIOrbyF+C1MNkUNRnB80NTNzPYL7VtecmfJtXm5MJspWNa +-ZPSIQekrxoyxGTkJiBvRSFTioH5RgwVhC5guX08c2sZL2aMZiBazytZz4H4K89qF +-ORwebPbq48QprvqHB8N1HFn2ygoab8HruWhoI6zz9sgbhOsKiqRQD6LcIcxMIwID +-AQABo4IB4jCCAd4wDgYDVR0PAQH/BAQDAgWgMEkGA1UdIARCMEAwPgYGZ4EMAQIC +-MDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9z +-aXRvcnkvMCkGA1UdEQQiMCCCDyouZGFuc2tlYmFuay5zZYINZGFuc2tlYmFuay5z +-ZTAJBgNVHRMEAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNV +-HR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2dzL2dzb3Jn +-YW5pemF0aW9udmFsc2hhMmcyLmNybDCBoAYIKwYBBQUHAQEEgZMwgZAwTQYIKwYB +-BQUHMAKGQWh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2dzb3Jn +-YW5pemF0aW9udmFsc2hhMmcycjEuY3J0MD8GCCsGAQUFBzABhjNodHRwOi8vb2Nz +-cDIuZ2xvYmFsc2lnbi5jb20vZ3Nvcmdhbml6YXRpb252YWxzaGEyZzIwHQYDVR0O +-BBYEFJcClG8LQNfWNbnpuFz9mOAqlhhRMB8GA1UdIwQYMBaAFJbeYfG9HBYpUxzA +-zH07gwBA5hp8MA0GCSqGSIb3DQEBCwUAA4IBAQC9Zg40R7JHvAyF7k+D/08+vqQT +-fpW0sxH8OBYGZgZ9sCLyuJuuqePWMh5dFpe1xjeDZUhF2WZx8rtBpe/bNEAcDOJM +-taxlJizeTzVGx9DUmGEyfn6U1ot+peaJbjlpXaMH9VAwf0uhjanXD3jDz7S/7Iwu +-ZHrJcgUmXVzxBzWHq3gd5zfbCrlBxvC+kZhO2j6Odl700NKSVSIYJI/E0VQI01x1 +-lgAQ+1dWq9vHu83nsAxYW56elie/kplkRvPzow3ihI3cx8HVjoR2YNUS4ZuaW1vE +-Ww8D9KttG3Qg6htbBX3lSUplls2Amto2aK99bjn6aN6jCdddgyj3xwc975tZ ++MIIFSjCCBDKgAwIBAgIMI2d4vBm6pr6l/ezfMA0GCSqGSIb3DQEBCwUAMGYxCzAJ ++BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTwwOgYDVQQDEzNH ++bG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gU0hBMjU2IC0g ++RzIwHhcNMTYwOTEzMTEzNjAxWhcNMTgwOTE0MTEzNjAxWjBtMQswCQYDVQQGEwJE ++SzETMBEGA1UECBMKQ29wZW5oYWdlbjEVMBMGA1UEBxMMQ29wZW5oYWdlbiBLMRgw ++FgYDVQQKEw9EYW5za2UgQmFuayBBL1MxGDAWBgNVBAMMDyouZGFuc2tlYmFuay5z ++ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANpBHTaIScLocNcQoOuj ++PSX3xwlbomedbXDaeM1LBRLWIiGNibC/XUYGNjn+4tvYyU+B9GDYXLL1C6m3YHsu ++Fts0CamxLYS2VSLCjc/v9sFbDZcodj+6sE9/AXhwmjYj8YC6p7FHcK7LGYYOoBAd ++YCuQl7Xd+yaCbajOwyyoItiEe6qf0/hmV2SH6rJsQtPSCbUqMX3kAgAlQOhCqMdD ++ke6w4TiQAHv+An4ceF7KuMIPOzHB2/PO1Z/YQLG1vLZMA892fuJeFH5KuvtN6d9a ++h1z21vyu7eHsAg/Ua1HvEGYaA4xjQM5czoP4yQSJaR0kbpp1hrCv0q3K9R6NIUhF ++lC0CAwEAAaOCAe8wggHrMA4GA1UdDwEB/wQEAwIFoDCBoAYIKwYBBQUHAQEEgZMw ++gZAwTQYIKwYBBQUHMAKGQWh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2Fj ++ZXJ0L2dzb3JnYW5pemF0aW9udmFsc2hhMmcycjEuY3J0MD8GCCsGAQUFBzABhjNo ++dHRwOi8vb2NzcDIuZ2xvYmFsc2lnbi5jb20vZ3Nvcmdhbml6YXRpb252YWxzaGEy ++ZzIwVgYDVR0gBE8wTTBBBgkrBgEEAaAyARQwNDAyBggrBgEFBQcCARYmaHR0cHM6 ++Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCAYGZ4EMAQICMAkGA1Ud ++EwQCMAAwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5nbG9iYWxzaWduLmNv ++bS9ncy9nc29yZ2FuaXphdGlvbnZhbHNoYTJnMi5jcmwwKQYDVR0RBCIwIIIPKi5k ++YW5za2ViYW5rLnNlgg1kYW5za2ViYW5rLnNlMB0GA1UdJQQWMBQGCCsGAQUFBwMB ++BggrBgEFBQcDAjAdBgNVHQ4EFgQU5QZdNIS6nLfk6lV4vHVRHg6DTlMwHwYDVR0j ++BBgwFoAUlt5h8b0cFilTHMDMfTuDAEDmGnwwDQYJKoZIhvcNAQELBQADggEBAB5P ++l1RAQdS2tXyefgJaymhVpcJds63grMyUztkU6lzYbTbdZsMa5x96WLjfvdDDTVmI ++pP5OMlv1q7Gh/4uhkIPOE9VH2thTyHsg9jUetBPSOAJqEi5DLGtlpYqlDRPqDrZp ++bSP5PpKWOC5AXy4cho/Ix4dkRamB9zT7lbYtusCP3Cgnbfm00b2gmOe9ax8jOpXb ++/1zLd7YTjmrGrElIuA0I1FmsEsVzPp0BONaSUVjWtJP4LJ+rQqp/0+iCKdBVLLbA ++sE/FCXopdjvWaQgHoUDKes6FJmY4h0rDpViU3ClTEvfN+DdRlxlODRw0STh+CFtl ++SnEPwHpG0wzZnwfPFvU= + -----END CERTIFICATE----- + mobil.danskebank.se:443 +diff --git a/bankdroid-legacy/src/main/res/raw/cert_meniga.pem b/bankdroid-legacy/src/main/res/raw/cert_meniga.pem +index 828d693..a899ce9 100644 +--- a/bankdroid-legacy/src/main/res/raw/cert_meniga.pem ++++ b/bankdroid-legacy/src/main/res/raw/cert_meniga.pem +@@ -1,31 +1,32 @@ + -----BEGIN CERTIFICATE----- +-MIIFLDCCBBSgAwIBAgIHS2MFZfZKXTANBgkqhkiG9w0BAQsFADCBtDELMAkGA1UE +-BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY +-BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMS0wKwYDVQQLEyRodHRwOi8vY2VydHMu +-Z29kYWRkeS5jb20vcmVwb3NpdG9yeS8xMzAxBgNVBAMTKkdvIERhZGR5IFNlY3Vy +-ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjAeFw0xNDEwMzAxNTA0MTJaFw0x +-NjEwMzAxNTA0MTJaMEwxCzAJBgNVBAYTAklTMRIwEAYDVQQHEwlSZXlramF2aWsx +-EzARBgNVBAoTCk1lbmlnYSBlaGYxFDASBgNVBAMMCyoubWVuaWdhLmlzMIIBIjAN +-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSMfGQ1DRMH6NuQm6AjlpnvHZMls +-iqtlgneL32kRd6FHNTk3HoEy5s+AnfJhx2AO5aNuOb9mht7TwNZnfdRsK7RUOcN1 +-w8hQDOlHeD4VlPzNm4rrlFjfMrsLG/8IlvKD7JWCh0rirPnSYfKXjTiEbCvHKXJ4 +-mEhxOKrVD4It1UhZqZ3enVkMkUhDJYlyW0sW0fWSZGZkDopK6VX5O/mQ+AQrBfXb +-UhJTubLAi0LRvQHexQPTs3hLLKWol0EUVoiqNALT19+y1+gy4Ojg8D2B/TOVP9vq +-TQl8WX0gXKY7tzQPDyQ9KfFL+yluqahyEf1PR2QkALnz0BU76Dg41AHN2wIDAQAB +-o4IBqDCCAaQwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB +-BQUHAwIwDgYDVR0PAQH/BAQDAgWgMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9j +-cmwuZ29kYWRkeS5jb20vZ2RpZzJzMi0wLmNybDBTBgNVHSAETDBKMEgGC2CGSAGG +-/W0BBxcCMDkwNwYIKwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRk +-eS5jb20vcmVwb3NpdG9yeS8wdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhho +-dHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jZXJ0 +-aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZGlnMi5jcnQwHwYDVR0j +-BBgwFoAUQMK9J47MNIMwojPX+2yz8LQsgM4wIQYDVR0RBBowGIILKi5tZW5pZ2Eu +-aXOCCW1lbmlnYS5pczAdBgNVHQ4EFgQUdvrJexWWM/V5ciXjgKRnPjE8byAwDQYJ +-KoZIhvcNAQELBQADggEBAIfo9SNMcfaYqgn8Fhydfr3rJM4qY8YMP/KIQfWhn/yZ +-Gver/aRIfsZp6eCOg/qk4F+zJvORkZhw8jzYRRlzJpcSvy9o8n6sPXkU2gw3FiZj +-B7EFJ2sdd2ZsmeZWbGANSRgEupxVsITu+HcDfjGcJ5q/3MLXQvthAB/hCU8h/q03 +-LzGIS3OGmbxZLZTQlMCT2nPwte6yd3xSRSBGXOFpT3KTHKe6Gggq5e865IodXFbX +-UGJNNqg9tMjg0n8iQp9Pn7I3J8vh673TmhFB05wfovKJ3GtB50U0tIwpGq38PLQ/ +-83CWGJvQw2hT0OP6EwRKXIESPvxFC269xJdUwAuHrg0= ++MIIFQDCCBCigAwIBAgIIHHBEGyxYdQQwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV ++BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow ++GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz ++LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1 ++cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMTYwODI1MTMzNDM4WhcN ++MTkxMDMwMTUwNDEyWjBVMQswCQYDVQQGEwJJUzETMBEGA1UEBwwKS8OzcGF2b2d1 ++cjEbMBkGA1UEChMSTWVuaWdhIEljZWxhbmQgZWhmMRQwEgYDVQQDDAsqLm1lbmln ++YS5pczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMEjHxkNQ0TB+jbk ++JugI5aZ7x2TJbIqrZYJ3i99pEXehRzU5Nx6BMubPgJ3yYcdgDuWjbjm/Zobe08DW ++Z33UbCu0VDnDdcPIUAzpR3g+FZT8zZuK65RY3zK7Cxv/CJbyg+yVgodK4qz50mHy ++l404hGwrxylyeJhIcTiq1Q+CLdVIWamd3p1ZDJFIQyWJcltLFtH1kmRmZA6KSulV +++Tv5kPgEKwX121ISU7mywItC0b0B3sUD07N4SyylqJdBFFaIqjQC09ffstfoMuDo ++4PA9gf0zlT/b6k0JfFl9IFymO7c0Dw8kPSnxS/spbqmochH9T0dkJAC589AVO+g4 ++ONQBzdsCAwEAAaOCAbIwggGuMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYB ++BQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB/wQEAwIFoDA1BgNVHR8ELjAsMCqgKKAm ++hiRodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkaWcyczItMy5jcmwwXQYDVR0gBFYw ++VDBIBgtghkgBhv1tAQcXAjA5MDcGCCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNh ++dGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMAgGBmeBDAECAjB2BggrBgEFBQcB ++AQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHkuY29tLzBABggr ++BgEFBQcwAoY0aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0 ++b3J5L2dkaWcyLmNydDAfBgNVHSMEGDAWgBRAwr0njsw0gzCiM9f7bLPwtCyAzjAh ++BgNVHREEGjAYggsqLm1lbmlnYS5pc4IJbWVuaWdhLmlzMB0GA1UdDgQWBBR2+sl7 ++FZYz9XlyJeOApGc+MTxvIDANBgkqhkiG9w0BAQsFAAOCAQEAR+uxgkI6AfSB+Txd ++IYbWQEYYjTXDWCNGoNp5Y+Dl1M8qdBKjYXfyYAKOWCNi4qRwDk1+QOtv6AB3CkOy ++H4O6HmhKcmeGOw2zpKzMLOD4y58VJr0LpIBvE4WNVHssjhKvZizaD5xGLtDbogXn ++O5o1STzUp0FzQKwVtLw4KdE7UEJwfA7Q/MNOjIuzylNmKa2dDjHv+DfcJab4Qhw1 ++1qUGdDIZxLOgyMkZiO1UbqBtctOeYgYNphBAoyzWurLmu0n7fzhhdCZTq67XHJAE ++xV/zSLYmh50rSN1GEAg69zo5fAQFn9SKTTGdDo5jqB3hAHBiuf4/F1j0DWQ96kNK ++2F8WeQ== + -----END CERTIFICATE----- + www.meniga.is:443 + +commit d32deec5dbe785ef35b1cb89484d6c29653e370c +Author: Johan Walles +Date: Mon Oct 31 21:42:39 2016 +0100 + + Enable PMD's field-can-be-local-var warning + +diff --git a/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java b/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java +index e9850ef..af07d75 100644 +--- a/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java ++++ b/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java +@@ -35,8 +35,6 @@ import java.util.Map; +  + public class DBAdapter { +  +- private DatabaseHelper mDbHelper; +- + private SQLiteDatabase mDb; +  + /** +@@ -46,8 +44,8 @@ public class DBAdapter { + * @param ctx the Context within which to work + */ + public DBAdapter(Context ctx) { +- mDbHelper = DatabaseHelper.getHelper(ctx); +- mDb = mDbHelper.getWritableDatabase(); ++ DatabaseHelper dbHelper = DatabaseHelper.getHelper(ctx); ++ mDb = dbHelper.getWritableDatabase(); + } +  + /** +diff --git a/app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java b/app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java +index 0e7502e..f17d78b 100644 +--- a/app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java ++++ b/app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java +@@ -36,8 +36,6 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi +  + private View mSkipButton; +  +- private View mImageView; +- + private AnimationDrawable mAnimation; +  + private Runnable mRunnable = new Runnable() { +@@ -94,10 +92,10 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi + mSkipButton = findViewById(R.id.skip_button); + mSkipButton.setOnClickListener(this); +  +- mImageView = (ImageView) findViewById(R.id.lock_anim); +- mImageView.setBackgroundResource(R.drawable.lock_anim); +- mImageView.setOnClickListener(this); +- mAnimation = (AnimationDrawable) mImageView.getBackground(); ++ View imageView = (ImageView) findViewById(R.id.lock_anim); ++ imageView.setBackgroundResource(R.drawable.lock_anim); ++ imageView.setOnClickListener(this); ++ mAnimation = (AnimationDrawable) imageView.getBackground(); + } +  + protected void startAnimation(final AnimationDrawable animation) { +diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java +index 86f7136..4817e11 100644 +--- a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java ++++ b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java +@@ -36,8 +36,6 @@ public class ColorPickerDialog +  + private ColorPickerView mColorPicker; +  +- private ColorPickerPanelView mOldColor; +- + private ColorPickerPanelView mNewColor; +  + private OnColorChangedListener mListener; +@@ -72,20 +70,20 @@ public class ColorPickerDialog + setTitle(R.string.dialog_color_picker); +  + mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view); +- mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel); ++ ColorPickerPanelView oldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel); + mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel); +  +- ((LinearLayout) mOldColor.getParent()).setPadding( ++ ((LinearLayout) oldColor.getParent()).setPadding( + Math.round(mColorPicker.getDrawingOffset()), + 0, + Math.round(mColorPicker.getDrawingOffset()), + 0 + ); +  +- mOldColor.setOnClickListener(this); ++ oldColor.setOnClickListener(this); + mNewColor.setOnClickListener(this); + mColorPicker.setOnColorChangedListener(this); +- mOldColor.setColor(color); ++ oldColor.setColor(color); + mColorPicker.setColor(color, true); +  + } +diff --git a/bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java b/bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java +index 62a1b46..3a47c5b 100644 +--- a/bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java ++++ b/bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java +@@ -8,19 +8,13 @@ import java.util.ArrayList; + import java.util.List; + import java.util.ResourceBundle; +  +-public enum DefaultConnectionConfiguration { +- +- INSTANCE; ++public class DefaultConnectionConfiguration { +  + public static final String NAME = "provider.configuration.name"; +  +- private List configuration; +- +- DefaultConnectionConfiguration() { +- configuration = createConfiguration(); +- } ++ private final static List configuration = createConfiguration(); +  +- private List createConfiguration() { ++ private static List createConfiguration() { + List configuration = new ArrayList<>(); + configuration.add(new FieldBuilder(NAME, ResourceBundle.getBundle("i18n.application")) + .placeholder("") +@@ -30,6 +24,6 @@ public enum DefaultConnectionConfiguration { + } +  + public static List fields() { +- return INSTANCE.configuration; ++ return configuration; + } + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java +index 84bcb8d..1ac76d6 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java +@@ -80,8 +80,6 @@ public class Coop extends Bank { +  + private ObjectMapper mObjectMapper; +  +- private String response; +- + public Coop(Context context) { + super(context, R.drawable.logo_coop); +  +@@ -141,7 +139,7 @@ public class Coop extends Bank { +  + login(); +  +- response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/"); ++ String response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/"); + Document dResponse = Jsoup.parse(response); + Account poang = new Account("\u2014 Poäng", + Helpers.parseBalance(dResponse.select(".Grid-cell--1 p").text()), +diff --git a/config/quality/pmd/pmd-ruleset.xml b/config/quality/pmd/pmd-ruleset.xml +index 19538ce..288976e 100644 +--- a/config/quality/pmd/pmd-ruleset.xml ++++ b/config/quality/pmd/pmd-ruleset.xml +@@ -113,7 +113,6 @@ +  +  +  +-  +  +  +  + +commit 37f16fda5cc03d3b2d6b9180e6bcb2ed5d600c57 +Author: Johan Walles +Date: Tue Nov 1 22:06:24 2016 +0100 + + Fix whitespace issues + +diff --git a/app/build.gradle b/app/build.gradle +index aafa141..11832d8 100644 +--- a/app/build.gradle ++++ b/app/build.gradle +@@ -19,7 +19,7 @@ apply plugin: 'com.android.application' + apply from: '../config/quality/quality.gradle' + apply plugin: "org.ajoberstar.grgit" +  +-if(new File('app/crashlytics.properties').exists()) { ++if (new File('app/crashlytics.properties').exists()) { + apply plugin: 'io.fabric' + } +  +diff --git a/app/src/main/java/com/liato/bankdroid/BankEditActivity.java b/app/src/main/java/com/liato/bankdroid/BankEditActivity.java +index fce0bbe..835c64e 100644 +--- a/app/src/main/java/com/liato/bankdroid/BankEditActivity.java ++++ b/app/src/main/java/com/liato/bankdroid/BankEditActivity.java +@@ -122,7 +122,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected +  + @OnClick(R.id.btnSettingsOk) + public void onSubmit(View v) { +- if(!validate()) { ++ if (!validate()) { + return; + } + SELECTED_BANK.setProperties(getFormParameters(SELECTED_BANK.getConnectionConfiguration())); +@@ -139,7 +139,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected + @Override + public void onItemSelected(AdapterView parentView, View selectedItemView, int pos, long id) { + Bank selectedBank = (Bank) parentView.getItemAtPosition(pos); +- if(SELECTED_BANK == null || !SELECTED_BANK.equals(selectedBank)) { ++ if (SELECTED_BANK == null || !SELECTED_BANK.equals(selectedBank)) { + SELECTED_BANK = selectedBank; + mFormContainer.removeAllViewsInLayout(); + createForm(SELECTED_BANK.getConnectionConfiguration(), +@@ -154,10 +154,10 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected +  +  + private void createForm(List... configurations) { +- for(List fields : configurations) { ++ for (List fields : configurations) { + for (Field field : fields) { + createLabel(field); +- if(field.getValues().isEmpty()) { ++ if (field.getValues().isEmpty()) { + createField(field); + } else { + createSpinner(field); +@@ -203,7 +203,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected + DefaultConnectionConfiguration.NAME); + customName.setText(bank.getCustomName()); +  +- for(Map.Entry property : bank.getProperties().entrySet()) { ++ for (Map.Entry property : bank.getProperties().entrySet()) { + EditText propertyInput = (EditText) mFormContainer.findViewWithTag(property.getKey()); + propertyInput.setText(property.getValue()); + } +@@ -211,7 +211,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected +  + private Map getFormParameters(List fields) { + Map properties = new HashMap<>(); +- for(Field field : fields) { ++ for (Field field : fields) { + properties.put(field.getReference(), getFormParameter(field.getReference())); + } + return properties; +@@ -219,10 +219,10 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected +  + private String getFormParameter(String property) { + View propertyView = mFormContainer.findViewWithTag(property); +- if(propertyView instanceof EditText) { ++ if (propertyView instanceof EditText) { + EditText propertyInput = (EditText) propertyView; + return propertyInput.getText().toString().trim(); +- } else if(propertyView instanceof Spinner) { ++ } else if (propertyView instanceof Spinner) { + Spinner spinnerProperty = (Spinner) propertyView; + Entry entry = (Entry) spinnerProperty.getSelectedItem(); + return entry.getKey(); +@@ -235,7 +235,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected + boolean valid = true; + Iterator fields = Iterators.concat(SELECTED_BANK.getConnectionConfiguration().iterator(), + DefaultConnectionConfiguration.fields().iterator()); +- while(fields.hasNext()) { ++ while (fields.hasNext()) { + Field field = fields.next(); + try { + field.validate(getFormParameter(field.getReference())); +diff --git a/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java b/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java +index 215c59f..e9850ef 100644 +--- a/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java ++++ b/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java +@@ -136,7 +136,7 @@ public class DBAdapter { +  + public Cursor fetchProperties(String bankId) { + return mDb.query(Database.PROPERTY_TABLE_NAME, null, +- Database.PROPERTY_CONNECTION_ID+"='"+bankId+"'", null, null, null, null); ++ Database.PROPERTY_CONNECTION_ID + "='" + bankId + "'", null, null, null, null); + } +  + public long updateBank(Bank bank) { +@@ -162,9 +162,9 @@ public class DBAdapter { + } + if (bankId != -1) { + Map properties = bank.getProperties(); +- for(Map.Entry property : properties.entrySet()) { ++ for (Map.Entry property : properties.entrySet()) { + String value = property.getValue(); +- if(value != null && !value.isEmpty()) { ++ if (value != null && !value.isEmpty()) { + ContentValues propertyValues = new ContentValues(); + propertyValues.put(Database.PROPERTY_KEY, property.getKey()); + propertyValues.put(Database.PROPERTY_VALUE, value); +diff --git a/app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java b/app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java +index e4b166a..a295de8 100644 +--- a/app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java ++++ b/app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java +@@ -74,7 +74,7 @@ final public class DatabaseHelper extends SQLiteOpenHelper { + db.execSQL("ALTER TABLE " + LegacyDatabase.BANK_TABLE_NAME + " ADD " + + LegacyDatabase.BANK_HIDE_ACCOUNTS + " integer;"); + } +- if(oldVersion <= 11) { ++ if (oldVersion <= 11) { + try { + db.beginTransaction(); + db.execSQL(Database.TABLE_CONNECTION_PROPERTIES); +@@ -104,7 +104,7 @@ final public class DatabaseHelper extends SQLiteOpenHelper { + + LegacyDatabase.BANK_HIDE_ACCOUNTS + " FROM " + tempTable); +  + // Add username, password and extras fields to properties table. +- Cursor c = db.query(tempTable, null, null, null,null,null,null); ++ Cursor c = db.query(tempTable, null, null, null, null, null, null); + try { + if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) { + while (!c.isLast() && !c.isAfterLast()) { +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java +index 8201e43..e0d04d0 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java +@@ -6,7 +6,7 @@ public class Entry { + private final String mValue; +  + public Entry(String key, String value) { +- if(key == null || key.trim().isEmpty()) { ++ if (key == null || key.trim().isEmpty()) { + throw new IllegalArgumentException("key cannot be null or empty."); + } + mKey = key; +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java +index ad41c8f..4d1ce55 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java +@@ -13,7 +13,7 @@ public class FieldBuilder { + private BasicField field; +  + /** +- * Create a new {@link Field} builder without i18n support.  ++ * Create a new {@link Field} builder without i18n support. + */ + public FieldBuilder(String reference) { + this(reference, null); +@@ -24,7 +24,7 @@ public class FieldBuilder { + * The following keys needs to be in the ResourceBundle: + * {@code field.{reference}.label} - Locale label value + * {@code field.{reference}.placeholder} - Locale placeholder value. +- *  ++ * + * Setting {@link #placeholder(String)} or {@link #label(String) specifically will override the i18n values. + * Otherwise they will be set to the value specified in the Locale bundle or in the default bundle if not present. + * If a key is not present at all in the ResourceBundle the key will will be returned. +@@ -32,7 +32,7 @@ public class FieldBuilder { + * @param bundle The ResourceBundle to be used for i18n support. + */ + public FieldBuilder(String reference, ResourceBundle bundle) { +- if(reference == null || reference.trim().isEmpty()) { ++ if (reference == null || reference.trim().isEmpty()) { + throw new IllegalArgumentException("reference must be provided."); + } + field = new BasicField(reference, bundle); +@@ -146,7 +146,7 @@ public class FieldBuilder { +  + @Override + public List getValues() { +- if(values == null) { ++ if (values == null) { + values = Collections.emptyList(); + } + return values; +@@ -154,18 +154,18 @@ public class FieldBuilder { +  + @Override + public void validate(String value) throws IllegalArgumentException { +- if(isRequired()) { +- if(value == null || value.trim().isEmpty()) { ++ if (isRequired()) { ++ if (value == null || value.trim().isEmpty()) { + throw new IllegalArgumentException(String.format("%s is required", getLabel())); + } +- if(validator != null) { ++ if (validator != null) { + validator.validate(value); + } + } + } +  + private String getLocaleString(String key) { +- if(!isLocale()) { ++ if (!isLocale()) { + return null; + } + String propertyKey = String.format("field.%s.%s", getReference(), key); +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java +index 44c8e9b..06b2566 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java +@@ -34,7 +34,7 @@ abstract class AbstractAccountBuilder> { + } +  + public T addCustomAttribute(String key, String value) { +- if(mCustomAttributes == null) { ++ if (mCustomAttributes == null) { + mCustomAttributes = new HashMap<>(); + } + mCustomAttributes.put(key, value); +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java +index 8dff297..ef3c9d2 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java +@@ -58,7 +58,7 @@ public class AccountBuilder extends AbstractAccountBuilder { +  + @Override + public Map getCustomAttributes() { +- return mCustomAttributes == null ? Collections.emptyMap() : mCustomAttributes; ++ return mCustomAttributes == null ? Collections.emptyMap() : mCustomAttributes; + } + } + } +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java +index f837bab..d5343cb 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java +@@ -10,7 +10,7 @@ import java.util.Map; +  + import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount; +  +-public class CreditCardAccountBuilder extends AbstractAccountBuilder{ ++public class CreditCardAccountBuilder extends AbstractAccountBuilder { +  + private BigDecimal mCreditLimit; +  +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java +index 67abd33..f34df22 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java +@@ -11,7 +11,7 @@ import java.util.Map; +  + import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount; +  +-public class EquityAccountBuilder extends AbstractAccountBuilder{ ++public class EquityAccountBuilder extends AbstractAccountBuilder { +  + private BigDecimal mCost; +  +@@ -38,7 +38,7 @@ public class EquityAccountBuilder extends AbstractAccountBuilder(); + } + mEquities.add(equity); +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java +index bd1a3e8..5743c7d 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java +@@ -19,9 +19,9 @@ public class EquityBuilder { + * a 25 % loss, while {@code 1.5} is 50 % profit. + * @param currency The currency of the equity. + */ +- public EquityBuilder(BigDecimal balance, double revenue, String currency){ ++ public EquityBuilder(BigDecimal balance, double revenue, String currency) { + mEquity = new BasicEquity(costFromBalanceAndRevenue(balance, revenue), +- revenueFromBalanceAndRevenueAsPerecntage(balance, revenue),currency); ++ revenueFromBalanceAndRevenueAsPerecntage(balance, revenue), currency); + } +  + public EquityBuilder name(String name) { +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java +index d99e715..1f6a20e 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java +@@ -30,7 +30,7 @@ public class LiabilityAccountBuilder extends AbstractAccountBuilder(); + } + mPayments.add(payment); +@@ -69,4 +69,4 @@ public class LiabilityAccountBuilder extends AbstractAccountBuilderemptyList() : mPayments; + } + } +-} +\ No newline at end of file ++} +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java +index 641fd7e..814ed20 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java +@@ -9,7 +9,7 @@ import java.util.Map; +  + import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount; +  +-public class PrePaidCardAccountBuilder extends AbstractAccountBuilder{ ++public class PrePaidCardAccountBuilder extends AbstractAccountBuilder { +  + private DateTime mValidFrom; + private DateTime mExpirationDate; +diff --git a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java +index 00e1e2f..6bd988f 100644 +--- a/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java ++++ b/bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java +@@ -24,7 +24,7 @@ public class TransactionAccountBuilder extends AbstractAccountBuilder(); + } + mTransactions.add(transaction); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java +index ceca10f..18a6a0c 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java +@@ -369,7 +369,7 @@ public abstract class Bank implements Comparable, IBankTypes { + } +  + public Map getProperties() { +- if(this.properties == null) { ++ if (this.properties == null) { + this.properties = new HashMap<>(); + } + return this.properties; +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java +index 496f9e4..d2aa87c 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java +@@ -14,7 +14,7 @@ public class LegacyBankHelper { + private static Map providerReferences; +  + public static String getReferenceFromLegacyId(int legacyId) { +- if(providerReferences == null) { ++ if (providerReferences == null) { + generateLegacyProviderReferences(); + } + return providerReferences.get(legacyId); +@@ -22,7 +22,7 @@ public class LegacyBankHelper { +  + // TODO Used during refactoring. Remove before 2.0 + public static int getLegacyIdFromReference(String reference) { +- if(legacyProviderReferences == null) { ++ if (legacyProviderReferences == null) { + generateLegacyProviderReferences(); + } + return legacyProviderReferences.get(reference); +@@ -32,15 +32,14 @@ public class LegacyBankHelper { + Map references = new HashMap<>(); + Map legacyIds = new HashMap<>(); + Field[] fields = IBankTypes.class.getFields(); +- for(int i = 0 ; i < fields.length; i++) { +- Field field = fields[i]; ++ for (Field field : fields) { + try { + String reference = field.getName().toLowerCase().replaceAll("_", "-"); + Integer legacyId = field.getInt(new IBankTypes() { + }); + references.put(legacyId, reference); + legacyIds.put(reference, legacyId); +- } catch(IllegalAccessException e) { ++ } catch (IllegalAccessException e) { + Timber.e(e, "Provider could not be mapped"); + } + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java +index b740b6e..c7fa006 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java +@@ -106,7 +106,7 @@ public class OKQ8 extends Bank { + } + String postAction = matcher.group(1); + postData.add(new BasicNameValuePair("javax.faces.ViewState", +- postAction.substring(postAction.length()-5,postAction.length()-1))); ++ postAction.substring(postAction.length() - 5, postAction.length() - 1))); + postData.add(new BasicNameValuePair("loginForm", "loginForm")); + postData.add(new BasicNameValuePair("button", "Logga in")); +  +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java +index 620c740..9aef3df 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java +@@ -124,7 +124,7 @@ public class SveaDirekt extends Bank { + response = urlopen.open(ACCOUNTS_URL); + Document doc = Jsoup.parse(response); + ArrayList accounts = parseAccounts(doc); +- for(Account account : accounts) { ++ for (Account account : accounts) { + response = urlopen.open(TRANSACTIONS_URL + "?account=" + account.getId()); + account.setTransactions(parseTransactions(response)); + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java +index 396af06..933ec1f 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java +@@ -116,9 +116,9 @@ public class AmericanExpress extends Bank { +  + urlopen = login(); +  +- for(Card card : loginResponse.getCards()) { ++ for (Card card : loginResponse.getCards()) { + Account account = asAccount(card); +- if(card.isTransactionsEnabled()) { ++ if (card.isTransactionsEnabled()) { + account.setTransactions(fetchTransactionsFor(card)); + } + accounts.add(account); +@@ -137,7 +137,7 @@ public class AmericanExpress extends Bank { + "\"sortedIndex\":" + card.getSortedIndex() + + "}", + HTTP.UTF_8), true); +- if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { ++ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + response.getEntity().consumeContent(); + throw new BankException( + res.getText(R.string.update_transactions_error).toString()); +@@ -147,10 +147,10 @@ public class AmericanExpress extends Bank { + .withType(TransactionsResponse.class) + .readValue(response.getEntity().getContent()); +  +- if(details.getTransactionDetails() == null) { ++ if (details.getTransactionDetails() == null) { + throw new BankException(res.getText(R.string.server_error_try_again).toString()); + } +- if(details.getTransactionDetails().getStatus() != 0) { ++ if (details.getTransactionDetails().getStatus() != 0) { + throw new BankException(details.getTransactionDetails().getMessage()); + } +  +@@ -159,8 +159,8 @@ public class AmericanExpress extends Bank { +  + private List transactionsOf(@Nullable TransactionDetails details) { + List transactions = new ArrayList<>(); +- if(details != null) { +- for(com.liato.bankdroid.banking.banks.americanexpress.model.Transaction transaction : details.getTransactions()) { ++ if (details != null) { ++ for (com.liato.bankdroid.banking.banks.americanexpress.model.Transaction transaction : details.getTransactions()) { + transactions.add(asTransaction(transaction)); + } + } +@@ -196,17 +196,17 @@ public class AmericanExpress extends Bank { + } +  + private LoginResponse parseLoginResponse(HttpResponse response) throws IOException, BankException { +- if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { ++ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + response.getEntity().consumeContent(); + throw new BankException(res.getText(R.string.server_error_try_again).toString()); + } + LoginResponse loginResponse = MAPPER.reader() + .withType(LoginResponse.class) + .readValue(response.getEntity().getContent()); +- if(loginResponse == null || loginResponse.getLogonData() == null) { ++ if (loginResponse == null || loginResponse.getLogonData() == null) { + throw new BankException(res.getText(R.string.server_error_try_again).toString()); + } +- if(loginResponse.getLogonData().getStatus() != 0) { ++ if (loginResponse.getLogonData().getStatus() != 0) { + throw new BankException(loginResponse.getLogonData().getMessage()); + } +  +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java +index c9abbe6..dbfe2d7 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java +@@ -70,7 +70,7 @@ public class Card { + } +  + public BigDecimal getBalance() { +- if(summary != null && summary.getTotalBalance() != null) { ++ if (summary != null && summary.getTotalBalance() != null) { + return Helpers.parseBalance(summary.getTotalBalance().getValue()).negate(); + } + return BigDecimal.ZERO; +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java +index b63fdd0..4d4ad79 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java +@@ -43,7 +43,7 @@ public class LoginResponse { + } +  + public List getCards() { +- if(summaryData != null && summaryData.getCardList() != null) { ++ if (summaryData != null && summaryData.getCardList() != null) { + return summaryData.getCardList(); + } + return Collections.emptyList(); +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java +index 2efa7ea..8673cb6 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java +@@ -40,7 +40,7 @@ public class TransactionDetails { + public List getTransactions() { + if (activityList != null) { + List transactions = new ArrayList<>(); +- for(AccountActivity activity : activityList) { ++ for (AccountActivity activity : activityList) { + transactions.addAll(activity.getTransactionList()); + } + return transactions; +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java +index 6969afa..7e8fe82 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java +@@ -129,7 +129,7 @@ public class Lansforsakringar extends Bank { + } finally { + try { + is.close(); +- } catch(IOException e) { ++ } catch (IOException e) { + Timber.w(e, "Closing JSON stream failed"); + } + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java +index c8b5272..1d58f40 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java +@@ -86,7 +86,7 @@ public class Rikslunchen extends Bank { + HttpResponse response = urlopen.openAsHttpResponse( + BASE_URL + "?cardid=" + getUsername(), + false); +- if(response.getStatusLine().getStatusCode() != 200) { ++ if (response.getStatusLine().getStatusCode() != 200) { + response.getEntity().consumeContent(); + throw new LoginException(context.getString(R.string.invalid_card_number)); + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java +index 6436bdb..b57554a 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java +@@ -8,7 +8,7 @@ import android.text.InputType; + public class FieldTypeMapper { +  + public static FieldType toFieldType(int androidFieldType) { +- switch(androidFieldType) { ++ switch (androidFieldType) { + case InputType.TYPE_CLASS_NUMBER: + return FieldType.NUMBER; + case InputType.TYPE_CLASS_PHONE: +@@ -20,7 +20,7 @@ public class FieldTypeMapper { + } + } + public static int fromFieldType(FieldType fieldType) { +- switch(fieldType) { ++ switch (fieldType) { + case NUMBER: + return InputType.TYPE_CLASS_NUMBER; + case PHONE: +diff --git a/config/quality/checkstyle/checkstyle.xml b/config/quality/checkstyle/checkstyle.xml +index 204efc7..0493359 100644 +--- a/config/quality/checkstyle/checkstyle.xml ++++ b/config/quality/checkstyle/checkstyle.xml +@@ -33,16 +33,17 @@ +  +  +  +-  ++  +  +  +  +- --> ++ +  +  +  +diff --git a/config/quality/quality.gradle b/config/quality/quality.gradle +index bf2f1c6..9f4833d 100644 +--- a/config/quality/quality.gradle ++++ b/config/quality/quality.gradle +@@ -63,7 +63,7 @@ task pmd(type: Pmd) { + } + } +  +-if(plugins.hasPlugin('android') || plugins.hasPlugin('com.android.library')) { ++if (plugins.hasPlugin('android') || plugins.hasPlugin('com.android.library')) { + check.dependsOn 'lint' + tasks.getByName("findbugs").dependsOn 'compileDebugSources' + tasks.getByName('findbugs').classes = files("$project.buildDir/intermediates/classes") +@@ -85,7 +85,7 @@ if(plugins.hasPlugin('android') || plugins.hasPlugin('com.android.library')) { + } + } + } +-if(plugins.hasPlugin('java')) { ++if (plugins.hasPlugin('java')) { + tasks.getByName('findbugs').classes = files("$project.buildDir/classes") + tasks.getByName('findbugs').dependsOn 'classes' + } + +commit e8ebeb2488435fbf9f990cd6bfc2d9fa12a561ac +Author: Robert Högberg +Date: Fri Oct 28 00:11:49 2016 +0200 + + Östgötatrafiken: Adapt to new login page + + Östgötatrafiken now supports three ways to log in/authenticate: + * An e-mail address + * A username (for legacy users (such as me)) + * Facebook login + + Bankdroid only supports e-mail/username login. + + (I haven't tested e-mail login, but I expect it to work the same way + as for username logins) + +diff --git a/CHANGELOG b/CHANGELOG +index 970ea23..5ebd411 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. +  + Not yet released + * Bioklubben: Use https. It's secure and http page no longer exists. ++* Östgötatrafiken: Adapt to new login page (Facebook login not supported) +  + v1.9.11 (2016-10-26) + * Warn about disabled banks in the transactions list +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java +index 37f3770..8524e38 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java +@@ -45,9 +45,6 @@ public class Ostgotatrafiken extends Bank { +  + private static final String NAME_SHORT = "ogt"; +  +- private static final String URL +- = "https://www.ostgotatrafiken.se/Priser--biljetter/Mina-sidor/Login/"; +- + private static final int BANKTYPE_ID = IBankTypes.OSTGOTATRAFIKEN; +  + private Pattern reViewState = Pattern.compile( +@@ -75,7 +72,6 @@ public class Ostgotatrafiken extends Bank { + super.NAME = NAME; + super.NAME_SHORT = NAME_SHORT; + super.BANKTYPE_ID = BANKTYPE_ID; +- super.URL = URL; + } +  + public Ostgotatrafiken(String username, String password, Context context) throws BankException, +@@ -90,18 +86,20 @@ public class Ostgotatrafiken extends Bank { + R.raw.cert_ostgotatrafiken_login, R.raw.cert_ostgotatrafiken_overview)); +  + List postData = new ArrayList(); +- postData.add(new BasicNameValuePair("Username", getUsername())); +- postData.add(new BasicNameValuePair("Password", getPassword())); +- postData.add(new BasicNameValuePair("Login", "Logga in")); ++ postData.add(new BasicNameValuePair("", "{\"authSource\":10," + ++ "\"keepMeLimitedLoggedIn\":true," + ++ "\"userName\":\"" + getUsername() + "\"," + ++ "\"password\":\"" + getPassword() + "\"," + ++ "\"impersonateUserName\":\"\"}")); +  +- return new LoginPackage(urlopen, postData, response, URL); ++ return new LoginPackage(urlopen, postData, response, "https://www.ostgotatrafiken.se/ajax/Login/Attempt"); + } +  + @Override + public Urllib login() throws LoginException, BankException, IOException { + LoginPackage lp = preLogin(); + response = urlopen.open(lp.getLoginTarget(), lp.getPostData()); +- if (!response.contains("Logga ut")) { ++ if (!response.contains("presentationUserName")) { + throw new LoginException(res.getText(R.string.invalid_username_password).toString()); + } + return urlopen; + +commit ff91ffbc69b9d82ce6e75063b8914c1a8bb28865 +Author: Johan Walles +Date: Tue Nov 1 02:24:33 2016 +0100 + + Log bank usage statistics to Crashlytics + + With this change in place we'll be able to see in Crashlytics: + * which banks are most frequently disabled + * which banks are most frequently used + * for which banks transactions updating doesn't work + +diff --git a/app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java b/app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java +index b8145f3..331cfc3 100644 +--- a/app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java ++++ b/app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java +@@ -24,6 +24,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException; + import com.liato.bankdroid.banking.exceptions.BankException; + import com.liato.bankdroid.banking.exceptions.LoginException; + import com.liato.bankdroid.db.DBAdapter; ++import com.liato.bankdroid.utils.LoggingUtils; + import com.liato.bankdroid.utils.NetworkUtils; +  + import android.app.AlertDialog; +@@ -80,6 +81,7 @@ public class DataRetrieverTask extends AsyncTask { + return this.dialog; + } +  ++ @Nullable + protected Bank getBankFromDb(long bankId, Context parent) { + return BankFactory.bankFromDb(bankId, parent, true); + } +@@ -122,6 +124,7 @@ public class DataRetrieverTask extends AsyncTask { + publishProgress(i, bank); +  + if (isListingAllBanks() && bank.isDisabled()) { ++ LoggingUtils.logDisabledBank(bank); + continue; + } +  +@@ -131,6 +134,8 @@ public class DataRetrieverTask extends AsyncTask { + bank.closeConnection(); + saveBank(bank, parent); + i++; ++ ++ LoggingUtils.logBankUpdate(bank, true); + } catch (final BankException e) { + this.errors.add(bank.getName() + " (" + bank.getUsername() + + ")"); +@@ -194,6 +199,7 @@ public class DataRetrieverTask extends AsyncTask { + .setIcon(android.R.drawable.ic_dialog_alert) + .setNeutralButton("Ok", + new DialogInterface.OnClickListener() { ++ @Override + public void onClick( + final DialogInterface dialog, + final int id) { +diff --git a/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java b/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java +index f289d76..7a82c5b 100644 +--- a/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java ++++ b/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java +@@ -27,6 +27,7 @@ import com.liato.bankdroid.banking.exceptions.BankException; + import com.liato.bankdroid.banking.exceptions.LoginException; + import com.liato.bankdroid.db.DBAdapter; + import com.liato.bankdroid.liveview.LiveViewService; ++import com.liato.bankdroid.utils.LoggingUtils; +  + import android.app.NotificationManager; + import android.app.PendingIntent; +@@ -289,7 +290,7 @@ public class AutoRefreshService extends Service { +  + @Override + protected Void doInBackground(final String... args) { +- errors = new ArrayList(); ++ errors = new ArrayList<>(); + Boolean refreshWidgets = false; + final List banks = getBanks(); + if (banks.isEmpty()) { +@@ -300,7 +301,7 @@ public class AutoRefreshService extends Service { + BigDecimal diff; + BigDecimal minDelta = new BigDecimal(prefs.getString("notify_min_delta", "0")); +  +- final HashMap accounts = new HashMap(); ++ final HashMap accounts = new HashMap<>(); +  + for (final Bank bank : banks) { + if (prefs.getBoolean("debug_mode", false) +@@ -311,6 +312,7 @@ public class AutoRefreshService extends Service { + continue; + } + if (bank.isDisabled()) { ++ LoggingUtils.logDisabledBank(bank); + continue; + } + try { +@@ -320,6 +322,7 @@ public class AutoRefreshService extends Service { + accounts.put(account.getId(), account); + } + bank.update(); ++ + diff = currentBalance.subtract(bank.getBalance()); +  + if (diff.compareTo(BigDecimal.ZERO) != 0) { +@@ -373,6 +376,9 @@ public class AutoRefreshService extends Service { + if (prefs.getBoolean( + "autoupdates_transactions_enabled", true)) { + bank.updateAllTransactions(); ++ LoggingUtils.logBankUpdate(bank, true); ++ } else { ++ LoggingUtils.logBankUpdate(bank, false); + } + } + bank.closeConnection(); +diff --git a/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java b/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java +index f0cf5dc..bea4936 100644 +--- a/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java ++++ b/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java +@@ -4,6 +4,8 @@ import com.crashlytics.android.Crashlytics; + import com.crashlytics.android.answers.Answers; + import com.crashlytics.android.answers.CustomEvent; + import com.liato.bankdroid.BuildConfig; ++import com.liato.bankdroid.banking.Account; ++import com.liato.bankdroid.banking.Bank; +  + import android.content.Context; + import android.text.TextUtils; +@@ -40,9 +42,41 @@ public class LoggingUtils { + } +  + public static void logCustom(CustomEvent event) { +- if (isCrashlyticsEnabled()) { +- event.putCustomAttribute("App Version", BuildConfig.VERSION_NAME); +- Answers.getInstance().logCustom(event); ++ if (!isCrashlyticsEnabled()) { ++ return; ++ } ++ ++ event.putCustomAttribute("App Version", BuildConfig.VERSION_NAME); ++ Answers.getInstance().logCustom(event); ++ } ++ ++ public static void logDisabledBank(Bank bank) { ++ if (!isCrashlyticsEnabled()) { ++ return; ++ } ++ ++ logCustom(new CustomEvent("Disabled Bank"). ++ putCustomAttribute("Name", bank.getDisplayName())); ++ } ++ ++ public static void logBankUpdate(Bank bank, boolean withTransactions) { ++ if (!isCrashlyticsEnabled()) { ++ return; ++ } ++ ++ logCustom(new CustomEvent("Bank Updated"). ++ putCustomAttribute("Name", bank.getDisplayName()). ++ putCustomAttribute("With Transactions", Boolean.toString(withTransactions))); ++ ++ boolean hasTransactions = false; ++ for (Account account : bank.getAccounts()) { ++ if (account.getTransactions() != null && !account.getTransactions().isEmpty()) { ++ hasTransactions = true; ++ } ++ } ++ if (withTransactions && !hasTransactions) { ++ logCustom(new CustomEvent("Bank Without Transactions"). ++ putCustomAttribute("Name", bank.getDisplayName())); + } + } +  + +commit cb2027c3121ca4c37ef8ef1c45656d27e52e37c3 +Author: Johan Walles +Date: Sun Oct 30 17:12:07 2016 +0100 + + Require closing result cursors + +diff --git a/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java b/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java +index d61e0ce..db905c8 100644 +--- a/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java ++++ b/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java +@@ -84,10 +84,10 @@ public class BankFactory { + ArrayList banks = new ArrayList<>(); + DBAdapter db = new DBAdapter(context); + Cursor c = db.fetchBanks(); +- if (c == null) { +- return banks; +- } + try { ++ if (c == null || c.getCount() == 0) { ++ return banks; ++ } + while (!c.isLast() && !c.isAfterLast()) { + c.moveToNext(); + try { +@@ -109,7 +109,9 @@ public class BankFactory { + } + } + } finally { +- c.close(); ++ if (c != null) { ++ c.close(); ++ } + } + return banks; + } +@@ -118,38 +120,50 @@ public class BankFactory { + public static Account accountFromDb(Context context, String accountId, + boolean loadTransactions) { + DBAdapter db = new DBAdapter(context); +- Cursor c = db.getAccount(accountId); ++ Cursor ac = db.getAccount(accountId); ++ ++ Account account; ++ try { ++ if (ac == null || ac.isClosed() || (ac.isBeforeFirst() && ac.isAfterLast())) { ++ return null; ++ } +  +- if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) { +- return null; ++ account = new Account(ac.getString(ac.getColumnIndex("name")), ++ new BigDecimal(ac.getString(ac.getColumnIndex("balance"))), ++ ac.getString(ac.getColumnIndex("id")).split("_", 2)[1], ++ ac.getLong(ac.getColumnIndex("bankid")), ++ ac.getInt(ac.getColumnIndex("acctype"))); ++ account.setHidden(ac.getInt(ac.getColumnIndex("hidden")) == 1); ++ account.setNotify(ac.getInt(ac.getColumnIndex("notify")) == 1); ++ account.setCurrency(ac.getString(ac.getColumnIndex("currency"))); ++ account.setAliasfor(ac.getString(ac.getColumnIndex("aliasfor"))); ++ } finally { ++ if (ac != null) { ++ ac.close(); ++ } + } +  +- Account account = new Account(c.getString(c.getColumnIndex("name")), +- new BigDecimal(c.getString(c.getColumnIndex("balance"))), +- c.getString(c.getColumnIndex("id")).split("_", 2)[1], +- c.getLong(c.getColumnIndex("bankid")), +- c.getInt(c.getColumnIndex("acctype"))); +- account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1); +- account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1); +- account.setCurrency(c.getString(c.getColumnIndex("currency"))); +- account.setAliasfor(c.getString(c.getColumnIndex("aliasfor"))); +- c.close(); + if (loadTransactions) { + ArrayList transactions = new ArrayList<>(); + String fromAccount = accountId; + if (account.getAliasfor() != null && account.getAliasfor().length() > 0) { + fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor(); + } +- c = db.fetchTransactions(fromAccount); +- if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) { +- while (!c.isLast() && !c.isAfterLast()) { +- c.moveToNext(); +- transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")), +- c.getString(c.getColumnIndex("btransaction")), +- new BigDecimal(c.getString(c.getColumnIndex("amount"))), +- c.getString(c.getColumnIndex("currency")))); ++ Cursor tc = db.fetchTransactions(fromAccount); ++ try { ++ if (!(tc == null || tc.isClosed() || (tc.isBeforeFirst() && tc.isAfterLast()))) { ++ while (!tc.isLast() && !tc.isAfterLast()) { ++ tc.moveToNext(); ++ transactions.add(new Transaction(tc.getString(tc.getColumnIndex("transdate")), ++ tc.getString(tc.getColumnIndex("btransaction")), ++ new BigDecimal(tc.getString(tc.getColumnIndex("amount"))), ++ tc.getString(tc.getColumnIndex("currency")))); ++ } ++ } ++ } finally { ++ if (tc != null) { ++ tc.close(); + } +- c.close(); + } + account.setTransactions(transactions); + } +@@ -160,10 +174,10 @@ public class BankFactory { + ArrayList accounts = new ArrayList<>(); + DBAdapter db = new DBAdapter(context); + Cursor c = db.fetchAccounts(bankId); +- if (c == null) { +- return accounts; +- } + try { ++ if (c == null || c.getCount() == 0) { ++ return accounts; ++ } + while (!c.isLast() && !c.isAfterLast()) { + c.moveToNext(); + try { +@@ -183,7 +197,9 @@ public class BankFactory { + } + } + } finally { +- c.close(); ++ if (c != null) { ++ c.close(); ++ } + } + return accounts; + } +@@ -193,10 +209,10 @@ public class BankFactory { + Map decryptedProperties = new HashMap<>(); + DBAdapter db = new DBAdapter(context); + Cursor c = db.fetchProperties(Long.toString(bankId)); +- if(c == null) { +- return properties; +- } + try { ++ if (c == null || c.getCount() == 0) { ++ return properties; ++ } + while (!c.isLast() && !c.isAfterLast()) { + c.moveToNext(); + String key = c.getString(c.getColumnIndex(Database.PROPERTY_KEY)); +@@ -214,7 +230,9 @@ public class BankFactory { + properties.put(key, value); + } + } finally { +- c.close(); ++ if (c != null) { ++ c.close(); ++ } + } +  + storeDecryptedProperties(context, bankId, decryptedProperties); +diff --git a/app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java b/app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java +index ea72715..e4b166a 100644 +--- a/app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java ++++ b/app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java +@@ -105,33 +105,38 @@ final public class DatabaseHelper extends SQLiteOpenHelper { +  + // Add username, password and extras fields to properties table. + Cursor c = db.query(tempTable, null, null, null,null,null,null); +- if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) { +- while (!c.isLast() && !c.isAfterLast()) { +- c.moveToNext(); +- long id = c.getLong(c.getColumnIndex(LegacyDatabase.BANK_ID)); +- +- ContentValues usernameProperty = new ContentValues(); +- usernameProperty.put(PROPERTY_CONNECTION_ID, id); +- usernameProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.USERNAME); +- usernameProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_USERNAME))); +- db.insert(PROPERTY_TABLE_NAME, null, usernameProperty); +- +- ContentValues passwordProperty = new ContentValues(); +- passwordProperty.put(PROPERTY_CONNECTION_ID, id); +- passwordProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.PASSWORD); +- passwordProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_PASSWORD))); +- db.insert(PROPERTY_TABLE_NAME, null, passwordProperty); +- +- String extras = c.getString(c.getColumnIndex(LegacyDatabase.BANK_EXTRAS)); +- if(extras != null && !extras.isEmpty()) { +- ContentValues extrasProperty = new ContentValues(); +- extrasProperty.put(PROPERTY_CONNECTION_ID, id); +- extrasProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.EXTRAS); +- extrasProperty.put(PROPERTY_VALUE, extras); +- db.insert(PROPERTY_TABLE_NAME, null, extrasProperty); ++ try { ++ if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) { ++ while (!c.isLast() && !c.isAfterLast()) { ++ c.moveToNext(); ++ long id = c.getLong(c.getColumnIndex(LegacyDatabase.BANK_ID)); ++ ++ ContentValues usernameProperty = new ContentValues(); ++ usernameProperty.put(PROPERTY_CONNECTION_ID, id); ++ usernameProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.USERNAME); ++ usernameProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_USERNAME))); ++ db.insert(PROPERTY_TABLE_NAME, null, usernameProperty); ++ ++ ContentValues passwordProperty = new ContentValues(); ++ passwordProperty.put(PROPERTY_CONNECTION_ID, id); ++ passwordProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.PASSWORD); ++ passwordProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_PASSWORD))); ++ db.insert(PROPERTY_TABLE_NAME, null, passwordProperty); ++ ++ String extras = c.getString(c.getColumnIndex(LegacyDatabase.BANK_EXTRAS)); ++ if (extras != null && !extras.isEmpty()) { ++ ContentValues extrasProperty = new ContentValues(); ++ extrasProperty.put(PROPERTY_CONNECTION_ID, id); ++ extrasProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.EXTRAS); ++ extrasProperty.put(PROPERTY_VALUE, extras); ++ db.insert(PROPERTY_TABLE_NAME, null, extrasProperty); ++ } + } + } +- c.close(); ++ } finally { ++ if (c != null) { ++ c.close(); ++ } + } + db.execSQL("DROP TABLE " + tempTable); + } +diff --git a/config/quality/pmd/pmd-ruleset.xml b/config/quality/pmd/pmd-ruleset.xml +index 3109e6b..19538ce 100644 +--- a/config/quality/pmd/pmd-ruleset.xml ++++ b/config/quality/pmd/pmd-ruleset.xml +@@ -25,6 +25,13 @@ +  +  +  ++  ++  ++  ++  ++  ++  ++ +  +  +  +diff --git a/tools/update-suppressions.sh b/tools/update-suppressions.sh +index 4148ea6..53ff534 100755 +--- a/tools/update-suppressions.sh ++++ b/tools/update-suppressions.sh +@@ -64,6 +64,13 @@ function set_pmd_suppressions() { +  +  +  ++  ++  ++  ++  ++  ++  ++ +  +  +  + +commit 63188088e36f3e351830d0e5b1f8b0b576fa5b54 +Author: Johan Walles +Date: Thu Oct 27 22:02:02 2016 +0200 + + Ensure on-disk passwords are unencrypted + + This is a step towards removing password encryption alltogether. + + The background is that it's broken on Androin Nougat anyway, and that it + didn't provide any extra security before that either. + + Since Bankdroid needs to send plain text passwords to the banks, it must + be possible to retrieve the plain text passwords automatically. And if + the passwords are encrypted on disk, Bankdroid needs to have the key. + And if Bankdroid stores both the key and the encrypted password on the + phone, a determined attacker could get both anyway, and the encryption + is useless. + + The only thing the encryption has protected against is a user rooting + their own device and retrieving their own plain text passwords. This + would enable the attacker to read their own account balance from the + bank. + + Which they likely already could even before this change... + + This change also disables an Android Lint check whose outcome changes + over time; these checks are impossible to maintain. And we fixed some + warnings. + +diff --git a/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java b/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java +index 9a7ea9c..d61e0ce 100644 +--- a/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java ++++ b/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java +@@ -16,15 +16,20 @@ +  + package com.liato.bankdroid.banking; +  ++import com.crashlytics.android.answers.CustomEvent; + import com.liato.bankdroid.banking.exceptions.BankException; + import com.liato.bankdroid.db.Crypto; + import com.liato.bankdroid.db.DBAdapter; + import com.liato.bankdroid.db.Database; ++import com.liato.bankdroid.db.DatabaseHelper; ++import com.liato.bankdroid.utils.LoggingUtils; +  + import net.sf.andhsli.hotspotlogin.SimpleCrypto; +  ++import android.content.ContentValues; + import android.content.Context; + import android.database.Cursor; ++import android.database.sqlite.SQLiteDatabase; + import android.support.annotation.Nullable; +  + import java.math.BigDecimal; +@@ -37,7 +42,7 @@ import timber.log.Timber; +  + public class BankFactory { +  +- public static Bank fromBanktypeId(int id, Context context) throws BankException { ++ private static Bank fromBanktypeId(int id, Context context) throws BankException { + return LegacyBankFactory.fromBanktypeId(id, context); + } +  +@@ -58,7 +63,7 @@ public class BankFactory { + bank.setProperties(loadProperties(id, context)); +  + bank.setData(new BigDecimal(c.getString(c.getColumnIndex("balance"))), +- (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), ++ (c.getInt(c.getColumnIndex("disabled")) != 0), + c.getLong(c.getColumnIndex("_id")), + c.getString(c.getColumnIndex("currency")), + c.getString(c.getColumnIndex("custname")), +@@ -76,36 +81,40 @@ public class BankFactory { + } +  + public static ArrayList banksFromDb(Context context, boolean loadAccounts) { +- ArrayList banks = new ArrayList(); ++ ArrayList banks = new ArrayList<>(); + DBAdapter db = new DBAdapter(context); + Cursor c = db.fetchBanks(); +- if (c == null || c.getCount() == 0) { ++ if (c == null) { + return banks; + } +- while (!c.isLast() && !c.isAfterLast()) { +- c.moveToNext(); +- try { +- Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context); +- long id = c.getLong(c.getColumnIndex("_id")); +- bank.setProperties(loadProperties(id, context)); +- bank.setData(new BigDecimal(c.getString(c.getColumnIndex("balance"))), +- (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), +- id, +- c.getString(c.getColumnIndex("currency")), +- c.getString(c.getColumnIndex("custname")), +- c.getInt(c.getColumnIndex("hideAccounts"))); +- if (loadAccounts) { +- bank.setAccounts(accountsFromDb(context, bank.getDbId())); ++ try { ++ while (!c.isLast() && !c.isAfterLast()) { ++ c.moveToNext(); ++ try { ++ Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context); ++ long id = c.getLong(c.getColumnIndex("_id")); ++ bank.setProperties(loadProperties(id, context)); ++ bank.setData(new BigDecimal(c.getString(c.getColumnIndex("balance"))), ++ (c.getInt(c.getColumnIndex("disabled")) != 0), ++ id, ++ c.getString(c.getColumnIndex("currency")), ++ c.getString(c.getColumnIndex("custname")), ++ c.getInt(c.getColumnIndex("hideAccounts"))); ++ if (loadAccounts) { ++ bank.setAccounts(accountsFromDb(context, bank.getDbId())); ++ } ++ banks.add(bank); ++ } catch (BankException e) { ++ Timber.w(e, "BankFactory.banksFromDb()"); + } +- banks.add(bank); +- } catch (BankException e) { +- Timber.w(e, "BankFactory.banksFromDb()"); + } ++ } finally { ++ c.close(); + } +- c.close(); + return banks; + } +  ++ @Nullable + public static Account accountFromDb(Context context, String accountId, + boolean loadTransactions) { + DBAdapter db = new DBAdapter(context); +@@ -120,13 +129,13 @@ public class BankFactory { + c.getString(c.getColumnIndex("id")).split("_", 2)[1], + c.getLong(c.getColumnIndex("bankid")), + c.getInt(c.getColumnIndex("acctype"))); +- account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false); +- account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false); ++ account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1); ++ account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1); + account.setCurrency(c.getString(c.getColumnIndex("currency"))); + account.setAliasfor(c.getString(c.getColumnIndex("aliasfor"))); + c.close(); + if (loadTransactions) { +- ArrayList transactions = new ArrayList(); ++ ArrayList transactions = new ArrayList<>(); + String fromAccount = accountId; + if (account.getAliasfor() != null && account.getAliasfor().length() > 0) { + fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor(); +@@ -147,56 +156,114 @@ public class BankFactory { + return account; + } +  +- public static ArrayList accountsFromDb(Context context, long bankId) { +- ArrayList accounts = new ArrayList(); ++ private static ArrayList accountsFromDb(Context context, long bankId) { ++ ArrayList accounts = new ArrayList<>(); + DBAdapter db = new DBAdapter(context); + Cursor c = db.fetchAccounts(bankId); +- if (c == null || c.getCount() == 0) { ++ if (c == null) { + return accounts; + } +- while (!c.isLast() && !c.isAfterLast()) { +- c.moveToNext(); +- try { +- Account account = new Account(c.getString(c.getColumnIndex("name")), +- new BigDecimal(c.getString(c.getColumnIndex("balance"))), +- c.getString(c.getColumnIndex("id")).split("_", 2)[1], +- c.getLong(c.getColumnIndex("bankid")), +- c.getInt(c.getColumnIndex("acctype"))); +- account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false); +- account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false); +- account.setCurrency(c.getString(c.getColumnIndex("currency"))); +- account.setAliasfor(c.getString(c.getColumnIndex("aliasfor"))); +- accounts.add(account); +- } catch (ArrayIndexOutOfBoundsException e) { +- // Probably an old Avanza account +- Timber.w(e, "Attempted to load an account without an ID: %d", bankId); ++ try { ++ while (!c.isLast() && !c.isAfterLast()) { ++ c.moveToNext(); ++ try { ++ Account account = new Account(c.getString(c.getColumnIndex("name")), ++ new BigDecimal(c.getString(c.getColumnIndex("balance"))), ++ c.getString(c.getColumnIndex("id")).split("_", 2)[1], ++ c.getLong(c.getColumnIndex("bankid")), ++ c.getInt(c.getColumnIndex("acctype"))); ++ account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1); ++ account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1); ++ account.setCurrency(c.getString(c.getColumnIndex("currency"))); ++ account.setAliasfor(c.getString(c.getColumnIndex("aliasfor"))); ++ accounts.add(account); ++ } catch (ArrayIndexOutOfBoundsException e) { ++ // Probably an old Avanza account ++ Timber.w(e, "Attempted to load an account without an ID: %d", bankId); ++ } + } ++ } finally { ++ c.close(); + } +- c.close(); + return accounts; + } +  +- private static Map loadProperties(long id, Context context) { ++ private static Map loadProperties(long bankId, Context context) { + Map properties = new HashMap<>(); ++ Map decryptedProperties = new HashMap<>(); + DBAdapter db = new DBAdapter(context); +- Cursor c = db.fetchProperties(Long.toString(id)); +- if(c == null || c.getCount() == 0) { ++ Cursor c = db.fetchProperties(Long.toString(bankId)); ++ if(c == null) { + return properties; + } +- while(!c.isLast() && !c.isAfterLast()) { +- c.moveToNext(); +- String key = c.getString(c.getColumnIndex(Database.PROPERTY_KEY)); +- String value = c.getString(c.getColumnIndex(Database.PROPERTY_VALUE)); +- if(LegacyProviderConfiguration.PASSWORD.equals(key)) { +- try { +- value = SimpleCrypto.decrypt(Crypto.getKey(), value); +- } catch (Exception e) { +- Timber.w(e, "Failed decrypting bank properties"); ++ try { ++ while (!c.isLast() && !c.isAfterLast()) { ++ c.moveToNext(); ++ String key = c.getString(c.getColumnIndex(Database.PROPERTY_KEY)); ++ String value = c.getString(c.getColumnIndex(Database.PROPERTY_VALUE)); ++ if (LegacyProviderConfiguration.PASSWORD.equals(key)) { ++ try { ++ value = SimpleCrypto.decrypt(Crypto.getKey(), value); ++ decryptedProperties.put(key, value); ++ } catch (Exception e) { ++ Timber.i("%s %s", ++ "Failed decrypting bank properties.", ++ "This usually means they are unencrypted, which is exactly what we want them to be."); ++ } + } ++ properties.put(key, value); + } +- properties.put(key, value); ++ } finally { ++ c.close(); + } +- c.close(); ++ ++ storeDecryptedProperties(context, bankId, decryptedProperties); ++ + return properties; + } ++ ++ /** ++ * Stores decrypted passwords on disk. ++ *

 ++ * This is a step in removing password encryption alltogether. ++ *

 ++ * The background is that it's broken on Androin Nougat anyway, and that it ++ * didn't provide any extra security before that either. ++ *

 ++ * Since Bankdroid needs to send plain text passwords to the banks, it must ++ * be possible to retrieve the plain text passwords automatically. And if the ++ * passwords are encrypted on disk, Bankdroid needs to have the key. And if ++ * Bankdroid stores both the key and the encrypted password on the phone, a ++ * determined attacker could get both anyway, and the encryption is useless. ++ *

 ++ * The only thing the encryption has protected against is a using rooting ++ * their own device and retrieving their own plain text passwords. This would ++ * enable the attacker to reaa their own account balance from the bank. Which ++ * they likely already could even before this change... ++ */ ++ private static void storeDecryptedProperties( ++ Context context, long bankId, Map decryptedProperties) ++ { ++ if (decryptedProperties.isEmpty()) { ++ return; ++ } ++ ++ Timber.i("Storing %d decrypted properties...", decryptedProperties.size()); ++ SQLiteDatabase db = DatabaseHelper.getHelper(context).getWritableDatabase(); ++ for (Map.Entry property : decryptedProperties.entrySet()) { ++ String value = property.getValue(); ++ if (value != null && !value.isEmpty()) { ++ ContentValues propertyValues = new ContentValues(); ++ propertyValues.put(Database.PROPERTY_KEY, property.getKey()); ++ propertyValues.put(Database.PROPERTY_VALUE, value); ++ propertyValues.put(Database.PROPERTY_CONNECTION_ID, bankId); ++ db.insertWithOnConflict( ++ Database.PROPERTY_TABLE_NAME, null, propertyValues, ++ SQLiteDatabase.CONFLICT_REPLACE); ++ } ++ } ++ Timber.i("%d decrypted properties stored", decryptedProperties.size()); ++ ++ LoggingUtils.logCustom(new CustomEvent("Passwords Decrypted")); ++ } + } +diff --git a/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java b/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java +index 240669b..215c59f 100644 +--- a/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java ++++ b/app/src/main/java/com/liato/bankdroid/db/DBAdapter.java +@@ -18,15 +18,13 @@ package com.liato.bankdroid.db; +  + import com.liato.bankdroid.banking.Account; + import com.liato.bankdroid.banking.Bank; +-import com.liato.bankdroid.banking.LegacyProviderConfiguration; + import com.liato.bankdroid.banking.Transaction; +  +-import net.sf.andhsli.hotspotlogin.SimpleCrypto; +- + import android.content.ContentValues; + import android.content.Context; + import android.database.Cursor; + import android.database.sqlite.SQLiteDatabase; ++import android.support.annotation.Nullable; +  + import java.text.SimpleDateFormat; + import java.util.ArrayList; +@@ -34,8 +32,6 @@ import java.util.Calendar; + import java.util.List; + import java.util.Map; +  +-import timber.log.Timber; +- +  + public class DBAdapter { +  +@@ -169,13 +165,6 @@ public class DBAdapter { + for(Map.Entry property : properties.entrySet()) { + String value = property.getValue(); + if(value != null && !value.isEmpty()) { +- if (LegacyProviderConfiguration.PASSWORD.equals(property.getKey())) { +- try { +- value = SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword()); +- } catch (Exception e) { +- Timber.e(e, "Could not encrypt password."); +- } +- } + ContentValues propertyValues = new ContentValues(); + propertyValues.put(Database.PROPERTY_KEY, property.getKey()); + propertyValues.put(Database.PROPERTY_VALUE, value); +@@ -227,6 +216,7 @@ public class DBAdapter { + mDb.update("banks", initialValues, "_id=" + bankId, null); + } +  ++ @Nullable + public Cursor getBank(String bankId) { + Cursor c = mDb.query("banks", + new String[]{"_id", "balance", "banktype", "disabled", +@@ -238,10 +228,12 @@ public class DBAdapter { + return c; + } +  ++ @Nullable + public Cursor getBank(long bankId) { + return getBank(Long.toString(bankId)); + } +  ++ @Nullable + public Cursor getAccount(String id) { + Cursor c = mDb.query("accounts", + new String[]{"id", "balance", "name", "bankid", "acctype", "hidden", "notify", +diff --git a/app/src/main/java/com/liato/bankdroid/db/Database.java b/app/src/main/java/com/liato/bankdroid/db/Database.java +index 0558483..93d3c14 100644 +--- a/app/src/main/java/com/liato/bankdroid/db/Database.java ++++ b/app/src/main/java/com/liato/bankdroid/db/Database.java +@@ -6,7 +6,7 @@ public class Database { +  + static final int DATABASE_VERSION = 12; +  +- static final String PROPERTY_TABLE_NAME = "connection_properties"; ++ public static final String PROPERTY_TABLE_NAME = "connection_properties"; + public static final String PROPERTY_CONNECTION_ID = "connection_id"; + public static final String PROPERTY_KEY = "property"; + public static final String PROPERTY_VALUE = "value"; +diff --git a/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java b/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java +index 4867459..f0cf5dc 100644 +--- a/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java ++++ b/app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java +@@ -1,12 +1,14 @@ + package com.liato.bankdroid.utils; +  ++import com.crashlytics.android.Crashlytics; ++import com.crashlytics.android.answers.Answers; ++import com.crashlytics.android.answers.CustomEvent; ++import com.liato.bankdroid.BuildConfig; ++ + import android.content.Context; + import android.text.TextUtils; + import android.util.Log; +  +-import com.crashlytics.android.Crashlytics; +-import com.liato.bankdroid.BuildConfig; +- + import io.fabric.sdk.android.Fabric; + import timber.log.Timber; +  +@@ -37,6 +39,13 @@ public class LoggingUtils { + !EmulatorUtils.RUNNING_ON_EMULATOR; + } +  ++ public static void logCustom(CustomEvent event) { ++ if (isCrashlyticsEnabled()) { ++ event.putCustomAttribute("App Version", BuildConfig.VERSION_NAME); ++ Answers.getInstance().logCustom(event); ++ } ++ } ++ + private static class CrashlyticsTree extends Timber.Tree { + CrashlyticsTree(Context context) { + Fabric.with(context, new Crashlytics()); +diff --git a/app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java b/app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java +index d4a1995..88e4154 100644 +--- a/app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java ++++ b/app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java +@@ -22,18 +22,14 @@ import javax.crypto.spec.SecretKeySpec; + * String cleartext = SimpleCrypto.decrypt(masterpassword, crypto) + *  + * ++ * @deprecated Broken ++ * on Android Nougat, ++ * considered ++ * broken by Android Lint even before then. ++ * + * @author ferenc.hechler + */ + public class SimpleCrypto { +- +- private final static String HEX = "0123456789ABCDEF"; +- +- public static String encrypt(String seed, String cleartext) throws Exception { +- byte[] rawKey = getRawKey(StringUtils.getBytes(seed)); +- byte[] result = encrypt(rawKey, StringUtils.getBytes(cleartext)); +- return toHex(result); +- } +- + public static String decrypt(String seed, String encrypted) throws Exception { + byte[] rawKey = getRawKey(StringUtils.getBytes(seed)); + byte[] enc = toByte(encrypted); +@@ -56,14 +52,6 @@ public class SimpleCrypto { + return raw; + } +  +- private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception { +- SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); +- Cipher cipher = Cipher.getInstance("AES"); +- cipher.init(Cipher.ENCRYPT_MODE, skeySpec); +- byte[] encrypted = cipher.doFinal(clear); +- return encrypted; +- } +- + private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception { + SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); + Cipher cipher = Cipher.getInstance("AES"); +@@ -72,7 +60,7 @@ public class SimpleCrypto { + return decrypted; + } +  +- public static byte[] toByte(String hexString) { ++ private static byte[] toByte(String hexString) { + int len = hexString.length() / 2; + byte[] result = new byte[len]; + for (int i = 0; i < len; i++) { +@@ -80,19 +68,4 @@ public class SimpleCrypto { + } + return result; + } +- +- public static String toHex(byte[] buf) { +- if (buf == null) { +- return ""; +- } +- StringBuffer result = new StringBuffer(2 * buf.length); +- for (int i = 0; i < buf.length; i++) { +- appendHex(result, buf[i]); +- } +- return result.toString(); +- } +- +- private static void appendHex(StringBuffer sb, byte b) { +- sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); +- } + } +diff --git a/config/quality/lint/lint.xml b/config/quality/lint/lint.xml +index 8195ce2..f81c4ca 100644 +--- a/config/quality/lint/lint.xml ++++ b/config/quality/lint/lint.xml +@@ -30,6 +30,7 @@ +  +  +  ++  +  +  +  + +commit eabc99cfadbf724f5d3129bc7b011587c6fd43d0 +Author: Robert Högberg +Date: Sat Oct 29 20:59:00 2016 +0200 + + Bioklubben: Update start web page + + http://bioklubben.sf.se -> https://bioklubben.sf.se + + The http version no longer exists + +diff --git a/CHANGELOG b/CHANGELOG +index fa02959..970ea23 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,5 +1,8 @@ + Please view this file on the master branch, on stable branches it's out of date. +  ++Not yet released ++* Bioklubben: Use https. It's secure and http page no longer exists. ++ + v1.9.11 (2016-10-26) + * Warn about disabled banks in the transactions list + * Show warning text about disabled banks in the main activity +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java +index e31540f..df9e368 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java +@@ -39,6 +39,7 @@ import java.math.BigDecimal; + import java.util.ArrayList; + import java.util.List; +  ++import eu.nullbyte.android.urllib.CertificateReader; + import eu.nullbyte.android.urllib.Urllib; +  + public class Bioklubben extends Bank { +@@ -47,7 +48,7 @@ public class Bioklubben extends Bank { +  + private static final String NAME_SHORT = "bioklubben"; +  +- private static final String URL = "http://bioklubben.sf.se/Start.aspx"; ++ private static final String URL = "https://bioklubben.sf.se/Start.aspx"; +  + private static final int BANKTYPE_ID = Bank.BIOKLUBBEN; +  +@@ -76,9 +77,9 @@ public class Bioklubben extends Bank { +  + @Override + protected LoginPackage preLogin() throws BankException, IOException { +- urlopen = new Urllib(context); ++ urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bioklubben)); + urlopen.setAllowCircularRedirects(true); +- response = urlopen.open("http://bioklubben.sf.se/Start.aspx"); ++ response = urlopen.open(URL); +  + Document d = Jsoup.parse(response); + Element e = d.getElementById("__VIEWSTATE"); +@@ -109,7 +110,7 @@ public class Bioklubben extends Bank { + postData.add( + new BasicNameValuePair("ctl00$ContentPlaceHolder1$LoginUserControl$PasswordTextBox", + getPassword())); +- return new LoginPackage(urlopen, postData, response, "http://bioklubben.sf.se/Start.aspx"); ++ return new LoginPackage(urlopen, postData, response, URL); + } +  + public Urllib login() throws LoginException, BankException, IOException { +@@ -129,7 +130,7 @@ public class Bioklubben extends Bank { + } + urlopen = login(); + Document d = Jsoup.parse(urlopen.open( +- "http://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1")); ++ "https://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1")); + Element e = d.getElementById("ctl00_ContentPlaceHolder1_BonusPointsLabel"); + if (e == null) { + throw new BankException( +diff --git a/bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem b/bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem +new file mode 100644 +index 0000000..a01ed1e +--- /dev/null ++++ b/bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem +@@ -0,0 +1,35 @@ ++-----BEGIN CERTIFICATE----- ++MIIF4TCCBMmgAwIBAgIQVPm9MeoE7SQFdlULvDppQjANBgkqhkiG9w0BAQsFADBE ++MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU ++R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTYwMjAxMDAwMDAwWhcNMTcwMTMxMjM1 ++OTU5WjBqMQswCQYDVQQGEwJTRTEYMBYGA1UECAwPU1RPQ0tIT0xNUyBMw6ROMQ4w ++DAYDVQQHDAVTb2xuYTESMBAGA1UEChQJU0YgQmlvIEFCMQswCQYDVQQLDAJJVDEQ ++MA4GA1UEAxQHKi5zZi5zZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ++AKLUmrPm9g2Z12yVD9jnGgk3C2xrdOYqjfjFGOrU2SfTaI1L8POt2s9YspYcKkFG ++5EB7Iv3aIwL0TccsbWT1PaiVvT7hgU94n5fYjjHlMiVMdPpHunGj9KqO12/zz++e ++Qa8xITx5AW3S7CYHIBqxPIU43/6ukXcmsGe4ngbHxhl7nfWcgWT/qxUA7guWqxON ++KNaNOsw4KeJizxhURT52nf5+dJIZ9j/3x8vu+WC8kJ9LQzKdFuFOZ05/Ivwj+WcI ++SbOOaisxaQCdkFMDtTfWPBX9CjEvAEqYsthFj2trvxZYgvnN6zR7eRdAH2chgrh9 ++//ljApp85rzAVClGncBZKq0CAwEAAaOCAqcwggKjMBkGA1UdEQQSMBCCByouc2Yu ++c2WCBXNmLnNlMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQkMCIw ++IKAeoByGGmh0dHA6Ly9nbi5zeW1jYi5jb20vZ24uY3JsMIGdBgNVHSAEgZUwgZIw ++gY8GBmeBDAECAjCBhDA/BggrBgEFBQcCARYzaHR0cHM6Ly93d3cuZ2VvdHJ1c3Qu ++Y29tL3Jlc291cmNlcy9yZXBvc2l0b3J5L2xlZ2FsMEEGCCsGAQUFBwICMDUMM2h0 ++dHBzOi8vd3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeS9sZWdh ++bDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0jBBgwFoAU0m/3 ++lvSFP3I8MH0j2oV4m6N8WnwwVwYIKwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNo ++dHRwOi8vZ24uc3ltY2QuY29tMCYGCCsGAQUFBzAChhpodHRwOi8vZ24uc3ltY2Iu ++Y29tL2duLmNydDCCAQMGCisGAQQB1nkCBAIEgfQEgfEA7wB2AN3rHSt6DU+mIIuB ++rYFocH4ujp0B1VyIjT0RxM227L7MAAABUp0mwQkAAAQDAEcwRQIgequqjt1sy5zl ++gCK93rW9xs6YxLs1bCfp96HIYhZ49kACIQDhjtfaakCmfkQ9UDMBp7WpE1kA4PFl ++jNIZnsUqdf4meAB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAAB ++Up0mvTEAAAQDAEYwRAIgR0W9StBOqzQ85oWMWO6h/P4M+p77PJQrjgdyQlcePVUC ++IHRoUg4Ywdh9ookJITb8K9dn5MGikr7I6om9QwWNBb+6MA0GCSqGSIb3DQEBCwUA ++A4IBAQAlL/o5EhDh5lNkjJkxPzFnX4xuf2/PtyepQmlE9f0/o1ICgUgHDy2Vs2r/ ++yCWyjKSl+APsd0AOuKJtxXm9s+TtHDRAysODUVhSQYLjWOZoWrpQ3d0bDhDHhy8S ++3AaqoE65tRXbZHZ7sSB95XpKgPARwn918y1Oe6aTEE8JvSV/cXVyHbng5RB2ddJP ++OFXUmh+/uLgbPQ/V4wPipTbWLDgA+D7XuyQVzCNvhPD4A8w0oBi/HxjjYMdPByoK ++LjVEmYCdw91c/h6Avm9AUK92XGXkNdiML+hBEY2YJQZghH1yz98hbqfm0x5b43GI ++Lk4ymn/K6HZMbtsrXfcWX8N3UmO5 ++-----END CERTIFICATE----- ++bioklubben.sf.se:443 + +commit 13e94fcea34623cfd5d3fa734ef1c855f190f7ba +Author: Robert Högberg +Date: Fri Oct 28 00:27:16 2016 +0200 + + Remove stray Villabanken logo + +diff --git a/assets/villabanken.psd b/assets/villabanken.psd +deleted file mode 100644 +index 2efedbb..0000000 +Binary files a/assets/villabanken.psd and /dev/null differ + +commit 94072b6173bdcbe1f96146cf1587cdc359ea3139 +Author: Johan Walles +Date: Thu Oct 27 06:19:09 2016 +0200 + + Fix empty catch blocks + + This should improve the Crashlytics statistics. + +diff --git a/app/src/main/java/com/liato/bankdroid/TimePreference.java b/app/src/main/java/com/liato/bankdroid/TimePreference.java +index 44586c5..fc13af3 100644 +--- a/app/src/main/java/com/liato/bankdroid/TimePreference.java ++++ b/app/src/main/java/com/liato/bankdroid/TimePreference.java +@@ -8,6 +8,8 @@ import android.util.AttributeSet; + import android.view.View; + import android.widget.TimePicker; +  ++import timber.log.Timber; ++ + public class TimePreference extends DialogPreference { +  + private int lastValue = 0; +@@ -64,6 +66,7 @@ public class TimePreference extends DialogPreference { + try { + val = Integer.parseInt(defaultValue.toString()); + } catch (NumberFormatException e) { ++ Timber.e(e, "TimePreference's defaultValue is not a number"); + } + } +  +diff --git a/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java b/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java +index 7e26254..f289d76 100644 +--- a/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java ++++ b/app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java +@@ -394,6 +394,7 @@ public class AutoRefreshService extends Service { + refreshWidgets = true; + db.disableBank(bank.getDbId()); + } catch (BankChoiceException e) { ++ Timber.w(e, "BankChoiceException"); + } catch (Exception e) { + Timber.e(e, "An unexpected error occurred while updating bank %s", bank.getShortName()); + } +diff --git a/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java b/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java +index 17c19ae..fd0011c 100644 +--- a/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java ++++ b/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java +@@ -395,6 +395,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider { + Timber.w(e, "Invalid credentials for bank %s", bank.getShortName()); + DBAdapter.disable(bank, context); + } catch (BankChoiceException e) { ++ Timber.w(e, "BankChoiceException"); + } catch (IOException e) { + if (NetworkUtils.isInternetAvailable()) { + Timber.e(e, "Could not update bank %s", bank.getShortName()); +diff --git a/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java b/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java +index b1a8888..9a7ea9c 100644 +--- a/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java ++++ b/app/src/main/java/com/liato/bankdroid/banking/BankFactory.java +@@ -99,7 +99,7 @@ public class BankFactory { + } + banks.add(bank); + } catch (BankException e) { +- //e.printStackTrace(); ++ Timber.w(e, "BankFactory.banksFromDb()"); + } + } + c.close(); +@@ -168,7 +168,8 @@ public class BankFactory { + account.setAliasfor(c.getString(c.getColumnIndex("aliasfor"))); + accounts.add(account); + } catch (ArrayIndexOutOfBoundsException e) { +- // Attempted to load an account without and ID, probably an old Avanza account. ++ // Probably an old Avanza account ++ Timber.w(e, "Attempted to load an account without an ID: %d", bankId); + } + } + c.close(); +diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java +index 2de42b7..87a0c1d 100644 +--- a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java ++++ b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java +@@ -236,10 +236,9 @@ public class ColorPickerPreference + } + mValue = color; + setPreviewColor(); +- try { +- getOnPreferenceChangeListener().onPreferenceChange(this, color); +- } catch (NullPointerException e) { +- ++ OnPreferenceChangeListener listener = getOnPreferenceChangeListener(); ++ if (listener != null) { ++ listener.onPreferenceChange(this, color); + } + } +  +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java +index 2c2e4ce..2ea759a 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java +@@ -142,7 +142,7 @@ public class Helpers { + .getMethod("overridePendingTransition", int.class, int.class); + method.invoke(activity, in, out); + } catch (Exception e) { +- // Can't change animation, so do nothing ++ Timber.w(e, "Can't change animation, so do nothing"); + } + } +  +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java +index 82ad171..496f9e4 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java +@@ -6,6 +6,8 @@ import java.lang.reflect.Field; + import java.util.HashMap; + import java.util.Map; +  ++import timber.log.Timber; ++ + public class LegacyBankHelper { +  + private static Map legacyProviderReferences; +@@ -39,7 +41,7 @@ public class LegacyBankHelper { + references.put(legacyId, reference); + legacyIds.put(reference, legacyId); + } catch(IllegalAccessException e) { +- //TODO log if provider could not be mapped. ++ Timber.e(e, "Provider could not be mapped"); + } + } + legacyProviderReferences = legacyIds; +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java +index b3c620f..fddf1bb 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java +@@ -42,6 +42,7 @@ import java.util.List; +  + import eu.nullbyte.android.urllib.CertificateReader; + import eu.nullbyte.android.urllib.Urllib; ++import timber.log.Timber; +  + public class Jojo extends Bank { +  +@@ -141,6 +142,7 @@ public class Jojo extends Bank { + } + } catch (IOException e) { + // Ignore and defaults to zero ++ Timber.w(e, "Getting Jojo card balance failed"); + } + return BigDecimal.ZERO; + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java +index d1ece28..6969afa 100644 +--- a/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java +@@ -130,10 +130,9 @@ public class Lansforsakringar extends Bank { + try { + is.close(); + } catch(IOException e) { +- // Ignore ++ Timber.w(e, "Closing JSON stream failed"); + } + } +- + } +  + private T readJsonValue(String url, String postData, Class valueType) +@@ -235,8 +234,7 @@ public class Lansforsakringar extends Bank { + } + account.setTransactions(transactions); + } catch (BankException e) { +- // No transactions for account if this fails. +- // readJsonValue will print the stack trace ++ Timber.e(e, "Failed updating Länsförsäkringar transactions"); + } +  + super.updateComplete(); +diff --git a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java +index 2a87b49..616084c 100644 +--- a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java ++++ b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java +@@ -46,6 +46,8 @@ import javax.net.ssl.SSLContext; + import javax.net.ssl.SSLSocket; + import javax.net.ssl.TrustManager; +  ++import timber.log.Timber; ++ + public class CertPinningSSLSocketFactory extends SSLSocketFactory { +  + private SSLContext sslcontext = null; +@@ -133,7 +135,9 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory { + // close the socket before re-throwing the exception + try { + sslsock.close(); +- } catch (Exception x) { /*ignore*/ } ++ } catch (Exception e) { ++ Timber.w(e, "Error closing SSL socket (ignored)"); ++ } + throw iox; + } + return sslsock; +diff --git a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java +index 4bb2e20..99d7338 100644 +--- a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java ++++ b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java +@@ -5,9 +5,6 @@ import android.content.Context; + import java.io.BufferedInputStream; + import java.io.IOException; + import java.io.InputStream; +-import java.security.KeyStore; +-import java.security.KeyStoreException; +-import java.security.NoSuchAlgorithmException; + import java.security.cert.Certificate; + import java.security.cert.CertificateException; + import java.security.cert.CertificateFactory; +@@ -21,7 +18,7 @@ public class CertificateReader { +  + public static Certificate[] getCertificates(Context context, + int... rawResCerts) { +- List certificates = new ArrayList(); ++ List certificates = new ArrayList<>(); + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + for (int resId : rawResCerts) { +@@ -43,26 +40,4 @@ public class CertificateReader { + } + return certificates.toArray(new Certificate[certificates.size()]); + } +- +- public static ClientCertificate getClientCertificate(Context context, int rawResCert, +- String password) { +- InputStream is = null; +- try { +- KeyStore keyStore = KeyStore.getInstance("PKCS12"); +- is = new BufferedInputStream(context.getResources().openRawResource(rawResCert)); +- keyStore.load(is, password.toCharArray()); +- return new ClientCertificate(keyStore, password); +- } catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException e) { +- Timber.w(e, "Failed to get client certificate"); +- } finally { +- if (is != null) { +- try { +- is.close(); +- } catch (IOException e) { +- //noop +- } +- } +- } +- return null; +- } + } +diff --git a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java +index 803be41..2636816 100644 +--- a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java ++++ b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java +@@ -16,6 +16,7 @@ +  + package eu.nullbyte.android.urllib; +  ++import com.liato.bankdroid.legacy.BuildConfig; + import com.liato.bankdroid.legacy.R; + import com.liato.bankdroid.utils.ExceptionUtils; +  +@@ -65,8 +66,6 @@ import org.apache.http.util.EntityUtils; +  + import android.content.Context; + import android.content.SharedPreferences; +-import android.content.pm.PackageInfo; +-import android.content.pm.PackageManager; + import android.content.res.Configuration; + import android.os.Build; + import android.preference.PreferenceManager; +@@ -396,22 +395,12 @@ public class Urllib { +  + private String createUserAgentString() { + String appName = mContext.getString(R.string.app_name); +- String packageName = ""; +- String appVersion = ""; +- +- try { +- PackageInfo packageInfo = mContext.getPackageManager() +- .getPackageInfo(mContext.getPackageName(), PackageManager.GET_CONFIGURATIONS); +- packageName = packageInfo.packageName; +- appVersion = packageInfo.versionName; +- } catch (PackageManager.NameNotFoundException ignore) { +- } +  + Configuration config = mContext.getResources().getConfiguration(); + return String + .format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %10$s Build/%7$s; %8$s) %9$s %10$s" + , appName +- , appVersion ++ , BuildConfig.VERSION_NAME + , System.getProperty("os.name", "Linux") + , Build.VERSION.RELEASE + , config.locale.getLanguage().toLowerCase() +diff --git a/config/quality/pmd/pmd-ruleset.xml b/config/quality/pmd/pmd-ruleset.xml +index 9dbddb2..3109e6b 100644 +--- a/config/quality/pmd/pmd-ruleset.xml ++++ b/config/quality/pmd/pmd-ruleset.xml +@@ -39,7 +39,6 @@ +  +  +  +-  +  +  +  +@@ -69,7 +68,6 @@ +  +  +  +-  +  +  +  + +commit 8e477f6eef16910b02b85f66f7a1402a30087bb2 (tag: v1.9.11) +Author: Mathias Åhsberg +Date: Wed Oct 26 21:12:58 2016 +0200 + + Create release v1.9.11 + +diff --git a/CHANGELOG b/CHANGELOG +index 5d85914..fa02959 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,10 +1,22 @@ + Please view this file on the master branch, on stable branches it's out of date. +  +-Not yet released ++v1.9.11 (2016-10-26) + * Warn about disabled banks in the transactions list + * Show warning text about disabled banks in the main activity +-* Remove TrustBuddy since they're no longer in business +-* Remove unused class MobilbankenBase ++* Removes support for TrustBuddy since they're no longer in business ++* Removes support for Audi since they require MobiltBankId ++* Removes support for VolvoFinans since they require MobiltBankId ++* Removes support for EasyCard since they require MobiltBankId ++* Removes support for Preem since they require MobiltBankId ++* Removes support for ResursBank since they require MobiltBankId ++* Removes support for Seat since they require MobiltBankId ++* Removes support for Shell since they require MobiltBankId ++* Removes support for Skoda since they require MobiltBankId ++* Removes support for SupremeCard since they require MobiltBankId ++* Removes support for Villabanken since they require MobiltBankId ++* Removes support for Volkswagen since they require MobiltBankId ++* Merged NordnetDirekt with Nordnet. ++* Merged AvanzaMini with Avanza. +  + v1.9.10.10 (2016-10-17) + * Fixes crash for Amex + +commit d42dea167a24ae90c840fcb7d6c0cb386f4db441 +Author: Mathias Åhsberg +Date: Wed Oct 26 20:53:40 2016 +0200 + + Upgrade gradle build tools to latest stable. + +diff --git a/app/build.gradle b/app/build.gradle +index da46be5..aafa141 100644 +--- a/app/build.gradle ++++ b/app/build.gradle +@@ -7,8 +7,12 @@ buildscript { + } +  + dependencies { +- classpath 'io.fabric.tools:gradle:1.+' + classpath "org.ajoberstar:gradle-git:1.5.1" ++ ++ // The dynamic version here is explicitly recommended by the Crashlytics docs: ++ // https://docs.fabric.io/android/fabric/integration.html#modify-build-gradle ++ //noinspection GradleDynamicVersion ++ classpath 'io.fabric.tools:gradle:1.+' + } + } + apply plugin: 'com.android.application' +@@ -83,7 +87,7 @@ dependencies { + compile project(':bankdroid-core') + compile 'com.jakewharton:butterknife:6.1.0' + compile 'com.jakewharton.timber:timber:4.3.1' +- compile "com.android.support:appcompat-v7:24.1.1" ++ compile "com.android.support:appcompat-v7:24.2.1" + compile 'com.google.collections:google-collections:1.0' + compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') { + transitive = true; +diff --git a/bankdroid-legacy/build.gradle b/bankdroid-legacy/build.gradle +index 943e966..2cda778 100644 +--- a/bankdroid-legacy/build.gradle ++++ b/bankdroid-legacy/build.gradle +@@ -27,14 +27,14 @@ android { + dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile project(':bankdroid-interface') +- compile 'com.android.support:appcompat-v7:24.1.1' ++ compile 'com.android.support:appcompat-v7:24.2.1' + compile 'com.jakewharton.timber:timber:4.3.1' + compile ('org.apache.commons:commons-io:1.3.2') {exclude module: 'commons-io'} + compile 'org.jsoup:jsoup:1.7.3' + compile 'com.fasterxml.jackson.core:jackson-core:2.1.0' + compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0' + compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0' +- compile('org.simpleframework:simple-xml:2.7.+') { ++ compile('org.simpleframework:simple-xml:2.7.1') { + exclude module: 'stax' + exclude module: 'stax-api' + exclude module: 'xpp3' +diff --git a/build.gradle b/build.gradle +index 8f0f520..43763d6 100644 +--- a/build.gradle ++++ b/build.gradle +@@ -5,7 +5,7 @@ buildscript { + jcenter() + } + dependencies { +- classpath 'com.android.tools.build:gradle:2.2.1' ++ classpath 'com.android.tools.build:gradle:2.2.2' +  + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files +diff --git a/config/quality/lint/lint.xml b/config/quality/lint/lint.xml +index 8f68763..8195ce2 100644 +--- a/config/quality/lint/lint.xml ++++ b/config/quality/lint/lint.xml +@@ -1,5 +1,8 @@ +  +  ++  ++  ++ +  +  +  +@@ -12,8 +15,6 @@ +  +  +  +-  +-  +  +  +  +diff --git a/tools/update-suppressions.sh b/tools/update-suppressions.sh +index 363091b..4148ea6 100755 +--- a/tools/update-suppressions.sh ++++ b/tools/update-suppressions.sh +@@ -21,6 +21,9 @@ function set_lint_suppressions() { + cat > ${LINT_XML} << EOF +  +  ++  ++  ++ +  +  + EOF + +commit f999a2aa8ded6f873c6ab8e8502255e3f7409675 +Author: Johan Walles +Date: Tue Oct 25 21:31:33 2016 +0200 + + Fake Urllib exception stack traces + + In Crashlytics we have a lot of stack traces originating in Urllib. + + With this change in place, those exceptions will appear to be + originating from whatever bank tried to call Urllib, and it will be + much more obvious in Crashlytics which banks actually have the most + problems. + +diff --git a/bankdroid-legacy/build.gradle b/bankdroid-legacy/build.gradle +index a5dd3f4..943e966 100644 +--- a/bankdroid-legacy/build.gradle ++++ b/bankdroid-legacy/build.gradle +@@ -39,4 +39,7 @@ dependencies { + exclude module: 'stax-api' + exclude module: 'xpp3' + } ++ ++ testCompile 'junit:junit:4.12' ++ testCompile 'org.mockito:mockito-core:1.10.19' + } +diff --git a/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java +new file mode 100644 +index 0000000..e61097b +--- /dev/null ++++ b/bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java +@@ -0,0 +1,67 @@ ++package com.liato.bankdroid.utils; ++ ++import java.lang.reflect.InvocationTargetException; ++import java.util.Arrays; ++ ++import timber.log.Timber; ++ ++public class ExceptionUtils { ++ private static final String PREFIX = "com.liato.bankdroid."; ++ ++ /** ++ * Take an exception thrown and make it look like it came from Bankdroid. ++ *

 ++ * Specifically, if Urllib.java, called by Bankdroid code, throws an exception, ++ * rewrite the exception so that it appears as if it was thrown from the ++ * Bankdroid method calling Urllib, but caused by the original Exception. ++ */ ++ public static T bankdroidifyException(T exception) { ++ StackTraceElement[] bankdroidifiedStacktrace = ++ bankdroidifyStacktrace(exception.getStackTrace()); ++ if (bankdroidifiedStacktrace.length == exception.getStackTrace().length) { ++ // Unable to bankdroidify stacktrace, never mind ++ return exception; ++ } ++ ++ T returnMe; ++ try { ++ returnMe = (T)exception.getClass().getConstructor(String.class) ++ .newInstance(exception.getMessage()); ++ } catch (InstantiationException e) { ++ Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass()); ++ return exception; ++ } catch (InvocationTargetException e) { ++ Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass()); ++ return exception; ++ } catch (IllegalAccessException e) { ++ Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass()); ++ return exception; ++ } catch (NoSuchMethodException e) { ++ Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass()); ++ return exception; ++ } ++ ++ returnMe.initCause(exception); ++ ++ returnMe.setStackTrace(bankdroidifiedStacktrace); ++ ++ return returnMe; ++ } ++ ++ /** ++ * Remove all initial non-Bankdroid frames from a stack. ++ * ++ * @return A copy of rawStack but with the initial non-Bankdroid frames removed ++ */ ++ private static StackTraceElement[] bankdroidifyStacktrace(final StackTraceElement[] rawStack) { ++ for (int i = 0; i < rawStack.length; i++) { ++ StackTraceElement stackTraceElement = rawStack[i]; ++ if (stackTraceElement.getClassName().startsWith(PREFIX)) { ++ return Arrays.copyOfRange(rawStack, i, rawStack.length); ++ } ++ } ++ ++ // No Bankdroid stack frames found, never mind ++ return rawStack; ++ } ++} +diff --git a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java +index 2cc5e36..803be41 100644 +--- a/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java ++++ b/bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java +@@ -17,6 +17,7 @@ + package eu.nullbyte.android.urllib; +  + import com.liato.bankdroid.legacy.R; ++import com.liato.bankdroid.utils.ExceptionUtils; +  + import org.apache.http.ConnectionReuseStrategy; + import org.apache.http.HttpEntity; +@@ -146,7 +147,11 @@ public class Urllib { + } +  + public String open(String url) throws ClientProtocolException, IOException { +- return this.open(url, new ArrayList()); ++ try { ++ return this.open(url, new ArrayList()); ++ } catch (IOException e) { ++ throw ExceptionUtils.bankdroidifyException(e); ++ } + } +  + public String post(String url) throws ClientProtocolException, IOException { +@@ -155,7 +160,11 @@ public class Urllib { +  + public String open(String url, List postData) + throws ClientProtocolException, IOException { +- return open(url, postData, false); ++ try { ++ return open(url, postData, false); ++ } catch (IOException e) { ++ throw ExceptionUtils.bankdroidifyException(e); ++ } + } +  + public String open(String url, List postData, boolean forcePost) +@@ -171,7 +180,11 @@ public class Urllib { + boolean forcePost) throws ClientProtocolException, IOException { + HttpEntity entity = (postData == null || postData.isEmpty()) && !forcePost ? null + : new UrlEncodedFormEntity(postData, this.charset); +- return openAsHttpResponse(url, entity, forcePost); ++ try { ++ return openAsHttpResponse(url, entity, forcePost); ++ } catch (IOException e) { ++ throw ExceptionUtils.bankdroidifyException(e); ++ } + } +  + public HttpResponse openAsHttpResponse(String url, boolean forcePost) +@@ -181,10 +194,14 @@ public class Urllib { +  + public HttpResponse openAsHttpResponse(String url, HttpEntity entity, boolean forcePost) + throws ClientProtocolException, IOException { +- if ((entity == null) && !forcePost) { +- return openAsHttpResponse(url, entity, HttpMethod.GET); +- } else { +- return openAsHttpResponse(url, entity, HttpMethod.POST); ++ try { ++ if ((entity == null) && !forcePost) { ++ return openAsHttpResponse(url, entity, HttpMethod.GET); ++ } else { ++ return openAsHttpResponse(url, entity, HttpMethod.POST); ++ } ++ } catch (IOException e) { ++ throw ExceptionUtils.bankdroidifyException(e); + } + } +  +@@ -273,8 +290,12 @@ public class Urllib { +  + public InputStream openStream(String url, String postData, boolean forcePost) + throws ClientProtocolException, IOException { +- return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null, +- forcePost); ++ try { ++ return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null, ++ forcePost); ++ } catch (IOException e) { ++ throw ExceptionUtils.bankdroidifyException(e); ++ } + } +  + public InputStream openStream(String url, HttpEntity postData, boolean forcePost) +diff --git a/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java b/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java +new file mode 100644 +index 0000000..803dc5f +--- /dev/null ++++ b/bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java +@@ -0,0 +1,41 @@ ++package com.liato.bankdroid.utils; ++ ++import org.junit.Assert; ++import org.junit.Test; ++ ++import eu.nullbyte.android.urllib.Urllib; ++ ++public class ExceptionUtilsTest { ++ @Test ++ @SuppressWarnings("PMD") // This is for the stack trace printing, we really want to do it here ++ public void bankdroidifyException() throws Exception { ++ Exception raw = null; ++ try { ++ new Urllib(null); ++ Assert.fail("Exception expected"); ++ } catch (NullPointerException e) { ++ raw = e; ++ } ++ ++ // Print stack traces, useful if the tests fail ++ System.err.println("Before:"); ++ raw.printStackTrace(); ++ ++ System.err.println(); ++ System.err.println("After:"); ++ Exception bankdroidified = ExceptionUtils.bankdroidifyException(raw); ++ bankdroidified.printStackTrace(); ++ ++ Assert.assertFalse("Test setup: Top frame of initial exception shouldn't be in Bankdroid", ++ raw.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid.")); ++ ++ Assert.assertTrue("Top frame of bankdroidified exception should be in Bankdroid", ++ bankdroidified.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid.")); ++ ++ // Verify that e is the cause of bankdroidified ++ Assert.assertSame(raw, bankdroidified.getCause()); ++ ++ // Verify that re-bankdroidifying is a no-op ++ Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified)); ++ } ++} + +commit b75ce9788c33d9d6ef70bfe6fbb3fae8647f9232 +Author: Johan Walles +Date: Thu Oct 20 20:04:51 2016 +0200 + + Show warning for disabled banks + + Before this change, in the banks list in the main UI, disabled banks + were marked with a warning icon. + + This change adds to that warning icon a text describing what's actually + going on and what the user can do about it. + + Before starting to work on this I fixed all Android Lint reported + warnings in the .java and .xml files I had to change, and re-enabled + those warnings. + + One of those warnings was about using sp rather than dp for text. I + suppressed that warning for the widgets, but heeded it in all other + places. This results in a UI that better adapts to the user's font size + preferences. + + The UI changes I have tested with both "small" and "huge" font size, + and it looks fine. + +diff --git a/CHANGELOG b/CHANGELOG +index 858714a..5d85914 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. +  + Not yet released + * Warn about disabled banks in the transactions list ++* Show warning text about disabled banks in the main activity + * Remove TrustBuddy since they're no longer in business + * Remove unused class MobilbankenBase +  +diff --git a/app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java b/app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java +index af4e6ec..9413be0 100644 +--- a/app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java ++++ b/app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java +@@ -25,6 +25,7 @@ import android.content.Context; + import android.content.SharedPreferences; + import android.graphics.Color; + import android.preference.PreferenceManager; ++import android.support.annotation.Nullable; + import android.view.LayoutInflater; + import android.view.View; + import android.view.ViewGroup; +@@ -42,50 +43,30 @@ public class AccountsAdapter extends BaseAdapter { +  + public final static int VIEWTYPE_EMPTY = 2; +  +- SharedPreferences prefs; ++ private final SharedPreferences prefs; +  + private ArrayList banks; +  +- private Context context; +- +- private LayoutInflater inflater; ++ private final LayoutInflater inflater; +  + private boolean showHidden; +  + public AccountsAdapter(Context context, boolean showHidden) { +- this.context = context; +- this.banks = new ArrayList(); +- inflater = LayoutInflater.from(this.context); ++ this.banks = new ArrayList<>(); ++ inflater = LayoutInflater.from(context); + this.showHidden = showHidden; + prefs = PreferenceManager.getDefaultSharedPreferences(context); + } +  +- public void addGroup(Bank bank) { +- banks.add(bank); +- } +- + public void setGroups(ArrayList banks) { + this.banks = banks; +- /*for (Bank b : this.banks) { +- ArrayList as = b.getAccounts(); +- for (Account a : as) { +- if (a.isHidden() && !showHidden) { +- as.remove(a); +- } +- +- } +- }*/ +- } +- +- public boolean isShowHidden() { +- return showHidden; + } +  + public void setShowHidden(boolean showHidden) { + this.showHidden = showHidden; + } +  +- public View newBankView(Bank bank, ViewGroup parent, View convertView) { ++ private View newBankView(Bank bank, ViewGroup parent, View convertView) { + if (convertView == null) { + convertView = inflater.inflate(R.layout.listitem_accounts_group, parent, false); + } +@@ -103,16 +84,16 @@ public class AccountsAdapter extends BaseAdapter { + bank.getDecimalFormatter(), + false)); + icon.setImageResource(bank.getImageResource()); +- ImageView warning = (ImageView) convertView.findViewById(R.id.imgWarning); ++ View warning = convertView.findViewById(R.id.txtDisabledWarningX); + if (bank.isDisabled()) { + warning.setVisibility(View.VISIBLE); + } else { +- warning.setVisibility(View.INVISIBLE); ++ warning.setVisibility(View.GONE); + } + return convertView; + } +  +- public View newAccountView(Account account, ViewGroup parent, View convertView) { ++ private View newAccountView(Account account, ViewGroup parent, View convertView) { + if ((account.isHidden() && !showHidden) || account.getBank().getHideAccounts()) { + return convertView == null ? inflater.inflate(R.layout.empty, parent, false) + : convertView; +@@ -158,6 +139,7 @@ public class AccountsAdapter extends BaseAdapter { + } +  + @Override ++ @Nullable + public Object getItem(int position) { + if (banks.size() == 0) { + return null; +@@ -188,19 +170,21 @@ public class AccountsAdapter extends BaseAdapter { + } +  + @Override ++ @Nullable + public View getView(int position, View convertView, ViewGroup parent) { + Object item = getItem(position); + if (item == null) { + return null; + } + if (item instanceof Bank) { +- return newBankView((Bank) item, parent, convertView); ++ return newBankView((Bank)item, parent, convertView); + } else if (item instanceof Account) { +- return newAccountView((Account) item, parent, convertView); ++ return newAccountView((Account)item, parent, convertView); + } + return null; + } +  ++ @Override + public boolean isEnabled(int position) { + if (getItemViewType(position) == VIEWTYPE_EMPTY) { + return false; +@@ -208,7 +192,6 @@ public class AccountsAdapter extends BaseAdapter { + return true; + } +  +- + @Override + public int getViewTypeCount() { + return 3; +@@ -220,8 +203,9 @@ public class AccountsAdapter extends BaseAdapter { + if (item instanceof Bank) { + return VIEWTYPE_BANK; + } else { +- if ((((Account) item).isHidden() && !showHidden) || +- ((Account) item).getBank().getHideAccounts()) { ++ final Account account = (Account)item; ++ if ((account.isHidden() && !showHidden) || ++ account.getBank().getHideAccounts()) { + return VIEWTYPE_EMPTY; + } + } +diff --git a/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java b/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java +index fb3ddf2..17c19ae 100644 +--- a/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java ++++ b/app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java +@@ -166,7 +166,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider { +  + //intent = new Intent(context, AccountsActivity.class); + pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); +- views.setOnClickPendingIntent(R.id.imgWarning, pendingIntent); ++ views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent); +  + intent = new Intent(context, WidgetService.class); + intent.setAction(AutoRefreshService.BROADCAST_WIDGET_REFRESH); +diff --git a/app/src/main/res/layout-land/choose_lock_pattern.xml b/app/src/main/res/layout-land/choose_lock_pattern.xml +index e32dc0a..a98f3a9 100644 +--- a/app/src/main/res/layout-land/choose_lock_pattern.xml ++++ b/app/src/main/res/layout-land/choose_lock_pattern.xml +@@ -1,10 +1,10 @@ +  +- +  +  ++ android:text="@string/lockpattern_confirm_button_text" ++ android:maxLines="1"/> +  +  +  +@@ -58,8 +58,8 @@ + android:layout_above="@id/footerRightButton" + android:layout_centerHorizontal="true" + android:ellipsize="marquee" +- android:singleLine="true" +- android:text="@string/lockpattern_restart_button_text" /> ++ android:text="@string/lockpattern_restart_button_text" ++ android:maxLines="1"/> +  +  +  +diff --git a/app/src/main/res/layout-land/dialog_color_picker.xml b/app/src/main/res/layout-land/dialog_color_picker.xml +index 7f63aff..fc0caa3 100644 +--- a/app/src/main/res/layout-land/dialog_color_picker.xml ++++ b/app/src/main/res/layout-land/dialog_color_picker.xml +@@ -4,9 +4,9 @@ + 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. +@@ -14,30 +14,31 @@ + limitations under the License. + --> +  +- +-  ++ +  +-  ++ +  +-  ++ +  +-  ++ +  +-  ++ tools:ignore="HardcodedText"/> ++ +  +-  ++ +  +-  +- +\ No newline at end of file ++ ++ +diff --git a/app/src/main/res/layout/about.xml b/app/src/main/res/layout/about.xml +index 82dda73..4faa0a1 100644 +--- a/app/src/main/res/layout/about.xml ++++ b/app/src/main/res/layout/about.xml +@@ -26,14 +26,14 @@ + android:id="@+id/imgTextLogo" + android:layout_marginTop="20dp" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_centerHorizontal="true"> +  +-  ++  +  +  ++ android:layout_width="fill_parent" android:textSize="20sp"> +  +