In the HTC world, there is such a thing as Dot View.
HTC Dot View is a very original case that allows users of advanced models from HTC (One line) to use their device in a very non-standard way. This accessory was designed to bring even greater fame to the company, and it seems that it successfully copes with its task: many people make their choice in favor of the HTC One * and thanks to the Dot View case.
Such accessories attract not only users to do their numerous reviews, but also mobile developers to create non-standard applications that use these cool features. The standard set of Dot View features from the manufacturer (HTC) is quite rich: a handy player with the flashing of tracks, displaying various notifications "to the dots" of the case, and even simple games that resemble the "eight-bit era" with their "big pixels". But the problem is that the official developer did not provide not only an API for use, but not even the slightest instruction on how his brainchild Dot View works. This led to the fact that enthusiasts had to understand
independently the mechanisms of pairing the cover with the device, and the researchers - to
investigate .
In this topic, we will try to understand how this magic case from HTC functions.
')
All this is one big conspiracy !?
As mentioned above, this case was released by the official manufacturer specifically for their devices.
The case is designed in such a way that the magnet, mounted in it, interacts with the internal equipment, allowing it to understand that the phone is wearing a case, and this case is the Dot View. And the magnet itself is located here, right below the HTC label:
After putting the cover on the device, the services launched in the system begin to interact with the cover, intercepting the device’s power management (state) control modes and starting “specific” activities from the official manufacturer. Ie, mobile devices are associated with this case both at the software level and in hardware. A little more detailed review can be viewed
here .
What if the API does not exist?
That was the question that had to be asked at first ... Indeed, it was hard to believe that for such a unique accessory no API for third-party developers was released. In the process of searching the network, there were some examples that were somehow relevant, such as the implementation of
the Dot View
module for the custom Xposed framework, but nothing that could really push off and finally use the capabilities of Dot View in its own applications. Therefore, I had to start my own investigation.
The first step towards understanding the truth was to view the
logcat , in which there were sorts, precisely indicating the presence in the system of some head component Dot View:
W/SensorService( 870): Listener[0] = com.htc.dotmatrix.CoverService$7@24541961 W/SensorService( 870): Listener[1] = com.htc.dotmatrix.CoverService$7@6b8ab5b W/SensorService( 870): Listener[2] = com.htc.dotmatrix.CoverService$7@f1d0b5a ... D/DotMatrix( 1287): [CoverService] resetCoverViewState, poleN: false, state: true D/DotMatrix( 1287): [CoverService] updateCoverState, (sticky)poleN: false, state: true D/DotMatrix( 1287): [CoverService] updateCoverState, (intent)poleN: false, state: false D/DotMatrix( 1287): [CoverService] updateCoverState, removeMessages EVENT_COVER_CLOSED D/DotMatrix( 1287): [CoverService] show cover D/DotMatrix( 1287): [DotImage] init com.htc.dotmatrix.ui.BackgroundImage D/DotMatrix( 1287): [DotImage] init com.htc.dotmatrix.ui.TemperatureImage D/DotMatrix( 1287): [DotImage] init com.htc.dotmatrix.ui.LastCallImage
The first thing that came to mind was the idea of ​​decompiling the APK of the official
HTC Dot View application, because the most interesting logs from logcat referred to the package name of this application. But in the end, no useful information, allowing you to write your code for the case, could be extracted except for the specific intent-action games used by broadcast receivers and intended to track the status of the case cover: open or closed.
After some time of unsuccessful attempts to reach the point, I accidentally managed to stumble upon the “Applications” section in the official HTC application for Dot View, which had several “default” applications:
It became interesting here how the usual Android application differs from the Dot View application. Ie at what level is the separation? Looking for other applications on Google Play, we managed to get to the implementation of
Dot Breaker , which is a “knock out building blocks” game. Of course, like everyone else, it was from the official manufacturer.
It is thanks to the Dot Breaker application that we managed to find out all the subtleties of the Dot View work and create our own application for the case.
Searches for the essence ...
Having performed the initial decompilation of the application, it is possible to look into the
application manifest (AndroidManifest.xml).
This manifesto was not much like the manifesto of the official HTC Dot View application. The very first thing that caught my eye was the lack of a “sheet” of permits:
<uses-permission android:name="android.permission.GET_TASKS"/> <uses-permission android:name="com.htc.permission.dotviewgame"/>
After all, the application, at least, controlled the state of the device. And the resolution GET_TASKS is generally recognized as
obsolete . Therefore, the following resolution was of the greatest interest. From his name it is obvious that it is non-standard.
Here is another constructive point, which is responsible for ensuring that the application appears in the very list of "Applications":
... <activity android:name=".WelcomePageActivity" android:screenOrientation="portrait" > <intent-filter> <action android:name="com.htc.intent.action.dotviewgame_launch"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> ...
Roughly speaking, this custom action is like
“android.intent.category.LAUNCHER” , only
“com.htc.intent.action.dotviewgame_launch” .
And in assets (assets) all the animation that was present in the game was collected:
... and in the future it will become clear why, because drawing on the points of the cover is not a very standard exercise.
This was followed by a secondary decompilation, the purpose of which was a direct analysis of the decompiled Java code of the application. (The decompiled code is presented in
the BitBucket repository .)
Based on the above piece of the manifest, we can conclude that the
WelcomePageActivity is the main activity of the Dot Breaker
application . The only thing she does is show the initial animation (not yet associated with the Dot View) for 2 seconds and start the
GameLevel activity, which is responsible for the level selection:
... this.mCountDownTimer = new CountDownTimer(2000L, 2000L) { public void onFinish() { WelcomePageActivity.this.finish(); WelcomePageActivity.this.startActivity(new Intent(WelcomePageActivity.this, GameLevel.class)); } } .start(); ...
Activity
GameLevel also allows you to select a level. In its restored Java code, you can see the “sheet” of initializations for all 20 levels of the application; when clicking on the View of each of them, an AlertDialog will pop up, containing the following code for calling the application’s key activity -
GameActivity :
... localBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) { GameLevel.this.startActivity(new Intent(GameLevel.this, GameActivity.class)); } }); ...
This code is the “last frontier”, which is finally followed by the internal mechanisms for implementing the HTC Dot View concept.
How does this dot view work?
The key activity of
GameActivity , which is an intermediary in the cycle of interaction with the Dot View, does not stand out in any way - it, like any other activity, is inherited from the
Activity class. This means that the interaction starts with the onCreate method. In the code of this
GameActivity activity
method, you can find many calls responsible for the configuration and styling of the window (fullscreen, brightness, etc.), followed by a key call at the very end of the method:
... this.mDotViewCommunity.bindDotViewService();
Here
this.mDotViewCommunity is an instance of the wrapper class, which is a simple abstraction and implemented within the GameActivity class as a nested class. You can ignore it, since this class does not play a significant role.
But an important role is played by the method with the speaking (even screaming) name
“bindDotViewService” contained in this class. At this stage, it can already be assumed that there is a linking with a certain service, possibly, for the purposes of interprocess communication (IPC).
Here is the key code from the
bindDotViewService method:
... DotViewSericeConnection mServiceConnect = new DotViewSericeConnection(); ... Intent localIntent = new Intent(); localIntent.setClassName("com.htc.dotmatrix", "com.htc.dotmatrix.GameService"); bool3 = GameActivity.this.bindService(localIntent, this.mServiceConnect, 1); ...
As you can see, there is actually a linking with the custom Dot View service in order to further interact with it. The class name of the service is
com.htc.dotmatrix.GameService , and the package (application) to which this service belongs is
the very official HTC Dot View application.
DotViewSericeConnection is a custom class Dot Breaker, which is an implementation of the standard Android
ServiceConnection interface for monitoring service status. The
DotViewSericeConnection class
is also implemented as a class nested in an activity class.
Well, maybe this is the expected outcome, but how does the interaction of the Dot Breaker game unfold after binding to the service from HTC?
The
ServiceConnection interface requires an overridden
onServiceConnected () method, which is called if it successfully connects to the service.
In the case of a successful connection with the service, the code is called, the execution of which is the first of two steps on the way to using the Dot View:
public void onServiceConnected(ComponentName paramComponentName, IBinder paramIBinder) { GameActivity.DotViewCommunity.this.mService = new Messenger(paramIBinder); try { Message localMessage = Message.obtain(null, 1); localMessage.replyTo = GameActivity.this.mMessenger; Bundle localBundle = new Bundle();
Here you can observe a fairly standard client-server "communication" with the remote service in the context of Android.
A message with
what-code = 1 is pulled out of the global pool.
And at the beginning of the activity class you can find the following set of constants:
static final int MSG_DOTVIEW_CLIENT_PAUSE = 4; static final int MSG_DOTVIEW_CLIENT_REGISTER = 1; static final int MSG_DOTVIEW_CLIENT_RESUME = 3; static final int MSG_DOTVIEW_CLIENT_UNREGISTER = 2;
This means that the code of this method registered the activity as a new potential user.
Then a similar code is called, but with what-code “3” -
MSG_DOTVIEW_CLIENT_RESUME .
Immediately after that, the Dot View stops responding to the slam of the lid
for a given activity and provides screen-Dot-View drawing of the activity that wants it, i.e. GameActivity.
Well, what about the bundle and communication with the service?
After telling
com.htc.dotmatrix.GameService that the activity wants and is ready to use the case “in its own way”, when the cover of the case is slammed, the screen will not go out (at first there will be a feeling that the Dot View functions simply stopped working) displaying the markup of the activity that “captured” the Dot View mode. If the screen goes out, then after double tapa (the standard way to “wake up” Dot View) instead of the splash screen, again, there will be a markup of “activity-invader”.
Activity works almost standardly: buttons can be placed on it, and their onclick will work, standard Android
gesture detectors can be used - everything will work quite normally.
But what is the difficulty then?
Somehow in the beginning it was said that Dot Breaker stores all its animation in pictures. One of the main reasons (but hardly the most important) is the specificity of drawing on the Dot View points. That is why none of the official application and does not use the standard Android View, because they simply will not be visible! A button with its standard font will not even look like a button, rather, like some kind of View-shaped spot, which can be clicked and something will happen “under the cover”. It would seem that you can increase the size of the button and the text, but, although everything will become more visually intelligible, you still need a more reliable approach.
Inside the
BrickView class of the Dot Breaker application, there are sorts (some of the logic may be misunderstood due to the not entirely correct decompilation) of the method of converting screen pixels to DotView pixels. He is definitely worth reading. There is also a simpler, but less accurate way - to count the number of points of the cover:
The result was 27 weighty points in X and 48 in Y. By "weighty" should be understood such a DotView-point, which is imposed on the display device. With such information, it is easy to write a method that would produce the desired scaling.
Completion: 1.
All the above material will be really interesting in the context of some practical implementation.
As such, some simple game for the Dot View would work well.
All test demo application encapsulates
3 activities :
1)
MainActivity - serves only to display the application in the application menu (support for standard launch) and to launch a second activity or exit from the application.
2)
DotRunner - intermediate activity, the main purpose of which is to monitor the condition of the cover of the cover by means of a broadcast receiver and start / stop the third activity:
... BroadcastReceiver dotReceiver = new DotReceiver();
3)
DotActivity - an activity that interacts with the Dot View according to the rules described in the previous sections.
For a more convenient drawing of the Dot View screen, taking into account scaling, it was necessary to create a custom view
DotMatrixView , in which the game-test-process takes place and which implements all the logic of rendering “large pixels”.
The game, in turn, is extremely simple: you need to tap the cube to prevent it from falling:
And to start a new game you will need to open and close the Dot View lid. In addition, a gesture recognition interface was implemented inside the
DotMatrixView game class (using the
GestureDetector class), with which you can start the game again by making a Fling gesture using the Dot View cover.
A demonstration video of the custom application can be viewed
here .
The source code of the test application is presented in
the BitBucket repository .
Completion: 0.
Having reviewed the principles of HTC Dot View, it became clear that this idea does not involve any secret principles: everything is the same old, but “under the new cover”.
Without a doubt, we can say that modern users are very lucky with the time in which they exist: there are so many useful and interesting devices around that you don’t even keep up with everything, let alone experience it. And the developers of things like the Dot View and create this modernity. After all, it is from such trivialities that the whole is formed. Therefore, an open and accessible API for such “trifles” is more than just a software interface. This is the ability to take a fresh look at the use of old concepts.
“Everything new is well forgotten old” (c).