Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ed3684b authored by Philip Junker's avatar Philip Junker Committed by Automerger Merge Worker
Browse files

Merge changes from topic "home_sound_exceptions" into sc-dev am: 2e998fc4

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13663067

Change-Id: I4ef245c7ee7d8aa883c918f5cf68333685469f7f
parents 3d123a82 2e998fc4
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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>
+107 −14
Original line number Diff line number Diff line
@@ -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);
    }
}
+293 −19

File changed.

Preview size limit exceeded, changes collapsed.