1 /*
2  * Copyright (C) 2015 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 
17 package android.support.car;
18 
19 import android.support.annotation.IntDef;
20 
21 import java.lang.annotation.Retention;
22 import java.lang.annotation.RetentionPolicy;
23 
24 /**
25  * Enables applications to set and listen for the current application focus (such as active
26  * navigation). Typically, only one such application should be running at a time. When another
27  * application gets ownership of a given APP_FOCUS_TYPE_*, the old app should stop using the
28  * feature represented by the focus type.
29  */
30 public abstract class CarAppFocusManager implements CarManagerBase {
31     /**
32      * Receives notifications when app focus changes.
33      */
34     public interface OnAppFocusChangedListener {
35         /**
36          * Indicates the application focus has changed. The {@link CarAppFocusManager} instance
37          * causing the change does not get this notification.
38          * @param manager the {@link CarAppFocusManager} this listener is attached to.  Useful if
39          * the app wished to unregister the listener.
40          * @param appType application type for which status changed
41          * @param active returns {@code true} if active
42          */
onAppFocusChanged(CarAppFocusManager manager, @AppFocusType int appType, boolean active)43         void onAppFocusChanged(CarAppFocusManager manager, @AppFocusType int appType,
44                 boolean active);
45     }
46 
47     /**
48      * Receives notifications when the application focus ownership changes.
49      */
50     public interface OnAppFocusOwnershipCallback {
51         /**
52          * Lost ownership for the focus, which occurs when another app has set the focus.
53          * The app losing focus should stop the action associated with the focus.
54          * For example, a navigation app running active navigation should stop navigation
55          * upon getting this for {@link CarAppFocusManager#APP_FOCUS_TYPE_NAVIGATION}.
56          * @param manager the {@link CarAppFocusManager} this callback is attached to.  Useful if
57          * the app wishes to unregister the callback.
58          * @param appType
59          */
onAppFocusOwnershipLost(CarAppFocusManager manager, @AppFocusType int appType)60         void onAppFocusOwnershipLost(CarAppFocusManager manager, @AppFocusType int appType);
61 
62         /**
63          * Granted ownership for the focus, which happens after app has requested the focus.
64          * The app getting focus can start the action associated with the focus.
65          * For example, navigation app can start navigation
66          * upon getting this for {@link CarAppFocusManager#APP_FOCUS_TYPE_NAVIGATION}.
67          * @param manager the {@link CarAppFocusManager} this callback is attached to.  Useful if
68          * the app wishes to unregister the callback.
69          * @param appType
70          */
onAppFocusOwnershipGranted(CarAppFocusManager manager, @AppFocusType int appType)71         void onAppFocusOwnershipGranted(CarAppFocusManager manager, @AppFocusType int appType);
72     }
73 
74     /**
75      * Represents navigation focus.
76      * <p/>
77      * When a program loses navigation focus they should no longer send navigation data to the
78      * instrument cluster via the
79      * {@link android.support.car.navigation.CarNavigationStatusManager}.  Furthermore they
80      * should stop sending audio updates and any notifications regarding navigation.
81      * Essentially, these apps should stop all navigation activities as this means another app is
82      * navigating.
83      */
84     public static final int APP_FOCUS_TYPE_NAVIGATION = 1;
85     /**
86      * Represents voice command focus.
87      * @hide
88      */
89     public static final int APP_FOCUS_TYPE_VOICE_COMMAND = 2;
90     /**
91      * Update this after adding a new app type.
92      * @hide
93      */
94     public static final int APP_FOCUS_TYPE_MAX = 2;
95 
96     /** @hide */
97     @IntDef({
98         APP_FOCUS_TYPE_NAVIGATION,
99         APP_FOCUS_TYPE_VOICE_COMMAND
100     })
101     @Retention(RetentionPolicy.SOURCE)
102     public @interface AppFocusType {}
103 
104     /**
105      * A failed focus change request.
106      */
107     public static final int APP_FOCUS_REQUEST_FAILED = 0;
108     /**
109      * A successful focus change request.
110      */
111     public static final int APP_FOCUS_REQUEST_SUCCEEDED = 1;
112 
113     /** @hide */
114     @IntDef({
115         APP_FOCUS_REQUEST_FAILED,
116         APP_FOCUS_REQUEST_SUCCEEDED
117     })
118     @Retention(RetentionPolicy.SOURCE)
119     public @interface AppFocusRequestResult {}
120 
121     /**
122      * Register listener to monitor app focus changes.
123      * Multiple listeners can be registered for a single focus and the same listener can be used
124      * for multiple focuses.
125      * @param listener Listener to register for focus events.
126      * @param appType Application type to get notification for.
127      * @throws CarNotConnectedException if the connection to the car service has been lost.
128      */
addFocusListener(OnAppFocusChangedListener listener, @AppFocusType int appType)129     public abstract void addFocusListener(OnAppFocusChangedListener listener,
130             @AppFocusType int appType) throws CarNotConnectedException;
131 
132     /**
133      * Unregister listener for app type and stop listening to focus change events.
134      * @param listener Listener to unregister from focus events.
135      * @param appType Application type to get notification for.
136      */
removeFocusListener(OnAppFocusChangedListener listener, @AppFocusType int appType)137     public abstract void removeFocusListener(OnAppFocusChangedListener listener,
138             @AppFocusType int appType);
139 
140     /**
141      * Unregister listener for all app types and stop listening to focus change events.
142      * @param listener Listener to unregister from focus events.
143      */
removeFocusListener(OnAppFocusChangedListener listener)144     public abstract void removeFocusListener(OnAppFocusChangedListener listener);
145 
146     /**
147      * Check if the current process owns the given focus.
148      * @param appType Application type.
149      * @param callback Callback that was used to request ownership.
150      * @return Returns {@code true} if current callback owns focus for application type.
151      * @throws CarNotConnectedException if the connection to the car service has been lost.
152      */
isOwningFocus(@ppFocusType int appType, OnAppFocusOwnershipCallback callback)153     public abstract boolean isOwningFocus(@AppFocusType int appType,
154             OnAppFocusOwnershipCallback callback) throws CarNotConnectedException;
155 
156     /**
157      * Request application focus.
158      * <p>
159      * By requesting this, the app gains the focus for this appType
160      * <p>
161      * This call is asynchronous, focus may not be granted immediately.
162      * {@link OnAppFocusOwnershipCallback#onAppFocusOwnershipGranted(CarAppFocusManager, int)} will
163      * be sent to the app when focus is granted.
164      * <p>
165      * {@link OnAppFocusOwnershipCallback#onAppFocusOwnershipLost(CarAppFocusManager, int)}
166      * will be sent to the app that currently holds focus.
167      * The foreground app will have higher priority; other apps cannot
168      * set the same focus while owner is in foreground.
169      * <p>
170      * The callback provided here is the identifier for the focus.  Apps need to pass it into
171      * other app focus methods such as {@link #isOwningFocus(int, OnAppFocusOwnershipCallback)}
172      * or {@link #abandonAppFocus(OnAppFocusOwnershipCallback)}.
173      *
174      * @param appType Application type to request focus for.
175      * @param ownershipCallback Ownership callback to request app focus for. Cannot be null.
176      *
177      * @return {@link #APP_FOCUS_REQUEST_FAILED} or {@link #APP_FOCUS_REQUEST_SUCCEEDED}
178      * @throws SecurityException if owner cannot be changed.
179      * @throws CarNotConnectedException if the connection to the car service has been lost.
180      */
requestAppFocus(int appType, OnAppFocusOwnershipCallback ownershipCallback)181     public abstract int requestAppFocus(int appType,
182             OnAppFocusOwnershipCallback ownershipCallback)
183             throws SecurityException, CarNotConnectedException;
184 
185     /**
186      * Abandon the given focus (mark it as inactive).
187      * @param ownershipCallback Ownership callback to abandon app focus for. Cannot be null.
188      * @param appType Application type to abandon focus for.
189      */
abandonAppFocus(OnAppFocusOwnershipCallback ownershipCallback, @AppFocusType int appType)190     public abstract void abandonAppFocus(OnAppFocusOwnershipCallback ownershipCallback,
191             @AppFocusType int appType);
192 
193     /**
194      * Abandon all focuses (mark them as inactive).
195      * @param ownershipCallback Ownership callback to abandon focus for. Cannot be null.
196      */
abandonAppFocus(OnAppFocusOwnershipCallback ownershipCallback)197     public abstract void abandonAppFocus(OnAppFocusOwnershipCallback ownershipCallback);
198 }
199