Merge "Open Notes from a KeyEvent dispatch" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c3c4201035
@@ -289,6 +289,12 @@
|
|||||||
<!-- Query all packages on device on R+ -->
|
<!-- Query all packages on device on R+ -->
|
||||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
|
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
|
||||||
|
|
||||||
|
<queries>
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.intent.action.NOTES" />
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
|
|
||||||
<!-- Permission to register process observer -->
|
<!-- Permission to register process observer -->
|
||||||
<uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER"/>
|
<uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER"/>
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import com.android.systemui.log.dagger.LogModule;
|
|||||||
import com.android.systemui.mediaprojection.appselector.MediaProjectionModule;
|
import com.android.systemui.mediaprojection.appselector.MediaProjectionModule;
|
||||||
import com.android.systemui.model.SysUiState;
|
import com.android.systemui.model.SysUiState;
|
||||||
import com.android.systemui.navigationbar.NavigationBarComponent;
|
import com.android.systemui.navigationbar.NavigationBarComponent;
|
||||||
|
import com.android.systemui.notetask.NoteTaskModule;
|
||||||
import com.android.systemui.people.PeopleModule;
|
import com.android.systemui.people.PeopleModule;
|
||||||
import com.android.systemui.plugins.BcSmartspaceDataPlugin;
|
import com.android.systemui.plugins.BcSmartspaceDataPlugin;
|
||||||
import com.android.systemui.privacy.PrivacyModule;
|
import com.android.systemui.privacy.PrivacyModule;
|
||||||
@@ -152,6 +153,7 @@ import dagger.Provides;
|
|||||||
TunerModule.class,
|
TunerModule.class,
|
||||||
UserModule.class,
|
UserModule.class,
|
||||||
UtilModule.class,
|
UtilModule.class,
|
||||||
|
NoteTaskModule.class,
|
||||||
WalletModule.class
|
WalletModule.class
|
||||||
},
|
},
|
||||||
subcomponents = {
|
subcomponents = {
|
||||||
|
|||||||
@@ -325,6 +325,9 @@ object Flags {
|
|||||||
// 1800 - shade container
|
// 1800 - shade container
|
||||||
@JvmField val LEAVE_SHADE_OPEN_FOR_BUGREPORT = UnreleasedFlag(1800, true)
|
@JvmField val LEAVE_SHADE_OPEN_FOR_BUGREPORT = UnreleasedFlag(1800, true)
|
||||||
|
|
||||||
|
// 1900 - note task
|
||||||
|
@JvmField val NOTE_TASKS = SysPropBooleanFlag(1900, "persist.sysui.debug.note_tasks")
|
||||||
|
|
||||||
// Pay no attention to the reflection behind the curtain.
|
// Pay no attention to the reflection behind the curtain.
|
||||||
// ========================== Curtain ==========================
|
// ========================== Curtain ==========================
|
||||||
// | |
|
// | |
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.notetask
|
||||||
|
|
||||||
|
import android.app.KeyguardManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.UserManager
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.util.kotlin.getOrNull
|
||||||
|
import com.android.wm.shell.floating.FloatingTasks
|
||||||
|
import java.util.Optional
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for creating and managing note.
|
||||||
|
*
|
||||||
|
* The controller decides how a note is launched based in the device state: locked or unlocked.
|
||||||
|
*
|
||||||
|
* Currently, we only support a single task per time.
|
||||||
|
*/
|
||||||
|
@SysUISingleton
|
||||||
|
internal class NoteTaskController
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val intentResolver: NoteTaskIntentResolver,
|
||||||
|
private val optionalFloatingTasks: Optional<FloatingTasks>,
|
||||||
|
private val optionalKeyguardManager: Optional<KeyguardManager>,
|
||||||
|
private val optionalUserManager: Optional<UserManager>,
|
||||||
|
@NoteTaskEnabledKey private val isEnabled: Boolean,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun handleSystemKey(keyCode: Int) {
|
||||||
|
if (!isEnabled) return
|
||||||
|
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_VIDEO_APP_1) {
|
||||||
|
showNoteTask()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showNoteTask() {
|
||||||
|
val floatingTasks = optionalFloatingTasks.getOrNull() ?: return
|
||||||
|
val keyguardManager = optionalKeyguardManager.getOrNull() ?: return
|
||||||
|
val userManager = optionalUserManager.getOrNull() ?: return
|
||||||
|
val intent = intentResolver.resolveIntent() ?: return
|
||||||
|
|
||||||
|
// TODO(b/249954038): We should handle direct boot (isUserUnlocked). For now, we do nothing.
|
||||||
|
if (!userManager.isUserUnlocked) return
|
||||||
|
|
||||||
|
if (keyguardManager.isKeyguardLocked) {
|
||||||
|
context.startActivity(intent)
|
||||||
|
} else {
|
||||||
|
// TODO(b/254606432): Should include Intent.EXTRA_FLOATING_WINDOW_MODE parameter.
|
||||||
|
floatingTasks.showOrSetStashed(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.notetask
|
||||||
|
|
||||||
|
import javax.inject.Qualifier
|
||||||
|
|
||||||
|
/** Key associated with a [Boolean] flag that enables or disables the note task feature. */
|
||||||
|
@Qualifier internal annotation class NoteTaskEnabledKey
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.notetask
|
||||||
|
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
|
import com.android.wm.shell.floating.FloatingTasks
|
||||||
|
import dagger.Lazy
|
||||||
|
import java.util.Optional
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/** Class responsible to "glue" all note task dependencies. */
|
||||||
|
internal class NoteTaskInitializer
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
private val optionalFloatingTasks: Optional<FloatingTasks>,
|
||||||
|
private val lazyNoteTaskController: Lazy<NoteTaskController>,
|
||||||
|
private val commandQueue: CommandQueue,
|
||||||
|
@NoteTaskEnabledKey private val isEnabled: Boolean,
|
||||||
|
) {
|
||||||
|
|
||||||
|
private val callbacks =
|
||||||
|
object : CommandQueue.Callbacks {
|
||||||
|
override fun handleSystemKey(keyCode: Int) {
|
||||||
|
lazyNoteTaskController.get().handleSystemKey(keyCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initialize() {
|
||||||
|
if (isEnabled && optionalFloatingTasks.isPresent) {
|
||||||
|
commandQueue.addCallback(callbacks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.notetask
|
||||||
|
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.PackageManager.ResolveInfoFlags
|
||||||
|
import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.NOTES_ACTION
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible to query all apps and find one that can handle the [NOTES_ACTION]. If found, an
|
||||||
|
* [Intent] ready for be launched will be returned. Otherwise, returns null.
|
||||||
|
*
|
||||||
|
* TODO(b/248274123): should be revisited once the notes role is implemented.
|
||||||
|
*/
|
||||||
|
internal class NoteTaskIntentResolver
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
private val packageManager: PackageManager,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun resolveIntent(): Intent? {
|
||||||
|
val intent = Intent(NOTES_ACTION)
|
||||||
|
val flags = ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY.toLong())
|
||||||
|
val infoList = packageManager.queryIntentActivities(intent, flags)
|
||||||
|
|
||||||
|
for (info in infoList) {
|
||||||
|
val packageName = info.serviceInfo.applicationInfo.packageName ?: continue
|
||||||
|
val activityName = resolveActivityNameForNotesAction(packageName) ?: continue
|
||||||
|
|
||||||
|
return Intent(NOTES_ACTION)
|
||||||
|
.setComponent(ComponentName(packageName, activityName))
|
||||||
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveActivityNameForNotesAction(packageName: String): String? {
|
||||||
|
val intent = Intent(NOTES_ACTION).setPackage(packageName)
|
||||||
|
val flags = ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY.toLong())
|
||||||
|
val resolveInfo = packageManager.resolveActivity(intent, flags)
|
||||||
|
|
||||||
|
val activityInfo = resolveInfo?.activityInfo ?: return null
|
||||||
|
if (activityInfo.name.isNullOrBlank()) return null
|
||||||
|
if (!activityInfo.exported) return null
|
||||||
|
if (!activityInfo.enabled) return null
|
||||||
|
if (!activityInfo.showWhenLocked) return null
|
||||||
|
if (!activityInfo.turnScreenOn) return null
|
||||||
|
|
||||||
|
return activityInfo.name
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// TODO(b/254606432): Use Intent.ACTION_NOTES and Intent.ACTION_NOTES_LOCKED instead.
|
||||||
|
const val NOTES_ACTION = "android.intent.action.NOTES"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val ActivityInfo.showWhenLocked: Boolean
|
||||||
|
get() = flags and ActivityInfo.FLAG_SHOW_WHEN_LOCKED != 0
|
||||||
|
|
||||||
|
private val ActivityInfo.turnScreenOn: Boolean
|
||||||
|
get() = flags and ActivityInfo.FLAG_TURN_SCREEN_ON != 0
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.notetask
|
||||||
|
|
||||||
|
import android.app.KeyguardManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.UserManager
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
|
import com.android.systemui.flags.FeatureFlags
|
||||||
|
import com.android.systemui.flags.Flags
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/** Compose all dependencies required by Note Task feature. */
|
||||||
|
@Module
|
||||||
|
internal class NoteTaskModule {
|
||||||
|
|
||||||
|
@[Provides NoteTaskEnabledKey]
|
||||||
|
fun provideIsNoteTaskEnabled(featureFlags: FeatureFlags): Boolean {
|
||||||
|
return featureFlags.isEnabled(Flags.NOTE_TASKS)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideOptionalKeyguardManager(context: Context): Optional<KeyguardManager> {
|
||||||
|
return Optional.ofNullable(context.getSystemService())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideOptionalUserManager(context: Context): Optional<UserManager> {
|
||||||
|
return Optional.ofNullable(context.getSystemService())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,6 +49,7 @@ import com.android.systemui.dagger.qualifiers.Main;
|
|||||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||||
import com.android.systemui.model.SysUiState;
|
import com.android.systemui.model.SysUiState;
|
||||||
|
import com.android.systemui.notetask.NoteTaskInitializer;
|
||||||
import com.android.systemui.settings.UserTracker;
|
import com.android.systemui.settings.UserTracker;
|
||||||
import com.android.systemui.shared.tracing.ProtoTraceable;
|
import com.android.systemui.shared.tracing.ProtoTraceable;
|
||||||
import com.android.systemui.statusbar.CommandQueue;
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
@@ -58,7 +59,6 @@ import com.android.systemui.tracing.ProtoTracer;
|
|||||||
import com.android.systemui.tracing.nano.SystemUiTraceProto;
|
import com.android.systemui.tracing.nano.SystemUiTraceProto;
|
||||||
import com.android.wm.shell.desktopmode.DesktopMode;
|
import com.android.wm.shell.desktopmode.DesktopMode;
|
||||||
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
||||||
import com.android.wm.shell.floating.FloatingTasks;
|
|
||||||
import com.android.wm.shell.nano.WmShellTraceProto;
|
import com.android.wm.shell.nano.WmShellTraceProto;
|
||||||
import com.android.wm.shell.onehanded.OneHanded;
|
import com.android.wm.shell.onehanded.OneHanded;
|
||||||
import com.android.wm.shell.onehanded.OneHandedEventCallback;
|
import com.android.wm.shell.onehanded.OneHandedEventCallback;
|
||||||
@@ -113,7 +113,6 @@ public final class WMShell implements
|
|||||||
private final Optional<Pip> mPipOptional;
|
private final Optional<Pip> mPipOptional;
|
||||||
private final Optional<SplitScreen> mSplitScreenOptional;
|
private final Optional<SplitScreen> mSplitScreenOptional;
|
||||||
private final Optional<OneHanded> mOneHandedOptional;
|
private final Optional<OneHanded> mOneHandedOptional;
|
||||||
private final Optional<FloatingTasks> mFloatingTasksOptional;
|
|
||||||
private final Optional<DesktopMode> mDesktopModeOptional;
|
private final Optional<DesktopMode> mDesktopModeOptional;
|
||||||
|
|
||||||
private final CommandQueue mCommandQueue;
|
private final CommandQueue mCommandQueue;
|
||||||
@@ -125,6 +124,7 @@ public final class WMShell implements
|
|||||||
private final WakefulnessLifecycle mWakefulnessLifecycle;
|
private final WakefulnessLifecycle mWakefulnessLifecycle;
|
||||||
private final ProtoTracer mProtoTracer;
|
private final ProtoTracer mProtoTracer;
|
||||||
private final UserTracker mUserTracker;
|
private final UserTracker mUserTracker;
|
||||||
|
private final NoteTaskInitializer mNoteTaskInitializer;
|
||||||
private final Executor mSysUiMainExecutor;
|
private final Executor mSysUiMainExecutor;
|
||||||
|
|
||||||
// Listeners and callbacks. Note that we prefer member variable over anonymous class here to
|
// Listeners and callbacks. Note that we prefer member variable over anonymous class here to
|
||||||
@@ -176,7 +176,6 @@ public final class WMShell implements
|
|||||||
Optional<Pip> pipOptional,
|
Optional<Pip> pipOptional,
|
||||||
Optional<SplitScreen> splitScreenOptional,
|
Optional<SplitScreen> splitScreenOptional,
|
||||||
Optional<OneHanded> oneHandedOptional,
|
Optional<OneHanded> oneHandedOptional,
|
||||||
Optional<FloatingTasks> floatingTasksOptional,
|
|
||||||
Optional<DesktopMode> desktopMode,
|
Optional<DesktopMode> desktopMode,
|
||||||
CommandQueue commandQueue,
|
CommandQueue commandQueue,
|
||||||
ConfigurationController configurationController,
|
ConfigurationController configurationController,
|
||||||
@@ -187,6 +186,7 @@ public final class WMShell implements
|
|||||||
ProtoTracer protoTracer,
|
ProtoTracer protoTracer,
|
||||||
WakefulnessLifecycle wakefulnessLifecycle,
|
WakefulnessLifecycle wakefulnessLifecycle,
|
||||||
UserTracker userTracker,
|
UserTracker userTracker,
|
||||||
|
NoteTaskInitializer noteTaskInitializer,
|
||||||
@Main Executor sysUiMainExecutor) {
|
@Main Executor sysUiMainExecutor) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mShell = shell;
|
mShell = shell;
|
||||||
@@ -203,7 +203,7 @@ public final class WMShell implements
|
|||||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||||
mProtoTracer = protoTracer;
|
mProtoTracer = protoTracer;
|
||||||
mUserTracker = userTracker;
|
mUserTracker = userTracker;
|
||||||
mFloatingTasksOptional = floatingTasksOptional;
|
mNoteTaskInitializer = noteTaskInitializer;
|
||||||
mSysUiMainExecutor = sysUiMainExecutor;
|
mSysUiMainExecutor = sysUiMainExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,6 +226,8 @@ public final class WMShell implements
|
|||||||
mSplitScreenOptional.ifPresent(this::initSplitScreen);
|
mSplitScreenOptional.ifPresent(this::initSplitScreen);
|
||||||
mOneHandedOptional.ifPresent(this::initOneHanded);
|
mOneHandedOptional.ifPresent(this::initOneHanded);
|
||||||
mDesktopModeOptional.ifPresent(this::initDesktopMode);
|
mDesktopModeOptional.ifPresent(this::initDesktopMode);
|
||||||
|
|
||||||
|
mNoteTaskInitializer.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.notetask
|
||||||
|
|
||||||
|
import android.app.KeyguardManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.UserManager
|
||||||
|
import android.test.suitebuilder.annotation.SmallTest
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import androidx.test.runner.AndroidJUnit4
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.NOTES_ACTION
|
||||||
|
import com.android.systemui.util.mockito.whenever
|
||||||
|
import com.android.wm.shell.floating.FloatingTasks
|
||||||
|
import java.util.*
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.never
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for [NoteTaskController].
|
||||||
|
*
|
||||||
|
* Build/Install/Run:
|
||||||
|
* - atest SystemUITests:NoteTaskControllerTest
|
||||||
|
*/
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
private val notesIntent = Intent(NOTES_ACTION)
|
||||||
|
|
||||||
|
@Mock lateinit var context: Context
|
||||||
|
@Mock lateinit var noteTaskIntentResolver: NoteTaskIntentResolver
|
||||||
|
@Mock lateinit var floatingTasks: FloatingTasks
|
||||||
|
@Mock lateinit var optionalFloatingTasks: Optional<FloatingTasks>
|
||||||
|
@Mock lateinit var keyguardManager: KeyguardManager
|
||||||
|
@Mock lateinit var optionalKeyguardManager: Optional<KeyguardManager>
|
||||||
|
@Mock lateinit var optionalUserManager: Optional<UserManager>
|
||||||
|
@Mock lateinit var userManager: UserManager
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
|
whenever(noteTaskIntentResolver.resolveIntent()).thenReturn(notesIntent)
|
||||||
|
whenever(optionalFloatingTasks.orElse(null)).thenReturn(floatingTasks)
|
||||||
|
whenever(optionalKeyguardManager.orElse(null)).thenReturn(keyguardManager)
|
||||||
|
whenever(optionalUserManager.orElse(null)).thenReturn(userManager)
|
||||||
|
whenever(userManager.isUserUnlocked).thenReturn(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNoteTaskController(isEnabled: Boolean = true): NoteTaskController {
|
||||||
|
return NoteTaskController(
|
||||||
|
context = context,
|
||||||
|
intentResolver = noteTaskIntentResolver,
|
||||||
|
optionalFloatingTasks = optionalFloatingTasks,
|
||||||
|
optionalKeyguardManager = optionalKeyguardManager,
|
||||||
|
optionalUserManager = optionalUserManager,
|
||||||
|
isEnabled = isEnabled,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_keyguardIsLocked_shouldStartActivity() {
|
||||||
|
whenever(keyguardManager.isKeyguardLocked).thenReturn(true)
|
||||||
|
|
||||||
|
createNoteTaskController().handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
|
||||||
|
|
||||||
|
verify(context).startActivity(notesIntent)
|
||||||
|
verify(floatingTasks, never()).showOrSetStashed(notesIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_keyguardIsUnlocked_shouldStartFloatingTask() {
|
||||||
|
whenever(keyguardManager.isKeyguardLocked).thenReturn(false)
|
||||||
|
|
||||||
|
createNoteTaskController().handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
|
||||||
|
|
||||||
|
verify(floatingTasks).showOrSetStashed(notesIntent)
|
||||||
|
verify(context, never()).startActivity(notesIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_receiveInvalidSystemKey_shouldDoNothing() {
|
||||||
|
createNoteTaskController().handleSystemKey(KeyEvent.KEYCODE_UNKNOWN)
|
||||||
|
|
||||||
|
verify(context, never()).startActivity(notesIntent)
|
||||||
|
verify(floatingTasks, never()).showOrSetStashed(notesIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_floatingTasksIsNull_shouldDoNothing() {
|
||||||
|
whenever(optionalFloatingTasks.orElse(null)).thenReturn(null)
|
||||||
|
|
||||||
|
createNoteTaskController().handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
|
||||||
|
|
||||||
|
verify(context, never()).startActivity(notesIntent)
|
||||||
|
verify(floatingTasks, never()).showOrSetStashed(notesIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_keyguardManagerIsNull_shouldDoNothing() {
|
||||||
|
whenever(optionalKeyguardManager.orElse(null)).thenReturn(null)
|
||||||
|
|
||||||
|
createNoteTaskController().handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
|
||||||
|
|
||||||
|
verify(context, never()).startActivity(notesIntent)
|
||||||
|
verify(floatingTasks, never()).showOrSetStashed(notesIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_userManagerIsNull_shouldDoNothing() {
|
||||||
|
whenever(optionalUserManager.orElse(null)).thenReturn(null)
|
||||||
|
|
||||||
|
createNoteTaskController().handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
|
||||||
|
|
||||||
|
verify(context, never()).startActivity(notesIntent)
|
||||||
|
verify(floatingTasks, never()).showOrSetStashed(notesIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_intentResolverReturnsNull_shouldDoNothing() {
|
||||||
|
whenever(noteTaskIntentResolver.resolveIntent()).thenReturn(null)
|
||||||
|
|
||||||
|
createNoteTaskController().handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
|
||||||
|
|
||||||
|
verify(context, never()).startActivity(notesIntent)
|
||||||
|
verify(floatingTasks, never()).showOrSetStashed(notesIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_flagDisabled_shouldDoNothing() {
|
||||||
|
createNoteTaskController(isEnabled = false).handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
|
||||||
|
|
||||||
|
verify(context, never()).startActivity(notesIntent)
|
||||||
|
verify(floatingTasks, never()).showOrSetStashed(notesIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleSystemKey_userIsLocked_shouldDoNothing() {
|
||||||
|
whenever(userManager.isUserUnlocked).thenReturn(false)
|
||||||
|
|
||||||
|
createNoteTaskController().handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
|
||||||
|
|
||||||
|
verify(context, never()).startActivity(notesIntent)
|
||||||
|
verify(floatingTasks, never()).showOrSetStashed(notesIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.notetask
|
||||||
|
|
||||||
|
import android.test.suitebuilder.annotation.SmallTest
|
||||||
|
import androidx.test.runner.AndroidJUnit4
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
|
import com.android.systemui.util.mockito.mock
|
||||||
|
import com.android.systemui.util.mockito.whenever
|
||||||
|
import com.android.wm.shell.floating.FloatingTasks
|
||||||
|
import java.util.*
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.ArgumentMatchers.any
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.never
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for [NoteTaskController].
|
||||||
|
*
|
||||||
|
* Build/Install/Run:
|
||||||
|
* - atest SystemUITests:NoteTaskInitializerTest
|
||||||
|
*/
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
internal class NoteTaskInitializerTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
@Mock lateinit var commandQueue: CommandQueue
|
||||||
|
@Mock lateinit var floatingTasks: FloatingTasks
|
||||||
|
@Mock lateinit var optionalFloatingTasks: Optional<FloatingTasks>
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
|
whenever(optionalFloatingTasks.isPresent).thenReturn(true)
|
||||||
|
whenever(optionalFloatingTasks.orElse(null)).thenReturn(floatingTasks)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNoteTaskInitializer(isEnabled: Boolean = true): NoteTaskInitializer {
|
||||||
|
return NoteTaskInitializer(
|
||||||
|
optionalFloatingTasks = optionalFloatingTasks,
|
||||||
|
lazyNoteTaskController = mock(),
|
||||||
|
commandQueue = commandQueue,
|
||||||
|
isEnabled = isEnabled,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun initialize_shouldAddCallbacks() {
|
||||||
|
createNoteTaskInitializer().initialize()
|
||||||
|
|
||||||
|
verify(commandQueue).addCallback(any())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun initialize_flagDisabled_shouldDoNothing() {
|
||||||
|
createNoteTaskInitializer(isEnabled = false).initialize()
|
||||||
|
|
||||||
|
verify(commandQueue, never()).addCallback(any())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun initialize_floatingTasksNotPresent_shouldDoNothing() {
|
||||||
|
whenever(optionalFloatingTasks.isPresent).thenReturn(false)
|
||||||
|
|
||||||
|
createNoteTaskInitializer().initialize()
|
||||||
|
|
||||||
|
verify(commandQueue, never()).addCallback(any())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.notetask
|
||||||
|
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.PackageManager.ResolveInfoFlags
|
||||||
|
import android.content.pm.ResolveInfo
|
||||||
|
import android.content.pm.ServiceInfo
|
||||||
|
import android.test.suitebuilder.annotation.SmallTest
|
||||||
|
import androidx.test.runner.AndroidJUnit4
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.NOTES_ACTION
|
||||||
|
import com.android.systemui.util.mockito.whenever
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.any
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for [NoteTaskIntentResolver].
|
||||||
|
*
|
||||||
|
* Build/Install/Run:
|
||||||
|
* - atest SystemUITests:NoteTaskIntentResolverTest
|
||||||
|
*/
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
internal class NoteTaskIntentResolverTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
@Mock lateinit var packageManager: PackageManager
|
||||||
|
|
||||||
|
private lateinit var resolver: NoteTaskIntentResolver
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
resolver = NoteTaskIntentResolver(packageManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createResolveInfo(
|
||||||
|
packageName: String = "PackageName",
|
||||||
|
activityInfo: ActivityInfo? = null,
|
||||||
|
): ResolveInfo {
|
||||||
|
return ResolveInfo().apply {
|
||||||
|
serviceInfo =
|
||||||
|
ServiceInfo().apply {
|
||||||
|
applicationInfo = ApplicationInfo().apply { this.packageName = packageName }
|
||||||
|
}
|
||||||
|
this.activityInfo = activityInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createActivityInfo(
|
||||||
|
name: String? = "ActivityName",
|
||||||
|
exported: Boolean = true,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
showWhenLocked: Boolean = true,
|
||||||
|
turnScreenOn: Boolean = true,
|
||||||
|
): ActivityInfo {
|
||||||
|
return ActivityInfo().apply {
|
||||||
|
this.name = name
|
||||||
|
this.exported = exported
|
||||||
|
this.enabled = enabled
|
||||||
|
if (showWhenLocked) {
|
||||||
|
flags = flags or ActivityInfo.FLAG_SHOW_WHEN_LOCKED
|
||||||
|
}
|
||||||
|
if (turnScreenOn) {
|
||||||
|
flags = flags or ActivityInfo.FLAG_TURN_SCREEN_ON
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun givenQueryIntentActivities(block: () -> List<ResolveInfo>) {
|
||||||
|
whenever(packageManager.queryIntentActivities(any(), any<ResolveInfoFlags>()))
|
||||||
|
.thenReturn(block())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun givenResolveActivity(block: () -> ResolveInfo?) {
|
||||||
|
whenever(packageManager.resolveActivity(any(), any<ResolveInfoFlags>())).thenReturn(block())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_shouldReturnNotesIntent() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity { createResolveInfo(activityInfo = createActivityInfo()) }
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
val expected =
|
||||||
|
Intent(NOTES_ACTION)
|
||||||
|
.setComponent(ComponentName("PackageName", "ActivityName"))
|
||||||
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
// Compares the string representation of both intents, as they are different instances.
|
||||||
|
assertThat(actual.toString()).isEqualTo(expected.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_activityInfoEnabledIsFalse_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity {
|
||||||
|
createResolveInfo(activityInfo = createActivityInfo(enabled = false))
|
||||||
|
}
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_activityInfoExportedIsFalse_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity {
|
||||||
|
createResolveInfo(activityInfo = createActivityInfo(exported = false))
|
||||||
|
}
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_activityInfoShowWhenLockedIsFalse_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity {
|
||||||
|
createResolveInfo(activityInfo = createActivityInfo(showWhenLocked = false))
|
||||||
|
}
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_activityInfoTurnScreenOnIsFalse_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity {
|
||||||
|
createResolveInfo(activityInfo = createActivityInfo(turnScreenOn = false))
|
||||||
|
}
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_activityInfoNameIsBlank_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity { createResolveInfo(activityInfo = createActivityInfo(name = "")) }
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_activityInfoNameIsNull_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity { createResolveInfo(activityInfo = createActivityInfo(name = null)) }
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_activityInfoIsNull_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity { createResolveInfo(activityInfo = null) }
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_resolveActivityIsNull_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo()) }
|
||||||
|
givenResolveActivity { null }
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_packageNameIsBlank_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { listOf(createResolveInfo(packageName = "")) }
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resolveIntent_activityNotFoundForAction_shouldReturnNull() {
|
||||||
|
givenQueryIntentActivities { emptyList() }
|
||||||
|
|
||||||
|
val actual = resolver.resolveIntent()
|
||||||
|
|
||||||
|
assertThat(actual).isNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ import com.android.systemui.SysuiTestCase;
|
|||||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||||
import com.android.systemui.model.SysUiState;
|
import com.android.systemui.model.SysUiState;
|
||||||
|
import com.android.systemui.notetask.NoteTaskInitializer;
|
||||||
import com.android.systemui.settings.UserTracker;
|
import com.android.systemui.settings.UserTracker;
|
||||||
import com.android.systemui.statusbar.CommandQueue;
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||||
@@ -36,7 +37,6 @@ import com.android.systemui.tracing.ProtoTracer;
|
|||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.desktopmode.DesktopMode;
|
import com.android.wm.shell.desktopmode.DesktopMode;
|
||||||
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
||||||
import com.android.wm.shell.floating.FloatingTasks;
|
|
||||||
import com.android.wm.shell.onehanded.OneHanded;
|
import com.android.wm.shell.onehanded.OneHanded;
|
||||||
import com.android.wm.shell.onehanded.OneHandedEventCallback;
|
import com.android.wm.shell.onehanded.OneHandedEventCallback;
|
||||||
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
|
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
|
||||||
@@ -78,18 +78,31 @@ public class WMShellTest extends SysuiTestCase {
|
|||||||
@Mock ProtoTracer mProtoTracer;
|
@Mock ProtoTracer mProtoTracer;
|
||||||
@Mock UserTracker mUserTracker;
|
@Mock UserTracker mUserTracker;
|
||||||
@Mock ShellExecutor mSysUiMainExecutor;
|
@Mock ShellExecutor mSysUiMainExecutor;
|
||||||
@Mock FloatingTasks mFloatingTasks;
|
@Mock NoteTaskInitializer mNoteTaskInitializer;
|
||||||
@Mock DesktopMode mDesktopMode;
|
@Mock DesktopMode mDesktopMode;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mWMShell = new WMShell(mContext, mShellInterface, Optional.of(mPip),
|
mWMShell = new WMShell(
|
||||||
Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mFloatingTasks),
|
mContext,
|
||||||
|
mShellInterface,
|
||||||
|
Optional.of(mPip),
|
||||||
|
Optional.of(mSplitScreen),
|
||||||
|
Optional.of(mOneHanded),
|
||||||
Optional.of(mDesktopMode),
|
Optional.of(mDesktopMode),
|
||||||
mCommandQueue, mConfigurationController, mKeyguardStateController,
|
mCommandQueue,
|
||||||
mKeyguardUpdateMonitor, mScreenLifecycle, mSysUiState, mProtoTracer,
|
mConfigurationController,
|
||||||
mWakefulnessLifecycle, mUserTracker, mSysUiMainExecutor);
|
mKeyguardStateController,
|
||||||
|
mKeyguardUpdateMonitor,
|
||||||
|
mScreenLifecycle,
|
||||||
|
mSysUiState,
|
||||||
|
mProtoTracer,
|
||||||
|
mWakefulnessLifecycle,
|
||||||
|
mUserTracker,
|
||||||
|
mNoteTaskInitializer,
|
||||||
|
mSysUiMainExecutor
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -4052,6 +4052,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
case KeyEvent.KEYCODE_DEMO_APP_2:
|
case KeyEvent.KEYCODE_DEMO_APP_2:
|
||||||
case KeyEvent.KEYCODE_DEMO_APP_3:
|
case KeyEvent.KEYCODE_DEMO_APP_3:
|
||||||
case KeyEvent.KEYCODE_DEMO_APP_4: {
|
case KeyEvent.KEYCODE_DEMO_APP_4: {
|
||||||
|
// TODO(b/254604589): Dispatch KeyEvent to System UI.
|
||||||
|
sendSystemKeyToStatusBarAsync(keyCode);
|
||||||
|
|
||||||
// Just drop if keys are not intercepted for direct key.
|
// Just drop if keys are not intercepted for direct key.
|
||||||
result &= ~ACTION_PASS_TO_USER;
|
result &= ~ACTION_PASS_TO_USER;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user