Apr 15, 2016

Lessons learned: Support for runtime permissions in Firefox for Android

Medium.com: Lessons leard - Adding support for runtime permissions to Firefox for Android
This article has been published on Medium.com

Sep 17, 2015

Support for restricted profiles in Firefox 42

One of our goals for Firefox for Android 42.0 was to create a kid and parent-friendly web experience (Project KinderFox / KidFox): The browser should be easy to use for a kid and at the same time parents want to be in control and decide what the kid can do with it.

There are a lot of things you can do to create a kid-friendly browsing experience. In this first version we focused on making the browser simpler by hiding complex or kid-unfriendly features and utilizing the parental controls of the Android system: Restricted profiles.

What are restricted profiles?


Restricted Profiles have been introduced in Android 4.3. The device administrator can create these profiles and restrict access to apps and features on the device. In addition to that restrictions inside an app can be configured if supported by the app.

Configuring which apps the restricted profile can acccess.

A unique feature of restricted profiles is that they share the Google account of the device owner. It does not allow full-access to everything connected to the account but it allows the restricted user to watch content (e.g. movies and music) bought with that account or use paid applications. Of course only if the device owner explicitly allowed this.

Unfortunately Restricted Profiles are only supported on tablets so far. It is a pity because in the meantime Google allowed to create full-featured and guest profiles on phones too.

The following DevBytes episodes gives a good overview about the Restricted Profiles APIs:




Being in control


Our final list of restrictable features for Firefox 42 contains 10 items:

    • Disable add-on installation
    • Disable 'Import from Android' (Bookmark import)
    • Disable developer tools
    • Disable Home customization (Home panels)
    • Disable Private Browsing
    • Disable Location Services (Contributing to Mozilla's Location Service)
    • Disable Display settings
    • Disable 'Clear browsing history'
    • Disable master password
    • Disable Guest Browsing

      Limiting access to features is a very personal decision. Not every parent wants to control every aspect of the browsing experience. That's why we decided to make these restrictions configurable by the parent. By implementing a broadcast receiver that listens to ACTION_GET_RESTRICTION_ENTRIES actions it's possible to send a list of restrictions to the system and so they will show up in the admin interface:

      Configuring restrictions of an application.
      Later the application can query the UserManager to ask which restrictions have been enabled or disabled.

      Technical details


      User restrictions vs. application restrictions
      There are two kinds of restrictions. User restrictions are imposed on the user by the system and application restrictions are added by an application via the broadcast mechanism mentioned above. An application can query the UserManager only for its own and global user restrictions.

      Detecting restricted profiles
      One of the first things you might want to do in your app is to detect if the current user is using a restricted or a normal profile. There's no API method to do that and the video linked above suggests to query the user restrictions from the UserManager and if the returned bundle is not empty then you are in a restricted profile.

      This worked fine until we deployed the application to a phone running an Android M preview build. On this phone - that doesn't even support restricted profiles - the UserManager always returned a restriction. Whoops, suddenly everyone with Android M on their phones had a very limited Firefox Nightly. We then switched to iterating over the returned Bundles (for application and user restrictions) and only assuming we are in a restricted profile if at least one restriction in those bundles is enabled (getBoolean() returns true).

      In general it is a better approach to never detect whether you are in a restricted profile or not but instead always check whether a specific (application) restriction is enabled or not. 

      A resource qualifier would be nice
      Hiding features and UI in restricted profiles will add a lot of if statements to the code base. It would have been nice to have a resource qualifier for restricted profiles to load different layouts, drawables and other configurations. Besides that this would also solve the "detect restricted profile" problem quite elegant.

      Strict mode: Disk read violation
      At runtime we noticed that we have been triggering a lot of disk read violations. Looking at Android's source code it turns out that UserManager.getApplicationRestrictions() reads and parses an XML file on every call. Without caching anything like SharedPreferences do. We worked around that by implementing our own memory cache and refreshing the list of restrictions whenever the application is resumed. To update restrictions the user will always have to switch to the admin profile and therefore leave (and later resume) the application.

      No Fun
      Android Marshmallow (6.0) introduced a new Easter egg system restriction: UserManager.DISALLOW_FUN - Specifies if the user is not allowed to have fun. In some cases, the device owner may wish to prevent the user from experiencing amusement or joy while using the device. The default value is false

      What's next?


      Simplified browser UI with custom theme using a restricted profile (Firefox 42).

      With the current set of restrictions parents can create a kid-friendly and simplified browsing experience. Of course there are a lot of more possible features around parental controls that come to mind like block lists and restricting Web APIs (Microphone, Webcam). Some of these ideas have already been filed (Bug 1125710) and in addition to that we just started planning features for the next version (Bug 1205615). More ideas are definitely welcome!

      Testing and feedback


      At the time of this writing support for restricted profiles is available in Aurora (42.0) and Nightly (43.0) builds of Firefox. Restricted Profiles serve a very specific use case and therefore do not get as much usage coverage like other browser features. If you do have a tablet and are interested in restricted profiles then help us testing it! :)

      Contributing


      Firefox for Android is open-source software and contributors are very welcome! You can find me on IRC (irc.mozilla.org) in #mobile (my nickname is "sebastian"), on Twitter and Google+. Get involved with Firefox for Android.

      More resources about Project KidFox


      Nov 20, 2014

      Introducing Android Network Intents

      Android Network Intents is a library that I wrote for Lands of Ruin - a game that two friends and I are developing. To avoid a complicated network setup to play the game against a friend, we needed a way to discover games running on the local network. Android offers a Network Service Discovery (NSD) since API level 16 (Android 4.1) but we kept running into problems using it. This lead to writing this library.

      What does the library do?
      The library allows you to send Intents to listening clients on the local network (WiFi) without knowing who these clients are. Sender and receiver do not need to connect to each other. Therefore the library can be used to write custom discovery protocols.

      Sending Intents (Transmitter)
      An Intent is sent by using the Transmitter class. A TransmitterException is thrown in case of error.

      Sending an Intent

      Receiving Intents (Receiver)
      Intents are received using the Discovery class. Once started by calling enable() the Discovery class will spawn a background thread that will wait for incoming Intent objects. A DiscoveryListener instance will be notified about every incoming Intent.

      Writing a DiscoveryListener to receive events.

      Starting and stoping the discovery.

      Things you should know
      The Intents are sent as UDP multicast packets. Unlike TCP the UDP protocol does not guarantee that a sent packet will be received and there is no confirmation or retry mechanism. Even though losing a packet only happens rarely in a stable WiFi, the library is not intended for using as a stable communication protocol. Instead you can use it to find other clients (by sending an Intent in a periodic interval) and then establish a stable TCP connection for communication.

      On GitHub you can find a chat sample application using the library. While this is a convenient example, it is not a good use of the library for the reasons state above. You obviously do not want to lose chat messages.

      We are using the library for almost two years in Lands of Ruin and didn't observe any problems. However the game only runs on tablets so far. In theory the library should run on all Android versions back to API level 3 (Android 1.5) but this has obviously never been tested.

      You can find Android Network Intents on GitHub.

      Dec 24, 2013

      Hello World Immersion - Developing for Google Glass #2

      This article describes how to create a simple hello world application for Google Glass using the Glass Development Kit (GDK). As described in the previous article you have two options how your Glassware should show up on the device: As a live card that is part of the timeline or as an immersion that is displayed outside of the context of the timeline. This article focuses on how to write an immersion.

      What is an immersion?
      An immersion is basically an Android activity. The name immersion implies that it is not part of the normal Glass timeline. Instead it takes full control of the device - except for the back gesture (Swipe down). To go back to the timeline you need to leave the immersion.

      Once started an immersion takes full control of the screen.

      Project setup
      Create a normal Android project with the following settings:

      • Set minSdkVersion and targetSdkVersion to 15 (Android 4.0.3)
      • Set compileSdkVersion to "Google Inc.:Glass Development Kit Sneak Peek:15"
      • Do not assign a theme to your application or derive your own theme from Theme.DeviceDefault

      Creating the immersion
      Let's create a simple activity. The Card class helps us to create a layout that looks like a timeline card.

      HelloWorldActivity.java

      Launching the Glassware - Voice commands
      After creating the activity we need a way to start our Glassware. A common way to launch Glassware is to use a voice trigger. Let's add a simple voice trigger to start our hello world activity.

      First we need to declare a string resource for our voice command.

      strings.xml

      The next step is to create an XML resource file for the voice trigger using the previously created string value.

      voice_trigger.xml

      Now we can add an intent filter for the VOICE_TRIGGER action to our activity. A meta-data tag links it to the XML file we wrote above.

      AndroidManifest.xml

      The developer guide requires you to add an icon for the touch menu to the activity (white in color on transparent background, 50x50 pixels). The Glass Asset Studio is a helpful tool to generate these icons.


      The final Glassware
      Now we can start our Glassware by saying "ok glass, show hello world":


      Another option to start our Glassware is to use the touch menu and scroll to the "show hello world" command:


      The source code for this Hello World Glassware is available on GitHub.

      Dec 22, 2013

      Android 2013


      It's the end of the year - YouTube and Google Zeitgeist have posted their reviews. Let's have a look on what happened in the Android world in 2013.


      January
      2012 is over and the Nexus 4 is the current flagship phone made by Google and LG.

      February
      Google+ Sign-In is integrated into the Google Play Services and Google starts accepting applications for the Google Glass Explorer program.

      March
      The new Android developer console is out of preview. While Google Play celebrates it first birthday, the market share of Android hits 64%.

      April
      The tablet guidelines are updated and the Android developer console starts to show tablet optimization tips. Google pushes a Google Play app update that features a redesigned UI. Samsung releases it new flaship phone - the Samsung Galaxy S4.

      May
      The Google I/O takes place for three days from May 15th to 17th. This time there won't be a new Android release. Instead Google releases new game services and a new location API. At the Google I/O a new IDE for Android development is introduced: Android Studio. Since then every couple of weeks a new Android Studio update is pushed to the developer community.



      July
      A new flavor of Android Jelly Bean is released: Android 4.3. Open GL ES 3.0 and support for low-power Bluetooth Smart devices are some of the new features. Furthermore a new version of the Nexus 7 is released. Together with the new tablet Google releases the Chromecast dongle and the Google Cast SDK preview.

      August
      Google releases version 3.2 of the Google Play Services. The update includes several enhancements to the Location Based Services. With the r18 release of the support library Google released a new backward-compatible Action Bar implementation called ActionBarCompat. Motorola is releasing the Moto X - its first phone since the company has been acquired by Google. The same month Hugo Barra announces to leave Google after 5½ years to join the Xiaomi team in China.

      September
      RenderScript is now part of the support library and can be used on plaform versions all the way back to Android 2.2 (Froyo). Jean-Baptiste Queru, who worked on the Android Open Source Project at Google, starts a new job at Yahoo. Google launches the Android device manager website to locate, lock and ring misplaced devices.

      October
      After a lot of leaks and rumors a new Nexus phone is released on Halloween. Together with the Nexus 5 a new Android version - Android 4.4 KitKat - is published. Full-screen immersive mode, a new transitions framework, a printing framework and a storage access framework are some of the many new features. In addition to that he Google Play Services are updated to version 4.0. With Romain Guy another popular Android team member is leaving - but remaining at Google.

      November
      The App Translation Service, announced at Google I/O, is now available for every developer. Motorola releases a second phone - the Moto G. Android hits a new record with 80% market share. The Google Glass team releases a first sneak peek version of the Glass development kit (GDK).

      December
      Two small updates for Android KitKat are released: Android 4.4.1 and 4.4.2. The Android device manager is now available as an app.

      The Android Design in Action team releases its 2013 Recap:



      2014?
      What has been your Android highlight in 2013 and what are your wishes for 2014?

      Dec 16, 2013

      Mirror API and GDK - Developing for Google Glass #1

      I recently got my hands on Google Glass and decided to write some articles about developing applications for Glass. After all it's Android that is running on Glass.

      What is Glass?
      It's very complicated to explain Google Glass just using text. Only wearing and using it will give you this aha moment. However the following video, made by Google, gives you a good impression about how it feels like.


      What is Glass from a developer's point of view?
      Google Glass is an Android device running Android 4.0.3. What you see through Glass is basically a customized Launcher / Home screen application (a timeline of cards about current and past events) and a slightly different theme. This makes it really interesting for Android developers to develop for Glass: You can use almost all the familiar Android framework APIs. However wearing Glass feels totally different than using a mobile phone. So there's a big difference in designing applications. But not only the UI is different: You can't just port an existing application to Glass. Use cases have to be designed especially for Glass. Some features of your app might not make sense on Glass. Some other interesting features might only be possible on Glass. It's almost impossible to get a feeling for that without using Glass for some days.

      Back to writing code.. Currently we can decide between two ways to develop for Glass: The Mirror API or an early preview of the Glass Development Kit (GDK). Let's have a look at both and see what they are capable of.

      The Mirror API
      The Mirror API has been the first API that has been introduced by the Glass team. It's a server-side API meaning the applications don't run on Glass itself but on your server and it's your server that interacts with Glass.

      The Mirror API is great for pushing cards to the timeline of Glass and sharing content from Glass with your server application.

      Some examples of applications that could use the Mirror API:
      • Twitter client: The server pushes interesting tweets to the timeline of the Glass owner. The user can share photos and messages with the application and they will be posted to the Twitter timeline.
      • Context-aware notifications: Your server subscribes to the user's location. Every now and then your server will receive the latest user location. You use this location to post interesting and related cards to the timeline of the user.

      More about the Mirror API:
      With the GDK you can build Android applications that run directly on Glass. Think of the GDK as Android 4.0.3 SDK with some extra APIs for Google Glass. It's worth mentioning that the GDK is currently in an early preview state. The API is not complete and some important parts are missing.

      When developing Glass you have two options how your application should show up on Glass:

      Live Cards

      How a live card shows up in the Glass timeline.

      Your application shows up as a card in the timeline (left of the Glass clock). You have again two options how to render these cards:
      • Low-Frequency Rendering: Your card is rendered using Remote Views. Think of it as a Home screen widget on Android phones. A background service is responsible for updating these views. You only update the views every now and then.
      • High Frequency Rendering: Your background service renders directly on the live card's surface. You can draw anything and are not limited to Android views. Furthermore you can update the card many times a second.
      Immersion

      An Immersion is not part of the timeline but "replaces" it.


      An immersion is at the bottom a regular Android activity. For your activity to look like a timeline card:
      • Don't assign a theme to your activity or use the DeviceDefault theme as base for your customization.
      • Even though you can use the touch pad of Glass almost like a d-pad: Try to avoid most input-related Android widgets. They don't make much sense on Glass because you are not using a touch screen. Instead try to use gestures with the GestureDetector class or voice input.
      • Use the Card class and its toView() method to create a view that looks like regular Glass card.

      More about the GDK

      Aug 22, 2013

      Read the code: IntentService

      In the new category Read the code I’m going to show the internals of the Android framework. Reading the code of the framework can give you a good impression about what’s going on under the hood. In addition to that knowing how the framework developers solved common problems can help you to find the best solutions when facing problems in your own app code.

      What is the IntentService class good for?
      This article is about the IntentService class of Android. Extending the IntentService class is the best solution for implementing a background service that is going to process something in a queue-like fashion. You can pass data via Intents to the IntentService and it will take care of queuing and processing the Intents on a worker thread one at a time. When writing your IntentService implementation you are required to override the onHandleIntent() method to process the data of the supplied Intents.

      Let’s take a look at a simple example: This DownloadService class receives Uris to download data from. It will download only one thing at a time with the other requests waiting in a queue.

      DownloadService


      The components
      Before we dip into the source code of the IntentService class, let's first take a look at the different components that we need to know in order to understand the source code.

      Handler (documentation) (source code)
      You may already have used Handler objects. When a Handler is created on the UI thread, messages can be posted to it and these messages will be processed on the UI thread.

      ServiceHandler (source code)
      The ServiceHandler inner-class is a helper class extending the Handler class to delegate the Intent wrapped inside a Message object to the IntentService for processing.

      ServiceHandler inner class of android.app.IntentService

      Looper (documentation) (source code)
      The Looper class has a MessageQueue object attached to it and blocks the current thread until a Message is received. This message will be passed to the assigned Handler. After that the Looper processes the next message in the queue or blocks again until a message is received.

      HandlerThread (documentation) (source code)
      A HandlerThread is a Thread implementation that does all the Looper setup for you. By creating and starting a HandlerThread instance you will have a running thread with a Looper attached to it waiting for messages to process.

      Read the code!

      Now we know enough about all the components to understand the IntentService code.

      onCreate()

      IntentService.onCreate()

      At first a HandlerThread is created and started. We now have a background thread running that already has a Looper assigned. This Looper is waiting on the background thread for messages to process.

      Next a ServiceHandler is created for this Looper. The Handler’s handleMessage() method will be called for every message received by the Looper. The ServiceHandler obtains the Intent object from the Message and passes it to the onHandleIntent() method of the IntentService.

      onStart()

      IntentService.onStart()

      The onStart() method is called every time startService() is called. We wrap the Intent in a Message object and post it to the Handler. The Handler will enqueue it in the message queue of the Looper. The onStart() method is deprecated since API level 5 (Android 2.0). Instead onStartCommand() should be implemented.

      onStartCommand()

      IntentService.onStartCommand()
      In onStartCommand() we call onStart() to enqueue the Intent. We return START_REDELIVER_INTENT or START_NOT_STICK depending on what the child class has set via setIntentRedelivery(). Depending on this setting an Intent will be redelivered to the service if the process dies before onHandleIntent() returns or the Intent will die as well.

      onDestroy()

      IntentService.onDestroy()
      In onDestroy() we just need to stop the Looper.

      Conclusion

      The IntentService code is quite short and simple, yet a powerful pattern. With the Handler, Looper and Thread class you can easily build your own simple processing queues.

      Oh, and if you are looking for an exercise. The code of the onCreate() method contains a TODO comment that I omitted above:

      TODO in onCreate()