Choosing the right storage experience

Posted by Yacine Rezgui - Developer Relations Engineer

The upcoming stable release of Android 14 is fast approaching. Now is a great time to test your app with this new release’s changes if you haven’t done so already. With Platform Stability, you can even submit apps targeting SDK 34 to the Google Play Store.

Android 14 introduces a new feature called Selected Photos Access, allowing users to grant apps access to specific images and videos in their library, rather than granting access to all media of a given type. This is a great way for users to feel more comfortable sharing media with apps, and it's also a great way for developers to build apps that respect user privacy.

Image in four panels showing Select Photos Access being used to share media from the user's on-device library
To ease the migration for apps that currently use storage permissions, apps will run in a compatibility mode. In this mode, if a user chooses “Select photos and videos” the permission will appear to be granted, but the app will only be able to access the selected photos. The permission will be revoked when your app process is killed or in the background for a certain time (similar to one time permissions). When the permission is once again requested by your app, users can select a different set of pictures or videos if they wish. Instead of letting the system manage this re-selection, it’s recommended for apps to handle this process to have a better user experience.

Image in four panels showing media reselection being used to update user's choice of which media to be shared

Choosing the right storage experience

Even when your app correctly manages media re-selection, we believe that for the vast majority of apps, the permissionless photo picker that we introduced last year will be the best media selection solution for both user experience and privacy. Most apps allow users to choose media to do tasks such as attaching to an email, changing a profile picture, sharing with friends, and the Android photo picker's familiar UI gives users a consistent, high-quality experience that helps users grant access in confidence, allowing you to focus on the differentiating features of your app. If you absolutely need a more tightly integrated solution, integrating with MediaStore can be considered as an alternative to the photo picker.


Android photo picker

Image of My Profile page on a mobile device

To use the photo picker in your app, you only need to register an activity result:

// Using Jetpack Compose, you should use rememberLauncherForActivityResult instead of registerForActivityResult // Registers a photo picker activity launcher in single-select mode val pickMedia = registerForActivityResult(PickVisualMedia()) { uri -> // Callback is invoked after the user selects a media item or closes the photo picker if (uri != null) { Log.d("PhotoPicker", "Selected URI: $uri") } else { Log.d("PhotoPicker", "No media selected") } }

The photo picker allows customization of media type selection between photos, videos, or a specific mime type when launched:

// Launch the photo picker and let the user choose images and videos. pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo)) // Launch the photo picker and let the user choose only images. pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly)) // Launch the photo picker and let the user choose only videos. pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly)) // Launch the photo picker and let the user choose only images/videos of a // specific MIME type, like GIFs. pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType("image/gif")))

You can set a maximum limit when allowing multiple selections:

// Registers a photo picker activity launcher in multi-select mode. // In this example, the app lets the user select up to 5 media files. val pickMultipleMedia = registerForActivityResult(PickMultipleVisualMedia(5)) { uris -> // Callback is invoked after the user selects media items or closes the // photo picker. if (uris.isNotEmpty()) { Log.d("PhotoPicker", "Number of items selected: ${uris.size}") } else { Log.d("PhotoPicker", "No media selected") } }

Lastly, you can enable the photo picker support on older devices from Android KitKat onwards (API 19+) using Google Play services, by adding this entry to your AndroidManifest.xml file:

<!-- Prompt Google Play services to install the backported photo picker module --> <service android:name="com.google.android.gms.metadata.ModuleDependencies" android:enabled="false" android:exported="false" tools:ignore="MissingClass"> <intent-filter> <action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" /> </intent-filter> <meta-data android:name="photopicker_activity:0:required" android:value="" /> </service>

In less than 20 lines of code you have a well-integrated photo/video picker within your app that doesn’t require any permissions!


Creating your own gallery picker

Creating your own gallery picker requires extensive development and maintenance, and the app needs to request storage permissions to get explicit user consent, which users can deny, or, as of Android 14, limit access to selected media.

First, request the correct storage permissions in the Android manifest depending on the OS version:

<!-- Devices running up to Android 12L --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Devices running Android 13+ --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- To handle the reselection within the app on Android 14+ (when targeting API 33+) --> <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />

Then, the app needs to request the correct runtime permissions, also depending on the OS version:

val requestPermissions = registerForActivityResult(RequestMultiplePermissions()) { results -> // Handle permission requests results // See the permission example in the Android platform samples: https://github.com/android/platform-samples } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED)) } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO)) } else { requestPermissions.launch(arrayOf(READ_EXTERNAL_STORAGE)) }

With the Selected Photos Access feature in Android 14, your app should adopt the new READ_MEDIA_VISUAL_USER_SELECTED permission to control media re-selection, and update your app’s UX to let users grant your app access to a different set of images and videos.

When opening the selection dialog, photos and/or videos will be shown depending on the permissions requested: if you're requesting the READ_MEDIA_VIDEO permission without the READ_MEDIA_IMAGES permission, only videos would appear in the UI for users to select files.

// Allowing the user to select only videos requestPermissions.launch(arrayOf(READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))

You can check if your app has full, partial or denied access to the device’s photo library and update your UX accordingly. It's even more important now to request these permissions when the app needs storage access, instead of at startup. Keep in mind that the permission grant can be changed between the onStart and onResume lifecycle callbacks, as the user can change the access in the settings without closing your app.

if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && ( ContextCompat.checkSelfPermission(context, READ_MEDIA_IMAGES) == PERMISSION_GRANTED || ContextCompat.checkSelfPermission(context, READ_MEDIA_VIDEO) == PERMISSION_GRANTED ) ) { // Full access on Android 13+ } else if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && ContextCompat.checkSelfPermission(context, READ_MEDIA_VISUAL_USER_SELECTED) == PERMISSION_GRANTED ) { // Partial access on Android 14+ } else if (ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED) { // Full access up to Android 12 } else { // Access denied }

Once you verified you have access to the right storage permissions, you can interact with MediaStore to query the device library (whether the granted access is partial or full):

data class Media( val uri: Uri, val name: String, val size: Long, val mimeType: String, val dateTaken: Long ) // We run our querying logic in a coroutine outside of the main thread to keep the app responsive. // Keep in mind that this code snippet is querying all the images of the shared storage suspend fun getImages(contentResolver: ContentResolver): List<Media> = withContext(Dispatchers.IO) { val projection = arrayOf( Images.Media._ID, Images.Media.DISPLAY_NAME, Images.Media.SIZE, Images.Media.MIME_TYPE, ) val collectionUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // This allows us to query all the device storage volumes instead of the primary only Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL) } else { Images.Media.EXTERNAL_CONTENT_URI } val images = mutableListOf<Media>() contentResolver.query( collectionUri, projection, null, null, "${Images.Media.DATE_ADDED} DESC" )?.use { cursor -> val idColumn = cursor.getColumnIndexOrThrow(Images.Media._ID) val displayNameColumn = cursor.getColumnIndexOrThrow(Images.Media.DISPLAY_NAME) val sizeColumn = cursor.getColumnIndexOrThrow(Images.Media.SIZE) val mimeTypeColumn = cursor.getColumnIndexOrThrow(Images.Media.MIME_TYPE) while (cursor.moveToNext()) { val uri = ContentUris.withAppendedId(collectionUri, cursor.getLong(idColumn)) val name = cursor.getString(displayNameColumn) val size = cursor.getLong(sizeColumn) val mimeType = cursor.getString(mimeTypeColumn) val dateTaken = cursor.getLong(4) val image = Media(uri, name, size, mimeType, dateTaken) images.add(image) } } return@withContext images }

The code snippet above is simplified to illustrate how to interact with MediaStore. In a proper production app, you should consider using pagination with something like the Paging library to ensure good performance.

You may not need permissions

As of Android 10 (API 29), you no longer need storage permissions to add files to shared storage. This means that you can add images to the gallery, record videos and save them to shared storage, or download PDF invoices without having to request storage permissions. If your app only adds files to shared storage and does not query images or videos, you should stop requesting storage permissions and set a maxSdkVersion of API 28 in your AndroidManifest.xml:

<!-- No permission is needed to add files from Android 10 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="28" />

ACTION_GET_CONTENT behavior change

In our last storage blog post, we announced that we’ll be rolling out a behavior change whenever ACTION_GET_CONTENT intent is launched with an image and/or video mime type. If you haven’t tested yet this change, you can enable it manually on your device:

adb shell device_config put storage_native_boot take_over_get_content true

That covers how to offer visual media selection in your app with the privacy-preserving changes we've made across multiple Android releases.If you have any feedback or suggestions, submit tickets to our issue tracker.

Chrome Dev for Desktop Update

The Dev channel has been updated to 117.0.5938.0 for Windows, Mac and Linux.

A partial list of changes is available in the Git log. Interested in switching release channels? Find out how. If you find a new issue, please let us know by filing a bug. The community help forum is also a great place to reach out for help or learn about common issues.

Prudhvi Bommana
Google Chrome

Chrome Stable for iOS Update

Hi everyone! We've just released Chrome Stable 116 (116.0.5845.90) for iOS; it'll become available on App Store in the next few hours.

This release includes stability and performance improvements. You can see a full list of the changes in the Git log. If you find a new issue, please let us know by filing a bug.

Erhu Akpobaro
Google Chrome

Android 14 Beta 5

Posted by Dave Burke, VP of Engineering
Android 14 logo

With the official release of Android 14 only weeks away, today we're bringing you Beta 5, the last scheduled update in our Android 14 beta program. It's the last chance to make sure your apps are ready and provide feedback before non-beta users start getting Android 14. To enable you to test your applications on devices spanning multiple form factors, Beta 5 is available for Pixel Tablet and Pixel Fold, in addition to the rest of the supported Pixel family and the Android emulator.

What's in Beta 5?

Beta 5 is our third Platform Stable Android 14 release, which means that the developer APIs and all app-facing behaviors are final for you to review and integrate into your apps, and you can publish apps on Google Play targeting Android 14's SDK version 34. It includes the latest fixes and optimizations, giving you everything you need to complete your testing.

Image of timeline showing Android 14 release is on schedule with Platform Stability testing happening in August

Get your apps, libraries, tools, and game engines ready!

The official Android 14 release is just weeks ahead, so please finish your final compatibility testing and publish any necessary updates to ensure a smooth app experience ahead of the final release of Android 14.

If you develop an SDK, library, tool, or game engine, it's even more important to release any necessary updates now to prevent your downstream app and game developers from being blocked by compatibility issues and allow them to target the latest SDK features. Please make sure to let your developers know if updates are needed to fully support Android 14.

Testing your app involves installing your production app onto a device running Android 14 Beta 5; you can use Google Play or other means. Work through all the app's flows and look for functional or UI issues. Review the behavior changes to focus your testing. Each release of Android contains changes to the platform that improve privacy, security, and the overall user experience, and these changes can affect your apps. Here are some top changes to test:

Remember to exercise libraries and SDKs that your app is using in your compatibility testing. You may need to update to current SDK versions or reach out to the developer for help.

Once you’ve published the compatible version of your current app, you can start the process to update your app's targetSdkVersion. Review the behavior changes that apply when your app targets Android 14 and use the compatibility framework to help detect issues quickly.

Get started with Android 14

Today's Beta 5 release has everything you need to try Android 14 features, test your apps, and give us feedback. You can enroll any supported Pixel device here to get this and future Android 14 Beta and feature drop Beta updates over-the-air, and 64-bit Android Emulator system images will be available soon in the Android Studio SDK Manager.

For the best development experience with Android 14, we recommend that you use the latest release of Android Studio Hedgehog. Once you’re set up, here are some of the things you should do:

  • Try the new features and APIs. Report issues in our tracker on the feedback page.
  • Test your current app for compatibility – learn whether your app is affected by default behavior changes in Android 14. Install your app onto a device or emulator running Android 14 and extensively test it.
  • Test your app with opt-in changes – Android 14 has opt-in behavior changes that only affect your app when it’s targeting the new platform. It’s important to understand and assess these changes early. To make it easier to test, you can toggle the changes on and off individually.
  • Update your app with the Android SDK Upgrade Assistant - Android Studio Hedgehog now filters and identifies the specific Android 14 API changes that are relevant to your app, and walks you through the steps to upgrade your targetSdkVersion with the Android SDK Upgrade Assistant.

We’ll update the beta system images regularly throughout the Android 14 release cycle.

If you are already enrolled in the Android 14 Beta program and your device is supported, Beta 5 will be made available to you as an Over The Air update without taking any additional action.

For complete information on how to get the Beta, visit the Android 14 developer site.

Add annotations to your presentations in Google Slides

What’s changing

We’re introducing a feature that lets you highlight or emphasize key content while you present in Google Slides. With the new pen tool, you can circle, underline, draw connections or make quick notes directly on your presentation. 


Whether in a board meeting or a brainstorming session, annotations can help make your presentations more engaging, interactive and impactful. 
Add annotations to your presentations in Google Slides

Getting started 

  • Admins: There is no admin control for this feature. 
  • End users
    • To annotate your Slides presentation, ​​open ‘slideshow mode’ by clicking the ‘Slideshow’ button in the appbar > mouse over the bottom-left side of the viewer and open the three dot menu by clicking on the ellipsis icon >select “Turn on the pen”. 
    • To erase annotations, use the eraser tool in the bottom left viewer menu. 
    • Visit the Help Center to learn more about presenting slides. 

 Rollout pace 

Availability 

  • Available to all Google Workspace customers and users with personal Google Accounts 

Resources 

Expanding our Fully Homomorphic Encryption offering

Posted by Miguel Guevara, Product Manager, Privacy and Data Protection Office

At Google, it’s our responsibility to keep users safe online and ensure they’re able to enjoy the products and services they love while knowing their personal information is private and secure. We’re able to do more with less data through the development of our privacy-enhancing technologies (PETs) like differential privacy and federated learning.

And throughout the global tech industry, we’re excited to see that adoption of PETs is on the rise. The UK’s Information Commissioner’s Office (ICO) recently published guidance for how organizations including local governments can start using PETs to aid with data minimization and compliance with data protection laws. Consulting firm Gartner predicts that within the next two years, 60% of all large organizations will be deploying PETs in some capacity.

We’re on the cusp of mainstream adoption of PETs, which is why we also believe it’s our responsibility to share new breakthroughs and applications from our longstanding development and investment in this space. By open sourcing dozens of our PETs over the past few years, we’ve made them freely available for anyone – developers, researchers, governments, business and more – to use in their own work, helping unlock the power of data sets without revealing personal information about users.

As part of this commitment, we open-sourced a first-of-its-kind Fully Homomorphic Encryption (FHE) transpiler two years ago, and have continued to remove barriers to entry along the way. FHE is a powerful technology that allows you to perform computations on encrypted data without being able to access sensitive or personal information and we’re excited to share our latest developments that were born out of collaboration with our developer and research community to expand what can be done with FHE.

Furthering the adoption of Fully Homomorphic Encryption

Today, we are introducing additional tools to help the community apply FHE technologies to video files. This advancement is important because video adoption can often be expensive and incur long run times, limiting the ability to scale FHE use to larger files and new formats.

This will encourage developers to try out more complex applications with FHE. Historically, FHE has been thought of as an intractable technology for large-scale applications. Our results processing large video files show it is possible to do FHE in previously unimaginable domains.Say you’re a developer at a company and are thinking of processing a large file (in the TBs order of magnitude, can be a video, or a sequence of characters) for a given task (e.g., convolution around specific data points to do a blurry filter on a video or detect object movement), you can now try this task using FHE.

To do so, we are expanding our FHE toolkit in three new ways to make it easier for developers to use FHE for a wider range of applications, such as private machine learning, text analysis, and video processing. As part of our toolkit, we will release new hardware, a software crypto library and an open source compiler toolchain. Our goal is to provide these new tools to researchers and developers to help advance how FHE is used to protect privacy while simultaneously lowering costs.


Expanding our toolkit

We believe—with more optimization and specialty hardware — there will be a wider amount of use cases for a myriad of similar private machine learning tasks, like privately analyzing more complex files, such as long videos, or processing text documents. Which is why we are releasing a TensorFlow-to-FHE compiler that will allow any developer to compile their trained TensorFlow Machine Learning models into a FHE version of those models.

Once a model has been compiled to FHE, developers can use it to run inference on encrypted user data without having access to the content of the user inputs or the inference results. For instance, our toolchain can be used to compile a TensorFlow Lite model to FHE, producing a private inference in 16 seconds for a 3-layer neural network. This is just one way we are helping researchers analyze large datasets without revealing personal information.

In addition, we are releasing Jaxite, a software library for cryptography that allows developers to run FHE on a variety of hardware accelerators. Jaxite is built on top of JAX, a high-performance cross-platform machine learning library, which allows Jaxite to run FHE programs on graphics processing units (GPUs) and Tensor Processing Units (TPUs). Google originally developed JAX for accelerating neural network computations, and we have discovered that it can also be used to speed up FHE computations.

Finally, we are announcing Homomorphic Encryption Intermediate Representation (HEIR), an open-source compiler toolchain for homomorphic encryption. HEIR is designed to enable interoperability of FHE programs across FHE schemes, compilers, and hardware accelerators. Built on top of MLIR, HEIR aims to lower the barriers to privacy engineering and research. We will be working on HEIR with a variety of industry and academic partners, and we hope it will be a hub for researchers and engineers to try new optimizations, compare benchmarks, and avoid rebuilding boilerplate. We encourage anyone interested in FHE compiler development to come to our regular meetings, which can be found on the HEIR website.

Launch diagram

Building advanced privacy technologies and sharing them with others

Organizations and governments around the world continue to explore how to use PETs to tackle societal challenges and help developers and researchers securely process and protect user data and privacy. At Google, we’re continuing to improve and apply these novel data processing techniques across many of our products, and investing in democratizing access to the PETs we’ve developed. We believe that every internet user deserves world-class privacy, and we continue to partner with others to further that goal. We’re excited for new testing and partnerships on our open source PETs and will continue investing in innovations, aiming at releasing more updates in the future.

These principles are the foundation for everything we make at Google and we’re proud to be an industry leader in developing and scaling new privacy-enhancing technologies (PETs) that make it possible to create helpful experiences while protecting our users’ privacy.

PETs are a key part of our Protected Computing effort at Google, which is a growing toolkit of technologies that transforms how, when and where data is processed to technically ensure its privacy and safety. And keeping users safe online shouldn’t stop with Google - it should extend to the whole of the internet. That’s why we continue to innovate privacy technologies and make them widely available to all.

Making Chrome more secure by bringing Key Pinning to Android

Chrome 106 added support for enforcing key pins on Android by default, bringing Android to parity with Chrome on desktop platforms. But what is key pinning anyway?

One of the reasons Chrome implements key pinning is the “rule of two”. This rule is part of Chrome’s holistic secure development process. It says that when you are writing code for Chrome, you can pick no more than two of: code written in an unsafe language, processing untrustworthy inputs, and running without a sandbox. This blog post explains how key pinning and the rule of two are related.

The Rule of Two

Chrome is primarily written in the C and C++ languages, which are vulnerable to memory safety bugs. Mistakes with pointers in these languages can lead to memory being misinterpreted. Chrome invests in an ever-stronger multi-process architecture built on sandboxing and site isolation to help defend against memory safety problems. Android-specific features can be written in Java or Kotlin. These languages are memory-safe in the common case. Similarly, we’re working on adding support to write Chrome code in Rust, which is also memory-safe.

Much of Chrome is sandboxed, but the sandbox still requires a core high-privilege “broker” process to coordinate communication and launch sandboxed processes. In Chrome, the broker is the browser process. The browser process is the source of truth that allows the rest of Chrome to be sandboxed and coordinates communication between the rest of the processes.

If an attacker is able to craft a malicious input to the browser process that exploits a bug and allows the attacker to achieve remote code execution (RCE) in the browser process, that would effectively give the attacker full control of the victim’s Chrome browser and potentially the rest of the device. Conversely, if an attacker achieves RCE in a sandboxed process, such as a renderer, the attacker's capabilities are extremely limited. The attacker cannot reach outside of the sandbox unless they can additionally exploit the sandbox itself.

Without sandboxing, which limits the actions an attacker can take, and without memory safety, which removes the ability of a bug to disrupt the intended control flow of the program, the rule of two requires that the browser process does not handle untrustworthy inputs. The relative risks between sandboxed processes and the browser process are why the browser process is only allowed to parse trustworthy inputs and specific IPC messages.

Trustworthy inputs are defined extremely strictly: A “trustworthy source” means that Chrome can prove that the data comes from Google. Effectively, this means that in situations where the browser process needs access to data from external sources, it must be read from Google servers. We can cryptographically prove that data came from Google servers if that data comes from:

The component updater and the variations framework are services specific to Chrome used to ship data-only updates and configuration information. These services both use asymmetric cryptography to authenticate their data, and the public key used to verify data sent by these services is shipped in Chrome.

However, Chrome is a feature-filled browser with many different use cases, and many different features beyond just updating itself. Certain features, such as Sign-In and the Discover Feed, need to communicate with Google. For features like this, that communication can be considered trustworthy if it comes from a pinned HTTPS server.

When Chrome connects to an HTTPS server, the server says “a 3rd party you trust (a certification authority; CA) has vouched for my identity.” It does this by presenting a certificate issued by a trusted certification authority. Chrome verifies the certificate before continuing. The modern web necessarily has a lot of CAs, all of whom can provide authentication for any website. To further ensure that the Chrome browser process is communicating with a trustworthy Google server we want to verify something more: whether a specific CA is vouching for the server. We do this by building a map of sites → expected CAs directly into Chrome. We call this key pinning. We call the map the pin set.

What is Key Pinning?

Key pinning was born as a defense against real attacks seen in the wild: attackers who can trick a CA to issue a seemingly-valid certificate for a server, and then the attacker can impersonate that server. This happened to Google in 2011, when the DigiNotar certification authority was compromised and used to issue malicious certificates for Google services. To defend against this risk, Chrome contains a pin set for all Google properties, and we only consider an HTTPS input trustworthy if it’s authenticated using a key in this pin set. This protects against malicious certificate issuance by third parties.

Key pinning can be brittle, and is rarely worth the risks. Allowing the pin set to get out of date can lead to locking users out of a website or other services, potentially permanently. Whenever pinning, it’s important to have safety-valves such as not enforcing pinning (i.e. failing open) when the pins haven't been updated recently, including a “backup” key pin, and having fallback mechanisms for bootstrapping. It's hard for individual sites to manage all of these mechanisms, which is why dynamic pinning over HTTPS (HPKP) was deprecated. Key pinning is still an important tool for some use cases, however, where there's high-privilege communication that needs to happen between a client and server that are operated by the same entity, such as web browsers, automatic software updates, and package managers.

Security Benefits of Key Pinning in Chrome, Now on Android

By pinning in Chrome, we can protect users from CA compromise. We take steps to prevent an out-of-date pinset from unnecessarily blocking users from accessing Google or Google's services. As both a browser vendor and site operator, however, we have additional tools to ensure we keep our pin sets up to date—if we use a new key or a new domain, we can add it to the pin set in Chrome at the same time. In our original implementation of pinning, the pin set is directly compiled into Chrome and updating the pin set requires updating the entire Chrome binary. To make sure that users of old versions of Chrome can still talk to Google, pinning isn't enforced if Chrome detects that it is more than 10 weeks old.

Historically, Chrome enforced the age limit by comparing the current time to the build timestamp in the Chrome binary. Chrome did not enforce pinning on Android because the build timestamp on Android wasn’t always reflective of the age of the Chrome pinset, which meant that the chance of a false positive pin mismatch was higher.

Without enforcing pins on Android, Chrome was limiting the ways engineers could build features that comply with the rule of two. To remove this limitation, we built an improved mechanism for distributing the built-in pin set to Chrome installs, including Android devices. Chrome still contains a built-in pin set compiled into the binary. However, we now additionally distribute the pin set via the component updater, which is a mechanism for Chrome to dynamically push out data-only updates to all Chrome installs without requiring a full Chrome update or restart. The component contains the latest version of the built-in pin set, as well as the certificate transparency log list and the contents of the Chrome Root Store. This means that even if Chrome is out of date, it can still receive updates to the pin set. The component also includes the timestamp the pin list was last updated, rather than relying on build timestamp. This drastically reduces the false positive risk of enabling key pinning on Android.

After we moved the pin set to component updater, we were able to do a slow rollout of pinning enforcement on Android. We determined that the false positive risk was now in line with desktop platforms, and enabled key pinning enforcement by default since Chrome 106, released in September 2022.

This change has been entirely invisible to users of Chrome. While not all of the changes we make in Chrome are flashy, we're constantly working behind the scenes to keep Chrome as secure as possible and we're excited to bring this protection to Android.

Chrome Dev for Android Update

Hi everyone! We've just released Chrome Dev 117 (117.0.5938.0) for Android. It's now available on Google Play.

You can see a partial list of the changes in the Git log. For details on new features, check out the Chromium blog, and for details on web platform updates, check here.

If you find a new issue, please let us know by filing a bug.

Harry Souders
Google Chrome