Analysis on IBinder for Android

current situation

Desc of IBinder

Base interface for a remotable object, the core part of a lightweight remote procedure call mechanism designed for high performance when performing in-process and cross-process calls. This interface describes the abstract protocol for interacting with a remotable object. Do not implement this interface directly, instead extend from Binder.

The key IBinder API is transact() matched by Binder.onTransact(). These methods allow you to send a call to an IBinder object and receive a call coming in to a Binder object, respectively. This transaction API is synchronous, such that a call to transact() does not return until the target has returned from Binder.onTransact(); this is the expected behavior when calling an object that exists in the local process, and the underlying inter-process communication (IPC) mechanism ensures that these same semantics apply when going across processes.

The data sent through transact() is a Parcel, a generic buffer of data that also maintains some meta-data about its contents. The meta data is used to manage IBinder object references in the buffer, so that those references can be maintained as the buffer moves across processes. This mechanism ensures that when an IBinder is written into a Parcel and sent to another process, if that other process sends a reference to that same IBinder back to the original process, then the original process will receive the same IBinder object back. These semantics allow IBinder/Binder objects to be used as a unique identity (to serve as a token or for other purposes) that can be managed across processes.

The system maintains a pool of transaction threads in each process that it runs in. These threads are used to dispatch all IPCs coming in from other processes. For example, when an IPC is made from process A to process B, the calling thread in A blocks in transact() as it sends the transaction to process B. The next available pool thread in B receives the incoming transaction, calls Binder.onTransact() on the target object, and replies with the result Parcel. Upon receiving its result, the thread in process A returns to allow its execution to continue. In effect, other processes appear to use as additional threads that you did not create executing in your own process.

The Binder system also supports recursion across processes. For example if process A performs a transaction to process B, and process B while handling that transaction calls transact() on an IBinder that is implemented in A, then the thread in A that is currently waiting for the original transaction to finish will take care of calling Binder.onTransact() on the object being called by B. This ensures that the recursion semantics when calling remote binder object are the same as when calling local objects.

Analysis of IBinder

Source of IBinder

IBinder is a interface is not a Controller or a type of View.

It has som abstract methods like dump, transact etc. as follows:

  • abstract void dump(FileDescriptor fd, String[] args)
    Print the object’s state into the given stream.
  • abstract void dumpAsync(FileDescriptor fd, String[] args)
    Like dump(FileDescriptor, String[]) but always executes asynchronously.
  • abstract String getInterfaceDescriptor()
    Get the canonical name of the interface supported by this binder.
  • abstract boolean isBinderAlive()
    Check to see if the process that the binder is in is still alive.
  • abstract void linkToDeath(IBinder.DeathRecipient recipient, int flags)
    Register the recipient for a notification if this binder goes away.
  • abstract boolean pingBinder()
    Check to see if the object still exists.
  • abstract IInterface queryLocalInterface(String descriptor)
    Attempt to retrieve a local implementation of an interface for this Binder object.
  • abstract boolean transact(int code, Parcel data, Parcel reply, int flags)
    Perform a generic operation with the object.
  • abstract boolean unlinkToDeath(IBinder.DeathRecipient recipient, int flags)
    Remove a previously registered death notification.

Implementation of IPC

The Binder’s main function is implemention of IPC, with the kernel driver.

Analysis on AIDL for Android

current situation

Field of use

AIDL is not used frequently. There may be two reasons existing. First, the AIDL program can not be developed easily lik java program. Second, We just needn't use AIDL, in other words, we can write other simple program insteadly. 

Analysis of ViewPager

Desc of ViewPager

AIDL(Android Interface definition language), is not a controller, but a language, and you can say it as designing pattern.

AIDL is similar to other IDLs you might have worked with. It allows you to define the programming interface that both the client and service agree upon in order to communicate with each other using interprocess communication (IPC). On Android, one process cannot normally access the memory of another process. So to talk, they need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary for you. The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.

Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger. Regardless, be sure that you understand Bound Services before implementing an AIDL.

Use of AIDL

To create a bounded service using AIDL, follow these steps:

Create the .aidl file

This file defines the programming interface with method signatures.

Implement the interface

The Android SDK tools generate an interface in the Java programming language, based on your .aidl file. This interface has an inner abstract class named Stub that extends Binder and implements methods from your AIDL interface. You must extend the Stub class and implement the methods.

Expose the interface to clients

Implement a Service and override onBind() to return your implementation of the Stub class.

Using ViewPager for Android Dev

current situation

Field of use

Most of apps will use viewpager in different format, even a very simple app. For example, the [wechat](https://play.google.com/store/apps/details?id=com.tencent.mm&hl=zh_CN). It only has for main content pages, but it uses viewpager. Our system app, luncher, uses viewpager as well. 

Formats of ViewPager

The main format is that a container wrapping many pages shown horizonally. It can be used show ad pictures, and also can be used show many fragments. In many situations, the other indicators will be used with it.

Analysis of ViewPager

Source Code

ViewPager is type of ViewGroup, so that it has all features of ViewGroup.

ViewPager shows data by the PageAdpter. It means that viewpager likes ListView showing data by adapter pattern.

The main feature of ViewPager unlike others views is its TouchEvent function. It intercept the touch events and translates them to the operation on its pages, such as scroll left or right, etc.

Use of ViewPager

Using ViewPager by declaring in the layout file, as follows:

<android.support.v4.view.ViewPager  
    android:id="@+id/viewpager"  
    android:layout_width="wrap_content"
    android:layout_height="200dip"  
    android:layout_gravity="center">  

    <android.support.v4.view.PagerTitleStrip  
        android:id="@+id/pagertitle"    
        android:layout_width="wrap_content"    
        android:layout_height="wrap_content"    
        android:layout_gravity="top"  
        />  

</android.support.v4.view.ViewPager> 

Of course, you can replace the PageTitleStrip by other indicators. You just need change the PageChangeListener for viewpager.

Android App Secure Problem Part 1

Security is important for applications involving direct money transactions or personal privacy concerns. Android system due to its open source properties, the market for open-source custom ROM vary, in the system level security and vulnerability are not the same, Android application market app review relatively iOS is also relatively broad, Many vulnerabilities provide an opportunity. Some mainstream app on the market although some have done some security precautions, but because most of the app does not involve financial security, so the importance of security is not enough; and because security is a door system disciplines, most of the app layer developers lack security Technology accumulation, measures are relatively limited.

This article will focus on analysis of Android APP facing security issues, preventive measures and a series of security technology program implementation.

The security issues facing

virus

Android virus is a mobile phone Trojans, mainly malicious applications. Such as last year, CCTV exposure of a “bank ruthless” mobile phone banking Trojan, imitate the real mobile banking software, through phishing access to user input phone number, ID number, bank account number, password and other information, and these Information uploaded to the hacker specified server. Steal bank account password, the user account in the funds immediately transferred away. Some of the independent existence of mobile phone Trojans, while others are disguised as a picture file attached to the genuine App, hidden very strong, some viruses will appear variants, and more powerful generation than generation.
These viruses have some general characteristics:

  • Mother packet + malicious sub-packet operating mechanism.

  • Through technical means to prevent users through the normal way to uninstall.

  • To steal the user account funds for the purpose.

  • To SMS as a command channel.

  • Critical Information Disclosure

Although the java code to do the general confusion, but several major components of Android is dependent on the way to create the injection, it can not be confused, and some commonly used anti-compiler tools such as apktool can be effortless to restore java in the clear text information , Native library information can also be obtained through objdump or IDA. So once java or native code in the existence of expressly sensitive information, basically there is no security in terms of.

APP re-packaged

That is, decompile and re-join the malicious code logic, a new package APK file. The purpose of re-packaging are generally mentioned above and the virus, the genuine apk to unpack, insert the malicious virus re-packaged and released, so a strong camouflage. Intercepted app re-packaged to a certain extent to prevent the spread of the virus.

Process was hijacked

This is almost the most targeted attack a way, usually through the process of injection or debugging process to hook the process to change the logic and order of running the program to obtain the memory information to run the program, that is, all the user behavior Was monitored, this is the most commonly used account password theft a way. Of course, hook behavior is not necessarily entirely malicious, such as some security software will use the hook function to do proactive defense (such as LBE and our mobile security laboratory latest apkprotect online reinforcement products). In general, hook need to get root privileges or the same process with the hook authority, so if your phone is not root, but is genuine apk, was injected is still very difficult.

Data is hijacked during transmission

The most common hijacking in the transmission process is a man-in-the-middle attack. Many of the more secure applications require that all business requests go through https, but the middleman attack on https is getting more and more, and we find that in practice, certificate exchange and authentication are in some cottage phones or non-mainstream ROMs There are some problems, so that the use of https encounter obstacles.

Keyboard input security risks

Payment password is generally entered through the keyboard, keyboard input directly affects the security of the security of the password. The security risks of the keyboard come from three aspects:

The use of third-party input method, all the click events are technically can be trilateral input method interception, if you are not careful to use some illegal input method, or input method to upload information and leaked, the consequences are unimaginable.

Screenshot, the method requires mobile phone with root privileges to run screenshots software

Getevent, by reading the system driver layer dev / input / event1 in the information to obtain the location of the phone touch screen coordinates, combined with the keyboard layout, you can figure out the incident with the specific number of mapping, which is currently more commonly used attacks the way.

Before doing a set of security keyboard program, that is, custom keyboard + digital layout randomization. But the randomization of the keyboard is very inconsistent with the operating habits of human nature. So after the random words have also been removed.

Also need to explain, there is a more secure way is now trustzone standard has GlobalPlatform_Trusted_User_Inteface, that is to say in the trustzone security interface in a set of standards, if the security keyboard in the trustzone in the pop-up, the hacker regardless of the means through the Sha Can not get the password, is the most secure way, but trustzone depends on the underlying equipment to achieve, if the device does not support trustzone, or trustzone does not support GlobalPlatform_Trusted_User_Inteface standard, we can not do anything. *

Webview vulnerability

As the prevalence of hybrid app now, Webview in the use of the app is more and more, Android system Webview there are some loopholes, resulting in js right to mention. The most famous is the legendary js injection vulnerabilities and webkit xss vulnerabilities, the following section we will detail.

The server did not deal with, was infiltration attacks

This is the most anti-replay attacks and injection attacks, this is not discussed in the context of this article.
Android APP security architecture

Familiarity with Https

In essence, https is a two-way authentication process, but because too many Android devices too messy, Android device certificate is not uniform, generally only client authentication server-side certificate, and the server-side in the https layer will not verify the customer End certificate, so the actual application scenario is a one-way authentication process.
SchemeRegistry.register (new Scheme ( “https”, SSLSocketFactory.getSocketFactory (), 443));

This is the use of google API to https for verification, the main check four aspects:

  • Whether the signature CA is legal

  • Domain names match

  • Is not a self-signed certificate

  • Whether the certificate has expired

If the root certificate used by the server is self-signed or if the signing authority is not in the list of trusted certificates for the appliance, then http connections using httpclient will fail. There are several ways to solve this problem:

The simplest approach is that httpclient does not open certificate validation, trust all the way the certificate. This approach is relatively simple, but the security is equivalent to http as bad, hackers can easily falsify the certificate for man-in-the-middle attacks, resulting in user transaction data and other sensitive information disclosure. Now most of the mobile browser in order to be compatible with the various certificates of the site is to take such a way, but also some mainstream browsers on the non-root certificate, only check the host and validity, if failed, to the user prompts, but also Can continue to browse or interrupt the prompt to ensure that the user experience at the same time to enhance security.

Using the default certificate covering google checking mechanism (X509TrustManager) way, before initiating https connections the server certificate is added to the list of trusted certificates httpclient, this is relatively complex, error-prone, and since each site The definition of certificates are not the same, it is difficult to find a unified approach to all non-root certificate for certificate inspection.

Payment Password Security

Payment password is only a representative of the data, it is actually representative of the client some sensitive data, such as bank card number, mobile phone number, password, cvv, expiration date. Especially against strong passwords and cvv such sensitive data, in order to improve the performance of applications and to prevent others from cracking.

We use RSA and AES encryption of these two sets of encryption methods, as shown below:

Anti-debug module

Debugging refers to the current app by other programs using a specific method (debugger, ptrace, etc.) tracking hijacking, after debugging all the behavior of the app can be viewed and modified by other programs, we can think of the next usually through gdb debugger. Anti-debugging function in two steps: first test whether the current app is being debugged. If the app is being debugged, it returns the process name of the process the debugger is in. If the app is not debugged, protecting the app is no longer debugged by other programs. There are two ways to protect the app from being debugged: - One is the debug option in the kernel that has a debugger turned off, but we can not change the kernel state as an app. - The other is a dual process anti-debugging. We know that a process allows only one debugger, so in the process up at the same time, will fork a daemon (daemon), and ptrace protected app process, the daemon will intercept the debugger entry to ensure that other programs can not debug The current app. Once the daemon is activated, it will remain until the current application exits, if the forced shutdown of the daemon, the current App will be closed. Here we should pay attention to signal processing.

Anti-injection module

Injection is the current App process by other programs using specific methods (ptrace, dlopen, etc.) into the module does not belong to the current App. In general, the injection is not an end, just means, so after the injection module generally has a special behavior, such as the collection of App’s privacy data, the use of methods such as Hook hijack App normal operation process. Which Hook is the most important security risks. From the technical means, the premise is the need to debug the injection. So if the current App has been protected for not being debugged, then theoretically there is no risk of being injected. However, if the anti-debug module is activated later, then before the activation, App still there is the possibility of being injected. Anti-injection function is to detect the current App which modules are injected and hijacked (Hook) the. Android Hook and Hook methods are divided into two categories: Java Hook and So Hook. Java Hook which is divided into static members Hook and function hook, you can check the vm dex memory fields and method field to determine whether there are java injection. So Hook is all linux system hook mode, divided into GOT Hook, Symbol Hook and Inline Hook. Inline Hook is generally compiled by way of injection, Symbol Hook is generally used LD_PRELOAD way to the function plus hook, the two injection are currently Not to prevent, the main anti-or GOT hook. I have been in a number of years ago through the GOT hook principle in the brush machine, no root privileges in the system implanted su program, the system to force a root. GOT Hook principle is simply to say that through cat / proc / pid / maps get the app process so the load address, and then through the analysis of the GOT table so that the offset function of each address, calculate the function of the absolute address of the entrance, And then replace the address function with the injection function. So anti-native injection method is: through the app process space, see the loaded library is not in / system or / data / data / app under, if not, then there must be injected.

Anti-tampering module

App is the traditional method to determine whether piracy, the industry’s usual practice is to collect a large number of genuine application of the information prior to do white list, and then use the current App’s package name, signature and other information to do matching. The accuracy of this method depends on the size of the white list library and requires network connectivity. Anti-tampering based on re-packaged App and genuine App’s dex arrangement features to determine whether the App is repackaged, fast, high accuracy.

Android security programming

For some Android-specific syntax and design, there is also the risk of being attacked, we usually code will be released before the security scan, security scanning sweep surface is the most important point of the following: - Security log this information is relatively simple, and does not allow Print sensitive data, and then must be closed before printing the print log switch. - Intent information disclosure in order to start another one application of Activity, we often use some implicit Intent, if it contains sensitive information, so long as the third-party app to register the same Intent Filter, it is possible to intercept sensitive information, so To send an implicit Intent, you must specify the receiver and permission.
Security of security components

Android includes four components: Activitie, Service, Content Provider, Broadband Receiver, each of them can be opened outside of Intent implicit way, so long as these components are not open to the public must be indicated in the manifest inside exported to false, prohibit other Program access to our components, and external components to be interactive, you should add some access control, but also need to pass on the data for safe verification.
IPC null reference

This occurred mainly in the opening assembly, since the opening of the component can receive Intent, which will generally contain some data when we do not judge these data when empty, app usually crash, an attacker might send data is empty Intent to attack.

WebView vulnerability attack and defense

Js injection vulnerability

The problem was first documented in a paper called “Attacks on WebView in the Android System” in 2011 [http://www.cis.syr.edu/~wedu/Research/paper/webview_acsac2011.pdf] (http://www.cis.syr.edu/~wedu/Research/paper/webview_acsac2011.pdf), this article points to the way addJavascriptInterface in the function of some of the risks, such as your app to achieve a read and write files Class, and then use the addJavascriptInterface interface allows js call, then it may lead to an attacker to directly call the class to read and write files to achieve the operation. This approach is the most primitive risk and does not directly point to the use of the getClass () method. Later, Baidu security group in 2013, the official release of the loopholes in the high-risk work order: http://security.baidu.com/risk/findNewsDetail.do; jsessionid = B09405787822801D67251543B2B8C5CB.security_client-web01? Id = 336. This vulnerability is mainly through the getClass () method directly call java. Lang. Runtime interface to execute system commands, so that any js has the same app operating authority!

The solution is mainly two:

For Android 4.2 and above, Google has fixed the vulnerability, only native
Interface add @ addJavaInterface label can be.
For Android4.2 previous version, you need to rewrite addJavaInterface, js calls and native calls to achieve their mapping. This is a classic cordova design, it is worth learning about.

WebView phishing vulnerability

Fishing this thing has been the most commonly used security sector attacks, but also the most difficult to solve a class of technical problems, and fishing means is strange to prevent fishing in addition to allowing users to improve security awareness, do not click on the link from unknown sources, The technical level can do the following two points: - Check WebView to load the target URL if there is phishing and other security risks - on the webview closed scripting environment
WebView cross-domain vulnerability

Mainly due to the JS XmlHttpRequest can read the local file to read to the app data database directory webviewCookiesChromium.db, the db is usually the system where the cookie is stored, the equivalent of disguised to read the cookie opened the permissions, the specific can For Android 4.1 and above, this does not exist in the cross-domain vulnerabilities, there is no targeted modification. [/ B] [/ color] [/ url] For all versions setAllowFileAccess (false), prohibit the page from the local html load.
other

Weak encryption: a lot of Android application encryption storage methods are relatively simple, just a simple md5, it is easy to be cracked.

Signature verification direction: Each apk will have a signature, the signature only the developer has, if someone else changes the code, it must be signed to run, but the modified signature and the official signature is inconsistent, so we inside Stored application of the official signature of the hashcode value, after the application starts so will check the signature is not the official signature, if not, the application directly closed, so inside the encryption function also does not work.

reference articles:

Getting Start Writing Custom Plugins of Gradle

Introduce

A Gradle plugin packages up reusable pieces of build logic, which can be used across many different projects and builds. Gradle allows you to implement your own custom plugins, so you can reuse your build logic, and share it with others.

You can implement a custom plugin in any language you like, provided the implementation ends up compiled as bytecode. For the examples here, we are going to use Groovy as the implementation language. You could use Java or Scala instead, if you want.

Writing a Custom Plugin

Packaging a plugin

There are several places where you can put the source for the plugin.

Build script

You can include the source for the plugin directly in the build script. This has the benefit that the plugin is automatically compiled and included in the classpath of the build script without you having to do anything. However, the plugin is not visible outside the build script, and so you cannot reuse the plugin outside the build script it is defined in.

buildSrc project

You can put the source for the plugin in the rootProjectDir/buildSrc/src/main/groovy directory. Gradle will take care of compiling and testing the plugin and making it available on the classpath of the build script. The plugin is visible to every build script used by the build. However, it is not visible outside the build, and so you cannot reuse the plugin outside the build it is defined in.

Organizing Build Logic for more details about the buildSrc project.

Standalone project

You can create a separate project for your plugin. This project produces and publishes a JAR which you can then use in multiple builds and share with others. Generally, this JAR might include some custom plugins, or bundle several related task classes into a single library. Or some combination of the two.

In our examples, we will start with the plugin in the build script, to keep things simple. Then we will look at creating a standalone project.

Writing a simple plugin

To create a custom plugin, you need to write an implementation of Plugin. Gradle instantiates the plugin and calls the plugin instance’s Plugin.apply(T) method when the plugin is used with a project. The project object is passed as a parameter, which the plugin can use to configure the project however it needs to. The following sample contains a greeting plugin, which adds a hello task to the project.

1
2
3
4
5
6
7
8
9
10
build.gradle
apply plugin: GreetingPlugin

class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('hello') << {
println "Hello from the GreetingPlugin"
}
}
}

run

1
2
3
Output of gradle -q hello
> gradle -q hello
Hello from the GreetingPlugin

One thing to note is that a new instance of a given plugin is created for each project it is applied to. Also note that the Plugin class is a generic type. This example has it receiving the Project type as a type parameter. It’s possible to write unusual custom plugins that take different type parameters, but this will be unlikely (until someone figures out more creative things to do here).

The other content will be completed later, Sleepping…………

Getting Start Using Graphics of Android

Introduce

In android’s view, bitmap,graphics, opengl and animation are included in graphics. The classes about shape will be introduced in this article. The other content will be introduced later.

Getting Started

Shape, Shader, ColorFilter and MaskFilter

Shape

Drawing a shape is very simplely. Here list codes drawing some simple shapes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// create Paint
Paint p = new Paint();
p.setColor(Color.RED);// set color as red

canvas.drawText("Draw circle", 10, 20, p);// draw text
canvas.drawCircle(60, 20, 10, p);// small circle
p.setAntiAlias(true);// set Jagged effect
canvas.drawCircle(120, 20, 20, p);// big circle

canvas.drawText("Line and Arc:", 10, 60, p);
p.setColor(Color.GREEN);// set green
canvas.drawLine(60, 40, 100, 40, p);// line
canvas.drawLine(110, 40, 190, 80, p);

p.setStyle(Paint.Style.STROKE);//only path draw
RectF oval1=new RectF(150,20,180,40);
canvas.drawArc(oval1, 180, 180, false, p);//small arc
oval1.set(190, 20, 220, 40);
canvas.drawArc(oval1, 180, 180, false, p);//small arc
oval1.set(160, 30, 210, 60);
canvas.drawArc(oval1, 0, 180, false, p);//small arc

canvas.drawText("draw Rect: ", 10, 80, p);
p.setColor(Color.GRAY);
p.setStyle(Paint.Style.FILL);
canvas.drawRect(60, 60, 80, 80, p);// rect
canvas.drawRect(60, 90, 160, 100, p);//rect

canvas.drawText("Arc and Oval:", 10, 120, p);

Shader mShader = new LinearGradient(0, 0, 100, 100,
new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.LTGRAY }, null, Shader.TileMode.REPEAT); // draw a shader
p.setShader(mShader);
// p.setColor(Color.BLUE);
RectF oval2 = new RectF(60, 100, 200, 240);
canvas.drawArc(oval2, 200, 130, true, p);
// draw arc when true, otherwise draw curve
//draw oval
oval2.set(210,100,250,130);
canvas.drawOval(oval2, p);

canvas.drawText("triangle:", 10, 200, p);

Path path = new Path();
path.moveTo(80, 200);// draw start point
path.lineTo(120, 250);
path.lineTo(80, 250);
path.close(); // let these pointer construct a shape
canvas.drawPath(path, p);

// draw hexagon, six edges
p.reset();//reset p
p.setColor(Color.LTGRAY);
p.setStyle(Paint.Style.STROKE);
Path path1=new Path();
path1.moveTo(180, 200);
path1.lineTo(200, 200);
path1.lineTo(210, 210);
path1.lineTo(200, 220);
path1.lineTo(180, 220);
path1.lineTo(170, 210);
path1.close();
canvas.drawPath(path1, p);


//Rounded Rectangle
p.setStyle(Paint.Style.FILL);
p.setColor(Color.LTGRAY);
p.setAntiAlias(true);
canvas.drawText("Rounded Rectangle:", 10, 260, p);
RectF oval3 = new RectF(80, 260, 200, 300)
canvas.drawRoundRect(oval3, 20, 15, p);

//Bezier curve
canvas.drawText("Bezier curve:", 10, 310, p);
p.reset();
p.setStyle(Paint.Style.STROKE);
p.setColor(Color.GREEN);
Path path2=new Path();
path2.moveTo(100, 320);//path start point
path2.quadTo(150, 310, 170, 400); //path end point
canvas.drawPath(path2, p);//draw

//Point
p.setStyle(Paint.Style.FILL);
canvas.drawText("画点:", 10, 390, p);
canvas.drawPoint(60, 390, p);//Point
canvas.drawPoints(new float[]{60,400,65,400,70,400}, p);//multi Points

//draw bitmap or Textures
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
canvas.drawBitmap(bitmap, 250,360, p);

Shader

Xml and java code can draw shader

1
2
3
4
5
6
7
8
9
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
type="rectangle">
<gradient
android:startColor="@color/blue"
android:centerColor="@color/white"
android:endColor="@color/red"
android:angle="45"/>
</shape>

1
2
3
4
5
6
7
8
9
10
int[] rainbow = getRainbowColors();
Shader shader = new LinearGradient(0, 0, 0, w, rainbow,
null, Shader.TileMode.MIRROR);

Matrix matrix = new Matrix();
matrix.setRotate(90);
shader.setLocalMatrix(matrix);

getPaint().setShader(shader);
}

Bitmap Shader

1
2
3
4
5
Bitmap bitmap = BitmapFactory.decodeResource(
getResources(), R.drawable.cheetah_tile);
Shader shader = new BitmapShader(bitmap,
Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
textView.getPaint().setShader(shader);

ColorFilter

ColorMatrix: Grayscale

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Bitmap bitmap = Bitmap.createBitmap(original.getWidth(), 
original.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);

Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(
getColorMatrix()));
canvas.drawBitmap(original, 0, 0, paint);

return bitmap;

private ColorMatrix getColorMatrix() {
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);
return colorMatrix;
}

ColorMatrix: Sepia

1
2
3
4
5
6
7
8
9
10
11
12
private ColorMatrix getColorMatrix() {
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);

ColorMatrix colorScale = new ColorMatrix();
colorScale.setScale(1, 1, 0.8f, 1);

// Convert to grayscale, then apply brown color
colorMatrix.postConcat(colorScale);

return colorMatrix;
}

ColorMatrix: Binary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private ColorMatrix getColorMatrix() {
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);

float m = 255f;
float t = -255*128f;
ColorMatrix threshold = new ColorMatrix(new float[] {
m, 0, 0, 1, t,
0, m, 0, 1, t,
0, 0, m, 1, t,
0, 0, 0, 1, 0
});

// Convert to grayscale, then scale and clamp
colorMatrix.postConcat(threshold);

return colorMatrix;
}

you also implement ColorMatrix: Invert, ColorMatrix: Alpha blue effect

LightingColorFilter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** Create a colorfilter that multiplies the RGB channels by one color, 
and then adds a second color. */
LightingColorFilter(int mul, int add)
R' = R * mul.R + add.R
G' = G * mul.G + add.G
B' = B * mul.B + add.B
//Little brother of ColorMatrixColorFilter
[ mul.R, 0, 0, 0, add.R
0, mul.G, 0, 0, add.G,
0, 0, mul.B, 0, add.B,
0, 0, 0, 1, 0 ]
/*
mul.R = Color.red(mul) / 255f
e.g. #ff0000 → 0xff / 255 = 255 / 255 = 1
*/

Porter-Duff Modes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Bitmap bitmap = Bitmap.createBitmap(
original.getWidth(), original.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);

// Draw the original bitmap (DST during Porter-Duff transfer)
canvas.drawBitmap(original, 0, 0, null);

// DST_IN = Whatever was there, keep the part that overlaps
// with what I'm drawing now
Paint maskPaint = new Paint();
maskPaint.setXfermode(
new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(mask, 0, 0, maskPaint);

Path effects and other effect all can be implemented with Porter-Duff

MaskFilter

EmbossMaskFilter

1
2
3
4
5
6
7
8
9
10
private void applyFilter(
TextView textView, float[] direction, float ambient,
float specular, float blurRadius) {
if (Build.VERSION.SDK_INT >= 11) {
textView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
EmbossMaskFilter filter = new EmbossMaskFilter(
direction, ambient, specular, blurRadius);
textView.getPaint().setMaskFilter(filter);
}

ref:

android-shaders-filters

Animation and Graphics

Difference Between Netty3 and Netty4

Instruction

Netty 4 has been released three years, compared to Netty 3, Netty 4 in the memory model and the thread model has been modified. Now Netty 4 is already very mature, and for the Square company, Netty 4 also has a significant feature: the HTTP/2 protocol of the native support. Square expects its mobile devices to use the HTTP/2 protocol and is switching the back-end RPC framework to gRPC: an RPC/2 protocol-based RPC framework. Therefore, Tracon as a proxy service, must support HTTP/2 protocol.

Analysis

Single Thread Channel

Unlike Netty 3, Netty 4’s inbound (data input) and outbound (data out) events are all in the same thread. This is the time to write the processor, you can remove the thread-safe code. However, this change also makes the upgrade process to meet the conditions of competition caused by the problem.

In Netty 3, the operation for the pipeline is thread-safe, but in Netty 4, all operations are placed as events in the event loop asynchronously. As a proxy service, Tracon will have an independent inbound channel to interact with the upstream server, and a separate outbound channel to interact with the downstream server. In order to improve performance, the connection to the downstream server is cached, so that these events may occur concurrently when an event in the event loop triggers a write operation. This is fine for Netty 3, and every write will be completed before returning; but for Netty 4, these operations go into an event loop, which can lead to out-of-order messages.

Therefore, in the block test, and occasionally encounter the data sent to the order is not arrived, resulting in test failure.

When upgrading from Netty 3 to Netty 4, it is important to note that events are dispatched asynchronously if they are triggered outside the event loop.

codes as follows:

1
2
3
4
5
6
7
8
9
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws
if (evt.equals(SslHandshakeCompletionEvent.SUCCESS)) {
Principal peerPrincipal = engine.getSession().getPeerPrincipal();
// 身份验证
// ...
}
super.userEventTriggered(ctx, evt);
}

Memory Leak

Since direct memory is used by NIO, it is necessary to monitor direct memory for Netty network libraries, which can be done by using JMX beanjava.nio: type = BufferPool, name = direct.

Netty 4 introduces a thread-local Recyler based on thread-local variables to reclaim object pools. By default, a collector can hold up to 262k objects, for ByteBuf, less than 64k of the default shared cache object. In other words, each collector can hold up to 17G of direct memory.

Normally, the NIO cache is sufficient to cope with an instantaneous amount of data. However, if you have a very slow reading of the back-end, will greatly increase the memory usage. In addition, when the cache memory in the NIO read and write by other threads, the allocation of the memory of the thread will not be able to reclaim the memory.

The Netty project has also made some corrections to the problem of limiting the growth of objects that can not be recovered by the reclaimer, which causes memory exhaustion:

  • Allows you to set the maximum number of WeakOrderQueue instances per thread;

  • The memory allocation / sharing ratio is introduced in the reclaimer;

  • Porting SendBufferPooled from Netty 3.10, used when using a non-shared ByteBuf allocator (ByteBufAllocator);

From the experience of upgrading Netty 4, it is recommended that all developers configure the Recycler based on available memory and threads. The maximum number of objects that the Reclaimer can hold can be set with the -Dio.netty.recycler.maxCapacity parameter, and the maximum memory limit can be set with the -Dio.netty.threadLocalDirectBufferSize parameter. If you want to completely close the collector, you can set-Dio.netty.recycler.maxCapacity 0

Use Global Exception Process, codes as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 class LoggingExceptionHandler implements Thread.UncaughtExceptionHandler {
private static final Logger logger = Logger.getLogger(LoggingExceptionHandler.class);
/** 注册成默认处理器 */
static void registerAsDefault() {
Thread.setDefaultUncaughtExceptionHandler(new LoggingExceptionHandler());
}
@Override
public void uncaughtException(Thread t, Throwable e) {
if (e instanceof Exception) {
logger.error("Uncaught exception killed thread named '" + t.getName() + "'.", e);
} else {
logger.fatal("Uncaught error killed thread named '" + t.getName() + "'." + " Exiting now.", e);
System.exit(1);
}
}
}

HTTP decoder refactor

Netty 4 refactored the HTTP decoders, and specifically improved support for chunked data. HTTP message body is split into HttpContent object, if the HTTP data through the block transmission, there will be more than one HttpContent order to arrive, when the data block transmission end, there will be a LastHttpContent object. It should be noted that, LastHttpContent inherited from HttpContent, must not be handled in the following manner:

1
2
3
4
5
6
If (msg instanceof HttpContent) {
   ...
}}
If (msg instanceof LastHttpContent) {
   ... / / The last block will be repeated, the previous if already contains the LastHttpContent
}}

For LastHttpContent there is a need to note that when receiving this object, HTTP message body may have been transmitted over, at this time LastHttpContent just as HTTP transmission end (similar to EOF).

Ref

Square-Netty-3-Netty-4