Since the launch of Android 5.0 last month, the sheer number of app updates has been magnificent – and downright overwhelming. Believe it or not, most of the new versions haven't done much more than add Lollipop support and splash a fresh coat of Materialized paint on the UIs. Seriously, we've been checking. This isn't entirely a bad thing, as it's giving me time to work on some other projects... You'll see soon enough <wink>. But, we've finally got something to talk about with the latest release of Google Play services 6.5. Strictly speaking, a few of tidbits to follow were actually first seen in different minor releases of 6.1, but we're putting it all together here. It's time for a teardown!

TeardownHero

Disclaimer: No matter the confidence level, there's always a chance product updates, features, and some or all details will be changed or cancelled altogether. As with all rumors, even those with physical evidence, nothing is 100% until it's officially announced.

Android Auto

Google just announced that work can officially begin on apps for Android Auto, but the details are sparse and developers are still limited to just two categories of apps: audio and messaging. However, we can already look to what's buried beneath the surface to get a hint at what might be available in the future.

Code

<permission android:description="@string/car_permission_desc_fuel" android:label="@string/car_permission_label_fuel" android:name="com.google.android.gms.permission.CAR_FUEL" android:protectionLevel="dangerous"/>
<permission android:description="@string/car_permission_desc_mileage" android:label="@string/car_permission_label_mileage" android:name="com.google.android.gms.permission.CAR_MILEAGE" android:protectionLevel="dangerous"/>
<permission android:description="@string/car_permission_desc_popup_dialogs" android:label="@string/car_permission_label_popup_dialogs" android:name="com.google.android.projection.gearhead.receivertest.DIALOG_PERMISSION" android:protectionLevel="signature"/>
<permission android:description="@string/car_permission_desc_speed" android:label="@string/car_permission_label_speed" android:name="com.google.android.gms.permission.CAR_SPEED" android:protectionLevel="dangerous"/>
<permission android:description="@string/car_permission_desc_vendor_extension" android:label="@string/car_permission_label_vendor_extension" android:name="com.google.android.gms.permission.CAR_VENDOR_EXTENSION" android:protectionLevel="dangerous"/>

It's obvious from the permissions that developers will eventually have access to data acquired from the car itself. Unfortunately, the current docs don't mention this, or even hint at what might be coming down the road. Since we can safely assume Google won't approve any app that tries to make use of the private APIs behind these permissions, don't be too surprised when the first volley of apps seem to be missing some obvious features. Notice the protection level for each of these is marked as "dangerous." That's not as bad as it sounds, but the documentation does note that users may be specifically prompted before an application can acquire said permission.

The strings don't offer much more insight, but they give a few hints at the verbiage early adopters of Android Auto are likely to see. At least we know Google's engineers aren't above a couple of puns, like saying "You have hit a roadblock" when there's an error in the initial setup process. Also, to any Googlers that may be reading this, please fix the typo marked below. ;)

Code

<string name="car_app_mode">Application Mode</string>
<string name="car_app_mode_default">Release</string>
<string name="car_app_name">Android Auto</string>
<string name="car_app_name_wifi">Android Auto Wifi</string>
<string name="car_collect_gps_data">Collect GPS Data</string>
<string name="car_dim_screen">Dim Screen</string>
<string name="car_disable_anr_monitoring">Disable ANR Monitoring</string>
<string name="car_dump_screenshot">Dump screenshot</string>
<string name="car_empty" />
<string name="car_error_message">Communication Error <g example="5" id="error_code">%1$d</g> - <g example="The phone and car are running incompatible software versions." id="error_code">%2$s</g></string>
<string name="car_feedback_client_service_name">FeedbackSenderService</string>
<string name="car_feedback_service_name">FeedbackMarshallerService</string>
<string name="car_force_logging">Force logging</string>
<string name="car_frx_android_auto_logo">Android Auto logo</string>
<string name="car_frx_cancel">Cancel setup</string>
<string name="car_frx_exit">Exit Android Auto setup</string>
<string name="car_frx_google_maps_logo">Google Maps logo</string>
<string name="car_frx_google_now_logo">Google Now logo</string>
<string name="car_frx_google_play_music_logo">Google Play Music logo</string>
<string name="car_frx_ok">Accept and move to next setup step</string>
<string name="car_frx_ok_">Allow car connection and move to next setup step</string>
<string name="car_frx_try_again">Try again</string>
<string name="car_notification_message">Connected to your car.</string>
<string name="car_permission_desc_fuel">"Access your car's fuel level information."</string>
<string name="car_permission_desc_mileage">"Access your car's mileage information."</string>
<string name="car_permission_desc_popup_dialogs">Required for displaying popup dialogs on the phone from a car application.</string>
<string name="car_permission_desc_speed">"Access your car's speed."</string>
<string name="car_permission_desc_vendor_extension">"Access your car's vendor channel to exchange car specific information."</string>
<string name="car_permission_label_fuel">car fuel level</string>
<string name="car_permission_label_mileage">car mileage</string>
<string name="car_permission_label_popup_dialogs">display popup</string>
<string name="car_permission_label_speed">car speed</string>
<string name="car_permission_label_vendor_extension">car vendor channel</string>
<string name="car_save_audio">Save Audio</string>
<string name="car_save_video">Save Video</string>
<string name="car_setup_accept">ACCEPT</string>
<string name="car_setup_app_label_gearhead">Android Auto</string>
<string name="car_setup_app_label_gmm">Google Maps</string>
<string name="car_setup_app_label_gsa">Google Search</string>
<string name="car_setup_app_label_music">Google Play Music</string>
<string name="car_setup_asking_installing_applications_message">Please stay parked. It should take a few minutes to download and configure your app.</string>
<string name="car_setup_asking_installing_applications_title">Download Android Auto applications</string>
<string name="car_setup_authorizing_car_connection_message">Your Android device needs permission to connect to the car.</string>
<string name="car_setup_authorizing_car_connection_title">Connect your device</string>
<string name="car_setup_cancel">CANCEL</string>
<string name="car_setup_car_moving_message">Android Auto setup will resume when the car is parked.</string>
<string name="car_setup_downloading_message">Downloading Android Auto applications.</string>
<string name="car_setup_error_message">Failed to set up Android Auto. Resolve the issue and reconnect your phone to the car.</string>
<string name="car_setup_exit">EXIT</string>
<string name="car_setup_failed_message">Android Auto needs permission to make your car smarter.</string>
<string name="car_setup_failed_title">You have hit a roadblock</string>
<string name="car_setup_install">Install</string>
<string name="car_setup_install_cancel_confirm_message">Android Auto requires you to enable Google Maps, Google Play Music, and Google Now.</string>
<string name="car_setup_install_cancel_confirm_title">You have hit a roadblock</string>
<string name="car_setup_logo">"android
auto
"</string>
<string name="car_setup_no_thanks">NO THANKS</string>
<string name="car_setup_ok">OK</string>
<string name="car_setup_try_again">TRY AGAIN</string>
<string name="car_share_screenshot">Share screenshot now</string>
<string name="car_skip_disclaimer">Skip Disclaimer</string>
<string name="car_take_vf_on_start">Request video focus on start</string>

<string-array name="car_error_user_friendly">
<item>The phone and car are running incompatible software versions. Please re-flash both of them to the latest version.</item>
<item>The car has advertised an incorrect set of audio and/or video configurations.</item>
<item>The USB connection had an error. Please make sure that you cable fits snugly on both ends and also try using another cable. Also, please make sure that the date and time have been set correctly on your head unit and phone.</item>
<item>The head unit requested that the session be terminated.</item>
<item>Session terminated as requested.</item>
<item>The car sent an unexpected message. The head unit software may be out of date.</item>
<item>It appears that you have tried to connect to an unauthorized head unit.</item>
<item>The car said that you are unauthorized. Please check the date and time on your head unit. Also, please verify that you are runnning the latest version of the code.</item>
<item>An action timed out. You should grab a bug report and file feedback.</item>
<item>"You don't seem to have a launcher installed, is your phone set up correctly?"</item>
<item>The graphics pipeline just died. You should grab a bug report and file feedback.</item>
<item>Car is not responding to messages from phone. Car may be in wrong state.</item>
</string-array>

And finally, we've got the activities, receivers, and services that make up Android Auto. Since we already know quite a bit about Android Auto from Google's announcements and previews, there's not much to get excited about; but again, these might give some insight and answer questions about real-world operation.

Code

<activity android:autoRemoveFromRecents="true" android:configChanges="keyboard|keyboardHidden|orientation|uiMode|screenSize" android:label="@string/car_empty" android:launchMode="singleTask" android:name="com.google.android.gms.car.CarHomeActivity" android:process=":car" android:theme="@style/CarWindowDisablePreview">
<meta-data android:name="android.dock_home" android:value="true"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.CAR_DOCK"/>
</intent-filter>
</activity>

<activity android:configChanges="keyboard|keyboardHidden|orientation|uiMode|screenSize" android:label="@string/car_app_name" android:name="com.google.android.gms.car.FirstActivity" android:process=":car" android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/com.google.android.gms.car"/>
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" android:resource="@xml/car_usb_accessory_filter"/>
</activity>

<activity android:label="@string/car_app_name" android:name="com.google.android.gms.car.CarErrorDisplayActivity" android:process=":car"/>

<activity android:label="@string/car_app_name" android:name="com.google.android.gms.car.CarServiceSettingsActivity" android:process=":car">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

<activity android:label="@string/car_empty" android:name="com.google.android.gms.car.SetupActivity" android:process=":car" android:theme="@style/CarFrx"/>

<receiver android:name="com.google.android.gms.car.BluetoothReceiver" android:process=":car">
<intent-filter>
<action android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED"/>
</intent-filter>
</receiver>

<service android:exported="true" android:name="com.google.android.gms.car.diagnostics.FeedbackSenderService" android:process=":car"/>

<service android:exported="true" android:name="com.google.android.gms.car.VoiceActionService" android:process=":car"/>

<service android:label="@string/car_app_name" android:name="com.google.android.gms.car.InCallServiceImpl" android:permission="android.permission.BIND_INCALL_SERVICE" android:process=":car">
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>

<service android:name="com.google.android.gms.car.CarService" android:process=":car">
<intent-filter>
<action android:name="com.google.android.gms.car.service.START"/>
</intent-filter>
</service>

<service android:name="com.google.android.gms.car.diagnostics.CrashReporterService"/>

<service android:name="com.google.android.gms.car.diagnostics.FeedbackUploaderService"/>

While there's not a lot you can do with it, one of these activities can actually be initiated with a simple adb command. You'll be able to modify some debug settings, but that's really all there is for now. Just plug your phone into a computer and run this command:

adb shell am start -n com.google.android.gms/.car.CarServiceSettingsActivity

2014-11-20 11.16.062014-11-20 11.16.152014-11-20 11.16.27

Kid Accounts (a.k.a. Google for Families)

If you're a parent of a young child, you've probably shared your phone or tablet for them to play with. As your bundle of joy gets a little older, you might even consider giving them a full-time device. The problem is, Android's built-in parental controls aren't that impressive, which leaves iOS to hold the lead. However, Google is preparing to step it up with some new tools to help keep those minors in check.

The new feature is called "Kid Accounts," though it's likely to be tied into the Google for Families project. It's obvious that this isn't anywhere near complete, as you can see from the WIP string below, but there's already some stuff here to discern a few of the plans. To begin with, parents will be able to limit device usage to certain times, and even set a bed time with a reminder message. Further, the service will be able to act as a device administrator, much like Google's Android Device Manager. This means it's capable of activating and deactivating the lockscreen, among several other capabilities that most apps generally don't have. And most importantly, it appears these restrictions will sync over Google's servers. This means that parents will be able to set rules on one device, and have them enforced on another only moments later. Just think, you won't even have to wrestle the tablet away from junior.

Code

strings.xml

<string name="kids_apps_restricted_message">Your device is restricted from using certain apps.</string>
<string name="kids_bed_timeout_message">Bedtime</string>
<string name="kids_device_lockout_message">Your device is locked right now.</string>
<string name="kids_device_restricted_message">Your device is restricted.</string>
<string name="kids_device_timeout_desc_message">You can use it again at %1$s.</string>
<string name="kids_family_app_title">Google for Families</string>
<string name="kids_generic_timeout_message">Time-Out</string>
<string name="kids_mdm_desc">Allow Google to provide parental supervision and family management.</string>
<string name="kids_restrictions_cannot_update_location">You are not allowed to update this setting.</string>
<string name="kids_wip_message">WIP</string>

AndroidManifest.xml

<activity android:exported="false" android:name="com.google.android.gms.kids.account.activities.KidsAccountSetupFlowActivity" android:process="com.google.android.gms.ui" android:theme="@style/Theme.AppCompat.Light">
<intent-filter>
<action android:name="com.google.android.gms.kids.action.ACCOUNT_SETUP"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

<provider android:authorities="com.google.android.gms.kids" android:exported="false" android:name="com.google.android.gms.kids.restrictions.sync.RestrictionsProvider" android:syncable="true"/>

<provider android:authorities="com.google.android.gms.kids.timeouts" android:exported="false" android:name="com.google.android.gms.kids.timeouts.sync.TimeoutsProvider" android:syncable="true"/>

<receiver android:description="@string/kids_mdm_desc" android:enabled="false" android:icon="@drawable/kids_family_ic_color" android:label="@string/kids_family_app_title" android:name="com.google.android.gms.kids.account.receiver.ProfileOwnerReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin" android:resource="@xml/profile_owner"/>
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
</intent-filter>
</receiver>

<receiver android:enabled="false" android:exported="false" android:name="com.google.android.gms.kids.account.receiver.ProfileOwnerSetupCompleteReceiver"/>

<receiver android:enabled="false" android:exported="false" android:name="com.google.android.gms.kids.GcmBroadcastReceiverLmp">
<intent-filter>
<action android:name="com.google.android.gms.kids.GcmBroadcastReceiverLmp"/>
</intent-filter>
</receiver>

<receiver android:enabled="false" android:exported="false" android:name="com.google.android.gms.kids.restrictions.receiver.RestrictionChangedReceiver">
<intent-filter>
<action android:name="com.google.android.gms.kids.restrictions.SYNCED"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>

<receiver android:enabled="false" android:exported="false" android:name="com.google.android.gms.kids.timeouts.TimeoutsChangedReceiver">
<intent-filter>
<action android:name="com.google.android.gms.kids.timeouts.SYNCED"/>
</intent-filter>
</receiver>

<receiver android:enabled="false" android:name="com.google.android.gms.kids.account.BootCompletedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

<receiver android:enabled="false" android:name="com.google.android.gms.kids.account.GmsCoreUpdateReceiver">
<intent-filter>
<action android:name="com.google.android.gms.GMS_UPDATED"/>
</intent-filter>
</receiver>

<receiver android:enabled="false" android:name="com.google.android.gms.kids.account.RetryKidsAccountSetupReceiver">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT"/>
</intent-filter>
</receiver>

<receiver android:enabled="false" android:name="com.google.android.gms.kids.timeouts.DeviceTimeAndDateChangeReceiver">
<intent-filter>
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
<action android:name="android.intent.action.DATE_CHANGED"/>
<action android:name="android.intent.action.TIME_SET"/>
</intent-filter>
</receiver>

<receiver android:exported="false" android:name="com.google.android.gms.kids.account.receiver.UpdateProfileOwnerReceiver">
<intent-filter>
<action android:name="com.google.android.gms.kids.account.receiver.UpdateProfileOwnerReceiver"/>
</intent-filter>
</receiver>

<receiver android:exported="true" android:name="com.google.android.gms.kids.account.receiver.RestrictionsProviderReceiver">
<intent-filter>
<action android:name="android.content.action.REQUEST_PERMISSION"/>
</intent-filter>
</receiver>

<receiver android:name="com.google.android.gms.kids.account.AccountChangeReceiver" android:permission="com.google.android.gms.auth.permission.GOOGLE_ACCOUNT_CHANGE">
<intent-filter>
<action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gms.auth.GOOGLE_ACCOUNT_CHANGE"/>
<category android:name="com.google.android.gms.auth.category.ACCOUNT_ADDED"/>
<category android:name="com.google.android.gms.auth.category.ACCOUNT_REMOVED"/>
<category android:name="com.google.android.gms.auth.category.ACCOUNT_MUTATED"/>
</intent-filter>
</receiver>

<receiver android:name="com.google.android.gms.kids.restrictions.receiver.ManualSyncReceiver">
<intent-filter>
<action android:name="com.google.android.gms.kids.restrictions.MANUAL_SYNC"/>
</intent-filter>
</receiver>

<service android:exported="false" android:name="com.google.android.gms.kids.account.KidsAccountSetupService"/>

<service android:exported="false" android:name="com.google.android.gms.kids.common.service.KidsApiService">
<intent-filter>
<action android:name="com.google.android.gms.kids.common.service.INTENT"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>

<service android:exported="false" android:name="com.google.android.gms.kids.common.service.SlowOperationService">
<intent-filter>
<action android:name="com.google.android.gms.kids.common.service.SlowOperationService.INTENT"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>

<service android:exported="false" android:name="com.google.android.gms.kids.GcmReceiverService"/>

<service android:exported="true" android:name="com.google.android.gms.kids.restrictions.sync.RestrictionsSyncService">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data android:name="android.content.SyncAdapter" android:resource="@xml/kids_restrictions_sync_adapter"/>
</service>

<service android:exported="true" android:name="com.google.android.gms.kids.timeouts.sync.TimeoutsSyncService">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data android:name="android.content.SyncAdapter" android:resource="@xml/kids_timeouts_sync_adapter"/>
</service>

People, Identity, and Smart Profile

Frankly, this one is still a mystery. However, the clues are there, and it's obvious that there's something coming... I just don't know what. Here's what stands out about the code:

  • Between v6.1 and v6.5, a branch of code named com.google.android.gms.people grew to almost 3x its original size (which was already fairly large).
  • A new branch of code appeared under the name com.google.android.gms.smart_profile, which is also very large.
  • The Smart Profile code directly calls on the code for People, so they are somehow related.

Unfortunately, there are no strings, activities, images, or anything else that clearly references the name "Smart Profile". However, there are a lot of newly added strings and a couple of simple activities with the prefix "profile." Are they related? I'm really not sure, because most of these strings don't appear to be used anywhere in code. This sort of thing can happen when resources and code are copied from one project to another, even if the strings aren't meant to appear anywhere. These particular strings look like they might have come from Google+, but that doesn't mean they won't be used. There are also quite a few layouts with similar naming.

Code

AndroidManifest.xml

<activity android:name="com.google.android.gms.smart_profile.ContactsPickerActivity" android:process="com.google.android.gms.ui" android:theme="@style/Theme.Profile.PeopleList"/>
<activity android:name="com.google.android.gms.smart_profile.PeopleListActivity" android:process="com.google.android.gms.ui" android:theme="@style/Theme.Profile.PeopleList"/>

strings.xml

<string name="people_list_add_to_circles_text">ADD</string>
<string name="people_list_avatar_content_description">Avatar</string>
<string name="people_list_empty_in_common">Sorry, there are no people in common to display.</string>
<string name="people_list_empty_in_their_circles">Sorry, there are no people in their circles to display.</string>
<string name="people_list_metadata_company">Works at <g id="company">%s</g></string>
<string name="people_list_metadata_location">Lives in <g id="location">%s</g></string>
<string name="people_list_metadata_school">Studies in <g id="school">%s</g></string>
<string name="profile_about_card_title">About</string>
<string name="profile_about_event">Event</string>
<string name="profile_about_instant_messaging">IM</string>
<string name="profile_about_nickname">Nickname</string>
<string name="profile_about_note">Note</string>
<string name="profile_about_relation">Relation</string>
<string name="profile_about_text_placeholder" formatted="false"><g id="about_text_first_row">%s</g>"
"<g id="about_text_second_row">%s</g>
</string>
<string name="profile_calendar_card_title">Shared events</string>
<string name="profile_call_log_card_title">Recent calls</string>
<string name="profile_call_type_incoming">Incoming call</string>
<string name="profile_call_type_missed">Missed call</string>
<string name="profile_call_type_outgoing">Outgoing call</string>
<string name="profile_call_type_unknown">Call</string>
<string name="profile_call_type_voicemail">Voicemail</string>
<string name="profile_card_recent_interactions_future_event">Coming up: <g id="date">%s</g></string>
<string name="profile_card_recent_interactions_title">Conversations</string>
<string name="profile_circle_button_circles"><g id="count">%d</g> circles</string>
<string name="profile_circle_button_profile_blocked">Blocked</string>
<string name="profile_communicate_address">Home Address</string>
<string name="profile_communicate_email">Email</string>
<string name="profile_communicate_entry_quick_contacts">More options…</string>
<string name="profile_communicate_hangout">Send a Hangout message</string>
<string name="profile_communicate_sms">SMS</string>
<string name="profile_communication_bar_title">Contact</string>
<string name="profile_contacts_picker_item_image_content_description">Avatar</string>
<string name="profile_contacts_picker_title">Choose a contact to edit</string>
<string name="profile_create_profile">Create a Google+ profile</string>
<string name="profile_date_time_fmt" formatted="false"><g id="date">%s</g>, <g id="time_interval">%s</g></string>
<string name="profile_edit_profile">Edit Google+ profile</string>
<string name="profile_education_current_details">Attends <g id="school">%1$s</g></string>
<string name="profile_education_details">Attended <g id="school">%1$s</g></string>
<string name="profile_employment_current_details"><g id="title">%1$s</g> at <g id="employer">%2$s</g></string>
<string name="profile_employment_current_details_no_title">Works at <g id="employer">%1$s</g></string>
<string name="profile_employment_details_no_title">Worked at <g id="employer">%1$s</g></string>
<string name="profile_error">Sorry, we were unable to find this person.</string>
<string name="profile_expanding_entry_card_icon_alt_content_description">Alternate Icon</string>
<string name="profile_expanding_entry_card_icon_content_description">Icon</string>
<string name="profile_expanding_entry_card_icon_sub_header_content_description">Sub Icon</string>
<string name="profile_expanding_entry_card_icon_text_content_description">Text Icon</string>
<string name="profile_follower_view_count_separator">|</string>
<string name="profile_header_add_to_circles">Add to circles</string>
<string name="profile_header_create_profile">Create a Google+ profile</string>
<string name="profile_header_edit_profile">Edit Google+ profile</string>
<string name="profile_header_follow_page">Follow</string>
<string name="profile_header_following_circle">Following</string>
<string name="profile_header_toolbar_add_contact_label">Add contact icon</string>
<string name="profile_header_toolbar_edit_contact_label">Edit contact icon</string>
<string name="profile_header_toolbar_overflow_content_description">More options</string>
<string name="profile_header_toolbar_star_content_description">Add star</string>
<string name="profile_header_toolbar_unstar_content_description">Remove star</string>
<string name="profile_header_view_page">View Google+ Page</string>
<string name="profile_header_view_profile">View Google+ profile</string>
<string name="profile_label">Profile</string>
<string name="profile_loading">Loading…</string>
<string name="profile_location_current_details">Lives in <g id="location">%1$s</g></string>
<string name="profile_location_details">Lived in <g id="location">%1$s</g></string>
<string name="profile_people_circled_title">People in their circles</string>
<string name="profile_people_common_title">People in common</string>
<string name="profile_people_image_label">People Card Avatar</string>
<string name="profile_photo_content_description">View this photo</string>
<string name="profile_photos_title">Photos</string>
<string name="profile_see_all">See all</string>
<string name="profile_see_all_count">See all (<g example="count" id="count">%s</g>)</string>
<string name="profile_see_less">See less</string>
<string name="profile_timestamp_string_today">Today</string>
<string name="profile_timestamp_string_tomorrow">Tomorrow</string>
<string name="profile_timestamp_string_yesterday">Yesterday</string>
<string name="profile_today_at_time_fmt">Today at <g id="time_interval">%s</g></string>
<string name="profile_tomorrow_at_time_fmt">Tomorrow at <g id="time_interval">%s</g></string>
<string name="profile_untitled_event">(Untitled event)</string>
<string name="profile_view_page">View Google+ Page</string>
<string name="profile_view_profile">View Google+ profile</string>

I'm normally comfortable with making some guesses, but there are too many unknowns here. The only thing that seems apparent is this will make some use of your contacts/connections to simplify some task related to your profile, be it on the device or Google+. Whatever the case may be, such a surge in code usually means something big is on the way.

Lockbox

Lockbox is another mystery feature, but there are enough clues to indicate that it's likely some kind of anti-theft component. After digging into the code, I found that Lockbox accessed both Location Services and "Telephony" (the actual telephone part of your smartphone). Additionally, there is a service and receiver responsible for watching account changes, for whatever purpose that would serve. Unfortunately, there's just not very much to look at here, but this could grow into something more tangible in the near future.

Code

<service android:name="com.google.android.gms.lockbox.LockboxService" android:exported="false" android:process="com.google.process.gapps" />

<service android:name="com.google.android.gms.lockbox.service.LockboxBrokerService" android:exported="true" android:process="com.google.process.gapps">
<intent-filter>
<action android:name="com.google.android.gms.lockbox.service.START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>

<service android:name="com.google.android.gms.lockbox.LockboxAccountsChangedService" android:exported="false" android:process="com.google.process.gapps" />

<receiver android:name="com.google.android.gms.lockbox.LockboxAlarmReceiver" android:exported="false" android:process="com.google.process.gapps" />

<receiver android:name="com.google.android.gms.lockbox.LockboxAccountsChangedReceiver" android:process="com.google.process.gapps">
<intent-filter>
<action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
</intent-filter>
</receiver>

Google Help

In a previous teardown, I found evidence that Google had plans to tightly integrate its support infrastructure with Hangouts. At the time, there were just a few strings to look at, but not much else. Things have progressed a little bit, and there are now images to associate with our future interaction with Google staffers. We already knew there were different types of interactions: chat, call, callback, email, and video call. Of course, these are also joined by icons for knowledge base articles and a general feedback action. Now, we can also see the different states each method can be in, represented by gray for disabled, yellow for preferred, and blue, which may just be the default.

icons

Firmware Updater! From SD Cards?

Back in May, I stumbled onto what was clearly the groundwork for a firmware updater included in the Play services package. At the time, I theorized that the updater would be used on Android Silver and Nexus devices to achieve more agility. As we know, Android Silver is probably toast, and the only noteworthy change to the Nexus updater seems to be purely cosmetic. With the latest release, it looks like the updater can now check installed SD cards for a flashable OTA file, just as if they were pulling it from the Internet.

Code

AndroidManifest.xml

<activity android:hardwareAccelerated="true" android:launchMode="singleTop" android:name="com.google.android.gms.update.UpdateFromSdCardActivity" android:theme="@style/systemUpdateActivityTheme">
<intent-filter>
<action android:name="android.settings.SYSTEM_UPDATE_SDCARD_INSTALLER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<service android:name="com.google.android.gms.update.UpdateFromSdCardService"/>

strings.xml

<string name="system_update_file_browser_cancel_button">Cancel</string>
<string name="system_update_file_browser_ok_button">Select</string>
<string name="system_update_file_browser_title">Select update file</string>
<string name="system_update_from_sd_card_button">Install from SD Card</string>
<string name="system_update_from_sd_card_title">Update from SD Card</string>
<string name="system_update_from_sd_card_unknown_status">Checking...</string>
<string name="system_update_from_sd_card_verified_description">Update is verified and ready to be installed.</string>

I'll go out on a limb here and propose that this change was made to support Android One devices. It makes a lot of sense, given that the target markets for Android One generally have very limited access to data. The idea might be that a group could download a single OTA file to a micro SD card and install it to each phone manually. This is certainly more efficient than dozens of phones competing with each other and splintering the bandwidth until it became completely unusable.

It doesn't look like this one is in use yet, but again, I think it's ready to launch whenever Google decides to hit the button.

Wrap-up

This teardown probably didn't answer as many questions as it created. But from any perspective, there is a lot of activity in some interesting places, and that gives us something to look forward to in the coming months. Google's engineers are never really at rest, and I can't wait to see what else they've got in store.