Loading quickstep/AndroidManifest.xml +2 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,8 @@ <service android:name="com.android.quickstep.TouchInteractionService" android:permission="android.permission.STATUS_BAR_SERVICE" > android:permission="android.permission.STATUS_BAR_SERVICE" android:directBootAware="true" > <intent-filter> <action android:name="android.intent.action.QUICKSTEP_SERVICE" /> </intent-filter> Loading quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.quickstep; import android.content.Context; import android.content.Intent; import android.view.MotionEvent; /** * A dummy input consumer used when the device is still locked, e.g. from secure camera. */ public class DeviceLockedInputConsumer implements InputConsumer { private final Context mContext; public DeviceLockedInputConsumer(Context context) { mContext = context; } @Override public void onMotionEvent(MotionEvent ev) { // For now, just start the home intent so user is prompted to unlock the device. if (ev.getAction() == MotionEvent.ACTION_DOWN) { mContext.startActivity(new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } } } quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +75 −9 Original line number Diff line number Diff line Loading @@ -23,13 +23,18 @@ import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYS import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.app.KeyguardManager; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Region; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Looper; import android.os.Process; import android.util.Log; import android.util.Pair; import android.view.Choreographer; Loading @@ -37,6 +42,8 @@ import android.view.InputEvent; import android.view.MotionEvent; import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.UiThreadHelper; import com.android.systemui.shared.recents.IOverviewProxy; Loading @@ -49,6 +56,8 @@ import com.android.systemui.shared.system.InputConsumerController; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; /** * Service connected by system-UI for handling touch interaction. Loading @@ -75,8 +84,10 @@ public class TouchInteractionService extends Service { public void onInitialize(Bundle bundle) { mISystemUiProxy = ISystemUiProxy.Stub .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY)); runWhenUserUnlocked(() -> { mRecentsModel.setSystemUiProxy(mISystemUiProxy); mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); }); disposeEventHandlers(); mInputEventReceiver = InputChannelCompat.fromBundle(bundle, KEY_EXTRA_INPUT_CHANNEL, Loading Loading @@ -128,8 +139,10 @@ public class TouchInteractionService extends Service { public void onBind(ISystemUiProxy iSystemUiProxy) { mISystemUiProxy = iSystemUiProxy; runWhenUserUnlocked(() -> { mRecentsModel.setSystemUiProxy(mISystemUiProxy); mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); }); // On Bind is received before onInitialize which will dispose these handlers disposeEventHandlers(); Loading @@ -138,7 +151,6 @@ public class TouchInteractionService extends Service { TouchInteractionService.this::onInputEvent); mDeprecatedDispatcher = pair.first; mInputEventReceiver = pair.second; } }; Loading @@ -148,6 +160,7 @@ public class TouchInteractionService extends Service { return sConnected; } private KeyguardManager mKM; private ActivityManagerWrapper mAM; private RecentsModel mRecentsModel; private ISystemUiProxy mISystemUiProxy; Loading @@ -159,6 +172,17 @@ public class TouchInteractionService extends Service { private InputConsumerController mInputConsumer; private SwipeSharedState mSwipeSharedState; private boolean mIsUserUnlocked; private List<Runnable> mOnUserUnlockedCallbacks; private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { initWhenUserUnlocked(); } } }; private InputConsumer mConsumer = InputConsumer.NO_OP; private Choreographer mMainChoreographer; Loading @@ -170,10 +194,29 @@ public class TouchInteractionService extends Service { @Override public void onCreate() { super.onCreate(); // Initialize anything here that is needed in direct boot mode. // Everything else should be initialized in initWhenUserUnlocked() below. mKM = getSystemService(KeyguardManager.class); mMainChoreographer = Choreographer.getInstance(); mOnUserUnlockedCallbacks = new ArrayList<>(); if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) { initWhenUserUnlocked(); } else { mIsUserUnlocked = false; registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED)); } sConnected = true; } private void initWhenUserUnlocked() { mIsUserUnlocked = true; mAM = ActivityManagerWrapper.getInstance(); mRecentsModel = RecentsModel.INSTANCE.get(this); mOverviewComponentObserver = new OverviewComponentObserver(this); mMainChoreographer = Choreographer.getInstance(); mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver); mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this); Loading @@ -183,18 +226,34 @@ public class TouchInteractionService extends Service { mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer(); mInputConsumer.registerInputConsumer(); sConnected = true; for (Runnable callback : mOnUserUnlockedCallbacks) { callback.run(); } mOnUserUnlockedCallbacks.clear(); // Temporarily disable model preload // new ModelPreload().start(this); Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver); } private void runWhenUserUnlocked(Runnable callback) { if (mIsUserUnlocked) { callback.run(); } else { mOnUserUnlockedCallbacks.add(callback); } } @Override public void onDestroy() { if (mIsUserUnlocked) { mInputConsumer.unregisterInputConsumer(); mOverviewComponentObserver.onDestroy(); } disposeEventHandlers(); sConnected = false; Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver); super.onDestroy(); } Loading Loading @@ -234,6 +293,13 @@ public class TouchInteractionService extends Service { } private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) { // TODO: this makes a binder call every touch down. we should move to a listener pattern. if (mKM.isDeviceLocked()) { // This handles apps launched in direct boot mode (e.g. dialer) as well as apps launched // while device is locked even after exiting direct boot mode (e.g. camera). return new DeviceLockedInputConsumer(this); } RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0); if (!useSharedState) { mSwipeSharedState.clearAllState(); Loading src/com/android/launcher3/LauncherAppState.java +5 −0 Original line number Diff line number Diff line Loading @@ -19,12 +19,14 @@ package com.android.launcher3; import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS; import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver; import android.app.KeyguardManager; import android.content.ComponentName; import android.content.ContentProviderClient; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.os.Process; import android.util.Log; import com.android.launcher3.compat.LauncherAppsCompat; Loading Loading @@ -66,6 +68,9 @@ public class LauncherAppState { } private LauncherAppState(Context context) { if (!UserManagerCompat.getInstance(context).isUserUnlocked(Process.myUserHandle())) { throw new RuntimeException("LauncherAppState should not start in direct boot mode"); } if (getLocalProvider(context) == null) { throw new RuntimeException( "Initializing LauncherAppState in the absence of LauncherProvider"); Loading src/com/android/launcher3/Utilities.java +10 −3 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package com.android.launcher3; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT; import android.app.ActivityManager; import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -67,9 +71,6 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT; /** * Various utilities shared amongst the Launcher's classes. */ Loading Loading @@ -590,4 +591,10 @@ public final class Utilities { outRect.set(viewLocationLeft, viewLocationTop, viewLocationLeft + rect.width(), viewLocationTop + rect.height()); } public static void unregisterReceiverSafely(Context context, BroadcastReceiver receiver) { try { context.unregisterReceiver(receiver); } catch (IllegalArgumentException e) { } } } Loading
quickstep/AndroidManifest.xml +2 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,8 @@ <service android:name="com.android.quickstep.TouchInteractionService" android:permission="android.permission.STATUS_BAR_SERVICE" > android:permission="android.permission.STATUS_BAR_SERVICE" android:directBootAware="true" > <intent-filter> <action android:name="android.intent.action.QUICKSTEP_SERVICE" /> </intent-filter> Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.quickstep; import android.content.Context; import android.content.Intent; import android.view.MotionEvent; /** * A dummy input consumer used when the device is still locked, e.g. from secure camera. */ public class DeviceLockedInputConsumer implements InputConsumer { private final Context mContext; public DeviceLockedInputConsumer(Context context) { mContext = context; } @Override public void onMotionEvent(MotionEvent ev) { // For now, just start the home intent so user is prompted to unlock the device. if (ev.getAction() == MotionEvent.ACTION_DOWN) { mContext.startActivity(new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } } }
quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +75 −9 Original line number Diff line number Diff line Loading @@ -23,13 +23,18 @@ import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYS import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.app.KeyguardManager; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Region; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Looper; import android.os.Process; import android.util.Log; import android.util.Pair; import android.view.Choreographer; Loading @@ -37,6 +42,8 @@ import android.view.InputEvent; import android.view.MotionEvent; import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.UiThreadHelper; import com.android.systemui.shared.recents.IOverviewProxy; Loading @@ -49,6 +56,8 @@ import com.android.systemui.shared.system.InputConsumerController; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; /** * Service connected by system-UI for handling touch interaction. Loading @@ -75,8 +84,10 @@ public class TouchInteractionService extends Service { public void onInitialize(Bundle bundle) { mISystemUiProxy = ISystemUiProxy.Stub .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY)); runWhenUserUnlocked(() -> { mRecentsModel.setSystemUiProxy(mISystemUiProxy); mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); }); disposeEventHandlers(); mInputEventReceiver = InputChannelCompat.fromBundle(bundle, KEY_EXTRA_INPUT_CHANNEL, Loading Loading @@ -128,8 +139,10 @@ public class TouchInteractionService extends Service { public void onBind(ISystemUiProxy iSystemUiProxy) { mISystemUiProxy = iSystemUiProxy; runWhenUserUnlocked(() -> { mRecentsModel.setSystemUiProxy(mISystemUiProxy); mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); }); // On Bind is received before onInitialize which will dispose these handlers disposeEventHandlers(); Loading @@ -138,7 +151,6 @@ public class TouchInteractionService extends Service { TouchInteractionService.this::onInputEvent); mDeprecatedDispatcher = pair.first; mInputEventReceiver = pair.second; } }; Loading @@ -148,6 +160,7 @@ public class TouchInteractionService extends Service { return sConnected; } private KeyguardManager mKM; private ActivityManagerWrapper mAM; private RecentsModel mRecentsModel; private ISystemUiProxy mISystemUiProxy; Loading @@ -159,6 +172,17 @@ public class TouchInteractionService extends Service { private InputConsumerController mInputConsumer; private SwipeSharedState mSwipeSharedState; private boolean mIsUserUnlocked; private List<Runnable> mOnUserUnlockedCallbacks; private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { initWhenUserUnlocked(); } } }; private InputConsumer mConsumer = InputConsumer.NO_OP; private Choreographer mMainChoreographer; Loading @@ -170,10 +194,29 @@ public class TouchInteractionService extends Service { @Override public void onCreate() { super.onCreate(); // Initialize anything here that is needed in direct boot mode. // Everything else should be initialized in initWhenUserUnlocked() below. mKM = getSystemService(KeyguardManager.class); mMainChoreographer = Choreographer.getInstance(); mOnUserUnlockedCallbacks = new ArrayList<>(); if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) { initWhenUserUnlocked(); } else { mIsUserUnlocked = false; registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED)); } sConnected = true; } private void initWhenUserUnlocked() { mIsUserUnlocked = true; mAM = ActivityManagerWrapper.getInstance(); mRecentsModel = RecentsModel.INSTANCE.get(this); mOverviewComponentObserver = new OverviewComponentObserver(this); mMainChoreographer = Choreographer.getInstance(); mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver); mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this); Loading @@ -183,18 +226,34 @@ public class TouchInteractionService extends Service { mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer(); mInputConsumer.registerInputConsumer(); sConnected = true; for (Runnable callback : mOnUserUnlockedCallbacks) { callback.run(); } mOnUserUnlockedCallbacks.clear(); // Temporarily disable model preload // new ModelPreload().start(this); Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver); } private void runWhenUserUnlocked(Runnable callback) { if (mIsUserUnlocked) { callback.run(); } else { mOnUserUnlockedCallbacks.add(callback); } } @Override public void onDestroy() { if (mIsUserUnlocked) { mInputConsumer.unregisterInputConsumer(); mOverviewComponentObserver.onDestroy(); } disposeEventHandlers(); sConnected = false; Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver); super.onDestroy(); } Loading Loading @@ -234,6 +293,13 @@ public class TouchInteractionService extends Service { } private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) { // TODO: this makes a binder call every touch down. we should move to a listener pattern. if (mKM.isDeviceLocked()) { // This handles apps launched in direct boot mode (e.g. dialer) as well as apps launched // while device is locked even after exiting direct boot mode (e.g. camera). return new DeviceLockedInputConsumer(this); } RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0); if (!useSharedState) { mSwipeSharedState.clearAllState(); Loading
src/com/android/launcher3/LauncherAppState.java +5 −0 Original line number Diff line number Diff line Loading @@ -19,12 +19,14 @@ package com.android.launcher3; import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS; import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver; import android.app.KeyguardManager; import android.content.ComponentName; import android.content.ContentProviderClient; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.os.Process; import android.util.Log; import com.android.launcher3.compat.LauncherAppsCompat; Loading Loading @@ -66,6 +68,9 @@ public class LauncherAppState { } private LauncherAppState(Context context) { if (!UserManagerCompat.getInstance(context).isUserUnlocked(Process.myUserHandle())) { throw new RuntimeException("LauncherAppState should not start in direct boot mode"); } if (getLocalProvider(context) == null) { throw new RuntimeException( "Initializing LauncherAppState in the absence of LauncherProvider"); Loading
src/com/android/launcher3/Utilities.java +10 −3 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package com.android.launcher3; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT; import android.app.ActivityManager; import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -67,9 +71,6 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT; /** * Various utilities shared amongst the Launcher's classes. */ Loading Loading @@ -590,4 +591,10 @@ public final class Utilities { outRect.set(viewLocationLeft, viewLocationTop, viewLocationLeft + rect.width(), viewLocationTop + rect.height()); } public static void unregisterReceiverSafely(Context context, BroadcastReceiver receiver) { try { context.unregisterReceiver(receiver); } catch (IllegalArgumentException e) { } } }