diff options
author | 2024-11-08 08:38:11 -0800 | |
---|---|---|
committer | 2024-11-08 14:24:36 -0800 | |
commit | 9c774c4cf08b39ec0effb60f368b090bc489ed43 (patch) | |
tree | 5fb628277c7b088de4c384955d7a87f23fd1c1ba | |
parent | 230b2f50a749bbe87a90eeaea5b7009ce5cb5dbe (diff) |
Introducing the MSDLPlayer in Launcher via a wrapper singleton.
The player is the main API to the MSDL library (also used in SysUI) that
implements the Multi-sensory Design Language in the system UI. This CL
also includes an example of the API usage, when the user swipes up to
reveal AllApps, or taps on QSB.
Test: manual. Verified that the MSDL haptics play when swiping to reveal
AllApps and tapping on QSB.
Flag: com.android.launcher3.msdl_feedback
Bug: 371322466
Bug: 371250001
Change-Id: Ie13fd5494efc9fc80cdb94a7bdd6e20b2e4633a8
-rw-r--r-- | Android.bp | 1 | ||||
-rw-r--r-- | src/com/android/launcher3/allapps/AllAppsTransitionController.java | 21 | ||||
-rw-r--r-- | src/com/android/launcher3/dagger/LauncherBaseAppComponent.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/util/MSDLPlayerWrapper.java | 61 |
4 files changed, 80 insertions, 5 deletions
diff --git a/Android.bp b/Android.bp index 223e2c2987..73d0fce260 100644 --- a/Android.bp +++ b/Android.bp @@ -387,6 +387,7 @@ android_library { "//frameworks/libs/systemui:view_capture", "//frameworks/libs/systemui:animationlib", "//frameworks/libs/systemui:contextualeducationlib", + "//frameworks/libs/systemui:msdl", "SystemUI-statsd", "launcher-testing-shared", "androidx.lifecycle_lifecycle-common-java8", diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index c6852e015c..1766e6eafd 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -48,6 +48,7 @@ import androidx.annotation.Nullable; import com.android.app.animation.Interpolators; import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; +import com.android.launcher3.Flags; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.R; @@ -57,14 +58,16 @@ import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.AllAppsSwipeController; +import com.android.launcher3.util.MSDLPlayerWrapper; import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.ScrollableLayoutManager; import com.android.launcher3.util.Themes; -import com.android.launcher3.util.VibratorWrapper; import com.android.launcher3.views.ScrimView; +import com.google.android.msdl.data.model.MSDLToken; + /** * Handles AllApps view transition. * 1) Slides all apps view using direct manipulation @@ -186,7 +189,7 @@ public class AllAppsTransitionController private boolean mIsTablet; private boolean mHasScaleEffect; - private final VibratorWrapper mVibratorWrapper; + private final MSDLPlayerWrapper mMSDLPlayerWrapper; public AllAppsTransitionController(Launcher l) { mLauncher = l; @@ -200,7 +203,7 @@ public class AllAppsTransitionController setShiftRange(dp.allAppsShiftRange); mAllAppScale.value = 1; mLauncher.addOnDeviceProfileChangeListener(this); - mVibratorWrapper = VibratorWrapper.INSTANCE.get(mLauncher.getApplicationContext()); + mMSDLPlayerWrapper = MSDLPlayerWrapper.INSTANCE.get(mLauncher.getApplicationContext()); } public float getShiftRange() { @@ -373,8 +376,16 @@ public class AllAppsTransitionController setAlphas(toState, config, builder); // This controls both haptics for tapping on QSB and going to all apps. if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL)) { - mLauncher.getAppsView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + if (Flags.msdlFeedback()) { + if (config.isUserControlled()) { + mMSDLPlayerWrapper.playToken(MSDLToken.SWIPE_THRESHOLD_INDICATOR); + } else { + mMSDLPlayerWrapper.playToken(MSDLToken.TAP_HIGH_EMPHASIS); + } + } else { + mLauncher.getAppsView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, + HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + } } } diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java index 0e20f7591b..fb486f7c43 100644 --- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java +++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java @@ -24,6 +24,7 @@ import com.android.launcher3.model.ItemInstallQueue; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.util.ApiWrapper; import com.android.launcher3.util.DaggerSingletonTracker; +import com.android.launcher3.util.MSDLPlayerWrapper; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PluginManagerWrapper; import com.android.launcher3.util.ScreenOnTracker; @@ -56,6 +57,7 @@ public interface LauncherBaseAppComponent { PackageManagerHelper getPackageManagerHelper(); PluginManagerWrapper getPluginManagerWrapper(); VibratorWrapper getVibratorWrapper(); + MSDLPlayerWrapper getMSDLPlayerWrapper(); /** Builder for LauncherBaseAppComponent. */ interface Builder { diff --git a/src/com/android/launcher3/util/MSDLPlayerWrapper.java b/src/com/android/launcher3/util/MSDLPlayerWrapper.java new file mode 100644 index 0000000000..1e53ac1e8a --- /dev/null +++ b/src/com/android/launcher3/util/MSDLPlayerWrapper.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.util; + +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + +import android.content.Context; +import android.os.Vibrator; + +import com.android.launcher3.dagger.ApplicationContext; +import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.dagger.LauncherBaseAppComponent; + +import com.google.android.msdl.data.model.MSDLToken; +import com.google.android.msdl.domain.InteractionProperties; +import com.google.android.msdl.domain.MSDLPlayer; + +import javax.inject.Inject; + +/** + * Wrapper around {@link com.google.android.msdl.domain.MSDLPlayer} to perform MSDL feedback. + */ +@LauncherAppSingleton +public class MSDLPlayerWrapper { + + public static final DaggerSingletonObject<MSDLPlayerWrapper> INSTANCE = + new DaggerSingletonObject<>(LauncherBaseAppComponent::getMSDLPlayerWrapper); + + /** Internal player */ + private final MSDLPlayer mMSDLPlayer; + + @Inject + public MSDLPlayerWrapper(@ApplicationContext Context context) { + Vibrator vibrator = context.getSystemService(Vibrator.class); + mMSDLPlayer = MSDLPlayer.Companion.createPlayer(vibrator, UI_HELPER_EXECUTOR, null); + } + + /** Perform MSDL feedback for a token with interaction properties */ + public void playToken(MSDLToken token, InteractionProperties properties) { + mMSDLPlayer.playToken(token, properties); + } + + /** Perform MSDL feedback for a token without properties */ + public void playToken(MSDLToken token) { + mMSDLPlayer.playToken(token, null); + } +} |