summaryrefslogtreecommitdiff
path: root/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/OverviewProxyService.java')
-rw-r--r--packages/SystemUI/src/com/android/systemui/OverviewProxyService.java535
1 files changed, 0 insertions, 535 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
deleted file mode 100644
index 1bf87506ab0c..000000000000
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
-import static android.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_UP;
-import static android.view.MotionEvent.ACTION_CANCEL;
-
-import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
-import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
-import static com.android.systemui.shared.system.NavigationBarCompat.InteractionType;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.graphics.Rect;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.PatternMatcher;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.MotionEvent;
-import com.android.systemui.OverviewProxyService.OverviewProxyListener;
-import com.android.systemui.shared.recents.IOverviewProxy;
-import com.android.systemui.shared.recents.ISystemUiProxy;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.policy.CallbackController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class to send information from overview to launcher with a binder.
- */
-public class OverviewProxyService implements CallbackController<OverviewProxyListener>, Dumpable {
-
- private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
-
- public static final String TAG_OPS = "OverviewProxyService";
- public static final boolean DEBUG_OVERVIEW_PROXY = false;
- private static final long BACKOFF_MILLIS = 1000;
- private static final long DEFERRED_CALLBACK_MILLIS = 5000;
-
- // Max backoff caps at 5 mins
- private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
-
- // Default interaction flags if swipe up is disabled before connecting to launcher
- private static final int DEFAULT_DISABLE_SWIPE_UP_STATE = FLAG_DISABLE_SWIPE_UP
- | FLAG_SHOW_OVERVIEW_BUTTON;
-
- private final Context mContext;
- private final Handler mHandler;
- private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
- private final ComponentName mRecentsComponentName;
- private final DeviceProvisionedController mDeviceProvisionedController
- = Dependency.get(DeviceProvisionedController.class);
- private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
- private final Intent mQuickStepIntent;
-
- private IOverviewProxy mOverviewProxy;
- private int mConnectionBackoffAttempts;
- private @InteractionType int mInteractionFlags;
- private boolean mIsEnabled;
- private int mCurrentBoundedUserId = -1;
- private float mBackButtonAlpha;
- private MotionEvent mStatusBarGestureDownEvent;
-
- private ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() {
-
- public void startScreenPinning(int taskId) {
- if (!verifyCaller("startScreenPinning")) {
- return;
- }
- long token = Binder.clearCallingIdentity();
- try {
- mHandler.post(() -> {
- StatusBar statusBar = SysUiServiceProvider.getComponent(mContext,
- StatusBar.class);
- if (statusBar != null) {
- statusBar.showScreenPinningRequest(taskId, false /* allowCancel */);
- }
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public void onStatusBarMotionEvent(MotionEvent event) {
- if (!verifyCaller("onStatusBarMotionEvent")) {
- return;
- }
- long token = Binder.clearCallingIdentity();
- try {
- // TODO move this logic to message queue
- mHandler.post(()->{
- StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
- if (bar != null) {
- bar.dispatchNotificationsPanelTouchEvent(event);
-
- int action = event.getActionMasked();
- if (action == ACTION_DOWN) {
- mStatusBarGestureDownEvent = MotionEvent.obtain(event);
- }
- if (action == ACTION_UP || action == ACTION_CANCEL) {
- mStatusBarGestureDownEvent.recycle();
- mStatusBarGestureDownEvent = null;
- }
- event.recycle();
- }
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public void onSplitScreenInvoked() {
- if (!verifyCaller("onSplitScreenInvoked")) {
- return;
- }
- long token = Binder.clearCallingIdentity();
- try {
- Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
- if (divider != null) {
- divider.onDockedFirstAnimationFrame();
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public void onOverviewShown(boolean fromHome) {
- if (!verifyCaller("onOverviewShown")) {
- return;
- }
- long token = Binder.clearCallingIdentity();
- try {
- mHandler.post(() -> {
- for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
- mConnectionCallbacks.get(i).onOverviewShown(fromHome);
- }
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public void setInteractionState(@InteractionType int flags) {
- if (!verifyCaller("setInteractionState")) {
- return;
- }
- long token = Binder.clearCallingIdentity();
- try {
- if (mInteractionFlags != flags) {
- mInteractionFlags = flags;
- mHandler.post(() -> {
- for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
- mConnectionCallbacks.get(i).onInteractionFlagsChanged(flags);
- }
- });
- }
- } finally {
- Prefs.putInt(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS, mInteractionFlags);
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public Rect getNonMinimizedSplitScreenSecondaryBounds() {
- if (!verifyCaller("getNonMinimizedSplitScreenSecondaryBounds")) {
- return null;
- }
- long token = Binder.clearCallingIdentity();
- try {
- Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
- if (divider != null) {
- return divider.getView().getNonMinimizedSplitScreenSecondaryBounds();
- }
- return null;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public void setBackButtonAlpha(float alpha, boolean animate) {
- if (!verifyCaller("setBackButtonAlpha")) {
- return;
- }
- long token = Binder.clearCallingIdentity();
- try {
- mBackButtonAlpha = alpha;
- mHandler.post(() -> {
- notifyBackButtonAlphaChanged(alpha, animate);
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private boolean verifyCaller(String reason) {
- final int callerId = Binder.getCallingUserHandle().getIdentifier();
- if (callerId != mCurrentBoundedUserId) {
- Log.w(TAG_OPS, "Launcher called sysui with invalid user: " + callerId + ", reason: "
- + reason);
- return false;
- }
- return true;
- }
- };
-
- private final Runnable mDeferredConnectionCallback = () -> {
- Log.w(TAG_OPS, "Binder supposed established connection but actual connection to service "
- + "timed out, trying again");
- retryConnectionWithBackoff();
- };
-
- private final BroadcastReceiver mLauncherStateChangedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- updateEnabledState();
-
- // When launcher service is disabled, reset interaction flags because it is inactive
- if (!isEnabled()) {
- mInteractionFlags = getDefaultInteractionFlags();
- Prefs.remove(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS);
- }
-
- // Reconnect immediately, instead of waiting for resume to arrive.
- startConnectionToCurrentUser();
- }
- };
-
- private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mHandler.removeCallbacks(mDeferredConnectionCallback);
- mCurrentBoundedUserId = mDeviceProvisionedController.getCurrentUser();
- mConnectionBackoffAttempts = 0;
- mOverviewProxy = IOverviewProxy.Stub.asInterface(service);
- // Listen for launcher's death
- try {
- service.linkToDeath(mOverviewServiceDeathRcpt, 0);
- } catch (RemoteException e) {
- Log.e(TAG_OPS, "Lost connection to launcher service", e);
- }
- try {
- mOverviewProxy.onBind(mSysUiProxy);
- } catch (RemoteException e) {
- mCurrentBoundedUserId = -1;
- Log.e(TAG_OPS, "Failed to call onBind()", e);
- }
- notifyConnectionChanged();
- }
-
- @Override
- public void onNullBinding(ComponentName name) {
- Log.w(TAG_OPS, "Null binding of '" + name + "', try reconnecting");
- mCurrentBoundedUserId = -1;
- retryConnectionWithBackoff();
- }
-
- @Override
- public void onBindingDied(ComponentName name) {
- Log.w(TAG_OPS, "Binding died of '" + name + "', try reconnecting");
- mCurrentBoundedUserId = -1;
- retryConnectionWithBackoff();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- // Do nothing
- mCurrentBoundedUserId = -1;
- }
- };
-
- private final DeviceProvisionedListener mDeviceProvisionedCallback =
- new DeviceProvisionedListener() {
- @Override
- public void onUserSetupChanged() {
- if (mDeviceProvisionedController.isCurrentUserSetup()) {
- internalConnectToCurrentUser();
- }
- }
-
- @Override
- public void onUserSwitched() {
- mConnectionBackoffAttempts = 0;
- internalConnectToCurrentUser();
- }
- };
-
- // This is the death handler for the binder from the launcher service
- private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
- = this::cleanupAfterDeath;
-
- public OverviewProxyService(Context context) {
- mContext = context;
- mHandler = new Handler();
- mConnectionBackoffAttempts = 0;
- mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
- com.android.internal.R.string.config_recentsComponentName));
- mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
- .setPackage(mRecentsComponentName.getPackageName());
- mInteractionFlags = Prefs.getInt(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS,
- getDefaultInteractionFlags());
-
- // Listen for the package update changes.
- if (mDeviceProvisionedController.getCurrentUser() == UserHandle.USER_SYSTEM) {
- updateEnabledState();
- mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback);
- IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
- filter.addDataScheme("package");
- filter.addDataSchemeSpecificPart(mRecentsComponentName.getPackageName(),
- PatternMatcher.PATTERN_LITERAL);
- filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- mContext.registerReceiver(mLauncherStateChangedReceiver, filter);
- }
- }
-
- public float getBackButtonAlpha() {
- return mBackButtonAlpha;
- }
-
- public void cleanupAfterDeath() {
- if (mStatusBarGestureDownEvent != null) {
- mHandler.post(()-> {
- StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
- if (bar != null) {
- System.out.println("MERONG dispatchNotificationPanelTouchEvent");
- mStatusBarGestureDownEvent.setAction(MotionEvent.ACTION_CANCEL);
- bar.dispatchNotificationsPanelTouchEvent(mStatusBarGestureDownEvent);
- mStatusBarGestureDownEvent.recycle();
- mStatusBarGestureDownEvent = null;
- }
- });
- }
- startConnectionToCurrentUser();
- }
-
- public void startConnectionToCurrentUser() {
- if (mHandler.getLooper() != Looper.myLooper()) {
- mHandler.post(mConnectionRunnable);
- } else {
- internalConnectToCurrentUser();
- }
- }
-
- private void internalConnectToCurrentUser() {
- disconnectFromLauncherService();
-
- // If user has not setup yet or already connected, do not try to connect
- if (!mDeviceProvisionedController.isCurrentUserSetup() || !isEnabled()) {
- Log.v(TAG_OPS, "Cannot attempt connection, is setup "
- + mDeviceProvisionedController.isCurrentUserSetup() + ", is enabled "
- + isEnabled());
- return;
- }
- mHandler.removeCallbacks(mConnectionRunnable);
- Intent launcherServiceIntent = new Intent(ACTION_QUICKSTEP)
- .setPackage(mRecentsComponentName.getPackageName());
- boolean bound = false;
- try {
- bound = mContext.bindServiceAsUser(launcherServiceIntent,
- mOverviewServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
- UserHandle.of(mDeviceProvisionedController.getCurrentUser()));
- } catch (SecurityException e) {
- Log.e(TAG_OPS, "Unable to bind because of security error", e);
- }
- if (bound) {
- // Ensure that connection has been established even if it thinks it is bound
- mHandler.postDelayed(mDeferredConnectionCallback, DEFERRED_CALLBACK_MILLIS);
- } else {
- // Retry after exponential backoff timeout
- retryConnectionWithBackoff();
- }
- }
-
- private void retryConnectionWithBackoff() {
- if (mHandler.hasCallbacks(mConnectionRunnable)) {
- return;
- }
- final long timeoutMs = (long) Math.min(
- Math.scalb(BACKOFF_MILLIS, mConnectionBackoffAttempts), MAX_BACKOFF_MILLIS);
- mHandler.postDelayed(mConnectionRunnable, timeoutMs);
- mConnectionBackoffAttempts++;
- Log.w(TAG_OPS, "Failed to connect on attempt " + mConnectionBackoffAttempts
- + " will try again in " + timeoutMs + "ms");
- }
-
- @Override
- public void addCallback(OverviewProxyListener listener) {
- mConnectionCallbacks.add(listener);
- listener.onConnectionChanged(mOverviewProxy != null);
- listener.onInteractionFlagsChanged(mInteractionFlags);
- }
-
- @Override
- public void removeCallback(OverviewProxyListener listener) {
- mConnectionCallbacks.remove(listener);
- }
-
- public boolean shouldShowSwipeUpUI() {
- return isEnabled() && ((mInteractionFlags & FLAG_DISABLE_SWIPE_UP) == 0);
- }
-
- public boolean isEnabled() {
- return mIsEnabled;
- }
-
- public IOverviewProxy getProxy() {
- return mOverviewProxy;
- }
-
- public int getInteractionFlags() {
- return mInteractionFlags;
- }
-
- private void disconnectFromLauncherService() {
- if (mOverviewProxy != null) {
- mOverviewProxy.asBinder().unlinkToDeath(mOverviewServiceDeathRcpt, 0);
- mContext.unbindService(mOverviewServiceConnection);
- mOverviewProxy = null;
- notifyBackButtonAlphaChanged(1f, false /* animate */);
- notifyConnectionChanged();
- }
- }
-
- private int getDefaultInteractionFlags() {
- // If there is no settings available use device default or get it from settings
- final boolean defaultState = getSwipeUpDefaultValue();
- final boolean swipeUpEnabled = getSwipeUpSettingAvailable()
- ? getSwipeUpEnabledFromSettings(defaultState)
- : defaultState;
- return swipeUpEnabled ? 0 : DEFAULT_DISABLE_SWIPE_UP_STATE;
- }
-
- private void notifyBackButtonAlphaChanged(float alpha, boolean animate) {
- for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
- mConnectionCallbacks.get(i).onBackButtonAlphaChanged(alpha, animate);
- }
- }
-
- private void notifyConnectionChanged() {
- for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
- mConnectionCallbacks.get(i).onConnectionChanged(mOverviewProxy != null);
- }
- }
-
- public void notifyQuickStepStarted() {
- for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
- mConnectionCallbacks.get(i).onQuickStepStarted();
- }
- }
-
- public void notifyQuickScrubStarted() {
- for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
- mConnectionCallbacks.get(i).onQuickScrubStarted();
- }
- }
-
- private void updateEnabledState() {
- mIsEnabled = mContext.getPackageManager().resolveServiceAsUser(mQuickStepIntent,
- MATCH_DIRECT_BOOT_UNAWARE,
- ActivityManagerWrapper.getInstance().getCurrentUserId()) != null;
- }
-
- private boolean getSwipeUpDefaultValue() {
- return mContext.getResources()
- .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_default);
- }
-
- private boolean getSwipeUpSettingAvailable() {
- return mContext.getResources()
- .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_setting_available);
- }
-
- private boolean getSwipeUpEnabledFromSettings(boolean defaultValue) {
- return Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, defaultValue ? 1 : 0) == 1;
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(TAG_OPS + " state:");
- pw.print(" recentsComponentName="); pw.println(mRecentsComponentName);
- pw.print(" isConnected="); pw.println(mOverviewProxy != null);
- pw.print(" isCurrentUserSetup="); pw.println(mDeviceProvisionedController
- .isCurrentUserSetup());
- pw.print(" connectionBackoffAttempts="); pw.println(mConnectionBackoffAttempts);
- pw.print(" interactionFlags="); pw.println(mInteractionFlags);
-
- pw.print(" quickStepIntent="); pw.println(mQuickStepIntent);
- pw.print(" quickStepIntentResolved="); pw.println(isEnabled());
-
- final boolean swipeUpDefaultValue = getSwipeUpDefaultValue();
- final boolean swipeUpEnabled = getSwipeUpEnabledFromSettings(swipeUpDefaultValue);
- pw.print(" swipeUpSetting="); pw.println(swipeUpEnabled);
- pw.print(" swipeUpSettingDefault="); pw.println(swipeUpDefaultValue);
- }
-
- public interface OverviewProxyListener {
- default void onConnectionChanged(boolean isConnected) {}
- default void onQuickStepStarted() {}
- default void onInteractionFlagsChanged(@InteractionType int flags) {}
- default void onOverviewShown(boolean fromHome) {}
- default void onQuickScrubStarted() {}
- default void onBackButtonAlphaChanged(float alpha, boolean animate) {}
- }
-}