/*
 * 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.shared.system;

import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityTaskManager;
import android.app.IActivityManager;
import android.app.TaskStackListener;
import android.content.ComponentName;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.Trace;
import android.util.Log;

import com.android.internal.os.SomeArgs;
import com.android.systemui.shared.recents.model.ThumbnailData;

import java.util.ArrayList;
import java.util.List;

/**
 * Tracks all the task stack listeners
 */
public class TaskStackChangeListeners extends TaskStackListener {

    private static final String TAG = TaskStackChangeListeners.class.getSimpleName();

    /**
     * List of {@link TaskStackChangeListener} registered from {@link #addListener}.
     */
    private final List<TaskStackChangeListener> mTaskStackListeners = new ArrayList<>();
    private final List<TaskStackChangeListener> mTmpListeners = new ArrayList<>();

    private final Handler mHandler;
    private boolean mRegistered;

    public TaskStackChangeListeners(Looper looper) {
        mHandler = new H(looper);
    }

    public void addListener(IActivityManager am, TaskStackChangeListener listener) {
        synchronized (mTaskStackListeners) {
            mTaskStackListeners.add(listener);
        }
        if (!mRegistered) {
            // Register mTaskStackListener to IActivityManager only once if needed.
            try {
                ActivityTaskManager.getService().registerTaskStackListener(this);
                mRegistered = true;
            } catch (Exception e) {
                Log.w(TAG, "Failed to call registerTaskStackListener", e);
            }
        }
    }

    public void removeListener(TaskStackChangeListener listener) {
        boolean isEmpty;
        synchronized (mTaskStackListeners) {
            mTaskStackListeners.remove(listener);
            isEmpty = mTaskStackListeners.isEmpty();
        }
        if (isEmpty && mRegistered) {
            // Unregister mTaskStackListener once we have no more listeners
            try {
                ActivityTaskManager.getService().unregisterTaskStackListener(this);
                mRegistered = false;
            } catch (Exception e) {
                Log.w(TAG, "Failed to call unregisterTaskStackListener", e);
            }
        }
    }

    @Override
    public void onTaskStackChanged() throws RemoteException {
        // Call the task changed callback for the non-ui thread listeners first. Copy to a set of
        // temp listeners so that we don't lock on mTaskStackListeners while calling all the
        // callbacks. This call is always on the same binder thread, so we can just synchronize
        // on the copying of the listener list.
        synchronized (mTaskStackListeners) {
            mTmpListeners.addAll(mTaskStackListeners);
        }
        for (int i = mTmpListeners.size() - 1; i >= 0; i--) {
            mTmpListeners.get(i).onTaskStackChangedBackground();
        }
        mTmpListeners.clear();

        mHandler.removeMessages(H.ON_TASK_STACK_CHANGED);
        mHandler.sendEmptyMessage(H.ON_TASK_STACK_CHANGED);
    }

    @Override
    public void onActivityPinned(String packageName, int userId, int taskId, int stackId)
            throws RemoteException {
        mHandler.removeMessages(H.ON_ACTIVITY_PINNED);
        mHandler.obtainMessage(H.ON_ACTIVITY_PINNED,
                new PinnedActivityInfo(packageName, userId, taskId, stackId)).sendToTarget();
    }

    @Override
    public void onActivityUnpinned() throws RemoteException {
        mHandler.removeMessages(H.ON_ACTIVITY_UNPINNED);
        mHandler.sendEmptyMessage(H.ON_ACTIVITY_UNPINNED);
    }

    @Override
    public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
            boolean clearedTask, boolean wasVisible) throws RemoteException {
        final SomeArgs args = SomeArgs.obtain();
        args.arg1 = task;
        args.argi1 = homeTaskVisible ? 1 : 0;
        args.argi2 = clearedTask ? 1 : 0;
        args.argi3 = wasVisible ? 1 : 0;
        mHandler.removeMessages(H.ON_ACTIVITY_RESTART_ATTEMPT);
        mHandler.obtainMessage(H.ON_ACTIVITY_RESTART_ATTEMPT, args).sendToTarget();
    }

    @Override
    public void onActivityForcedResizable(String packageName, int taskId, int reason)
            throws RemoteException {
        mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, reason, packageName)
                .sendToTarget();
    }

    @Override
    public void onActivityDismissingDockedStack() throws RemoteException {
        mHandler.sendEmptyMessage(H.ON_ACTIVITY_DISMISSING_DOCKED_STACK);
    }

    @Override
    public void onActivityLaunchOnSecondaryDisplayFailed(RunningTaskInfo taskInfo,
            int requestedDisplayId) throws RemoteException {
        mHandler.obtainMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED, requestedDisplayId,
                0 /* unused */,
                taskInfo).sendToTarget();
    }

    @Override
    public void onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo,
            int requestedDisplayId) throws RemoteException {
        mHandler.obtainMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED,
                requestedDisplayId, 0 /* unused */, taskInfo).sendToTarget();
    }

    @Override
    public void onTaskProfileLocked(int taskId, int userId) throws RemoteException {
        mHandler.obtainMessage(H.ON_TASK_PROFILE_LOCKED, taskId, userId).sendToTarget();
    }

    @Override
    public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException {
        mHandler.obtainMessage(H.ON_TASK_SNAPSHOT_CHANGED, taskId, 0, snapshot).sendToTarget();
    }

    @Override
    public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
        mHandler.obtainMessage(H.ON_TASK_CREATED, taskId, 0, componentName).sendToTarget();
    }

    @Override
    public void onTaskRemoved(int taskId) throws RemoteException {
        mHandler.obtainMessage(H.ON_TASK_REMOVED, taskId, 0).sendToTarget();
    }

    @Override
    public void onTaskMovedToFront(RunningTaskInfo taskInfo)
            throws RemoteException {
        mHandler.obtainMessage(H.ON_TASK_MOVED_TO_FRONT, taskInfo).sendToTarget();
    }

    @Override
    public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) throws RemoteException {
        mHandler.obtainMessage(H.ON_BACK_PRESSED_ON_TASK_ROOT, taskInfo).sendToTarget();
    }

    @Override
    public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation)
            throws RemoteException {
        mHandler.obtainMessage(H.ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE, taskId,
                requestedOrientation).sendToTarget();
    }

    @Override
    public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken)
            throws RemoteException {
        mHandler.obtainMessage(H.ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED, displayId, 0 /* unused */,
                activityToken).sendToTarget();
    }

    @Override
    public void onSingleTaskDisplayDrawn(int displayId) throws RemoteException {
        mHandler.obtainMessage(H.ON_SINGLE_TASK_DISPLAY_DRAWN, displayId,
                0 /* unused */).sendToTarget();
    }

    @Override
    public void onSingleTaskDisplayEmpty(int displayId) throws RemoteException {
        mHandler.obtainMessage(H.ON_SINGLE_TASK_DISPLAY_EMPTY, displayId,
                0 /* unused */).sendToTarget();
    }

    @Override
    public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException {
        mHandler.obtainMessage(H.ON_TASK_DISPLAY_CHANGED, taskId, newDisplayId).sendToTarget();
    }

    @Override
    public void onRecentTaskListUpdated() throws RemoteException {
        mHandler.obtainMessage(H.ON_TASK_LIST_UPDATED).sendToTarget();
    }

    @Override
    public void onRecentTaskListFrozenChanged(boolean frozen) {
        mHandler.obtainMessage(H.ON_TASK_LIST_FROZEN_UNFROZEN, frozen ? 1 : 0, 0 /* unused */)
                .sendToTarget();
    }

    @Override
    public void onTaskDescriptionChanged(RunningTaskInfo taskInfo) {
        mHandler.obtainMessage(H.ON_TASK_DESCRIPTION_CHANGED, taskInfo).sendToTarget();
    }

    private final class H extends Handler {
        private static final int ON_TASK_STACK_CHANGED = 1;
        private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
        private static final int ON_ACTIVITY_PINNED = 3;
        private static final int ON_ACTIVITY_RESTART_ATTEMPT = 4;
        private static final int ON_ACTIVITY_FORCED_RESIZABLE = 6;
        private static final int ON_ACTIVITY_DISMISSING_DOCKED_STACK = 7;
        private static final int ON_TASK_PROFILE_LOCKED = 8;
        private static final int ON_ACTIVITY_UNPINNED = 10;
        private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED = 11;
        private static final int ON_TASK_CREATED = 12;
        private static final int ON_TASK_REMOVED = 13;
        private static final int ON_TASK_MOVED_TO_FRONT = 14;
        private static final int ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE = 15;
        private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED = 16;
        private static final int ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED = 17;
        private static final int ON_BACK_PRESSED_ON_TASK_ROOT = 18;
        private static final int ON_SINGLE_TASK_DISPLAY_DRAWN = 19;
        private static final int ON_TASK_DISPLAY_CHANGED = 20;
        private static final int ON_TASK_LIST_UPDATED = 21;
        private static final int ON_SINGLE_TASK_DISPLAY_EMPTY = 22;
        private static final int ON_TASK_LIST_FROZEN_UNFROZEN = 23;
        private static final int ON_TASK_DESCRIPTION_CHANGED = 24;


        public H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            synchronized (mTaskStackListeners) {
                switch (msg.what) {
                    case ON_TASK_STACK_CHANGED: {
                        Trace.beginSection("onTaskStackChanged");
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onTaskStackChanged();
                        }
                        Trace.endSection();
                        break;
                    }
                    case ON_TASK_SNAPSHOT_CHANGED: {
                        Trace.beginSection("onTaskSnapshotChanged");
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1,
                                    new ThumbnailData((TaskSnapshot) msg.obj));
                        }
                        Trace.endSection();
                        break;
                    }
                    case ON_ACTIVITY_PINNED: {
                        final PinnedActivityInfo info = (PinnedActivityInfo) msg.obj;
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onActivityPinned(
                                    info.mPackageName, info.mUserId, info.mTaskId, info.mStackId);
                        }
                        break;
                    }
                    case ON_ACTIVITY_UNPINNED: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onActivityUnpinned();
                        }
                        break;
                    }
                    case ON_ACTIVITY_RESTART_ATTEMPT: {
                        final SomeArgs args = (SomeArgs) msg.obj;
                        final RunningTaskInfo task = (RunningTaskInfo) args.arg1;
                        final boolean homeTaskVisible = args.argi1 != 0;
                        final boolean clearedTask = args.argi2 != 0;
                        final boolean wasVisible = args.argi3 != 0;
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onActivityRestartAttempt(task,
                                    homeTaskVisible, clearedTask, wasVisible);
                        }
                        break;
                    }
                    case ON_ACTIVITY_FORCED_RESIZABLE: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onActivityForcedResizable(
                                    (String) msg.obj, msg.arg1, msg.arg2);
                        }
                        break;
                    }
                    case ON_ACTIVITY_DISMISSING_DOCKED_STACK: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onActivityDismissingDockedStack();
                        }
                        break;
                    }
                    case ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED: {
                        final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i)
                                    .onActivityLaunchOnSecondaryDisplayFailed(info);
                        }
                        break;
                    }
                    case ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED: {
                        final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i)
                                    .onActivityLaunchOnSecondaryDisplayRerouted(info);
                        }
                        break;
                    }
                    case ON_TASK_PROFILE_LOCKED: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onTaskProfileLocked(msg.arg1, msg.arg2);
                        }
                        break;
                    }
                    case ON_TASK_CREATED: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onTaskCreated(msg.arg1,
                                    (ComponentName) msg.obj);
                        }
                        break;
                    }
                    case ON_TASK_REMOVED: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onTaskRemoved(msg.arg1);
                        }
                        break;
                    }
                    case ON_TASK_MOVED_TO_FRONT: {
                        final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onTaskMovedToFront(info);
                        }
                        break;
                    }
                    case ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i)
                                    .onActivityRequestedOrientationChanged(msg.arg1, msg.arg2);
                        }
                        break;
                    }
                    case ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onSizeCompatModeActivityChanged(
                                    msg.arg1, (IBinder) msg.obj);
                        }
                        break;
                    }
                    case ON_BACK_PRESSED_ON_TASK_ROOT: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onBackPressedOnTaskRoot(
                                    (RunningTaskInfo) msg.obj);
                        }
                        break;
                    }
                    case ON_SINGLE_TASK_DISPLAY_DRAWN: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onSingleTaskDisplayDrawn(msg.arg1);
                        }
                        break;
                    }
                    case ON_SINGLE_TASK_DISPLAY_EMPTY: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onSingleTaskDisplayEmpty(
                                    msg.arg1);
                        }
                        break;
                    }
                    case ON_TASK_DISPLAY_CHANGED: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onTaskDisplayChanged(msg.arg1, msg.arg2);
                        }
                        break;
                    }
                    case ON_TASK_LIST_UPDATED: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onRecentTaskListUpdated();
                        }
                        break;
                    }
                    case ON_TASK_LIST_FROZEN_UNFROZEN: {
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onRecentTaskListFrozenChanged(msg.arg1 != 0);
                        }
                        break;
                    }
                    case ON_TASK_DESCRIPTION_CHANGED: {
                        final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                            mTaskStackListeners.get(i).onTaskDescriptionChanged(info);
                        }
                        break;
                    }
                }
            }
            if (msg.obj instanceof SomeArgs) {
                ((SomeArgs) msg.obj).recycle();
            }
        }
    }

    private static class PinnedActivityInfo {
        final String mPackageName;
        final int mUserId;
        final int mTaskId;
        final int mStackId;

        PinnedActivityInfo(String packageName, int userId, int taskId, int stackId) {
            mPackageName = packageName;
            mUserId = userId;
            mTaskId = taskId;
            mStackId = stackId;
        }
    }
}
