Merge "Make TouchInteractionService direct boot aware" into ub-launcher3-master
This commit is contained in:
commit
3efd32adea
|
@ -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>
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -75,8 +84,10 @@ public class TouchInteractionService extends Service {
|
|||
public void onInitialize(Bundle bundle) {
|
||||
mISystemUiProxy = ISystemUiProxy.Stub
|
||||
.asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
|
||||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
runWhenUserUnlocked(() -> {
|
||||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
});
|
||||
|
||||
disposeEventHandlers();
|
||||
mInputEventReceiver = InputChannelCompat.fromBundle(bundle, KEY_EXTRA_INPUT_CHANNEL,
|
||||
|
@ -128,8 +139,10 @@ public class TouchInteractionService extends Service {
|
|||
|
||||
public void onBind(ISystemUiProxy iSystemUiProxy) {
|
||||
mISystemUiProxy = iSystemUiProxy;
|
||||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
runWhenUserUnlocked(() -> {
|
||||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
});
|
||||
|
||||
// On Bind is received before onInitialize which will dispose these handlers
|
||||
disposeEventHandlers();
|
||||
|
@ -138,7 +151,6 @@ public class TouchInteractionService extends Service {
|
|||
TouchInteractionService.this::onInputEvent);
|
||||
mDeprecatedDispatcher = pair.first;
|
||||
mInputEventReceiver = pair.second;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -148,6 +160,7 @@ public class TouchInteractionService extends Service {
|
|||
return sConnected;
|
||||
}
|
||||
|
||||
private KeyguardManager mKM;
|
||||
private ActivityManagerWrapper mAM;
|
||||
private RecentsModel mRecentsModel;
|
||||
private ISystemUiProxy mISystemUiProxy;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
mInputConsumer.unregisterInputConsumer();
|
||||
mOverviewComponentObserver.onDestroy();
|
||||
if (mIsUserUnlocked) {
|
||||
mInputConsumer.unregisterInputConsumer();
|
||||
mOverviewComponentObserver.onDestroy();
|
||||
}
|
||||
disposeEventHandlers();
|
||||
sConnected = false;
|
||||
Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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…
Reference in New Issue