Allow Activity/Service to get media keys across the boot
Bug: 121122701 Test: Manually tested Change-Id: Id56f3ebfad9ed3472d28712eed3fa539c6e3e485
This commit is contained in:
@@ -27,8 +27,10 @@ import android.content.ComponentName;
|
|||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
@@ -634,11 +636,16 @@ public class MediaSessionService extends SystemService implements Monitor {
|
|||||||
* <p>The contents of this object is guarded by {@link #mLock}.
|
* <p>The contents of this object is guarded by {@link #mLock}.
|
||||||
*/
|
*/
|
||||||
final class FullUserRecord implements MediaSessionStack.OnMediaButtonSessionChangedListener {
|
final class FullUserRecord implements MediaSessionStack.OnMediaButtonSessionChangedListener {
|
||||||
|
public static final int COMPONENT_TYPE_BROADCAST = 0;
|
||||||
|
public static final int COMPONENT_TYPE_ACTIVITY = 1;
|
||||||
|
public static final int COMPONENT_TYPE_SERVICE = 2;
|
||||||
private static final String COMPONENT_NAME_USER_ID_DELIM = ",";
|
private static final String COMPONENT_NAME_USER_ID_DELIM = ",";
|
||||||
|
|
||||||
private final int mFullUserId;
|
private final int mFullUserId;
|
||||||
private final MediaSessionStack mPriorityStack;
|
private final MediaSessionStack mPriorityStack;
|
||||||
private PendingIntent mLastMediaButtonReceiver;
|
private PendingIntent mLastMediaButtonReceiver;
|
||||||
private ComponentName mRestoredMediaButtonReceiver;
|
private ComponentName mRestoredMediaButtonReceiver;
|
||||||
|
private int mRestoredMediaButtonReceiverComponentType;
|
||||||
private int mRestoredMediaButtonReceiverUserId;
|
private int mRestoredMediaButtonReceiverUserId;
|
||||||
|
|
||||||
private IOnVolumeKeyLongPressListener mOnVolumeKeyLongPressListener;
|
private IOnVolumeKeyLongPressListener mOnVolumeKeyLongPressListener;
|
||||||
@@ -655,17 +662,23 @@ public class MediaSessionService extends SystemService implements Monitor {
|
|||||||
mFullUserId = fullUserId;
|
mFullUserId = fullUserId;
|
||||||
mPriorityStack = new MediaSessionStack(mAudioPlayerStateMonitor, this);
|
mPriorityStack = new MediaSessionStack(mAudioPlayerStateMonitor, this);
|
||||||
// Restore the remembered media button receiver before the boot.
|
// 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);
|
Settings.System.MEDIA_BUTTON_RECEIVER, mFullUserId);
|
||||||
if (mediaButtonReceiver == null) {
|
if (mediaButtonReceiverInfo == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String[] tokens = mediaButtonReceiver.split(COMPONENT_NAME_USER_ID_DELIM);
|
String[] tokens = mediaButtonReceiverInfo.split(COMPONENT_NAME_USER_ID_DELIM);
|
||||||
if (tokens == null || tokens.length != 2) {
|
if (tokens == null || (tokens.length != 2 && tokens.length != 3)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mRestoredMediaButtonReceiver = ComponentName.unflattenFromString(tokens[0]);
|
mRestoredMediaButtonReceiver = ComponentName.unflattenFromString(tokens[0]);
|
||||||
mRestoredMediaButtonReceiverUserId = Integer.parseInt(tokens[1]);
|
mRestoredMediaButtonReceiverUserId = Integer.parseInt(tokens[1]);
|
||||||
|
if (tokens.length == 3) {
|
||||||
|
mRestoredMediaButtonReceiverComponentType = Integer.parseInt(tokens[2]);
|
||||||
|
} else {
|
||||||
|
mRestoredMediaButtonReceiverComponentType =
|
||||||
|
getComponentType(mRestoredMediaButtonReceiver);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroySessionsForUserLocked(int userId) {
|
public void destroySessionsForUserLocked(int userId) {
|
||||||
@@ -696,6 +709,8 @@ public class MediaSessionService extends SystemService implements Monitor {
|
|||||||
pw.println(indent + "Callback: " + mCallback);
|
pw.println(indent + "Callback: " + mCallback);
|
||||||
pw.println(indent + "Last MediaButtonReceiver: " + mLastMediaButtonReceiver);
|
pw.println(indent + "Last MediaButtonReceiver: " + mLastMediaButtonReceiver);
|
||||||
pw.println(indent + "Restored MediaButtonReceiver: " + mRestoredMediaButtonReceiver);
|
pw.println(indent + "Restored MediaButtonReceiver: " + mRestoredMediaButtonReceiver);
|
||||||
|
pw.println(indent + "Restored MediaButtonReceiverComponentType: "
|
||||||
|
+ mRestoredMediaButtonReceiverComponentType);
|
||||||
mPriorityStack.dump(pw, indent);
|
mPriorityStack.dump(pw, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,17 +737,21 @@ public class MediaSessionService extends SystemService implements Monitor {
|
|||||||
PendingIntent receiver = record.getMediaButtonReceiver();
|
PendingIntent receiver = record.getMediaButtonReceiver();
|
||||||
mLastMediaButtonReceiver = receiver;
|
mLastMediaButtonReceiver = receiver;
|
||||||
mRestoredMediaButtonReceiver = null;
|
mRestoredMediaButtonReceiver = null;
|
||||||
String componentName = "";
|
|
||||||
|
String mediaButtonReceiverInfo = "";
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
ComponentName component = receiver.getIntent().getComponent();
|
ComponentName component = receiver.getIntent().getComponent();
|
||||||
if (component != null
|
if (component != null
|
||||||
&& record.getPackageName().equals(component.getPackageName())) {
|
&& 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.Secure.putStringForUser(mContentResolver,
|
||||||
Settings.System.MEDIA_BUTTON_RECEIVER,
|
Settings.System.MEDIA_BUTTON_RECEIVER, mediaButtonReceiverInfo,
|
||||||
componentName + COMPONENT_NAME_USER_ID_DELIM + record.getUserId(),
|
|
||||||
mFullUserId);
|
mFullUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,6 +781,32 @@ public class MediaSessionService extends SystemService implements Monitor {
|
|||||||
return isGlobalPriorityActiveLocked()
|
return isGlobalPriorityActiveLocked()
|
||||||
? mGlobalPrioritySession : mPriorityStack.getMediaButtonSession();
|
? mGlobalPrioritySession : mPriorityStack.getMediaButtonSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getComponentType(ComponentName componentName) {
|
||||||
|
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 {
|
final class SessionsListenerRecord implements IBinder.DeathRecipient {
|
||||||
@@ -1580,14 +1625,32 @@ public class MediaSessionService extends SystemService implements Monitor {
|
|||||||
} else {
|
} else {
|
||||||
ComponentName receiver =
|
ComponentName receiver =
|
||||||
mCurrentFullUserRecord.mRestoredMediaButtonReceiver;
|
mCurrentFullUserRecord.mRestoredMediaButtonReceiver;
|
||||||
|
int componentType = mCurrentFullUserRecord
|
||||||
|
.mRestoredMediaButtonReceiverComponentType;
|
||||||
|
UserHandle userHandle = UserHandle.of(mCurrentFullUserRecord
|
||||||
|
.mRestoredMediaButtonReceiverUserId);
|
||||||
if (DEBUG_KEY_EVENT) {
|
if (DEBUG_KEY_EVENT) {
|
||||||
Log.d(TAG, "Sending " + keyEvent + " to the restored intent "
|
Log.d(TAG, "Sending " + keyEvent + " to the restored intent "
|
||||||
+ receiver);
|
+ receiver + ", type=" + componentType);
|
||||||
}
|
}
|
||||||
mediaButtonIntent.setComponent(receiver);
|
mediaButtonIntent.setComponent(receiver);
|
||||||
getContext().sendBroadcastAsUser(mediaButtonIntent,
|
try {
|
||||||
UserHandle.of(mCurrentFullUserRecord
|
switch (componentType) {
|
||||||
.mRestoredMediaButtonReceiverUserId));
|
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) {
|
if (mCurrentFullUserRecord.mCallback != null) {
|
||||||
mCurrentFullUserRecord.mCallback
|
mCurrentFullUserRecord.mCallback
|
||||||
.onMediaKeyEventDispatchedToMediaButtonReceiver(
|
.onMediaKeyEventDispatchedToMediaButtonReceiver(
|
||||||
|
|||||||
Reference in New Issue
Block a user