blob: 5920f46b12f6067d0b69ead0feb8056a7a00dc23 [file] [log] [blame]
/*
* Copyright (C) 2016 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.stackdivider;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.UserHandle;
import android.util.ArraySet;
import android.widget.Toast;
import com.android.systemui.R;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
import com.android.systemui.recents.events.component.ShowUserToastEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
import com.android.systemui.stackdivider.events.StartedDragingEvent;
import com.android.systemui.stackdivider.events.StoppedDragingEvent;
/**
* Controller that decides when to show the {@link ForcedResizableInfoActivity}.
*/
public class ForcedResizableInfoActivityController {
private static final String SELF_PACKAGE_NAME = "com.android.systemui";
private static final int TIMEOUT = 1000;
private final Context mContext;
private final Handler mHandler = new Handler();
private final ArraySet<Integer> mPendingTaskIds = new ArraySet<>();
private final ArraySet<String> mPackagesShownInSession = new ArraySet<>();
private boolean mDividerDraging;
private final Runnable mTimeoutRunnable = new Runnable() {
@Override
public void run() {
showPending();
}
};
public ForcedResizableInfoActivityController(Context context) {
mContext = context;
EventBus.getDefault().register(this);
SystemServicesProxy.getInstance(context).registerTaskStackListener(
new TaskStackListener() {
@Override
public void onActivityForcedResizable(String packageName, int taskId) {
activityForcedResizable(packageName, taskId);
}
@Override
public void onActivityDismissingDockedStack() {
activityDismissingDockedStack();
}
});
}
public void notifyDockedStackExistsChanged(boolean exists) {
if (!exists) {
mPackagesShownInSession.clear();
}
}
public final void onBusEvent(AppTransitionFinishedEvent event) {
if (!mDividerDraging) {
showPending();
}
}
public final void onBusEvent(StartedDragingEvent event) {
mDividerDraging = true;
mHandler.removeCallbacks(mTimeoutRunnable);
}
public final void onBusEvent(StoppedDragingEvent event) {
mDividerDraging = false;
showPending();
}
private void activityForcedResizable(String packageName, int taskId) {
if (debounce(packageName)) {
return;
}
mPendingTaskIds.add(taskId);
postTimeout();
}
private void activityDismissingDockedStack() {
EventBus.getDefault().send(new ShowUserToastEvent(
R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT));
}
private void showPending() {
mHandler.removeCallbacks(mTimeoutRunnable);
for (int i = mPendingTaskIds.size() - 1; i >= 0; i--) {
Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class);
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchTaskId(mPendingTaskIds.valueAt(i));
options.setTaskOverlay(true);
mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
}
mPendingTaskIds.clear();
}
private void postTimeout() {
mHandler.removeCallbacks(mTimeoutRunnable);
mHandler.postDelayed(mTimeoutRunnable, TIMEOUT);
}
private boolean debounce(String packageName) {
if (packageName == null) {
return false;
}
// We launch ForcedResizableInfoActivity into a task that was forced resizable, so that
// triggers another notification. So ignore our own activity.
if (SELF_PACKAGE_NAME.equals(packageName)) {
return true;
}
boolean debounce = mPackagesShownInSession.contains(packageName);
mPackagesShownInSession.add(packageName);
return debounce;
}
}