1/*
2 * Copyright (C) 2014 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 */
16
17package com.android.testingcamera2;
18
19import java.util.ArrayList;
20import java.util.HashSet;
21import java.util.List;
22import java.util.Set;
23
24import android.os.Handler;
25import android.os.Looper;
26
27/**
28 * Tracks currently-available panes of various kinds, for other panes to find targets/etc.
29 *
30 */
31public class PaneTracker {
32
33    private Set<ControlPane> mActivePanes = new HashSet<ControlPane>();
34    private Set<PaneSetChangedListener<?>> mActiveListeners = new HashSet<PaneSetChangedListener<?>>();
35
36    /**
37     * Various events panes might alert other panes about
38     */
39    public enum PaneEvent {
40        NEW_CAMERA_SELECTED,
41        CAMERA_CONFIGURED
42    }
43
44    public PaneTracker() {
45    }
46
47    public void addPane(ControlPane pane) {
48        boolean added = mActivePanes.add(pane);
49        if (!added) return;
50        for (PaneSetChangedListener<?> listener : mActiveListeners) {
51            if (listener.getFilterType().isInstance(pane)) {
52                listener.onPaneAdded(pane);
53            }
54        }
55    }
56
57    public void removePane(ControlPane pane) {
58        boolean existed = mActivePanes.remove(pane);
59        if (!existed) return;
60        for (PaneSetChangedListener<?> listener : mActiveListeners) {
61            if (listener.getFilterType().isInstance(pane)) {
62                listener.onPaneRemoved(pane);
63            }
64        }
65    }
66
67    public <T extends ControlPane> List<T> getPanes(Class<T> paneClass) {
68        List<T> filteredPanes = new ArrayList<T>();
69        for (ControlPane pane : mActivePanes ) {
70            if (paneClass.isInstance(pane)) {
71                filteredPanes.add(paneClass.cast(pane));
72            }
73        }
74        return filteredPanes;
75    }
76
77    public void notifyOtherPanes(final ControlPane sourcePane, final PaneEvent event) {
78        Handler mainHandler = new Handler(Looper.getMainLooper());
79        mainHandler.post(new Runnable() {
80            public void run() {
81                for (ControlPane pane: mActivePanes ) {
82                    pane.notifyPaneEvent(sourcePane, event);
83                }
84            }
85        });
86    }
87
88    /**
89     * Notify all panes that the UI orientation has changed
90     *
91     * @param orientation one of the Surface.ROTATION_* constants
92     */
93    public void notifyOrientationChange(int orientation) {
94        for (ControlPane pane: mActivePanes ) {
95            pane.onOrientationChange(orientation);
96        }
97    }
98
99    public void addPaneListener(PaneSetChangedListener<?> listener) {
100        mActiveListeners.add(listener);
101    }
102
103    public void removePaneListener(PaneSetChangedListener<?> listener) {
104        mActiveListeners.remove(listener);
105    }
106
107    /**
108     * Interface for clients to listen to additions and removals of panes
109     * of specific types.
110     */
111    public static abstract class PaneSetChangedListener<T extends ControlPane> {
112        private Class<T> mFilterType;
113
114        public PaneSetChangedListener(Class<T> filterType) {
115            mFilterType = filterType;
116        }
117
118        public Class<T> getFilterType() {
119            return mFilterType;
120        }
121
122        public abstract void onPaneAdded(ControlPane pane);
123        public abstract void onPaneRemoved(ControlPane pane);
124    }
125
126}
127