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  */
16 package android.support.car.navigation;
17 
18 import android.graphics.Bitmap;
19 import android.support.annotation.IntDef;
20 import android.support.car.CarManagerBase;
21 import android.support.car.CarNotConnectedException;
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
24 
25 /**
26  * APIs for providing navigation status to the instrument cluster. For cars that have a navigation
27  * display built into the instrument cluster, a navigation application should also provide
28  * turn-by-turn information to the cluster through this manager.
29  * <p/>
30  * Navigation applications should first call
31  * {@link android.support.car.CarAppFocusManager#requestAppFocus(int,
32  * android.support.car.CarAppFocusManager.OnAppFocusOwnershipCallback)} and request
33  * {@link android.support.car.CarAppFocusManager#APP_FOCUS_TYPE_NAVIGATION}.
34  * <p/>
35  * After navigation focus is granted, applications should call {@code
36  * sendNavigationStatus(STATUS_ACTIVE);} to initialize the cluster and let it know the app will be
37  * sending turn events. Then, for each turn of the turn-by-turn guidance, the app calls {@link
38  * #sendNavigationTurnEvent(int, CharSequence, int, int, int)}; this sends image data to the cluster
39  * (and is why that data is not sent in subsequent turn distance events). To update the distance
40  * and time to the next turn, the app should make periodic calls to {@link
41  * #sendNavigationTurnDistanceEvent(int, int, int, int)}.
42  * <p/>
43  * Calling {@code sendNavigationStatus(STATUS_INACTIVE);} when the route is completed allows the
44  * car to use the cluster panel for other data (such as media, weather, etc.) and is what a well
45  * behaved app is expected to do.
46  */
47 public abstract class CarNavigationStatusManager implements CarManagerBase {
48 
49     /**
50      * Listener for navigation related events. Callbacks are called in the Looper context.
51      */
52     public interface CarNavigationCallback {
53         /**
54          * Instrument Cluster started in navigation mode.
55          * @param manager The manager the callback is attached to.  Useful if the app wishes to
56          * unregister.
57          * @param instrumentCluster An object describing the configuration and state of the car's
58          * navigation instrument cluster.
59          */
onInstrumentClusterStarted(CarNavigationStatusManager manager, CarNavigationInstrumentCluster instrumentCluster)60         void onInstrumentClusterStarted(CarNavigationStatusManager manager,
61                 CarNavigationInstrumentCluster instrumentCluster);
62 
63         /**
64          * Instrument cluster ended.
65          * @param manager The manager the callback is attached to.  Useful if the app wished to
66          * unregister.
67          */
onInstrumentClusterStopped(CarNavigationStatusManager manager)68         void onInstrumentClusterStopped(CarNavigationStatusManager manager);
69     }
70 
71     /* Navigation statuses */
72     public static final int STATUS_UNAVAILABLE = 0;
73     public static final int STATUS_ACTIVE = 1;
74     public static final int STATUS_INACTIVE = 2;
75 
76     /** @hide */
77     @IntDef({
78         STATUS_UNAVAILABLE,
79         STATUS_ACTIVE,
80         STATUS_INACTIVE
81     })
82     @Retention(RetentionPolicy.SOURCE)
83     public @interface Status {}
84 
85     /* Turn Types */
86     /** Turn is of an unknown type.*/
87     public static final int TURN_UNKNOWN = 0;
88     /** Starting point of the navigation. */
89     public static final int TURN_DEPART = 1;
90     /** No turn, but the street name changes. */
91     public static final int TURN_NAME_CHANGE = 2;
92     /** Slight turn. */
93     public static final int TURN_SLIGHT_TURN = 3;
94     /** Regular turn. */
95     public static final int TURN_TURN = 4;
96     /** Sharp turn. */
97     public static final int TURN_SHARP_TURN = 5;
98     /** U-turn. */
99     public static final int TURN_U_TURN = 6;
100     /** On ramp. */
101     public static final int TURN_ON_RAMP = 7;
102     /** Off ramp. */
103     public static final int TURN_OFF_RAMP = 8;
104     /** Road forks (diverges). */
105     public static final int TURN_FORK = 9;
106     /** Road merges. */
107     public static final int TURN_MERGE = 10;
108     /** Roundabout entrance on which the route ends. Instruction says "Enter roundabout". */
109     public static final int TURN_ROUNDABOUT_ENTER = 11;
110     /** Roundabout exit. */
111     public static final int TURN_ROUNDABOUT_EXIT = 12;
112     /**
113      * Roundabout entrance and exit. For example, "At the roundabout, take Nth exit." Be sure to
114      * specify the "turnNumber" parameter when using this type.
115      */
116     public static final int TURN_ROUNDABOUT_ENTER_AND_EXIT = 13;
117     /** Potentially confusing intersection where the user should steer straight. */
118     public static final int TURN_STRAIGHT = 14;
119     /** You're on a boat! */
120     public static final int TURN_FERRY_BOAT = 16;
121     /** Train ferries for vehicles. */
122     public static final int TURN_FERRY_TRAIN = 17;
123     /** You have arrived. */
124     public static final int TURN_DESTINATION = 19;
125 
126     /** @hide */
127     @IntDef({
128         TURN_UNKNOWN,
129         TURN_DEPART,
130         TURN_NAME_CHANGE,
131         TURN_SLIGHT_TURN,
132         TURN_TURN,
133         TURN_SHARP_TURN,
134         TURN_U_TURN,
135         TURN_ON_RAMP,
136         TURN_OFF_RAMP,
137         TURN_FORK,
138         TURN_MERGE,
139         TURN_ROUNDABOUT_ENTER,
140         TURN_ROUNDABOUT_EXIT,
141         TURN_ROUNDABOUT_ENTER_AND_EXIT,
142         TURN_STRAIGHT,
143         TURN_FERRY_BOAT,
144         TURN_FERRY_TRAIN,
145         TURN_DESTINATION
146     })
147     @Retention(RetentionPolicy.SOURCE)
148     public @interface TurnEvent {}
149 
150     /* Turn Side */
151     /** Turn is on the left side of the vehicle. */
152     public static final int TURN_SIDE_LEFT = 1;
153     /** Turn is on the right side of the vehicle. */
154     public static final int TURN_SIDE_RIGHT = 2;
155     /** Turn side is unspecified. */
156     public static final int TURN_SIDE_UNSPECIFIED = 3;
157 
158     /** @hide */
159     @IntDef({
160         TURN_SIDE_LEFT,
161         TURN_SIDE_RIGHT,
162         TURN_SIDE_UNSPECIFIED
163     })
164     public @interface TurnSide {}
165 
166     /*
167      * Distance units for use in {@link #sendNavigationTurnDistanceEvent(int, int, int, int)}.
168      */
169     /** Distance is specified in meters. */
170     public static final int DISTANCE_METERS = 1;
171     /** Distance is specified in kilometers. */
172     public static final int DISTANCE_KILOMETERS = 2;
173     /** Distance is specified in miles. */
174     public static final int DISTANCE_MILES = 3;
175     /** Distance is specified in feet. */
176     public static final int DISTANCE_FEET = 4;
177     /** Distance is specified in yards. */
178     public static final int DISTANCE_YARDS = 5;
179 
180     /** @hide */
181     @IntDef({
182         DISTANCE_METERS,
183         DISTANCE_KILOMETERS,
184         DISTANCE_MILES,
185         DISTANCE_FEET,
186         DISTANCE_YARDS
187     })
188     public @interface DistanceUnit {}
189 
190     /**
191      * Inform the instrument cluster if navigation is active or not.
192      * @param status New instrument cluster navigation status, one of the STATUS_* constants in
193      * this class.
194      * @throws CarNotConnectedException if the connection to the car service has been lost.
195      */
sendNavigationStatus(@tatus int status)196     public abstract void sendNavigationStatus(@Status int status) throws CarNotConnectedException;
197 
198     /**
199      * Send a Navigation Next Step event to the car.
200      * <p/>
201      * Roundabout Example: In a roundabout with four, evenly spaced exits, the
202      * first exit is turnNumber=1, turnAngle=90; the second exit is turnNumber=2,
203      * turnAngle=180; the third exit is turnNumber=3, turnAngle=270. turnNumber and turnAngle are
204      * counted in the direction of travel around the roundabout (clockwise for roads where the car
205      * drives on the left side of the road, such as Australia; counter-clockwise for roads
206      * where the car drives on the right side of the road, such as the USA).
207      *
208      * @param turnEvent Turn event type ({@link #TURN_TURN}, {@link #TURN_U_TURN}, {@link
209      * #TURN_ROUNDABOUT_ENTER_AND_EXIT}, etc).
210      * @param eventName Name of the turn event like road name to turn. For example "Charleston road"
211      *        in "Turn right to Charleston road"
212      * @param turnAngle Turn angle in degrees between the roundabout entry and exit (0..359). Used
213      * only for event type {@link #TURN_ROUNDABOUT_ENTER_AND_EXIT}. -1 if unused.
214      * @param turnNumber Turn number, counting from the roundabout entry to the exit. Used only
215      * for event type {@link #TURN_ROUNDABOUT_ENTER_AND_EXIT}. -1 if unused.
216      * @param turnSide Turn side ({@link #TURN_SIDE_LEFT}, {@link #TURN_SIDE_RIGHT} or {@link
217      * #TURN_SIDE_UNSPECIFIED}).
218      * @throws CarNotConnectedException if the connection to the car service has been lost.
219      */
sendNavigationTurnEvent(@urnEvent int turnEvent, CharSequence eventName, int turnAngle, int turnNumber, @TurnSide int turnSide)220     public abstract void sendNavigationTurnEvent(@TurnEvent int turnEvent, CharSequence eventName,
221             int turnAngle, int turnNumber, @TurnSide int turnSide) throws CarNotConnectedException;
222 
223     /**
224      * Same as the public version ({@link #sendNavigationTurnEvent(int, CharSequence, int, int,
225      * Bitmap, int)}) except a custom image can be sent to the cluster. See documentation for that
226      * method.
227      *
228      * @param image image to be shown in the instrument cluster. Null if instrument cluster type is
229      * {@link CarNavigationInstrumentCluster.ClusterType#CLUSTER_TYPE_IMAGE_CODES_ONLY}, or if
230      * the image parameters are malformed (length or width non-positive, or illegal
231      * imageColorDepthBits) in the initial NavigationStatusService call.
232      *
233      * @hide only first party applications may send a custom image to the cluster.
234      */
sendNavigationTurnEvent(@urnEvent int turnEvent, CharSequence eventName, int turnAngle, int turnNumber, Bitmap image, @TurnSide int turnSide)235     public abstract void sendNavigationTurnEvent(@TurnEvent int turnEvent, CharSequence eventName,
236             int turnAngle, int turnNumber, Bitmap image, @TurnSide int turnSide)
237                     throws CarNotConnectedException;
238 
239     /**
240      * Send a Navigation Next Step Distance event to the car.
241      *
242      * @param distanceMeters Distance to next event in meters.
243      * @param timeSeconds Time to next event in seconds.
244      * @param displayDistanceMillis Distance to the next event formatted as it will be displayed by
245      * the calling app, in milli-units. For example, 1.25 should be supplied as 1250.
246      * @param displayDistanceUnit Unit type to use on of the DISTANCE_* types defined in this
247      * file.
248      * @return Returns {@code true} if successful.
249      * @throws CarNotConnectedException if the connection to the car service has been lost.
250      */
sendNavigationTurnDistanceEvent(int distanceMeters, int timeSeconds, int displayDistanceMillis, int displayDistanceUnit)251     public abstract void sendNavigationTurnDistanceEvent(int distanceMeters, int timeSeconds,
252             int displayDistanceMillis, int displayDistanceUnit) throws CarNotConnectedException;
253 
254     /**
255      * @param callback {@link CarNavigationCallback} to be registered, replacing any existing
256      * listeners.
257      * @throws CarNotConnectedException if the connection to the car service has been lost.
258      */
addListener(CarNavigationCallback callback)259     public abstract void addListener(CarNavigationCallback callback)
260             throws CarNotConnectedException;
261 
262     /**
263      * Unregister the {@link CarNavigationCallback} associated with this instance.
264      */
removeListener()265     public abstract void removeListener();
266 }
267