Android, architecture, Design, Mobile, User Experience

MDM Tablet Architecture

This is the second part of my blog series that talks about building a custom MDM (Mobile Device Management) solution. If you haven’t read the first part, you should check it out here.

As mentioned in the previous blog, as part of the MDM solution, we have the MDM agent running on the tablet that fetches operations from the server, executes them and returns back status of the operations to the MDM server. As a quick reminder, here are some examples of these operations:

  • Silent installation of application/s
  • Block settings on the tablet
  • Block application/s on the tablet
  • Reset the pin on the tablet
  • Factory reset the tablet

In this post, I am going to talk about how we realized the implementation of some of these challenging operations.

So, to put things in context, if you are developing a regular Android application, you would have access only to Android’s publicly exposed APIs. Your architecture would look something like the one below.
normal-app-tablet-architecture

But when you are building an MDM agent, the publicly exposed APIs are not sufficient for implementing some of the operations. So, for example, if you wanted to silently install an application (install happens in the background, without the user knowing about it), there is no public API to do such a thing. But if you look at the source code of Android there exists a method that does exactly that. Now what do we do?

Now here is where we need to broaden our horizon a little bit. As I mentioned before, we are responsible for the end-to-end solution, hardware and software. This gives us great leverage in terms of customizing the Android platform and here is how we do it.

We work directly with the hardware vendor for procuring the Android devices. The devices come with an Android system image that is built specifically for our needs. A system image is a combination of the Android operating system, OEM (Original Equipment Manufacturer, in this case, the hardware vendor) applications, device specific drivers, et al. As we all know, Android is an open source platform and hardware vendors are free to customize it, as long as it satisfies Android’s CTS (Compatibility Test Suite).

We built an Android service that would expose some of the non-publicly available Android APIs. Lets call it the “bridge service”. We handed this service over to our hardware vendor for it to be included in our custom system image. Including the bridge service in the system image, gives it access to Android’s non-public APIs, since the service will be considered part of the Android operating system. This bridge service will in turn be accessed by our MDM agent for realizing the implementation of some of the operations. And boom, there you go! Now we have access to Android’s non-public APIs.

We did not stop with just exposing non-public APIs; we went one step further. We have some custom Android components included in the system image. For example, one of the business requirements is to, only allow certain applications to run on the tablet. For this, we have a App Killer utility that kills applications that are not part of a “allowed apps” list. This list is fetched from the MDM server as part of an operation and fed to the App Killer utility on the tablet.

Some of the other requirements, like blocking certain settings on the tablet, are implemented by overriding the Settings application code that’s part of the Android operating system. With all these customizations, this is how our architecture looks like.

mdm-tablet-architecture

Its a pretty cool realization that we can do anything we want with the Android operating system! :). But, of course, all of this, comes at a cost.

First of all, this bridge service presents a security risk and we mitigate it by making sure that it can only be accessed by our MDM agent. The other big concern is that, when Android changes one of these APIs, which they are free to do, since they are not publicly exposed, we would have to make corresponding changes to our bridge service. Also, working out the logistics hasn’t been easy, primarily due to the long feedback cycles involved in testing the integration between system image, bridge service and the MDM agent. Each of the system image changes have to be certified by Google by passing the CTS, which adds to the delay. Making changes to the system image requires us to go back to the hardware vendor which is time consuming. At the moment, it takes the hardware vendor roughly about 3 days to turn over a single system image change, depending on the complexity of the change. Hence, we have to plan these changes well in advance.

But when you are building a mobile device management solution, you need these capabilities. It has made a vast improvement in the user experience for the tablet users. So for example, on the tablet, we can silently install applications without the user having to go through the normal process of clicking OK button on multiple screens. Imagine if the user has to do this for 100s of applications! At that point, it becomes a necessity as opposed to a ‘nice-to-have’.

Its been incredible fun “hacking” with the Android operating system. I hope you have liked the blog. Feel free to let me know what you think. Thanks for reading!

Standard
Design, User Experience

Design Studio

My dream job would be a place where I get to play with, interact with, and build physical objects. It is incredibly satisfying to hold something in your hand and say I built this. It gives you that instant connection with the fruit of your labor. Now given the business that I am in, of building software (which I love by the way), there are no physical objects in a software system. The closest we get, is drawing some diagrams to represent the components in a software system or show how data flows between those components. Physical objects are great not only from a gratification point of view, but they also provide valuable feedback on the design and usability of the system.

Enter the idea of design studio for software. The idea is to have entities in a software system represented by physical objects, that you can touch and feel. When you interact with this physical world of software, you would get a much better feel for the system you are building and it would accelerate your learning about the system under construction. Also it levels the playing field between the designer of the software system and the innocent user. Let me explain how.

Lets say you are building a website that comprises of multiple screens. In this design studio, these screens would be represented by wooden blocks that would be placed on the floor, large enough for a person to stand on it. A user navigating these screens in a real world would be represented by a person jumping from one wooden block to the other. In addition to moving around on these blocks, the person would have to carry weights on her/him. These weights would be representative of the “effort” that the user has to put in, to use the website. Example of such “effort” would be the presence of too many UI (User Interface) elements on the screen, like buttons, drop-downs, et al (more UI elements, more effort required on part of the user to understand what they do), waiting time spent on the screen, information user has to hold across screens (did I click that checkbox 2 screens ago or am I shipping this to the right address on the checkout page with no shipping address on it), etc. All these things negatively affect the user experience on the website and hence, in a physical world, weights would be added as and when the user is subjected to such “effort”, when jumping from block to block.

So the first justification for building such a design studio would be to reduce the user interface complexity of a system. When professionals design a website, they often do not realize what a user really goes through when navigating a website. This is partly because websites are built by professionals for people who have little or no experience in working with a website. Imagine if you were to click a couple of extra links to get somewhere on a website, you might not think of it as a big deal. But if you were to hop around a few extra blocks carrying all those weights, then it seems a bit too much. When the designer is feeling the pain (literally) the user goes through on a real website, in a sense we are leveling the playing field between the designer and the user.

For usability testing, you could bring in some real users and have them walk through this physical world of the software system. You could introduce them to this “game”, hand them a task and see how they perform. You could have the person, leave a breadcrumb, when she/he jumps over the wooden blocks. This way you could study the paths they take through the system. With the help of the physical trace, you might notice that people, when performing apparently simple tasks, jump through a lot of “hoops” (in our case blocks), when it should have been rather obvious to begin with. This could be because of bad layout or just incorrect assumptions about user behavior. The solution could be as simple as placing related blocks adjacent to each other or providing appropriate directions to the user on the blocks. This would translate to providing a better workflow to the user in the software system and placing related screens closer to each other and linking them in a easy-to-find way.

The other justification for the design studio would be to get feedback on the system architecture. Same situation, you were building a website with some screens. Lets say each screen was backed by a combination of databases and services. Now as per the previous analogy, each screen would be represented by a wooden block and each external service/database would be represented by a physical box. There would be ropes connected from a screen to all the external systems that it talks to. What do I get out of this?

First of all you get the system view of things. You can easily tell if a screen is backed by too many external connections and infer that the screen might be slow to respond to user input. May be you should think of consolidating the external system end points or move some of the functionality to a different screen. Going back to the earlier example, you would add additional weights proportional to the connections the screen makes, to account for the latency introduced by the system integration, when you jumped on the wooden block representing that screen. Typically this kind of system integration information is left out of initial prototyping and becomes cumbersome to incorporate later into the user experience. User experience is not just about how the software looks but also how it behaves. Integration points can have a huge bearing on the design of the user experience and it is better to identify them sooner than later.

One other thing that I would like to throw in there is that the lengths of the ropes connecting the screens to the external systems should be proportional to the integration effort. Say a database is quick and easy to work with, so it gets a shorter rope, whereas an external uncontrolled service gets a relatively longer rope. A crazy idea would be, just by measuring the lengths of these ropes, you should be able to put some estimates around the actual integration effort. Yaa, how about putting some science into estimation!

All in all, it feels that this experiment might be worthwhile to give it a shot. I hope I can try this out soon enough on a real project. Thanks for reading and let me know how you feel about this idea.

Standard