diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-12-28 04:39:32 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-12-28 04:39:32 +0000 |
commit | 2f16d51c993c5957bcecf63b72ae28488355a8be (patch) | |
tree | 5eda6d8178672e075404e1631f4f29df82a616eb | |
parent | 5999fd7ec32746e864b07f91ff72575c6e487d57 (diff) | |
parent | 5b9c2c2ffdbb481232c04de26d7978a9144b4300 (diff) |
Merge "Allow Activity/Service to get media keys across the boot"
-rw-r--r-- | services/core/java/com/android/server/media/MediaSessionService.java | 93 |
1 files changed, 81 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 93b66208e752..40ae2d95482e 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -16,6 +16,7 @@ package com.android.server.media; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.INotificationManager; import android.app.KeyguardManager; @@ -27,8 +28,10 @@ import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.media.AudioManager; @@ -634,11 +637,17 @@ public class MediaSessionService extends SystemService implements Monitor { * <p>The contents of this object is guarded by {@link #mLock}. */ final class FullUserRecord implements MediaSessionStack.OnMediaButtonSessionChangedListener { + public static final int COMPONENT_TYPE_INVALID = 0; + public static final int COMPONENT_TYPE_BROADCAST = 1; + public static final int COMPONENT_TYPE_ACTIVITY = 2; + public static final int COMPONENT_TYPE_SERVICE = 3; private static final String COMPONENT_NAME_USER_ID_DELIM = ","; + private final int mFullUserId; private final MediaSessionStack mPriorityStack; private PendingIntent mLastMediaButtonReceiver; private ComponentName mRestoredMediaButtonReceiver; + private int mRestoredMediaButtonReceiverComponentType; private int mRestoredMediaButtonReceiverUserId; private IOnVolumeKeyLongPressListener mOnVolumeKeyLongPressListener; @@ -655,17 +664,23 @@ public class MediaSessionService extends SystemService implements Monitor { mFullUserId = fullUserId; mPriorityStack = new MediaSessionStack(mAudioPlayerStateMonitor, this); // Restore the remembered media button receiver before the boot. - String mediaButtonReceiver = Settings.Secure.getStringForUser(mContentResolver, + String mediaButtonReceiverInfo = Settings.Secure.getStringForUser(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER, mFullUserId); - if (mediaButtonReceiver == null) { + if (mediaButtonReceiverInfo == null) { return; } - String[] tokens = mediaButtonReceiver.split(COMPONENT_NAME_USER_ID_DELIM); - if (tokens == null || tokens.length != 2) { + String[] tokens = mediaButtonReceiverInfo.split(COMPONENT_NAME_USER_ID_DELIM); + if (tokens == null || (tokens.length != 2 && tokens.length != 3)) { return; } mRestoredMediaButtonReceiver = ComponentName.unflattenFromString(tokens[0]); mRestoredMediaButtonReceiverUserId = Integer.parseInt(tokens[1]); + if (tokens.length == 3) { + mRestoredMediaButtonReceiverComponentType = Integer.parseInt(tokens[2]); + } else { + mRestoredMediaButtonReceiverComponentType = + getComponentType(mRestoredMediaButtonReceiver); + } } public void destroySessionsForUserLocked(int userId) { @@ -696,6 +711,8 @@ public class MediaSessionService extends SystemService implements Monitor { pw.println(indent + "Callback: " + mCallback); pw.println(indent + "Last MediaButtonReceiver: " + mLastMediaButtonReceiver); pw.println(indent + "Restored MediaButtonReceiver: " + mRestoredMediaButtonReceiver); + pw.println(indent + "Restored MediaButtonReceiverComponentType: " + + mRestoredMediaButtonReceiverComponentType); mPriorityStack.dump(pw, indent); } @@ -722,17 +739,22 @@ public class MediaSessionService extends SystemService implements Monitor { PendingIntent receiver = record.getMediaButtonReceiver(); mLastMediaButtonReceiver = receiver; mRestoredMediaButtonReceiver = null; - String componentName = ""; + mRestoredMediaButtonReceiverComponentType = COMPONENT_TYPE_INVALID; + + String mediaButtonReceiverInfo = ""; if (receiver != null) { ComponentName component = receiver.getIntent().getComponent(); if (component != null && record.getPackageName().equals(component.getPackageName())) { - componentName = component.flattenToString(); + String componentName = component.flattenToString(); + int componentType = getComponentType(component); + mediaButtonReceiverInfo = String.join(COMPONENT_NAME_USER_ID_DELIM, + componentName, String.valueOf(record.getUserId()), + String.valueOf(componentType)); } } Settings.Secure.putStringForUser(mContentResolver, - Settings.System.MEDIA_BUTTON_RECEIVER, - componentName + COMPONENT_NAME_USER_ID_DELIM + record.getUserId(), + Settings.System.MEDIA_BUTTON_RECEIVER, mediaButtonReceiverInfo, mFullUserId); } @@ -762,6 +784,35 @@ public class MediaSessionService extends SystemService implements Monitor { return isGlobalPriorityActiveLocked() ? mGlobalPrioritySession : mPriorityStack.getMediaButtonSession(); } + + private int getComponentType(@Nullable ComponentName componentName) { + if (componentName == null) { + return COMPONENT_TYPE_INVALID; + } + PackageManager pm = getContext().getPackageManager(); + try { + ActivityInfo activityInfo = pm.getActivityInfo(componentName, + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.GET_ACTIVITIES); + if (activityInfo != null) { + return COMPONENT_TYPE_ACTIVITY; + } + } catch (NameNotFoundException e) { + } + try { + ServiceInfo serviceInfo = pm.getServiceInfo(componentName, + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.GET_SERVICES); + if (serviceInfo != null) { + return COMPONENT_TYPE_SERVICE; + } + } catch (NameNotFoundException e) { + } + // Pick legacy behavior for BroadcastReceiver or unknown. + return COMPONENT_TYPE_BROADCAST; + } } final class SessionsListenerRecord implements IBinder.DeathRecipient { @@ -1580,14 +1631,32 @@ public class MediaSessionService extends SystemService implements Monitor { } else { ComponentName receiver = mCurrentFullUserRecord.mRestoredMediaButtonReceiver; + int componentType = mCurrentFullUserRecord + .mRestoredMediaButtonReceiverComponentType; + UserHandle userHandle = UserHandle.of(mCurrentFullUserRecord + .mRestoredMediaButtonReceiverUserId); if (DEBUG_KEY_EVENT) { Log.d(TAG, "Sending " + keyEvent + " to the restored intent " - + receiver); + + receiver + ", type=" + componentType); } mediaButtonIntent.setComponent(receiver); - getContext().sendBroadcastAsUser(mediaButtonIntent, - UserHandle.of(mCurrentFullUserRecord - .mRestoredMediaButtonReceiverUserId)); + try { + switch (componentType) { + case FullUserRecord.COMPONENT_TYPE_ACTIVITY: + getContext().startActivityAsUser(mediaButtonIntent, userHandle); + break; + case FullUserRecord.COMPONENT_TYPE_SERVICE: + getContext().startForegroundServiceAsUser(mediaButtonIntent, + userHandle); + break; + default: + // Legacy behavior for other cases. + getContext().sendBroadcastAsUser(mediaButtonIntent, userHandle); + } + } catch (Exception e) { + Log.w(TAG, "Error sending media button to the restored intent " + + receiver + ", type=" + componentType, e); + } if (mCurrentFullUserRecord.mCallback != null) { mCurrentFullUserRecord.mCallback .onMediaKeyEventDispatchedToMediaButtonReceiver( |