Search This Blog

21 April 2016

Don't be clever


I remember reading a concept in a book, but it seems that I can't find which book it was. But while I was reading some of the Golang documentation I came across something that is in the exact same spirit. Here it is from the Golang Memory Model - http://golang.org/ref/mem:

"If you must read the rest of this document to understand the behavior of your program, you are being too clever.
Don't be clever."

18 February 2016

Remote work

    One of the things that gets cited as an advantage to be physically in the office is collaboration. You get to walk to someone’s desk, meet with people face to face and chat, and discuss things. What actually happens is that there are always people “collaborating” - talking, most often near you, there is a constant "buzz"(noise) in the open space like it is a factory floor. Put on headphones, or ear muffs, you would say. So be in the office to be near people and in the same time think of ways to isolate from them. Make meetings only in dedicated places, you say. So be in the office to have the freedom to walk to anyone and collaborate, but forbid this and cripple it by requiring meetings be held in dedicated areas instead.
    What in our connected world prevents us from collaborating regardless of physical location. We have lots and lots of tools to connect, meet, talk, chat, collaborate all we need is an internet connection and it doesn’t matter where each of our team members is physically located. When you are collaborating with a person you are not interfering the work of lots of others that don’t need your noise and distraction. We could be at home, at a coffee shop, at the park, you name it, just pick the place where you could be most productive and that is your office.
    You could check out a book “Remote office not required” by 37signals:


14 February 2016

Native mobile applications with cross content




What is the right format for a mobile application? Some would insist on native only all the way, every day. Some would go cross platform in an attempt to save time and reuse development resources.
We would argue firmly against cross platform development. It doesn't matter if it is HTML/Javascript or C#/Xamarin (some of the most frequently used technologies for cross platform development). In the case of HTML/Javascript we would say that one would be far better off with just a mobile friendly/responsive web app. In the case of C# it is just plain doing it wrong, because it is almost impossible to have a C# developer that would be familiar with the mobile's platform SDK and almost no experience when it comes to the UI, because it is developed in the native platforms technique.
The way to go is definitely native. But what if you have a big amount of content that can be displayed in the same way for multiple mobile platforms. Then just use HTML pages for that content. We would have a native mobile application that uses HTML for part of the content (something that we like to call cross platform content). We could call it a custom cross platform solution/technology, because it is, and in the same time it is more appropriate to think of it as a native application with some (little or a lot) of HTML content with or without the capability to interact with the native code (depending if the solution needs it or not), because this is the intent purpose of this solution.
This is the sweet spot for complete set of capabilities on the device and time and resource savings.

Here are some native applications which can be used for templates where a custom HTML5 content can be added:

07 February 2016

SSL interception - Man in the middle attack

How to check visually for the security of a site we are visiting
When we open a site the address bar of the browser shows if the connection is secure (SSL). Usually there is a green padlock. If we click on it we can get detailed information of the SSL certificate that is used by the web site. If the SSL is an Extended Verification Certificate there is also an additional area that is green next to the padlock to get a quick visual indication that the site uses an EV certificate.
If we are using a connection that is passing through a proxy it can intercept the connection and start the communication with the site we request on our behalf, read all of the contents, resign it with a forged certificate and send it to us. Normally the browser won’t accept that certificate, because it has not been signed by the proper CA. But if someone has access to the machine we are using, he may have installed an additional CA in the browser and that CA is the one that is used to sign the forged certificate and it is trusted by our browser(it got installed in our browser by that person) and we would see a green padlock in the browser’s address bar. But there is no way that we would see the additional green area in the browser address field. If we know that a domain is using an EV Certificate, this can be used as a quick visual check to alert us that there is something wrong with the certificate.






Comparing the certificate fingerprint.
To verify that the certificate that a site is presenting is the actual certificate that was issued to that domain we need to check the certificate fingerprint. We can do that if for example we access the same site from another location/network which we know is secure and take the certificate fingerprint and compare it with the one we get from the other location/network, or we can use a site like 

which can provide us with the fingerprint.
In the browser we can click on the padlock (in the address bar) and select to see more information for the used certificate:



 In that window we can select to see the certificate and find out what the fingerprint is:




28 December 2015

Shadows for Android applications. Pre Lollipop and post Lollipop (with all API levels)

ShadowViewDecorator:

https://github.com/ektodorov/ShadowViewDecorator

is a project that provides drop shadows for views in Android. It does not use the new APIs introduced in Android Lollipop, which means it can be used in an Android project regardless of the minimum API level used by the application.
There are methods with extensive parameters in the ShadowViewDecorator. We have taken that decision so that the shadow is completely configurable and not just a single implementation of a shadow that we think is appropriate. Every user can make the adjustments that are most appropriate in a use case.
We have provided methods that use CSS box shadow style parameters and we expect these methods to be the most used. This way we don't have to work with all the parameters of a shadow every time. We can use one of the many available online tools for previewing a CSS box shadow and then apply the same settings in an Android application. This also provides us with a quick way to change settings during development without the need to fiddle with graphic assets, because with ShadowViewDecorator the change will be only in code (a few parameters).

16 February 2015

Drop shadows in Android pre Lollipop

Android Lollipop arrived and with it so did "Material" design. One of the new things is that views can cast shadows according to their elevation property. We wanted to simulate this in previous Android OS versions and we went ahead and made a Shadow View Decorator. It draws shadows and glow around views. It also has a compatibility methods which will use the elevation property if the application is running on Android 5+.

Take a look on github:

https://github.com/ektodorov/ShadowViewDecorator

08 February 2015

Java Box Blur (code for Android)

We will quickly cover how to do box blur in Java.
To create a blur effect on an image we have to average a pixel with the data from its neighboring pixels. How much pixels we have to average depends on how big of a blur we want. Most of the time the size of the blur is called a radius, because we think of the area of pixels we want to cover as a circle.
For example if we want a blur with size 1:

1 1 1
1 2 1
1 1 1

"2" marks the location of the current pixel and "1"s mark the position of its neighbors.
One way to get the average of all these pixels is to add their values and then divide that value to the count of the pixels:

(1 + 1 + 1 + 1 + 2 + 1 + 1 + 1 + 1) / 9 = averageValue

Then we set pixel "2" to the "averageValue".

Another way is to use what is called a convolution kernel. For our blur, the kernel would be:

1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9

It is a matrix with the size of our blur, and we can imagine we are moving it over every pixel of our image and multiplying the pixel color values with the corresponding kernel value (here they are all the same, and this is called a box blur. In Gaussian blur, the center of the kernel has more weight than the other parts).
For our example we will multiply all the pixels with 1/9 and will assign as color value for pixel at position marked with "2":
1*1/9 + 1*1/9 + 1*1/9 + 1*1/9 + 2*1/9 + 1*1/9 + 1*1/9 + 1*1/9 + 1*1/9

If we use a bigger radius for the blur we need a bigger kernel. What stays the same is that when we add all values of the kernel together they must add up to 1.
1/9 + 1/9 + 1/9 + 1/9 + 1/9 + 1/9 + 1/9 + 1/9 + 1/9 = 9/9 = 1

Kernel with radius 3, which gives us a 7x7 matrix:
1/49 + 1/49 ... = 49/49 = 1

Instead of doing a 2D calculation we can split the kernel into two 1D kernels
1/9 1/9 1/9 and 1/9 and multiply each pixel with these kernels separately.
                        1/9
                        1/9










This way we would gain a little bit of speed.
Another way of speeding up is scaling down the image before we apply blur. And then scale it back up or just draw it in a bigger rectangle.
If we are blurring a grey scale image we don't need to multiply each color channel, because they all are the same. Just multiply the alpha and one of the color channels. (we have a note on that in the code).

And here is our code:
1:  public static Bitmap boxBlur(Bitmap aBitmap, int aSize, boolean aCreateNewBitmap) 
2:       { 
3:            float kernel = 1.0f / ((aSize * 2) + 1); 
4:            Bitmap bitmap = null; 
5:            if(aCreateNewBitmap) { 
6:                 bitmap = Bitmap.createBitmap(aBitmap.getWidth(), aBitmap.getHeight(), Config.ARGB_8888); 
7:            } else { 
8:                 bitmap = aBitmap; 
9:            } 
10:             
11:            Rect rectSrc = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 
12:            Rect rectDest = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 
13:             
14:            Canvas canvas = new Canvas(bitmap); 
15:             
16:            //box blur 
17:            int colsCount = bitmap.getWidth(); 
18:            int rowsCount = bitmap.getHeight(); 
19:             
20:            for(int row = 0; row < rowsCount; row++) { 
21:                 for(int col = 0; col < colsCount; col++) { 
22:                      float sumAlpha = 0; 
23:                      float sumRed = 0; 
24:                      float sumGreen = 0; 
25:                      float sumBlue = 0; 
26:                      for(int k = col - aSize; k <= col + aSize; k++) { 
27:                           int x = k; 
28:                           if(x < 0) {x = Math.abs(x);} 
29:                           if(x >= colsCount) {x = (colsCount - 1) - (x - colsCount);} 
30:                            
31:                           int pixel = bitmap.getPixel(x, row); 
32:                            
33:                           int alpha = Color.alpha(pixel); 
34:                           int red = Color.red(pixel); 
35:                           int green = Color.green(pixel); 
36:                           int blue = Color.blue(pixel); 
37:                                 
38:                           float resultAlpha = (float)alpha * kernel; 
39:                           float resultRed = (float)red * kernel; 
40:                           float resultGreen = (float)green * kernel; 
41:                           float resultBlue = (float)blue * kernel; 
42:                                 
43:                           sumAlpha += resultAlpha; 
44:                           sumRed += resultRed; 
45:                           sumGreen += resultGreen; 
46:                           sumBlue += resultBlue; 
47:                      } 
48:                      bitmap.setPixel(col, row, Color.argb((int)sumAlpha, (int)sumRed, (int)sumGreen, (int)sumBlue)); 
49:                 } 
50:            } 
51:             
52:            for(int col = 0; col < colsCount; col++) { 
53:                 for(int row = 0; row < rowsCount; row++) { 
54:                      float sumAlpha = 0; 
55:                      float sumRed = 0; 
56:                      float sumGreen = 0; 
57:                      float sumBlue = 0; 
58:                      for(int k = row - aSize; k <= row + aSize; k++) { 
59:                           int y = k; 
60:                           if(y < 0) {y = Math.abs(y);} 
61:                           if(y >= rowsCount) {y = (rowsCount - 1) - (y - rowsCount);} 
62:                            
63:                           int pixel = bitmap.getPixel(col, y); 
64:                            
65:                           int alpha = Color.alpha(pixel); 
66:                           int red = Color.red(pixel); 
67:                           int green = Color.green(pixel); 
68:                           int blue = Color.blue(pixel); 
69:                                 
70:                           float resultAlpha = (float)alpha * kernel; 
71:                           float resultRed = (float)red * kernel; 
72:                           float resultGreen = (float)green * kernel; 
73:                           float resultBlue = (float)blue * kernel; 
74:                                 
75:                           sumAlpha += resultAlpha; 
76:                           sumRed += resultRed; 
77:                           sumGreen += resultGreen; 
78:                           sumBlue += resultBlue; 
79:                      } 
80:                      bitmap.setPixel(col, row, Color.argb((int)sumAlpha, (int)sumRed, (int)sumGreen, (int)sumBlue)); 
81:                 } 
82:            } 
83:                       
84:            canvas.drawBitmap(bitmap, rectSrc, rectDest, null); 
85:            return bitmap; 
86:       }