1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.systemui.recents.tv.views;
17
18import android.animation.Animator;
19import android.animation.AnimatorSet;
20import android.content.Context;
21import android.support.v17.leanback.widget.HorizontalGridView;
22import android.util.AttributeSet;
23import android.view.View;
24
25import com.android.systemui.R;
26import com.android.systemui.recents.RecentsActivity;
27import com.android.systemui.recents.events.EventBus;
28import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
29import com.android.systemui.recents.model.Task;
30import com.android.systemui.recents.model.TaskStack;
31import com.android.systemui.recents.model.TaskStack.TaskStackCallbacks;
32import com.android.systemui.recents.views.AnimationProps;
33
34/**
35 * Horizontal Grid View Implementation to show the Task Stack for TV.
36 */
37public class TaskStackHorizontalGridView extends HorizontalGridView implements TaskStackCallbacks {
38    private static final int ANIMATION_DELAY_MS = 50;
39    private static final int MSG_START_RECENT_ROW_FOCUS_ANIMATION = 100;
40    private TaskStack mStack;
41    private Task mFocusedTask;
42    private AnimatorSet mRecentsRowFocusAnimation;
43
44    public TaskStackHorizontalGridView(Context context) {
45        this(context, null);
46    }
47
48    public TaskStackHorizontalGridView(Context context, AttributeSet attrs) {
49        super(context, attrs);
50    }
51
52    @Override
53    protected void onAttachedToWindow() {
54        EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
55        setWindowAlignment(WINDOW_ALIGN_NO_EDGE);
56        setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
57        super.onAttachedToWindow();
58    }
59
60    @Override
61    protected void onDetachedFromWindow() {
62        super.onDetachedFromWindow();
63        EventBus.getDefault().unregister(this);
64    }
65
66    /**
67     * Initializes the grid view.
68     * @param stack
69     */
70    public void init(TaskStack stack) {
71        // Set new stack
72        mStack = stack;
73        if (mStack != null) {
74            mStack.setCallbacks(this);
75        }
76    }
77
78    /**
79     * @return Returns the task stack.
80     */
81    public TaskStack getStack() {
82        return mStack;
83    }
84
85    /**
86     * @return - The focused task.
87     */
88    public Task getFocusedTask() {
89        if (findFocus() != null) {
90            mFocusedTask = ((TaskCardView)findFocus()).getTask();
91        }
92        return mFocusedTask;
93    }
94
95    /**
96     * @param task
97     * @return Child view for given task
98     */
99    public TaskCardView getChildViewForTask(Task task) {
100        for (int i = 0; i < getChildCount(); i++) {
101            TaskCardView tv = (TaskCardView) getChildAt(i);
102            if (tv.getTask() == task) {
103                return tv;
104            }
105        }
106        return null;
107    }
108
109
110    /**
111     * Starts the Recents row's focus gain animation.
112     */
113    public void startFocusGainAnimation() {
114        for (int i = 0; i < getChildCount(); i++) {
115            TaskCardView v = (TaskCardView) getChildAt(i);
116            if (v.hasFocus()) {
117                v.getViewFocusAnimator().changeSize(true);
118            }
119            v.getRecentsRowFocusAnimationHolder().startFocusGainAnimation();
120        }
121    }
122
123    /**
124     * Starts the Recents row's focus loss animation.
125     */
126    public void startFocusLossAnimation() {
127        for (int i = 0; i < getChildCount(); i++) {
128            TaskCardView v = (TaskCardView) getChildAt(i);
129            if (v.hasFocus()) {
130                v.getViewFocusAnimator().changeSize(false);
131            }
132            v.getRecentsRowFocusAnimationHolder().startFocusLossAnimation();
133        }
134    }
135
136    @Override
137    public void onStackTaskAdded(TaskStack stack, Task newTask) {
138        ((TaskStackHorizontalViewAdapter) getAdapter()).addTaskAt(newTask,
139                stack.indexOfStackTask(newTask));
140    }
141
142    @Override
143    public void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask,
144            AnimationProps animation, boolean fromDockGesture) {
145        ((TaskStackHorizontalViewAdapter) getAdapter()).removeTask(removedTask);
146        if (mFocusedTask == removedTask) {
147            mFocusedTask = null;
148        }
149        // If there are no remaining tasks, then just close recents
150        if (mStack.getStackTaskCount() == 0) {
151            boolean shouldFinishActivity = (mStack.getStackTaskCount() == 0);
152            if (shouldFinishActivity) {
153                EventBus.getDefault().send(new AllTaskViewsDismissedEvent(fromDockGesture
154                        ? R.string.recents_empty_message
155                        : R.string.recents_empty_message_dismissed_all));
156            }
157        }
158    }
159
160    @Override
161    public void onStackTasksRemoved(TaskStack stack) {
162        // Do nothing
163    }
164
165    @Override
166    public void onStackTasksUpdated(TaskStack stack) {
167        // Do nothing
168    }
169}
170