Merge changes from topic "home_sound_exceptions" into sc-dev
* changes: Check if package matches home package and allow exceptions. Define private manifest flag for home sound exception and add permission
This commit is contained in:
committed by
Android (Google) Code Review
commit
2e998fc497
@@ -92,6 +92,7 @@ package android {
|
||||
field public static final String CREATE_USERS = "android.permission.CREATE_USERS";
|
||||
field public static final String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER";
|
||||
field public static final String DEVICE_POWER = "android.permission.DEVICE_POWER";
|
||||
field public static final String DISABLE_SYSTEM_SOUND_EFFECTS = "android.permission.DISABLE_SYSTEM_SOUND_EFFECTS";
|
||||
field public static final String DISPATCH_PROVISIONING_MESSAGE = "android.permission.DISPATCH_PROVISIONING_MESSAGE";
|
||||
field public static final String DOMAIN_VERIFICATION_AGENT = "android.permission.DOMAIN_VERIFICATION_AGENT";
|
||||
field public static final String ENTER_CAR_MODE_PRIORITIZED = "android.permission.ENTER_CAR_MODE_PRIORITIZED";
|
||||
@@ -311,6 +312,7 @@ package android {
|
||||
field public static final int hotwordDetectionService = 16844326; // 0x1010626
|
||||
field public static final int isVrOnly = 16844152; // 0x1010578
|
||||
field public static final int minExtensionVersion = 16844305; // 0x1010611
|
||||
field public static final int playHomeTransitionSound = 16844358; // 0x1010646
|
||||
field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
|
||||
field public static final int requiredSystemPropertyValue = 16844134; // 0x1010566
|
||||
field public static final int sdkVersion = 16844304; // 0x1010610
|
||||
|
||||
@@ -549,10 +549,19 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
*/
|
||||
public static final int FLAG_INHERIT_SHOW_WHEN_LOCKED = 0x1;
|
||||
|
||||
/**
|
||||
* Bit in {@link #privateFlags} indicating whether a home sound effect should be played if the
|
||||
* home app moves to front after the activity with this flag set.
|
||||
* Set from the {@link android.R.attr#playHomeTransitionSound} attribute.
|
||||
* @hide
|
||||
*/
|
||||
public static final int PRIVATE_FLAG_HOME_TRANSITION_SOUND = 0x2;
|
||||
|
||||
/**
|
||||
* Options that have been set in the activity declaration in the manifest.
|
||||
* These include:
|
||||
* {@link #FLAG_INHERIT_SHOW_WHEN_LOCKED}.
|
||||
* {@link #FLAG_INHERIT_SHOW_WHEN_LOCKED},
|
||||
* {@link #PRIVATE_FLAG_HOME_TRANSITION_SOUND}.
|
||||
* @hide
|
||||
*/
|
||||
public int privateFlags;
|
||||
|
||||
@@ -149,7 +149,10 @@ public class ParsedActivityUtils {
|
||||
| flag(ActivityInfo.FLAG_TURN_SCREEN_ON, R.styleable.AndroidManifestActivity_turnScreenOn, sa)
|
||||
| flag(ActivityInfo.FLAG_PREFER_MINIMAL_POST_PROCESSING, R.styleable.AndroidManifestActivity_preferMinimalPostProcessing, sa);
|
||||
|
||||
activity.privateFlags |= flag(ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED, R.styleable.AndroidManifestActivity_inheritShowWhenLocked, sa);
|
||||
activity.privateFlags |= flag(ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED,
|
||||
R.styleable.AndroidManifestActivity_inheritShowWhenLocked, sa)
|
||||
| flag(ActivityInfo.PRIVATE_FLAG_HOME_TRANSITION_SOUND,
|
||||
R.styleable.AndroidManifestActivity_playHomeTransitionSound, true, sa);
|
||||
|
||||
activity.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode, ActivityInfo.COLOR_MODE_DEFAULT);
|
||||
activity.documentLaunchMode = sa.getInt(R.styleable.AndroidManifestActivity_documentLaunchMode, ActivityInfo.DOCUMENT_LAUNCH_NONE);
|
||||
|
||||
@@ -4440,6 +4440,13 @@
|
||||
<permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
|
||||
<!-- @SystemApi Allows an application to disable system sound effects when the user exits one of
|
||||
the application's activities.
|
||||
<p>Not for use by third-party applications.</p>
|
||||
@hide -->
|
||||
<permission android:name="android.permission.DISABLE_SYSTEM_SOUND_EFFECTS"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
|
||||
<!-- @SystemApi Allows an application to provide remote displays.
|
||||
<p>Not for use by third-party applications.</p>
|
||||
@hide -->
|
||||
|
||||
@@ -2862,6 +2862,13 @@
|
||||
{@link android.content.Context#sendBroadcast(Intent, String)} being used.
|
||||
Multiple tags can be specified separated by '|'. -->
|
||||
<attr name="attributionTags"/>
|
||||
<!-- Specifies whether a home sound effect should be played if the home app moves to
|
||||
front after an activity with this flag set to <code>true</code>.
|
||||
<p>The default value of this attribute is <code>true</code>.
|
||||
<p>Also note that home sounds are only played if the device supports home sounds,
|
||||
usually TVs.
|
||||
<p>Requires permission {@code android.permission.DISABLE_SYSTEM_SOUND_EFFECTS}. -->
|
||||
<attr name="playHomeTransitionSound" format="boolean"/>
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The <code>activity-alias</code> tag declares a new
|
||||
|
||||
@@ -3093,6 +3093,8 @@
|
||||
<public name="suppressesSpellChecker" />
|
||||
<public name="usesPermissionFlags" />
|
||||
<public name="requestOptimizedExternalStorageAccess" />
|
||||
<!-- @hide @SystemApi -->
|
||||
<public name="playHomeTransitionSound" />
|
||||
</public-group>
|
||||
|
||||
<public-group type="drawable" first-id="0x010800b5">
|
||||
|
||||
@@ -591,4 +591,12 @@
|
||||
|
||||
<!-- Determines whether to allow the nav bar handle to be forced to be opaque. -->
|
||||
<bool name="allow_force_nav_bar_handle_opaque">true</bool>
|
||||
|
||||
<!-- Whether a transition of ACTIVITY_TYPE_DREAM to the home app should play a home sound
|
||||
effect -->
|
||||
<bool name="config_playHomeSoundAfterDream">false</bool>
|
||||
|
||||
<!-- Whether a transition of ACTIVITY_TYPE_ASSISTANT to the home app should play a home sound
|
||||
effect -->
|
||||
<bool name="config_playHomeSoundAfterAssistant">false</bool>
|
||||
</resources>
|
||||
|
||||
@@ -16,38 +16,64 @@
|
||||
|
||||
package com.android.systemui.media.systemsounds;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SystemUI;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListeners;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* If a sound effect is defined for {@link android.media.AudioManager#FX_HOME}, a sound is played
|
||||
* when the home task moves to front and the last task that moved to front was not the home task.
|
||||
* If a sound effect is defined for {@link android.media.AudioManager#FX_HOME}, a
|
||||
* {@link TaskStackChangeListener} is registered to play a home sound effect when conditions
|
||||
* documented at {@link #handleTaskStackChanged} apply.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class HomeSoundEffectController extends SystemUI {
|
||||
|
||||
private static final String TAG = "HomeSoundEffectController";
|
||||
private final AudioManager mAudioManager;
|
||||
private final TaskStackChangeListeners mTaskStackChangeListeners;
|
||||
private final ActivityManagerWrapper mActivityManagerWrapper;
|
||||
private final PackageManager mPm;
|
||||
private final boolean mPlayHomeSoundAfterAssistant;
|
||||
private final boolean mPlayHomeSoundAfterDream;
|
||||
// Initialize true because home sound should not be played when the system boots.
|
||||
private boolean mIsLastTaskHome = true;
|
||||
// mLastHomePackageName could go out of sync in rare circumstances if launcher changes,
|
||||
// but it's cheaper than the alternative and potential impact is low
|
||||
private String mLastHomePackageName;
|
||||
private @WindowConfiguration.ActivityType int mLastActivityType;
|
||||
private boolean mLastActivityHasNoHomeSound = false;
|
||||
private int mLastTaskId;
|
||||
|
||||
@Inject
|
||||
public HomeSoundEffectController(
|
||||
Context context,
|
||||
AudioManager audioManager,
|
||||
TaskStackChangeListeners taskStackChangeListeners) {
|
||||
TaskStackChangeListeners taskStackChangeListeners,
|
||||
ActivityManagerWrapper activityManagerWrapper,
|
||||
PackageManager packageManager) {
|
||||
super(context);
|
||||
mAudioManager = audioManager;
|
||||
mTaskStackChangeListeners = taskStackChangeListeners;
|
||||
mActivityManagerWrapper = activityManagerWrapper;
|
||||
mPm = packageManager;
|
||||
mPlayHomeSoundAfterAssistant = context.getResources().getBoolean(
|
||||
R.bool.config_playHomeSoundAfterAssistant);
|
||||
mPlayHomeSoundAfterDream = context.getResources().getBoolean(
|
||||
R.bool.config_playHomeSoundAfterDream);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,27 +82,94 @@ public class HomeSoundEffectController extends SystemUI {
|
||||
mTaskStackChangeListeners.registerTaskStackListener(
|
||||
new TaskStackChangeListener() {
|
||||
@Override
|
||||
public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
handleHomeTaskMovedToFront(taskInfo);
|
||||
public void onTaskStackChanged() {
|
||||
ActivityManager.RunningTaskInfo currentTask =
|
||||
mActivityManagerWrapper.getRunningTask();
|
||||
if (currentTask == null || currentTask.topActivityInfo == null) {
|
||||
return;
|
||||
}
|
||||
handleTaskStackChanged(currentTask);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isHomeTask(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
return taskInfo.getActivityType() == WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
private boolean hasFlagNoSound(ActivityInfo activityInfo) {
|
||||
if ((activityInfo.privateFlags & ActivityInfo.PRIVATE_FLAG_HOME_TRANSITION_SOUND) == 0) {
|
||||
// Only allow flag if app has permission
|
||||
if (mPm.checkPermission(Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS,
|
||||
activityInfo.packageName) == PackageManager.PERMISSION_GRANTED) {
|
||||
return true;
|
||||
} else {
|
||||
Slog.w(TAG,
|
||||
"Activity has flag playHomeTransition set to false but doesn't hold "
|
||||
+ "required permission "
|
||||
+ Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* To enable a home sound, check if the home app moves to front.
|
||||
* The home sound is played if all of the following conditions are met:
|
||||
* <ul>
|
||||
* <li>The last task which moved to front was not home. This avoids playing the sound
|
||||
* e.g. after FallbackHome transitions to home, another activity of the home app like a
|
||||
* notification panel moved to front, or in case the home app crashed.</li>
|
||||
* <li>The current activity which moved to front is home</li>
|
||||
* <li>The topActivity of the last task has {@link android.R.attr#playHomeTransitionSound} set
|
||||
* to <code>true</code>.</li>
|
||||
* <li>The topActivity of the last task is not of type
|
||||
* {@link WindowConfiguration#ACTIVITY_TYPE_ASSISTANT} if config_playHomeSoundAfterAssistant is
|
||||
* set to <code>false</code> (default).</li>
|
||||
* <li>The topActivity of the last task is not of type
|
||||
* {@link WindowConfiguration#ACTIVITY_TYPE_DREAM} if config_playHomeSoundAfterDream is
|
||||
* set to <code>false</code> (default).</li>
|
||||
* </ul>
|
||||
*/
|
||||
private void handleHomeTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
boolean isCurrentTaskHome = isHomeTask(taskInfo);
|
||||
// If the last task is home we don't want to play the home sound. This avoids playing
|
||||
// the home sound after FallbackHome transitions to Home
|
||||
if (!mIsLastTaskHome && isCurrentTaskHome) {
|
||||
private boolean shouldPlayHomeSoundForCurrentTransition(
|
||||
ActivityManager.RunningTaskInfo currentTask) {
|
||||
boolean isHomeActivity =
|
||||
currentTask.topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
if (currentTask.taskId == mLastTaskId) {
|
||||
return false;
|
||||
}
|
||||
if (mIsLastTaskHome || !isHomeActivity) {
|
||||
return false;
|
||||
}
|
||||
if (mLastActivityHasNoHomeSound) {
|
||||
return false;
|
||||
}
|
||||
if (mLastActivityType == WindowConfiguration.ACTIVITY_TYPE_ASSISTANT
|
||||
&& !mPlayHomeSoundAfterAssistant) {
|
||||
return false;
|
||||
}
|
||||
if (mLastActivityType == WindowConfiguration.ACTIVITY_TYPE_DREAM
|
||||
&& !mPlayHomeSoundAfterDream) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateLastTaskInfo(ActivityManager.RunningTaskInfo currentTask) {
|
||||
mLastTaskId = currentTask.taskId;
|
||||
mLastActivityType = currentTask.topActivityType;
|
||||
mLastActivityHasNoHomeSound = hasFlagNoSound(currentTask.topActivityInfo);
|
||||
boolean isHomeActivity =
|
||||
currentTask.topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
boolean isHomePackage = currentTask.topActivityInfo.packageName.equals(
|
||||
mLastHomePackageName);
|
||||
mIsLastTaskHome = isHomeActivity || isHomePackage;
|
||||
if (isHomeActivity && !isHomePackage) {
|
||||
mLastHomePackageName = currentTask.topActivityInfo.packageName;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTaskStackChanged(ActivityManager.RunningTaskInfo frontTask) {
|
||||
if (shouldPlayHomeSoundForCurrentTransition(frontTask)) {
|
||||
mAudioManager.playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
mIsLastTaskHome = isCurrentTaskHome;
|
||||
updateLastTaskInfo(frontTask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,16 +21,20 @@ import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListeners;
|
||||
|
||||
@@ -41,30 +45,50 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class HomeSoundEffectControllerTest extends SysuiTestCase {
|
||||
|
||||
private @Mock Context mContext;
|
||||
private static final String HOME_PACKAGE_NAME = "com.android.apps.home";
|
||||
private static final String NON_HOME_PACKAGE_NAME = "com.android.apps.not.home";
|
||||
private static final int HOME_TASK_ID = 0;
|
||||
private static final int NON_HOME_TASK_ID = 1;
|
||||
|
||||
private @Mock AudioManager mAudioManager;
|
||||
private @Mock TaskStackChangeListeners mTaskStackChangeListeners;
|
||||
private @Mock ActivityManager.RunningTaskInfo mStandardActivityTaskInfo;
|
||||
private @Mock ActivityManager.RunningTaskInfo mHomeActivityTaskInfo;
|
||||
private @Mock ActivityManagerWrapper mActivityManagerWrapper;
|
||||
private @Mock PackageManager mPackageManager;
|
||||
|
||||
private ActivityManager.RunningTaskInfo mTaskAStandardActivity;
|
||||
private ActivityManager.RunningTaskInfo mTaskAExceptionActivity;
|
||||
private ActivityManager.RunningTaskInfo mHomeTaskHomeActivity;
|
||||
private ActivityManager.RunningTaskInfo mHomeTaskStandardActivity;
|
||||
private ActivityManager.RunningTaskInfo mEmptyTask;
|
||||
private HomeSoundEffectController mController;
|
||||
private TaskStackChangeListener mTaskStackChangeListener;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
doReturn(WindowConfiguration.ACTIVITY_TYPE_STANDARD).when(
|
||||
mStandardActivityTaskInfo).getActivityType();
|
||||
doReturn(WindowConfiguration.ACTIVITY_TYPE_HOME).when(
|
||||
mHomeActivityTaskInfo).getActivityType();
|
||||
|
||||
mTaskAStandardActivity = createRunningTaskInfo(NON_HOME_PACKAGE_NAME,
|
||||
WindowConfiguration.ACTIVITY_TYPE_STANDARD, NON_HOME_TASK_ID,
|
||||
true /* playHomeTransitionSound */);
|
||||
mTaskAExceptionActivity = createRunningTaskInfo(NON_HOME_PACKAGE_NAME,
|
||||
WindowConfiguration.ACTIVITY_TYPE_STANDARD, NON_HOME_TASK_ID,
|
||||
false /* playHomeTransitionSound */);
|
||||
mHomeTaskHomeActivity = createRunningTaskInfo(HOME_PACKAGE_NAME,
|
||||
WindowConfiguration.ACTIVITY_TYPE_HOME, HOME_TASK_ID,
|
||||
true /* playHomeTransitionSound */);
|
||||
mHomeTaskStandardActivity = createRunningTaskInfo(HOME_PACKAGE_NAME,
|
||||
WindowConfiguration.ACTIVITY_TYPE_STANDARD, HOME_TASK_ID,
|
||||
true /* playHomeTransitionSound */);
|
||||
mEmptyTask = new ActivityManager.RunningTaskInfo();
|
||||
mContext.setMockPackageManager(mPackageManager);
|
||||
when(mPackageManager.checkPermission(Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS,
|
||||
NON_HOME_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_GRANTED);
|
||||
mController = new HomeSoundEffectController(mContext, mAudioManager,
|
||||
mTaskStackChangeListeners);
|
||||
mTaskStackChangeListeners, mActivityManagerWrapper, mPackageManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,43 +97,60 @@ public class HomeSoundEffectControllerTest extends SysuiTestCase {
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskMovedToFront(mHomeActivityTaskInfo);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(mHomeTaskHomeActivity);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then no home sound effect should be played.
|
||||
verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Task A (playHomeTransitionSound = true) -> HOME
|
||||
* Expectation: Home sound is played
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectPlayedWhenEnabled() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAStandardActivity,
|
||||
mHomeTaskHomeActivity);
|
||||
|
||||
// And first a task different from the home task moves to front,
|
||||
mTaskStackChangeListener.onTaskMovedToFront(mStandardActivityTaskInfo);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskMovedToFront(mHomeActivityTaskInfo);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then the home sound effect should be played.
|
||||
verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Task A (playHomeTransitionSound = true) -> HOME -> HOME
|
||||
* Expectation: Home sound is played once after HOME moves to front the first time
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectNotPlayedTwiceInRow() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAStandardActivity,
|
||||
mHomeTaskHomeActivity,
|
||||
mHomeTaskHomeActivity);
|
||||
|
||||
|
||||
// And first a task different from the home task moves to front,
|
||||
mTaskStackChangeListener.onTaskMovedToFront(mStandardActivityTaskInfo);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskMovedToFront(mHomeActivityTaskInfo);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then the home sound effect should be played.
|
||||
verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
|
||||
|
||||
// If the home task moves to front a second time in a row,
|
||||
mTaskStackChangeListener.onTaskMovedToFront(mHomeActivityTaskInfo);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then no home sound effect should be played.
|
||||
verify(mAudioManager, times(1)).playSoundEffect(AudioManager.FX_HOME);
|
||||
@@ -121,7 +162,59 @@ public class HomeSoundEffectControllerTest extends SysuiTestCase {
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
|
||||
// And a standard, non-home task, moves to the front,
|
||||
mTaskStackChangeListener.onTaskMovedToFront(mStandardActivityTaskInfo);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(mTaskAStandardActivity);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then no home sound effect should be played.
|
||||
verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Task A (playHomeTransitionSound = true) -> HOME -> HOME (activity type standard)
|
||||
* Expectation: Home sound is played once after HOME moves to front
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectNotPlayedWhenOtherHomeActivityMovesToFront() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAStandardActivity,
|
||||
mHomeTaskHomeActivity,
|
||||
mHomeTaskStandardActivity);
|
||||
|
||||
// And first a task different from the home task moves to front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then the home sound effect should be played.
|
||||
verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
|
||||
|
||||
// If the home task moves to front a second time in a row,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then no home sound effect should be played.
|
||||
verify(mAudioManager, times(1)).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Task A (playHomeTransitionSound = true) -> HOME (activity type standard)
|
||||
* Expectation: Home sound is not played
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectNotPlayedWhenOtherHomeActivityMovesToFrontOfOtherApp() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
|
||||
// And first a task different from the home task moves to front,
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAStandardActivity,
|
||||
mHomeTaskStandardActivity);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And an activity from the home package but not the home root activity moves to front
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then no home sound effect should be played.
|
||||
verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
|
||||
@@ -137,6 +230,171 @@ public class HomeSoundEffectControllerTest extends SysuiTestCase {
|
||||
any(TaskStackChangeListener.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Task A (playHomeTransitionSound = false) -> HOME
|
||||
* Expectation: Home sound is not played
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectNotPlayedWhenHomeActivityMovesToFrontAfterException() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
|
||||
// And first a task different from the home task moves to front, which has
|
||||
// {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>false</code>
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAExceptionActivity,
|
||||
mHomeTaskHomeActivity);
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then no home sound effect should be played because the last package is an exception.
|
||||
verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* HOME -> Task A (playHomeTransitionSound = true) -> Task A (playHomeTransitionSound = false)
|
||||
* -> HOME
|
||||
* Expectation: Home sound is not played
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectNotPlayedWhenHomeActivityMovesToFrontAfterException2() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAStandardActivity,
|
||||
mTaskAExceptionActivity,
|
||||
mHomeTaskHomeActivity);
|
||||
|
||||
// And first a task different from the home task moves to front
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then a different activity from the same task moves to front, which has
|
||||
// {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>false</code>
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then no home sound effect should be played.
|
||||
verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* HOME -> Task A (playHomeTransitionSound = false) -> Task A (playHomeTransitionSound = true)
|
||||
* -> HOME
|
||||
* Expectation: Home sound is played
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectPlayedWhenHomeActivityMovesToFrontAfterException() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAExceptionActivity,
|
||||
mTaskAStandardActivity,
|
||||
mHomeTaskHomeActivity);
|
||||
|
||||
// And first a task different from the home task moves to front,
|
||||
// the topActivity of this task has {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND}
|
||||
// set to <code>false</code>
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then a different activity from the same task moves to front, which has
|
||||
// {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>true</code>
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then the home sound effect should be played.
|
||||
verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* HOME -> Task A (playHomeTransitionSound = false) -> Task A (empty task, no top activity)
|
||||
* -> HOME
|
||||
* Expectation: Home sound is not played
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectNotPlayedWhenEmptyTaskMovesToFrontAfterException() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAExceptionActivity,
|
||||
mEmptyTask,
|
||||
mHomeTaskHomeActivity);
|
||||
|
||||
// And first a task different from the home task moves to front, whose topActivity has
|
||||
// {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>false</code>
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then a task with no topActivity moves to front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then no home sound effect should be played.
|
||||
verify(mAudioManager, never()).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* HOME -> Task A (playHomeTransitionSound = true) -> Task A (empty task, no top activity)
|
||||
* -> HOME
|
||||
* Expectation: Home sound is played
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectPlayedWhenEmptyTaskMovesToFrontAfterStandardActivity() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAStandardActivity,
|
||||
mEmptyTask,
|
||||
mHomeTaskHomeActivity);
|
||||
|
||||
// And first a task different from the home task moves to front, whose topActivity has
|
||||
// {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>false</code>
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then a task with no topActivity moves to front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then the home sound effect should be played.
|
||||
verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* HOME -> Task A (playHomeTransitionSound = false, no permission) -> HOME
|
||||
* Expectation: Home sound is played
|
||||
*/
|
||||
@Test
|
||||
public void testHomeSoundEffectPlayedWhenFlagSetButPermissionNotGranted() {
|
||||
// When HomeSoundEffectController is started and the home sound effect is enabled,
|
||||
startController(true /* isHomeSoundEffectEnabled */);
|
||||
when(mActivityManagerWrapper.getRunningTask()).thenReturn(
|
||||
mTaskAStandardActivity,
|
||||
mHomeTaskHomeActivity);
|
||||
when(mPackageManager.checkPermission(Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS,
|
||||
NON_HOME_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_DENIED);
|
||||
|
||||
// And first a task different from the home task moves to front, whose topActivity has
|
||||
// {@link ActivityInfo#PRIVATE_FLAG_HOME_TRANSITION_SOUND} set to <code>true</code>,
|
||||
// but the app doesn't have the right permission granted
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
|
||||
// And the home task moves to the front,
|
||||
mTaskStackChangeListener.onTaskStackChanged();
|
||||
|
||||
// Then the home sound effect should be played.
|
||||
verify(mAudioManager).playSoundEffect(AudioManager.FX_HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets {@link AudioManager#isHomeSoundEffectEnabled()} and starts HomeSoundEffectController.
|
||||
* If the home sound effect is enabled, the registered TaskStackChangeListener is extracted.
|
||||
@@ -155,4 +413,20 @@ public class HomeSoundEffectControllerTest extends SysuiTestCase {
|
||||
mTaskStackChangeListener = listenerCaptor.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
private ActivityManager.RunningTaskInfo createRunningTaskInfo(String packageName,
|
||||
int activityType, int taskId, boolean playHomeTransitionSound) {
|
||||
ActivityManager.RunningTaskInfo res = new ActivityManager.RunningTaskInfo();
|
||||
res.topActivityInfo = new ActivityInfo();
|
||||
res.topActivityInfo.packageName = packageName;
|
||||
res.topActivityType = activityType;
|
||||
res.taskId = taskId;
|
||||
if (!playHomeTransitionSound) {
|
||||
// set the flag to 0
|
||||
res.topActivityInfo.privateFlags &= ~ActivityInfo.PRIVATE_FLAG_HOME_TRANSITION_SOUND;
|
||||
} else {
|
||||
res.topActivityInfo.privateFlags |= ActivityInfo.PRIVATE_FLAG_HOME_TRANSITION_SOUND;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user