Author Archives: Android Developers

Google releases source for Google I/O 2017 for Android

Posted by Shailen Tuli

Today we're releasing the source code for the official Google I/O 2017 for Android app.

This year's app substantially modifies existing functionality and adds several new features. It also expands the tech stack to use Firebase. In this post, we'll highlight several notable changes to the app as well as their design considerations.

The most prominent new feature for 2017 is the event reservation system, designed to help save in-person attendees' time and provide a streamlined conference experience. Registered attendees could reserve sessions and join waitlists prior to and during the conference; a reservation provided expedited entry to sessions without having to wait in long lines. Reservation data was synced with attendees' conference badges, allowing event staff to verify reservations using NFC-enabled phones. Not only was the reservation feature incredibly popular, but the reservation data helped event staff change the size of session rooms both before and during I/O to adjust for actual demand for seats.

The reservation feature was implemented using Firebase Realtime Database (RTDB) and Cloud Functions for Firebase. RTDB provided easy sync across user devices — we just had to implement a listener in our code to receive database updates. RTDB also provided out-of-the-box offline support, allowing conference data to be available even in the face of intermittent network connectivity while traveling. A Cloud Function processed reservation requests in the background for the user, using transactions to ensure correctness of state (preventing mischievous users from grabbing too many seats!) and communicating with the event badging system.

As in previous years, we used a ContentProvider as an abstraction layer over all app data, which meant we had to figure out how to integrate RTDB data with the ContentProvider. We needed to negotiate between having two local caches for data: 1) the extant local SQLite database accessed via the ContentProvider, and 2) the local cache created by RTDB to facilitate offline access. We decided to integrate all app data under the ContentProvider: whenever reservation data for the user changed in RTDB, we updated the ContentProvider, making it the single source of truth for app data at all times. This meant that we needed to keep open connections to RTDB only on a single screen, the Session Detail Activity, where users might be actively managing their reservations. Reservation data displayed in other parts of the app was backed by the ContentProvider. In offline mode, or in case of a flaky or delayed connection to RTDB, we could just get the last known state of the user's reservations from the ContentProvider.

We also had to figure out good patterns for integrating RTDB into the overall sync logic of IOSched, especially since RTDB comes with a very different sync model than the ping-and-fetch approach we were using in the app. We decided to continue using Cloud Endpoints to synchronize user data across devices and with the web and iOS clients (the data itself was stored in Datastore). While RTDB provides out-of-the-box data syncing, we wanted to make sure that a user's reservation data was current across all devices, even when the app was not in the foreground. We used a Cloud Function to integrate RTDB reservation data into the sync flow: once reservation data for a user changed in RTDB, the function updated the endpoint, which triggered a Firebase Cloud Messaging downstream message to all the user's devices, which then scheduled data syncs.

This year's app also featured a Feed to apprise users about hour-by-hour developments at I/O (most of the app's users were remote, and the Feed was a window into the conference for them). The Feed was also powered by RTDB, with data pushed to the server using a simple CMS. We used a Cloud Function to monitor RTDB feed data; when feed data was updated on the server, the Function sent a Cloud Messaging downstream message to clients, which visually surfaced the presence of new feed items to the user.

In 2015 and 2016, we had adopted an MVP architecture for IOSched, and we continued using that this year. This architecture provides us with good separation of concerns, facilitates testing, and in general makes our code cleaner and easier to maintain. For the Feed feature, we decided to experiment with a more lightweight MVP implementation inspired by Android Architecture Blueprints, which provided the necessary modularity while being very easy to conceptualize. The goal here was both pedagogical and practical: we wanted to showcase an alternate MVP pattern for developers; we also wanted to showcase an architecture that was an appropriate fit for our needs for this feature.

For the first time, IOSched made heavy use of Firebase Remote Config. In the past, we had found ourselves unable to inform users when non-session data - wifi information, shuttle schedule, discount codes for ridesharing, etc. - changed just before or during the conference. Forcing an app update was not feasible; we just wanted in-app default values to be updatable. Using remote config easily solved this problem for us.

In the end, we ended up with a three-tier system of informing users about changes:

  1. Conference data and user data changes were communicated via Cloud Messaging and data syncs (ping and fetch model).
  2. Feed data changes were controlled via RTDB.
  3. Changes to in-app constants were controlled via Remote Config.

Future plans

Even though we're releasing the 2017 code, we still have work ahead of us for the coming months. We'll be updating the code to follow modern patterns for background processing (and making our app "O" compliant), and in the future we'll be adopting Android's Architecture Components to simplify the overall design of the app. Developers can follow changes to the code on GitHub.

500 million devices now supported for Android Instant Apps

Posted by Jonathan Karmel

Since our public launch at Google I/O this year, we've been hard at work expanding the number of supported devices and the availability of instant apps, so that users can run your apps instantly, without installation. We're excited to announce that 500 million Android users now have access to instant apps across countries where Google Play operates.

A number of Google Play apps and games businesses across a range of industries have already started building with instant apps. Following the launch of their instant apps, they have seen strong results in engagement, acquisition and retention.

Vimeo: WIth more than 50M creators and 240M viewers worldwide, Vimeo has built a platform whereby people can easily share videos with friends. The company wanted to implement Android Instant Apps to enable their audience to easily immerse themselves in content through a native app experience. Vimeo increased session duration by 130% with their instant app. Discover how Vimeo drove increased engagement with their instant app.
Jet: Based in the US, Jet provides a shopping platform, using a real-time savings engine to surface opportunities for customers to pay less. The company wanted to expand the reach of their existing app, and updated their app in order to support instant apps. Following the launch of their instant app, Jet found that their conversion rate increased by 27%. Learn about how Jet launched their instant app.
NYTimes Crosswords: The NYTimes Crosswords instant app provides users with crossword puzzles as printed in the New York Times daily newspaper. Their aim was to create a more native experience for their audience, increasing app engagement. Instant apps have 2x the number of sessions per user. Based on early results, they are also seeing more effective acquisition, conversion, and long term retention. Learn more about how NYTimes increased app sessions.
dotloop: dotloop is a real estate transaction platform which makes it easier for real estate professionals to interact with home buyers and sellers, and for them to be able to sign documents anytime, anywhere. Their aim for instant apps was to provide more users a native app experience for the signing process of documents. dotloop increased their key metric with a 62% increase in users who sign a document. Discover how dotloop supported Android Instant Apps and increased engagement.
Onefootball: Based in Berlin, the app provides news, live scores, fixtures, results, tables and stats for over 230 leagues and 15 languages. Onefootball built an instant app by reducing its APK size alongside other updates. The number of users who read news and share content increased 55% in their instant app. Find out more about how Onefootball increased engagement following their launch.
Realtor.com: A leading online real estate destination that attracts nearly 60 million unique visitors each month to its desktop and mobile platforms. Realtor.com enabled Android Instant Apps support by modularizing its 12 MB app into instant app modules. With Instant Apps, Realtor.com increased their key conversion metrics having doubled the number of leads per property listing details pageview. Find out how Realtor.com reduced its instant app APK size.

Learn more best practices for managing your download size with Android Instant Apps, and also visit g.co/instantapps for more information on building instant apps and get started today!

How useful did you find this blogpost?

Android Instant Apps: Best practices for managing download size

Posted by Maru Ahues Bouza, Developer Relations Partner, Google Play
Android Instant Apps provides rich, native experiences at the tap of a web link. People can experience your app without upfront installation, enabling a higher level and quality of engagement.
However, to provide comparable latency of loading a mobile webpage, an instant app needs to be lean and well structured, so it can be downloaded and run quickly in response to a URL tap. In light of that, we encourage that the binary loaded in response any entry-point URL is as small as possible, with a maximum of 4MB. The smaller the binaries, the faster the instant app will load and the smoother the user experience.
This document will propose best practices for managing the application structure and binary size to enable a smooth instant app experience. These practices will also benefit your installable app.

Refactoring your codebase

The biggest binary size benefit comes from refactoring your app into multiple feature modules. Even if your current size and feature set don't require multiple features, we recommend designing for it, so you can quickly add more features in the future without affecting the binary size of existing features. We also highly recommend having a unified modular codebase to produce both installable and instant application binaries, as this will reduce the burden of maintaining separate projects and code and provide a cleaner project structure across both. Based on the experience of our early access partners, we believe this will have the largest impact to the binary size at download. However, it also requires the most investment.
To get to that end, you can start with a single (base) module and then refactor code by moving relevant portions to feature module(s). Note that you do not need to worry about the binary size while developing your instant app, as the size limit does not apply for locally built binaries. You can also publish your binary through the Play Developers Console to the Development track (special track for quick deployment of your instant app during development), where the size limit is 10MB. [1, 2] The 4MB restriction is applied once your binary graduate out of the Development track.
Each feature module can have one (or more) entry points – activities – that correspond to a given URL. When splitting a single code base into multiple modules, you will have different entry points for different features, and the platform will load the relevant feature as needed. Remember, the total binary to be downloaded for any given entry point should be under 4MB, so the combined size of any feature module and the base module must be below 4MB.
It is advised to define the feature–activity–entry point mappings first, and then structure the refactoring effort towards reducing the binary size for each entrypoint..
Also consider how your libraries are included. If a specific feature module requires certain libraries they should be included in the feature module only, instead of being added in the base APK. This will reduce the size of the base module. For example, let's say you have an application that depends on libraries X, Y, and Z. Initially, you may pack all the libraries in the base module by placing all the dependencies in the base gradle.build file. But if only the code in the feature module requires library Z, it makes sense to move that dependency from the base module to the feature module.This works as long as no other feature modules depend on the same library. If multiple feature modules use the same library it definitely makes sense to keep it in the base module.

Lint checks

Many apps tend to acquire a lot of resources, and over a period of time, some of them are no longer used. Android Studio has useful built in lint check for unused resources. Press Alt+Ctrl+Shift+I (Cmd+Alt+Shift+I on Mac OS), type "unused resources" and start "Unused resources Android|Lint|Performance" inspection. It helps to reduce the size of the installable APK as well.

String resources

Similar to resources, pay attention to strings, not all of them may be in use, and typically the application size can be reduced significantly by removing unused string resources. If application supports multiple languages, you may want to reduce the number of localized resources, as it typically removes large chunks of the resources assets. This is especially important if the app supports only a few languages but uses AppCompat library, which includes messages in multiple languages. Use resConfig to select specific resources configurations only. Hint: typically you can use "auto" to restrict configurations pulled from third-party libraries to match the set of configurations defined in your project.

Switch to WebP

Significant reduction of the drawable resources size may be achieved by switching to WebP images instead of PNGs. Android Instant Apps supports all features of the WebP format (transparency, lossless, etc.) so there will be no loss in functionality. Keep in mind that application launcher icons must use PNG format, but it should not be a problem since projects normally keep those in mipmap- directories. If a backward compatible solution is required, you need to include the original PNG images in the APK module and it will override WebP resources automatically (main source set overrides all resources from AAR/feature module). [4]
Of course, going with vector drawables may let you save even more of the precious space, but using vector drawables will require a code change while the above mentioned trick with WebP images for the instant app and PNG images for the installable APK requires no code modifications.

Download assets at runtime

Finally, remember that technically there is no need to pack all the resources in the instant app APKs, as the application can download additional assets at run time. This approach also enables the app to download the required assets only. These modifications may require significant changes to the code base, but will also help you to reduce the size of the installable APK.
If shrinking resources does not bring your app feature modules size under the limit, it is time to look for the ways to reduce the code size.

Review native libraries

Some third-party libraries may include native code, which may not be used in the instant app at all. So the first step is to review the native libraries packaged within the APK and make sure the instant app has only those that are actually used. Remember to look into the compiled APK using APK Analyzer (Build -> APK Analyzer…) [5]

Review external libraries

Next review the list of all external libraries linked with the app's code. You may find some unexpected surprises courtesy of transitive dependencies. Transitive dependencies occur when the library your project relies upon depends on another library, which in turn may depend on yet another library. Sometimes those transitive dependencies may contain unexpected surprises such as libraries you do not need at all (i.e. a JSON processing library you never use in your code.) Please see "Excluding transitive dependencies" section in the Gradle User Guide for further details.
Android Studio has several useful tools for analyzing the external dependencies for the project. It always helps to start with the Project view:
The "Project" view shows a section called "External libraries", where you can see all the libraries used by the project including any transitive dependencies:
In order to further reduce the base feature size you may need to pay attention to the code dependencies and external libraries. Check the "Project" view and look for unused libraries that might be transitive dependencies the project does not need. Also look for libraries that provide the same functionality (e.g. multiple libraries for image loading/caching). [4]
You can also compare different builds with APK Analyzer tool, and it works with instant APKs, too.
Finally, review the list of transitive dependencies and exclude the ones you do not need. Use the following command to review the dependencies graph: gradle -q :MODULE:dependencies --configuration compile. Further details can be found in the Gradle documentation.

Other tips

Android Studio 3.0 includes the App Links Assistant tool, which can help to generate the necessary intent filters, and help in splitting the project into several modules. [3]
Once you got the instant app bundles under the size limit, it is the time to make sure the building process is up to date. Check that the application package and instant app APKs are signed using the "APK Signature Scheme v2". If you sign the APKs using the latest version of the SDK tools, everything should be done automatically. However, if you manually sign the build artifacts you need to avoid using jarsigner and switch to apksigner instead.
And a few useful tips for adapting the app's code to the instant runtime environment. Keep in mind that having a small branches of code for instant/installable applications, based on the InstantApps.isInstantApp(...), should be fine and typically does not make the source code unreadable (unless you abuse it, of course). Also, when using share intents make sure the code does not explicitly enumerate applications installed on the device, instant app security model does not allow that. Simply use regular Intent.createChooser() to present the list of all possible actions to the user.
The level of effort of developing an instant app for an existing Android application varies across developers and is heavily dependent on how your application is organized today. For some, it will be easy as your project is already organized as multiple modules. However, for some, the focus will be on reducing the code and resource assets size, and we have introduced tools and Android platform features above to help you with that.

Hear from other developers using Android Instant Apps

Finally, check out these great posts by developers that have already built an instant app:
Visit the Android Developers website to get started with Android Instant Apps and check out more instant apps success stories from other developers.

Playdemic drives user engagement and revenue with live game operations on Google Play

Posted by Adriana Puchianu, Developer Marketing, Google Play

Based in the UK, Playdemic is a free-to-play mobile games developer. Their leading game Golf Clash is designed to provide a short and fun, competitive experience. It uses a simple and accessible game mechanics based on one-thumb gaming which has generated substantial user engagement, with an average of 44 minutes played over three sessions a day. Golf Clash is now played by more than 1.5 million players every day whilst the average revenue per user is equal to other platforms.

Watch Paul Gouge, CEO & Co-founder, and Gareth Jones, Head of Production, discuss how Playdemic uses live game operations ("live ops") to continuously engage players and grow their business on Google Play. Live ops are also referred to as "running games as a service"; they include the strategic distribution of content and interactions with players that are limited in time and are designed to increase engagement and monetization.

Watch more developer stories and learn about other features and best practices you can use to succeed on Google Play with the updated Playbook app.

How useful did you find this blogpost?

Build a subscriptions business on Google Play with these new features and best practices

Posted by Tom Grinsted, Product Manager

Subscriptions can be a sustainable source of revenue, allowing you to invest in your long-term business growth with confidence. Subscription apps are growing rapidly on Google Play; the number of subscribers doubled in the last year and spend on subscriptions has increased 10-times over the past three years. To help the growing number of subscription businesses we're seeing, we introduced the subscriptions dashboard in the Google Play Console at I/O 2017. Today, we're adding three new subscription reports covering acquisition, retention, and cancellations to help you understand your data and make informed business decisions. Find information below on the new features, our updated best practices to help you grow your subscriptions business, and stories from other developers succeeding on Google Play.

New subscription reports now available in the Google Play Console

Three new subscription reports in the Google Play Console

The acquisition report enables you to evaluate different acquisition channels, including Adwords and UTM-tagged campaigns. This can help you identify which channels and campaigns are the most successful in acquiring new subscribers.

The retention report displays the lifetime retention of a customized cohort of your subscribers. It allows you to easily compare different subscription products, plots key events such as the end of a free trial, and provides forecasts to enable you to make decisions faster.

Finally, the cancellations report. This detailed cancellation data shows when a user cancels, either voluntarily (such as when they choose to cancel) or involuntarily (for example, when there is payment failure). You can also see whether the cancellation was accompanied by the person uninstalling.

We're continually working to improve the Google Play Console. If you have ideas or feedback on how we can improve the subscriptions features, please let us know.

Take advantage of the new Google Play Billing Library

To benefit from these features, you need to be using Google Play Billing as the payment method for subscriptions in your app. Implementing Play Billing is easy with the new Google Play Billing Library. We've also updated Play Billing so the billing permission will be enforced when the buyer tries to initiate a purchase rather than when you publish your app. This means you can publish a single APK in both Play Billing supported and non-supported countries (rather than maintaining a separate APK that does not use the Billing permission for non-supported countries). Remember to check first if billing is supported before trying to offer any in-app purchases.

Become a 'subscriptions first' company and succeed on Google Play

As developers become more sophisticated with their subscriptions offerings on Google Play, our most successful partners have learned a lot about what does and doesn't work well. Niko Schröer, a partner manager with expert knowledge of subscription apps, has a new post on Medium to help you become a successful subscriptions company. In the post, you'll find a link to our detailed user research on Android subscribers [PDF] published in June 2017, which offers helpful insights into what users look for in a subscription product. We've also published some new best practices on subscriptions, which you can read along with other tips to succeed on Google Play in the Playbook app.

How other developers are succeeding with subscriptions on Play

Viki, a Singapore based video app, uses subscriptions to build a sustainable and predictable revenue stream, allowing them to invest in original content and provide better premium experiences for their users. Total revenue from subscriptions grew over 200% over the year, and by 700% in emerging markets like the Middle East and Latin America. Watch Alex Chan, Senior VP of Product and Engineering at Viki, tell the story.

The developer of Anghami, a popular music service in the Middle East and North Africa, increased the number of subscribers in their app with user interface experiments and introductory pricing. During one promotional period, Anghami used introductory pricing to increase new sign-ups by 400% compared to their average daily sign-ups. Find out more about how Anghami achieves subscription success.

How useful did you find this blogpost?

Next-generation Dex Compiler Now in Preview

Posted by James Lau, Product Manager

Android developers know that dex compilation is a key step in building an APK. This is the process of transforming .class bytecode into .dex bytecode for the Android Runtime (or Dalvik, for older versions of Android). The dex compiler mostly works under the hood in your day-to-day app development, but it directly impacts your app's build time, .dex file size, and runtime performance.

That's why we are investing in making important improvements in the dex compiler. We're excited to announce that the next-generation dex compiler, D8, is now available for preview as part of Android Studio 3.0 Beta release.

When comparing with the current DX compiler, D8 compiles faster and outputs smaller .dex files, while having the same or better app runtime performance.

* Tested with benchmark project here.
*Tested with benchmark project here.

How to try it?

D8 is available for your preview starting with Android Studio 3.0 Beta. To try it, set the following in your project's gradle.properties file:

android.enableD8=true

We have tested D8's correctness and performance on a number of apps, and the results are encouraging. We're confident enough with the results that we are switching to use D8 as the default dex compiler for building AOSP. There are currently no known issues, but we would love to hear your feedback. You can file a bug report using this link.

What's next?

We plan to preview D8 over the next several months with the Android Studio 3.0 release. During this time, we will focus on addressing any critical bug reports we receive from the community. We plan to bring D8 out of preview and enable it as the default dex compiler in Android Studio 3.1. At that time, the DX compiler will officially be put in maintenance mode. Only critical issues with DX will be fixed moving forward.

Beyond D8, we are also working on R8, which is a Proguard replacement for whole program minification and optimization. While the R8 project has already been open sourced, it has not yet been integrated with the Android Gradle plugin. We will provide more details about R8 in the near future when we are ready to preview it with the community.

Tool developers: get your bytecode tools Java 8 ready

In April, we announced Java 8 language features with desugaring. The desugaring step currently happens immediately after Java compilation (javac) and before any bytecode reading or rewriting tools are run. Over the next couple of months, the desugar step will move to a later stage in the pipeline, as part of D8. This will allow us to further reduce the overall build time and produce more optimized code. This change means that any bytecode reading or rewriting tools will run before the desugar step. If you develop .class bytecode reading or rewriting tools for Android, you will need to make sure they can handle the Java 8 bytecode format so they can continue to work properly when we move desugaring into D8.

Happy dex'ing!

Android Things Developer Preview 5

Posted by Wayne Piekarski, Developer Advocate for IoT

Today, we're releasing Developer Preview 5 (DP5) of Android Things, which includes the major change of being based on the upcoming Android O release. Android Things is Google's platform to enable Android Developers to create Internet of Things (IoT) devices, and seamlessly scale from prototype to production.

Android O

Android O is currently under Developer Preview for phones and tablets, and DP5 is now based on this upcoming release (previous releases were based on Android N). This means that your future Android Things applications should target API 26 to work correctly on the platform with our support libraries.

Hardware Changes

DP5 now adds support for the new NXP SprIoT i.MX6UL design, as listed in our developer kits documentation. With Intel discontinuing the Edison and Joule hardware designs, these platforms are moving to legacy support. They will not continue to receive the latest platform updates, but developers may continue to access the DP4.1 system images from the Android Things Console.

An important goal of Android Things is to help developers seamlessly scale from prototype to production. When we exit Developer Preview, we will differentiate between hardware platforms targeted for prototyping-only and hardware reference designs that can scale to production. Production-ready hardware will satisfy Google's security requirements and include long term support from the silicon manufacturers. We will have more to share later on.

Improvements

With the move to the Android O codebase, there are new API features from Android as well as specific features for Android Things. For those developers using UserDriver APIs, you will need to add new permissions to your AndroidManifest.xml. The documentation contains details about the permissions needed for each driver type. DP5 also now supports OpenGL ES 2.0 and WebView on the Raspberry Pi 3, which was a highly requested feature from developers. We have also implemented dynamic pin muxing for the Raspberry Pi 3, with pins being configured at runtime depending on what features are being used.

Android Studio

The samples for Android Things are now available directly in Android Studio for browsing and importing. You can now go to File, New, Import Samples, and search for Things to see everything that is available. We have a wide range of samples, demonstrating how to interact with buttons, sensors, LEDs, and displays, as well as implementing Google Assistant and TensorFlow.

Android Things Console

We recently launched the Android Things Console, which provides the ability to support over-the-air updates (OTA) to Android Things devices. We have recently made a number of UX improvements to the console to improve usability and functionality. DP5 is now available within the Android Things Console, but the DP5 update will not be pushed automatically to devices without your intervention. You will need to update your application for DP5, then create a new update and push it via the console yourself.

Feedback

With Android Things being updated to Android O, significant changes have been made to the platform. Please send us your feedback by filing bug reports and feature requests, and asking any questions on Stack Overflow. To start using DP5, use the Android Things Console to download system images and update existing devices. More information about the changes are available in the release notes. You can also join Google's IoT Developers Community on Google+, a great resource to get updates and discuss ideas. Also, we have our new hackster.io community, where everyone can share the amazing projects they have built!

Your next growth market on Google Play: launch your title in Russia

Posted by Dmitri Martynov, Business Development, Google Play

For many international developers Russia is considered to be an opportunity to grow their app or games business. According to the 2017 report on the 'Mobile Internet Economy in Russia [PDF]', Russia's population is young with 45% of people being under 35 years old.1 The report also found that mobile subscriptions are at 160% of the population of 146 million people, meaning people with data plans have more than one on average – considerably higher than other well connected countries.2 Last year Android accounted for 84% of all smartphones in Russia and smartphone shipments are still growing with demand up 11% in early 2017 compared to 2016.

Russian people are very engaged in terms of smartphone mobile usage, Russia is one of the top countries in terms of apps downloaded per person3. Half of the population are gamers; their favorite game genres being strategy, builders and farms, shooters, puzzles and fighters. The most popular app categories are dating (with strong local developers), music & video, social & messaging and shopping.4

Tips to help you successfully localize for Russian

Along with understanding Russian mobile trends, there are market specific best practices which can help you tailor your apps and games for a local audience to increase your chance of business success.

  • Language localization
    • Proofread and quality assure your entire app or game after translating text resources and visual assets. After localization, you should quality assure your app or game as a whole and not just text resources.
    • Use proficient native speakers. Contextually relevant translations are best done by native speakers familiar with mobile apps or games terminology.
    • Localize all content where possible. Aim to provide as much localized content as possible, providing a similar level in the local language as the original.
    • Ensure consistent language and style. Semantically check the translated text in the context of the whole app/game experience to make it look and sound relevant to local users. Ensure use of consistent language style (such as formal/informal addressing) and use of the same terms or names across all the text and visual assets.
    • Don't forget language rules. Follow language rules on quantities, gender, word breaking, acronyms, etc. If the user gender is unknown, consider making a careful choice of words so that to omit specifying user's gender or use a passive voice.
    • Be aware of the length of translated text. In Cyrillic languages words and phrases tend to be longer than English, and might not fit into a tightly designed UI. Be creative in finding alternative contextually and locally relevant alternative translations.
    • Use local date and time formats. Check the country specific date / time format which local users are familiar with.
    • Take note of the "you" translation. "You" translation is contextual and can be translated to singular (similar to early modern english thou) or plural form (when refer to multiple people or in polite form). And as a reminder, when choosing to address your user informally ("thou"), make sure to avoid specifying user's gender, unless it is known.
  • Play Store assets
    • Provide localized store assets, such as the title (for example when title is not a universally known brand), store listing, screenshots and videos. Do not forget to localize the "what's new" section if included.
    • Avoid keywords in your app or game title which attempt to improve its visibility on the Play Store.
  • Local pricing, price points, rounding rules
    • Avoid adding your own currency indicators (such as $ or £) as some markets use local pricing - find out more about local pricing. Use the Russian Ruble official symbol (₽) after the number with a space, and use comma as a decimal separator, e.g. 49,99 ₽.
    • Generally, in-app, subscriptions, or paid app/games prices should be lower than in Western markets. Research industry best practices and experiment which price points are best for your app or game business model.
    • Make sure price rounding follows the "99" or "49" rules. Use the Google Play Console to set local prices.
  • Text resources
    • Avoid abbreviations, and if shortening is absolutely necessary, follow language rules to shorten words.
    • Avoid breaking single words and punctuation into a new line. Follow language rules of breaking words across lines (such as app- and -lication).
    • Ensure consistent font styles. Some font families may be displayed differently in non-English locales. Always check how your chosen font will be displayed on user devices in different locales.
  • In-game visual and audio assets
    • When appropriate and relevant, consider localizing visual assets in addition to text strings. Pay attention to splash screens!
    • Localize video and audio, and use native speakers to make it sound locally relevant.

For more guidance, read the localization checklist.

Nominate your title for the "Now in Russian" collection on the Google Play Store

On July 24st we launched the first Now in Russian collection on Google Play, featuring 24 titles from international developers such as Kabam's Transformers, GTarcade's Legacy of Discord, Yodo1's Crossy Road, im30's Last Empire - War Z and others.

We are planning to refresh the collection by the end of the year and we would love to include your title! Submit your recently localized title for a chance to be included.

How useful did you find this blogpost?

How we’re helping people find quality apps and games on Google Play

Posted by Andrew Ahn, Product Manager, Google Play

People enjoy using apps and games which meet their performance and quality expectations. Excessive battery usage, slow render times, and crashes, on the other hand, can be a source of frustration. In fact, in an internal analysis of app reviews on Google Play, we noticed that half of 1-star reviews mentioned app stability. Developers who focus on app quality can see improvements in their rating, and ultimately their retention and monetization.

As part of our continued effort to deliver the best possible Google Play experience, we recently enhanced our search and discovery algorithms to reflect app quality. This results in higher quality apps being surfaced in the Play Store more than similar apps of lower quality (eg: apps that exhibit more frequent crashes). The change has had a positive impact on engagement -- we've seen that people go on to use higher quality apps more and uninstall them less.

Developers focusing on performance can use the Play Console to help find and fix a number of quality issues. Android vitals identifies key performance issues, reported by opted-in devices which have your app installed, so you can address them. The pre-launch report shows you the result of testing your alpha or beta app on popular physical devices so you can catch issues before launching updates. Also, ratings and reviews can provide additional insights related to app quality, directly from people using your app. To see the positive effect this can have, find out how Busuu increased their rating from 4.1☆ to 4.5☆ by focusing on app performance.

Google Play strives to help people find and discover safe, high quality, useful, and relevant apps. By focusing on the quality and performance of your app, you'll find more success on Google Play. For more tips and best practices to grow your app or game business, get the Playbook app.

How useful did you find this blogpost?

Android Bug Swatting with Sanitizers

Posted by Dan Austin, Android Security team

LLVM, the compiler infrastructure used to build Android, contains multiple components that perform static and dynamic analysis. One set of these components that have been used extensively when analyzing Android are the sanitizers, specifically AddressSanitizer, UndefinedBehaviorSanitizer and SanitizerCoverage. These sanitizers are compiler-based instrumentation components contained in compiler-rt that can be used in the development and testing process to push out bugs and make Android better. The sanitizers that are currently available in Android can discover and diagnose many memory misuse bugs and undefined behavior and can give code coverage metrics to ensure that your test suite is as complete as possible.

This blog post details the internals of the current Android sanitizers—AddressSanitizer, UndefinedBehaviorSanitizer and SanitizerCoverage—and show how they can be used within the Android build system.

Address Sanitizer

AddressSanitizer (ASan) is a compiler based instrumentation capability that allows for runtime detection of many types of memory errors in C/C++ code. In Android, the checks for the following classes of memory errors have been tested:

  • Out-of-bounds accesses to heap, stack and globals
  • Use-after-free
  • Use-after-return (runtime flag ASAN_OPTIONS=detect_stack_use_after_return=1)
  • Use-after-scope (clang flag -fsanitize-address-use-after-scope)
  • Double-free, invalid free

Android allows for full build instrumentation by ASan, and also allows for ASan instrumentation at the app level through asanwrapper. Instructions for both instrumentation techniques can be found on source.android.com.

AddressSanitizer is built upon two high-level concepts. The first is instrumentation of all memory-related function calls, including alloca, malloc, and free, with information to track memory allocation, free, and usage statistics. This instrumentation allows for ASan to detect invalid memory usage bugs including double-free, use-after scope, return, and free. ASan can also detect reads and writes that occur out of bounds of defined memory regions. It does this by padding all allocated memory buffers and variables. If a read or write to this padding region occurs, ASan catches it and outputs information useful for diagnosing the memory violation. This padding is known as poisoned memory in ASan terms. Here is an example of what poisoned memory padding looks like with stack allocated variables:

Figure 1. Example of ASANified stack variables with an int8_t array of 8 elements, a uint32_t, and an int8_t array of 16 elements. The memory layout after compiling with ASAN is on the right, with padding between each variable. For each stack variable, there are 32 bytes of padding before and after the variable. If the object size of a variable is not 32 bytes, then an additional 32 - n bytes of padding are inserted, where n is the object size.

ASan uses shadow memory to keep track of which bytes are normal memory and which bytes are poisoned memory. Bytes can be marked as completely normal (marked as 0 in shadow memory), completely poisoned (high bit of the corresponding shadow byte is set), or the first k bytes are unpoisoned (shadow byte value is k). If shadow memory indicates a byte is poisoned, then ASan crashes the program and outputs information useful for debugging purposes, including the call stack, shadow memory map, the type of memory violation, what was read or written, PC that caused the violation and the memory contents.

AddressSanitizer: heap-buffer-overflow on address 0xe6146cf3 at pc 0xe86eeb3c bp 0xffe67348 sp 0xffe66f14
WRITE of size 39 at 0xe6146cf3 thread T0
    #0 0xe86eeb3b  (/system/lib/libclang_rt.asan-arm-android.so+0x64b3b)
    #1 0xaddc5d27  (/data/simple_test_fuzzer+0x4d27)
    #2 0xaddd08b9  (/data/simple_test_fuzzer+0xf8b9)
    #3 0xaddd0a97  (/data/simple_test_fuzzer+0xfa97)
    #4 0xaddd0fbb  (/data/simple_test_fuzzer+0xffbb)
    #5 0xaddd109f  (/data/simple_test_fuzzer+0x1009f)
    #6 0xaddcbfb9  (/data/simple_test_fuzzer+0xafb9)
    #7 0xaddc9ceb  (/data/simple_test_fuzzer+0x8ceb)
    #8 0xe8655635  (/system/lib/libc.so+0x7a635)
0xe6146cf3 is located 0 bytes to the right of 35-byte region [0xe6146cd0,0xe6146cf3)
allocated by thread T0 here:
    #0 0xe87159df  (/system/lib/libclang_rt.asan-arm-android.so+0x8b9df)
    #1 0xaddc5ca7  (/data/simple_test_fuzzer+0x4ca7)
    #2 0xaddd08b9  (/data/simple_test_fuzzer+0xf8b9)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/system/lib/libclang_rt.asan-arm-android.so+0x64b3b) 
Shadow bytes around the buggy address:
  0x1cc28d40: fa fa 00 00 00 00 07 fa fa fa fd fd fd fd fd fd
  0x1cc28d50: fa fa 00 00 00 00 07 fa fa fa fd fd fd fd fd fd
  0x1cc28d60: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd
  0x1cc28d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1cc28d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x1cc28d90: fa fa fa fa fa fa fa fa fa fa 00 00 00 00[03]fa
  0x1cc28da0: fa fa 00 00 00 00 07 fa fa fa 00 00 00 00 03 fa
  0x1cc28db0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x1cc28dc0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd
  0x1cc28dd0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd
  0x1cc28de0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb

More information on what each part of the report means, and how to make it more user-friendly can be found on the LLVM website and in Github.

Sometimes, the bug discovery process can appear to be non-deterministic, especially when bugs require special setup or more advanced techniques, such as heap priming or race condition exploitation. Many of these bugs are not immediately apparent, and could surface thousands of instructions away from the memory violation that was the actual root cause. As ASan instruments all memory-related functions and pads data with areas that cannot be accessed without triggering an ASan-related callback, memory violations are caught the instant they occur, instead of waiting for a crash-inducing corruption. This is extremely useful in bug discovery and root cause diagnosis. In addition, ASAN is an extremely useful tool for fuzzing, and has been used in many fuzzing efforts on Android.

UBSan

UndefinedBehaviorSanitizer (UBSan) performs compile-time instrumentation to check for various types of undefined behavior. Device manufacturers can include it in their test builds by including LOCAL_SANITIZE:=default-ub in their makefiles or default-ub: true in the sanitize block of blueprint files. While UBSan can detect many undefined behaviors, Android's build system directly supports:

  • bool
  • integer-divide-by-zero
  • return
  • returns-nonnull-attribute
  • shift-exponent
  • unreachable
  • vla-bound

UBSan's integer overflow checking is also used in Android's build system. UBSan also supports unsigned-integer-overflow, which is not technically undefined behavior, but is included in the sanitizer. These can be enabled in makefiles by setting LOCAL_SANITIZE to signed-integer-overflow, unsigned-integer-overflow, or the combination flag integer, which enables signed-integer-overflow, unsigned-integer-overflow, integer-divide-by-zero, shift-base, and shift-exponent. These can be enabled in blueprint files by setting Misc_undefined to the desired flag. These UBSan targets, especially unsigned-integer-overflow are used extensively in the mediaserver components to eliminate any latent integer overflow vulnerabilities.

The default implementation on Android is to abort the program when undefined behavior is encountered. However, starting in October 2016, UBSan on Android has an optional runtime library that gives more detailed error reporting, including type of undefined behavior encountered, file and source code line information.

In Android.mk files, this is enabled with:

LOCAL_SANITIZE:=unsigned-integer-overflow signed-integer-overflow
LOCAL_SANITIZE_DIAG:=unsigned-integer-overflow signed-integer-overflow

And in Android.bp files, it is enabled with:

sanitize: {
        misc_undefined: [
            "unsigned-integer-overflow",
            "signed-integer-overflow",
        ],
        diag: {
            misc_undefined: [
                "unsigned-integer-overflow",
                "signed-integer-overflow",
            ],
        },
    },

Here is an example of the information provided by the UBSan runtime library:

external/icu/icu4c/source/common/ucnv.c:1193:23: runtime error: unsigned integer overflow: 4291925010 + 2147483647 cannot be represented in type 'unsigned int'
external/icu/icu4c/source/common/cstring.c:288:16: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'uint32_t' (aka 'unsigned int')
external/harfbuzz_ng/src/hb-private.hh:894:16: runtime error: unsigned integer overflow: 72 - 55296 cannot be represented in type 'unsigned int'
external/harfbuzz_ng/src/hb-set-private.hh:82:24: runtime error: unsigned integer overflow: 32 - 562949953421312 cannot be represented in type 'unsigned long'
system/keymaster/authorization_set.cpp:500:37: runtime error: unsigned integer overflow: 6843601868186924302 * 24 cannot be represented in type 'unsigned long'

SanitizerCoverage

Sanitizer tools have a very simple code coverage tool built in. SanitizerCoverage allows for code coverage at the call level, basic block level, or edge level. These can be used as a standalone instrumentation technique or in conjunction with any of the sanitizers, including AddressSanitizer and UndefinedBehaviorSanitizer. To use the new guard-based coverage, set fsanitize-coverage=trace-pc-guard. This causes the compiler to insert __sanitizer_cov_trace_pc_guard(&guard_variable) on every edge. Each edge has its own uint32_t guard_variable. In addition, a module constructor, __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) is also generated. All the __sanitizer_cov_ functions should be provided by the user. You can follow the example on Tracing PCs with guards.

In addition to control flow tracing, SanitizerCoverage allows for data flow tracing. This is activated with fsanitize-coverage=trace-cmp and is implemented by instrumenting all switch and comparison instructions with __sanitizer_cov_trace_* functions. Similar functionality exists for integer division and GEP instructions, activated with fsanitize-coverage=trace-div and fsanitize-coverage=trace-gep respectively. This is an experimental interface, is not thread-safe, and could change at any time, however, it is available and functional in Android builds.

During a coverage sanitizer session, the coverage information is recorded in two files, a .sancov file, and a sancov.map file. The first contains all instrumented points in the program, and the other contains the execution trace represented as a sequence of indices into the first file. By default, these files are stored in the current working directory, with one created for each executable and shared object that ran during the execution.

Conclusion

ASan, UBSan, and SanitizerCoverage are just the beginning of LLVM sanitizer use in Android. More LLVM Sanitizers are being integrated into the Android build system. The sanitizers described here can be used as a code health and system stability mechanism and are even currently being used by Android Security to find and prevent security bugs!