public final class

Maneuver

extends java.lang.Object

 java.lang.Object

↳androidx.car.app.navigation.model.Maneuver

Gradle dependencies

compile group: 'androidx.car.app', name: 'app', version: '1.2.0-rc01'

  • groupId: androidx.car.app
  • artifactId: app
  • version: 1.2.0-rc01

Artifact androidx.car.app:app:1.2.0-rc01 it located at Google repository (https://maven.google.com/)

Overview

Information about a maneuver that the driver will be required to perform.

Summary

Fields
public static final intTYPE_DEPART

Starting point of the navigation.

public static final intTYPE_DESTINATION

Arrival at a destination.

public static final intTYPE_DESTINATION_LEFT

Arrival to a destination located to the left side of the road.

public static final intTYPE_DESTINATION_RIGHT

Arrival to a destination located to the right side of the road.

public static final intTYPE_DESTINATION_STRAIGHT

Arrival to a destination located straight ahead.

public static final intTYPE_FERRY_BOAT

Drive towards a boat ferry for vehicles, where the entrance is straight ahead or in an unknown direction.

public static final intTYPE_FERRY_BOAT_LEFT

Drive towards a boat ferry for vehicles, where the entrance is to the left.

public static final intTYPE_FERRY_BOAT_RIGHT

Drive towards a boat ferry for vehicles, where the entrance is to the right.

public static final intTYPE_FERRY_TRAIN

Drive towards a train ferry for vehicles (e.g.

public static final intTYPE_FERRY_TRAIN_LEFT

Drive towards a train ferry for vehicles (e.g.

public static final intTYPE_FERRY_TRAIN_RIGHT

Drive towards a train ferry for vehicles (e.g.

public static final intTYPE_FORK_LEFT

Keep to the left as the road diverges.

public static final intTYPE_FORK_RIGHT

Keep to the right as the road diverges.

public static final intTYPE_KEEP_LEFT

No turn, from 0 (included) to 10 (excluded) degrees.

public static final intTYPE_KEEP_RIGHT

No turn, from 0 (included) to 10 (excluded) degrees.

public static final intTYPE_MERGE_LEFT

Current road joins another on the left.

public static final intTYPE_MERGE_RIGHT

Current road joins another on the right.

public static final intTYPE_MERGE_SIDE_UNSPECIFIED

Current road joins another without direction specified.

public static final intTYPE_NAME_CHANGE

No turn, but the street name changes.

public static final intTYPE_OFF_RAMP_NORMAL_LEFT

A left turn to exit a turnpike or freeway, from 45 (included) to 135 (excluded) degrees.

public static final intTYPE_OFF_RAMP_NORMAL_RIGHT

A left right to exit a turnpike or freeway, from 45 (included) to 135 (excluded) degrees.

public static final intTYPE_OFF_RAMP_SLIGHT_LEFT

A left turn to exit a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.

public static final intTYPE_OFF_RAMP_SLIGHT_RIGHT

A right turn to exit a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.

public static final intTYPE_ON_RAMP_NORMAL_LEFT

Regular left turn to enter a turnpike or freeway, from 45 (included) to 135 (excluded) degrees.

public static final intTYPE_ON_RAMP_NORMAL_RIGHT

Regular right turn to enter a turnpike or freeway, from 45 (included) to 135 (excluded) degrees.

public static final intTYPE_ON_RAMP_SHARP_LEFT

Sharp left turn to enter a turnpike or freeway, from 135 (included) to 175 (excluded) degrees.

public static final intTYPE_ON_RAMP_SHARP_RIGHT

Sharp right turn to enter a turnpike or freeway, from 135 (included) to 175 (excluded) degrees.

public static final intTYPE_ON_RAMP_SLIGHT_LEFT

Slight left turn to enter a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.

public static final intTYPE_ON_RAMP_SLIGHT_RIGHT

Slight right turn to enter a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.

public static final intTYPE_ON_RAMP_U_TURN_LEFT

Left turn onto the opposite side of the same street to enter a turnpike or freeway, from 175 (included) to 180 (included).

public static final intTYPE_ON_RAMP_U_TURN_RIGHT

Right turn onto the opposite side of the same street to enter a turnpike or freeway, from 175 (included) to 180 (included).

public static final intTYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW

Enter a counter-clockwise roundabout and take the Nth exit.

public static final intTYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE

Enter a counter-clockwise roundabout and take the Nth exit after angle A degrees.

public static final intTYPE_ROUNDABOUT_ENTER_AND_EXIT_CW

Enter a clockwise roundabout and take the Nth exit.

public static final intTYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE

Enter a clockwise roundabout and take the Nth exit after angle A degrees.

public static final intTYPE_ROUNDABOUT_ENTER_CCW

Entrance to a counter-clockwise roundabout on which the current road ends.

public static final intTYPE_ROUNDABOUT_ENTER_CW

Entrance to a clockwise roundabout on which the current road ends.

public static final intTYPE_ROUNDABOUT_EXIT_CCW

Used when leaving a counter-clockwise roundabout when the step starts in it.

public static final intTYPE_ROUNDABOUT_EXIT_CW

Used when leaving a clockwise roundabout when the step starts in it.

public static final intTYPE_STRAIGHT

Driver should steer straight.

public static final intTYPE_TURN_NORMAL_LEFT

Regular left turn at an intersection, from 45 (included) to 135 (excluded) degrees.

public static final intTYPE_TURN_NORMAL_RIGHT

Regular right turn at an intersection, from 45 (included) to 135 (excluded) degrees.

public static final intTYPE_TURN_SHARP_LEFT

Sharp left turn at an intersection, from 135 (included) to 175 (excluded) degrees.

public static final intTYPE_TURN_SHARP_RIGHT

Sharp right turn at an intersection, from 135 (included) to 175 (excluded) degrees.

public static final intTYPE_TURN_SLIGHT_LEFT

Slight left turn at an intersection, from 10 (included) to 45 (excluded) degrees.

public static final intTYPE_TURN_SLIGHT_RIGHT

Slight right turn at an intersection, from 10 (included) to 45 (excluded) degrees.

public static final intTYPE_U_TURN_LEFT

Left turn onto the opposite side of the same street, from 175 (included) to 180 (included) degrees.

public static final intTYPE_U_TURN_RIGHT

A right turn onto the opposite side of the same street, from 175 (included) to 180 (included) degrees.

public static final intTYPE_UNKNOWN

Maneuver type is unknown, no maneuver information should be displayed.

Methods
public booleanequals(java.lang.Object other)

public CarIcongetIcon()

Returns the icon for the maneuver.

public intgetRoundaboutExitAngle()

Returns the roundabout exit angle in degrees to designate the amount of distance to travel around the roundabout.

public intgetRoundaboutExitNumber()

Returns the roundabout exit number, starting from 1 to designate the first exit after joining the roundabout, and increasing in circulation order.

public intgetType()

Returns the maneuver type.

public inthashCode()

public java.lang.StringtoString()

from java.lang.Objectclone, finalize, getClass, notify, notifyAll, wait, wait, wait

Fields

public static final int TYPE_UNKNOWN

Maneuver type is unknown, no maneuver information should be displayed.

This type may be interpreted differently depending on the consumer. In some cases the previous maneuver will continue to be shown while in others no maneuver will be shown at all.

public static final int TYPE_DEPART

Starting point of the navigation.

For example, "Start driving on Main St."

public static final int TYPE_NAME_CHANGE

No turn, but the street name changes.

For example, "Continue on Main St."

public static final int TYPE_KEEP_LEFT

No turn, from 0 (included) to 10 (excluded) degrees.

This is used in contrast to Maneuver.TYPE_STRAIGHT for disambiguating cases where there is more than one option to go into the same general direction.

public static final int TYPE_KEEP_RIGHT

No turn, from 0 (included) to 10 (excluded) degrees.

This is used in contrast to Maneuver.TYPE_STRAIGHT for disambiguating cases where there is more than one option to go into the same general direction.

public static final int TYPE_TURN_SLIGHT_LEFT

Slight left turn at an intersection, from 10 (included) to 45 (excluded) degrees.

public static final int TYPE_TURN_SLIGHT_RIGHT

Slight right turn at an intersection, from 10 (included) to 45 (excluded) degrees.

public static final int TYPE_TURN_NORMAL_LEFT

Regular left turn at an intersection, from 45 (included) to 135 (excluded) degrees.

public static final int TYPE_TURN_NORMAL_RIGHT

Regular right turn at an intersection, from 45 (included) to 135 (excluded) degrees.

public static final int TYPE_TURN_SHARP_LEFT

Sharp left turn at an intersection, from 135 (included) to 175 (excluded) degrees.

public static final int TYPE_TURN_SHARP_RIGHT

Sharp right turn at an intersection, from 135 (included) to 175 (excluded) degrees.

public static final int TYPE_U_TURN_LEFT

Left turn onto the opposite side of the same street, from 175 (included) to 180 (included) degrees.

public static final int TYPE_U_TURN_RIGHT

A right turn onto the opposite side of the same street, from 175 (included) to 180 (included) degrees.

public static final int TYPE_ON_RAMP_SLIGHT_LEFT

Slight left turn to enter a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.

public static final int TYPE_ON_RAMP_SLIGHT_RIGHT

Slight right turn to enter a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.

public static final int TYPE_ON_RAMP_NORMAL_LEFT

Regular left turn to enter a turnpike or freeway, from 45 (included) to 135 (excluded) degrees.

public static final int TYPE_ON_RAMP_NORMAL_RIGHT

Regular right turn to enter a turnpike or freeway, from 45 (included) to 135 (excluded) degrees.

public static final int TYPE_ON_RAMP_SHARP_LEFT

Sharp left turn to enter a turnpike or freeway, from 135 (included) to 175 (excluded) degrees.

public static final int TYPE_ON_RAMP_SHARP_RIGHT

Sharp right turn to enter a turnpike or freeway, from 135 (included) to 175 (excluded) degrees.

public static final int TYPE_ON_RAMP_U_TURN_LEFT

Left turn onto the opposite side of the same street to enter a turnpike or freeway, from 175 (included) to 180 (included).

public static final int TYPE_ON_RAMP_U_TURN_RIGHT

Right turn onto the opposite side of the same street to enter a turnpike or freeway, from 175 (included) to 180 (included).

public static final int TYPE_OFF_RAMP_SLIGHT_LEFT

A left turn to exit a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.

public static final int TYPE_OFF_RAMP_SLIGHT_RIGHT

A right turn to exit a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.

public static final int TYPE_OFF_RAMP_NORMAL_LEFT

A left turn to exit a turnpike or freeway, from 45 (included) to 135 (excluded) degrees.

public static final int TYPE_OFF_RAMP_NORMAL_RIGHT

A left right to exit a turnpike or freeway, from 45 (included) to 135 (excluded) degrees.

public static final int TYPE_FORK_LEFT

Keep to the left as the road diverges.

For example, this is used to indicate "Keep left at the fork".

public static final int TYPE_FORK_RIGHT

Keep to the right as the road diverges.

For example, this is used to indicate "Keep right at the fork".

public static final int TYPE_MERGE_LEFT

Current road joins another on the left.

For example, this is used to indicate "Merge left onto Main St.".

public static final int TYPE_MERGE_RIGHT

Current road joins another on the right.

For example, this is used to indicate "Merge left onto Main St.".

public static final int TYPE_MERGE_SIDE_UNSPECIFIED

Current road joins another without direction specified.

For example, this is used to indicate "Merge onto Main St.".

public static final int TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW

Enter a clockwise roundabout and take the Nth exit.

The exit number must be passed when created the maneuver.

For example, this is used to indicate "At the roundabout, take the Nth exit".

public static final int TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE

Enter a clockwise roundabout and take the Nth exit after angle A degrees.

The exit angle must be passed when creating the maneuver.

For example, this is used to indicate "At the roundabout, take the exit at 135 degrees".

public static final int TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW

Enter a counter-clockwise roundabout and take the Nth exit.

The exit number must be passed when created the maneuver.

For example, this is used to indicate "At the roundabout, take the Nth exit".

public static final int TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE

Enter a counter-clockwise roundabout and take the Nth exit after angle A degrees.

The exit angle must be passed when creating the maneuver.

For example, this is used to indicate "At the roundabout, take a sharp right at 35 degrees".

public static final int TYPE_STRAIGHT

Driver should steer straight.

public static final int TYPE_FERRY_BOAT

Drive towards a boat ferry for vehicles, where the entrance is straight ahead or in an unknown direction.

For example, this is used to indicate "Take the ferry".

public static final int TYPE_FERRY_TRAIN

Drive towards a train ferry for vehicles (e.g. "Take the train"), where the entrance is straight ahead or in an unknown direction.

public static final int TYPE_DESTINATION

Arrival at a destination.

public static final int TYPE_DESTINATION_STRAIGHT

Arrival to a destination located straight ahead.

public static final int TYPE_DESTINATION_LEFT

Arrival to a destination located to the left side of the road.

public static final int TYPE_DESTINATION_RIGHT

Arrival to a destination located to the right side of the road.

public static final int TYPE_ROUNDABOUT_ENTER_CW

Entrance to a clockwise roundabout on which the current road ends.

For example, this is used to indicate "Enter the roundabout".

public static final int TYPE_ROUNDABOUT_EXIT_CW

Used when leaving a clockwise roundabout when the step starts in it.

For example, this is used to indicate "Exit the roundabout".

public static final int TYPE_ROUNDABOUT_ENTER_CCW

Entrance to a counter-clockwise roundabout on which the current road ends.

For example, this is used to indicate "Enter the roundabout".

public static final int TYPE_ROUNDABOUT_EXIT_CCW

Used when leaving a counter-clockwise roundabout when the step starts in it.

For example, this is used to indicate "Exit the roundabout".

public static final int TYPE_FERRY_BOAT_LEFT

Drive towards a boat ferry for vehicles, where the entrance is to the left.

For example, this is used to indicate "Take the ferry".

public static final int TYPE_FERRY_BOAT_RIGHT

Drive towards a boat ferry for vehicles, where the entrance is to the right.

For example, this is used to indicate "Take the ferry".

public static final int TYPE_FERRY_TRAIN_LEFT

Drive towards a train ferry for vehicles (e.g. "Take the train"), where the entrance is to the left.

public static final int TYPE_FERRY_TRAIN_RIGHT

Drive towards a train ferry for vehicles (e.g. "Take the train"), where the entrance is to the right.

Methods

public int getType()

Returns the maneuver type.

Required to be set at all times.

public int getRoundaboutExitNumber()

Returns the roundabout exit number, starting from 1 to designate the first exit after joining the roundabout, and increasing in circulation order. Only relevant if the type is any variation of TYPE_ROUNDABOUT_ENTER_AND_EXIT_*.

For example, if the driver is joining a counter-clockwise roundabout with 4 exits, then the exit to the right would be exit #1, the one straight ahead would be exit #2, the one to the left would be exit #3 and the one used by the driver to join the roundabout would be exit #4.

Required when the type is a roundabout.

public int getRoundaboutExitAngle()

Returns the roundabout exit angle in degrees to designate the amount of distance to travel around the roundabout. Only relevant if the type is Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE or Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE.

For example, if the drive is joining a counter-clockwise roundabout with equally spaced exits then the exit to the right would be at 90 degrees, the one straight ahead would be at 180 degrees, the one to the left would at 270 degrees and the one used by the driver to join the roundabout would be at 360 degrees.

The angle can also be set for irregular roundabouts. For example a roundabout with three exits at 90, 270 and 360 degrees could also have the desired exit angle specified.

Required with the type is a roundabout with an angle.

public CarIcon getIcon()

Returns the icon for the maneuver.

Optional field that when not set may be shown in the target display by a generic image representing the specific maneuver.

public java.lang.String toString()

public int hashCode()

public boolean equals(java.lang.Object other)

Source

/*
 * Copyright 2020 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 androidx.car.app.navigation.model;

import static androidx.annotation.RestrictTo.Scope.LIBRARY;

import static java.util.Objects.requireNonNull;

import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.car.app.annotations.CarProtocol;
import androidx.car.app.model.CarIcon;
import androidx.car.app.model.constraints.CarIconConstraints;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/** Information about a maneuver that the driver will be required to perform. */
// TODO(b/154671667): Update when host(s) updates or a scheme for auto sync is established.
@CarProtocol
public final class Maneuver {
    /**
     * Possible maneuver types.
     *
     * @hide
     */
    @IntDef({
            TYPE_UNKNOWN,
            TYPE_DEPART,
            TYPE_NAME_CHANGE,
            TYPE_KEEP_LEFT,
            TYPE_KEEP_RIGHT,
            TYPE_TURN_SLIGHT_LEFT,
            TYPE_TURN_SLIGHT_RIGHT,
            TYPE_TURN_NORMAL_LEFT,
            TYPE_TURN_NORMAL_RIGHT,
            TYPE_TURN_SHARP_LEFT,
            TYPE_TURN_SHARP_RIGHT,
            TYPE_U_TURN_LEFT,
            TYPE_U_TURN_RIGHT,
            TYPE_ON_RAMP_SLIGHT_LEFT,
            TYPE_ON_RAMP_SLIGHT_RIGHT,
            TYPE_ON_RAMP_NORMAL_LEFT,
            TYPE_ON_RAMP_NORMAL_RIGHT,
            TYPE_ON_RAMP_SHARP_LEFT,
            TYPE_ON_RAMP_SHARP_RIGHT,
            TYPE_ON_RAMP_U_TURN_LEFT,
            TYPE_ON_RAMP_U_TURN_RIGHT,
            TYPE_OFF_RAMP_SLIGHT_LEFT,
            TYPE_OFF_RAMP_SLIGHT_RIGHT,
            TYPE_OFF_RAMP_NORMAL_LEFT,
            TYPE_OFF_RAMP_NORMAL_RIGHT,
            TYPE_FORK_LEFT,
            TYPE_FORK_RIGHT,
            TYPE_MERGE_LEFT,
            TYPE_MERGE_RIGHT,
            TYPE_MERGE_SIDE_UNSPECIFIED,
            TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW,
            TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE,
            TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW,
            TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE,
            TYPE_STRAIGHT,
            TYPE_FERRY_BOAT,
            TYPE_FERRY_TRAIN,
            TYPE_DESTINATION,
            TYPE_DESTINATION_STRAIGHT,
            TYPE_DESTINATION_LEFT,
            TYPE_DESTINATION_RIGHT,
            TYPE_ROUNDABOUT_ENTER_CW,
            TYPE_ROUNDABOUT_EXIT_CW,
            TYPE_ROUNDABOUT_ENTER_CCW,
            TYPE_ROUNDABOUT_EXIT_CCW,
            TYPE_FERRY_BOAT_LEFT,
            TYPE_FERRY_BOAT_RIGHT,
            TYPE_FERRY_TRAIN_LEFT,
            TYPE_FERRY_TRAIN_RIGHT,
    })
    @Retention(RetentionPolicy.SOURCE)
    @RestrictTo(LIBRARY)
    public @interface Type {
    }

    /**
     * Maneuver type is unknown, no maneuver information should be displayed.
     *
     * <p>This type may be interpreted differently depending on the consumer. In some
     * cases the previous maneuver will continue to be shown while in others no maneuver will be
     * shown at all.
     */
    @Type
    public static final int TYPE_UNKNOWN = 0;

    /**
     * Starting point of the navigation.
     *
     * <p>For example, "Start driving on Main St."
     */
    @Type
    public static final int TYPE_DEPART = 1;

    /**
     * No turn, but the street name changes.
     *
     * <p>For example, "Continue on Main St."
     */
    @Type
    public static final int TYPE_NAME_CHANGE = 2;

    /**
     * No turn, from 0 (included) to 10 (excluded) degrees.
     *
     * <p>This is used in contrast to {@link #TYPE_STRAIGHT} for disambiguating cases where there is
     * more than one option to go into the same general direction.
     */
    @Type
    public static final int TYPE_KEEP_LEFT = 3;

    /**
     * No turn, from 0 (included) to 10 (excluded) degrees.
     *
     * <p>This is used in contrast to {@link #TYPE_STRAIGHT} for disambiguating cases where there is
     * more than one option to go into the same general direction.
     */
    @Type
    public static final int TYPE_KEEP_RIGHT = 4;

    /** Slight left turn at an intersection, from 10 (included) to 45 (excluded) degrees. */
    @Type
    public static final int TYPE_TURN_SLIGHT_LEFT = 5;

    /** Slight right turn at an intersection, from 10 (included) to 45 (excluded) degrees. */
    @Type
    public static final int TYPE_TURN_SLIGHT_RIGHT = 6;

    /** Regular left turn at an intersection, from 45 (included) to 135 (excluded) degrees. */
    @Type
    public static final int TYPE_TURN_NORMAL_LEFT = 7;

    /** Regular right turn at an intersection, from 45 (included) to 135 (excluded) degrees. */
    @Type
    public static final int TYPE_TURN_NORMAL_RIGHT = 8;

    /** Sharp left turn at an intersection, from 135 (included) to 175 (excluded) degrees. */
    @Type
    public static final int TYPE_TURN_SHARP_LEFT = 9;

    /** Sharp right turn at an intersection, from 135 (included) to 175 (excluded) degrees. */
    @Type
    public static final int TYPE_TURN_SHARP_RIGHT = 10;

    /**
     * Left turn onto the opposite side of the same street, from 175 (included) to 180 (included)
     * degrees.
     */
    @Type
    public static final int TYPE_U_TURN_LEFT = 11;

    /**
     * A right turn onto the opposite side of the same street, from 175 (included) to 180 (included)
     * degrees.
     */
    @Type
    public static final int TYPE_U_TURN_RIGHT = 12;

    /**
     * Slight left turn to enter a turnpike or freeway, from 10 (included) to 45 (excluded) degrees.
     */
    @Type
    public static final int TYPE_ON_RAMP_SLIGHT_LEFT = 13;

    /**
     * Slight right turn to enter a turnpike or freeway, from 10 (included) to 45 (excluded)
     * degrees.
     */
    @Type
    public static final int TYPE_ON_RAMP_SLIGHT_RIGHT = 14;

    /**
     * Regular left turn to enter a turnpike or freeway, from 45 (included) to 135 (excluded)
     * degrees.
     */
    @Type
    public static final int TYPE_ON_RAMP_NORMAL_LEFT = 15;

    /**
     * Regular right turn to enter a turnpike or freeway, from 45 (included) to 135 (excluded)
     * degrees.
     */
    @Type
    public static final int TYPE_ON_RAMP_NORMAL_RIGHT = 16;

    /**
     * Sharp left turn to enter a turnpike or freeway, from 135 (included) to 175 (excluded)
     * degrees.
     */
    @Type
    public static final int TYPE_ON_RAMP_SHARP_LEFT = 17;

    /**
     * Sharp right turn to enter a turnpike or freeway, from 135 (included) to 175 (excluded)
     * degrees.
     */
    @Type
    public static final int TYPE_ON_RAMP_SHARP_RIGHT = 18;

    /**
     * Left turn onto the opposite side of the same street to enter a turnpike or freeway, from 175
     * (included) to 180 (included).
     */
    @Type
    public static final int TYPE_ON_RAMP_U_TURN_LEFT = 19;

    /**
     * Right turn onto the opposite side of the same street to enter a turnpike or freeway, from 175
     * (included) to 180 (included).
     */
    @Type
    public static final int TYPE_ON_RAMP_U_TURN_RIGHT = 20;

    /** A left turn to exit a turnpike or freeway, from 10 (included) to 45 (excluded) degrees. */
    @Type
    public static final int TYPE_OFF_RAMP_SLIGHT_LEFT = 21;

    /** A right turn to exit a turnpike or freeway, from 10 (included) to 45 (excluded) degrees. */
    @Type
    public static final int TYPE_OFF_RAMP_SLIGHT_RIGHT = 22;

    /** A left turn to exit a turnpike or freeway, from 45 (included) to 135 (excluded) degrees. */
    @Type
    public static final int TYPE_OFF_RAMP_NORMAL_LEFT = 23;

    /** A left right to exit a turnpike or freeway, from 45 (included) to 135 (excluded) degrees. */
    @Type
    public static final int TYPE_OFF_RAMP_NORMAL_RIGHT = 24;

    /**
     * Keep to the left as the road diverges.
     *
     * <p>For example, this is used to indicate "Keep left at the fork".
     */
    @Type
    public static final int TYPE_FORK_LEFT = 25;

    /**
     * Keep to the right as the road diverges.
     *
     * <p>For example, this is used to indicate "Keep right at the fork".
     */
    @Type
    public static final int TYPE_FORK_RIGHT = 26;

    /**
     * Current road joins another on the left.
     *
     * <p>For example, this is used to indicate "Merge left onto Main St.".
     */
    @Type
    public static final int TYPE_MERGE_LEFT = 27;

    /**
     * Current road joins another on the right.
     *
     * <p>For example, this is used to indicate "Merge left onto Main St.".
     */
    @Type
    public static final int TYPE_MERGE_RIGHT = 28;

    /**
     * Current road joins another without direction specified.
     *
     * <p>For example, this is used to indicate "Merge onto Main St.".
     */
    @Type
    public static final int TYPE_MERGE_SIDE_UNSPECIFIED = 29;

    /**
     * Enter a clockwise roundabout and take the Nth exit.
     *
     * <p>The exit number must be passed when created the maneuver.
     *
     * <p>For example, this is used to indicate "At the roundabout, take the Nth exit".
     */
    @Type
    public static final int TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW = 32;

    /**
     * Enter a clockwise roundabout and take the Nth exit after angle A degrees.
     *
     * <p>The exit angle must be passed when creating the maneuver.
     *
     * <p>For example, this is used to indicate "At the roundabout, take the exit at 135 degrees".
     */
    @Type
    public static final int TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE = 33;

    /**
     * Enter a counter-clockwise roundabout and take the Nth exit.
     *
     * <p>The exit number must be passed when created the maneuver.
     *
     * <p>For example, this is used to indicate "At the roundabout, take the Nth exit".
     */
    @Type
    public static final int TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW = 34;

    /**
     * Enter a counter-clockwise roundabout and take the Nth exit after angle A degrees.
     *
     * <p>The exit angle must be passed when creating the maneuver.
     *
     * <p>For example, this is used to indicate "At the roundabout, take a sharp right at 35
     * degrees".
     */
    @Type
    public static final int TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE = 35;

    /** Driver should steer straight. */
    @Type
    public static final int TYPE_STRAIGHT = 36;

    /**
     * Drive towards a boat ferry for vehicles, where the entrance is straight ahead or in an
     * unknown direction.
     *
     * <p>For example, this is used to indicate "Take the ferry".
     */
    @Type
    public static final int TYPE_FERRY_BOAT = 37;

    /**
     * Drive towards a train ferry for vehicles (e.g. "Take the train"), where the entrance is
     * straight ahead or in an unknown direction.
     */
    @Type
    public static final int TYPE_FERRY_TRAIN = 38;

    /** Arrival at a destination. */
    @Type
    public static final int TYPE_DESTINATION = 39;

    /** Arrival to a destination located straight ahead. */
    @Type
    public static final int TYPE_DESTINATION_STRAIGHT = 40;

    /** Arrival to a destination located to the left side of the road. */
    @Type
    public static final int TYPE_DESTINATION_LEFT = 41;

    /** Arrival to a destination located to the right side of the road. */
    @Type
    public static final int TYPE_DESTINATION_RIGHT = 42;

    /**
     * Entrance to a clockwise roundabout on which the current road ends.
     *
     * <p>For example, this is used to indicate "Enter the roundabout".
     */
    @Type
    public static final int TYPE_ROUNDABOUT_ENTER_CW = 43;

    /**
     * Used when leaving a clockwise roundabout when the step starts in it.
     *
     * <p>For example, this is used to indicate "Exit the roundabout".
     */
    @Type
    public static final int TYPE_ROUNDABOUT_EXIT_CW = 44;

    /**
     * Entrance to a counter-clockwise roundabout on which the current road ends.
     *
     * <p>For example, this is used to indicate "Enter the roundabout".
     */
    @Type
    public static final int TYPE_ROUNDABOUT_ENTER_CCW = 45;

    /**
     * Used when leaving a counter-clockwise roundabout when the step starts in it.
     *
     * <p>For example, this is used to indicate "Exit the roundabout".
     */
    @Type
    public static final int TYPE_ROUNDABOUT_EXIT_CCW = 46;

    /**
     * Drive towards a boat ferry for vehicles, where the entrance is to the left.
     *
     * <p>For example, this is used to indicate "Take the ferry".
     */
    @Type
    public static final int TYPE_FERRY_BOAT_LEFT = 47;

    /**
     * Drive towards a boat ferry for vehicles, where the entrance is to the right.
     *
     * <p>For example, this is used to indicate "Take the ferry".
     */
    @Type
    public static final int TYPE_FERRY_BOAT_RIGHT = 48;

    /**
     * Drive towards a train ferry for vehicles (e.g. "Take the train"), where the entrance is to
     * the
     * left.
     */
    @Type
    public static final int TYPE_FERRY_TRAIN_LEFT = 49;

    /**
     * Drive towards a train ferry for vehicles (e.g. "Take the train"), where the entrance is to
     * the
     * right.
     */
    @Type
    public static final int TYPE_FERRY_TRAIN_RIGHT = 50;

    @Keep
    @Type
    private final int mType;
    @Keep
    private final int mRoundaboutExitNumber;
    @Keep
    private final int mRoundaboutExitAngle;
    @Keep
    @Nullable
    private final CarIcon mIcon;

    /**
     * Returns the maneuver type.
     *
     * <p>Required to be set at all times.
     */
    @Type
    public int getType() {
        return mType;
    }

    /**
     * Returns the roundabout exit number, starting from 1 to designate the first exit after joining
     * the roundabout, and increasing in circulation order. Only relevant if the type is any
     * variation of {@code TYPE_ROUNDABOUT_ENTER_AND_EXIT_*}.
     *
     * <p>For example, if the driver is joining a counter-clockwise roundabout with 4 exits, then
     * the exit to the right would be exit #1, the one straight ahead would be exit #2, the one
     * to the left would be exit #3 and the one used by the driver to join the roundabout would
     * be exit #4.
     *
     * <p>Required when the type is a roundabout.
     */
    public int getRoundaboutExitNumber() {
        return mRoundaboutExitNumber;
    }

    /**
     * Returns the roundabout exit angle in degrees to designate the amount of distance to travel
     * around the roundabout. Only relevant if the type is {@link
     * #TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE} or {@link
     * #TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE}.
     *
     * <p>For example, if the drive is joining a counter-clockwise roundabout with equally spaced
     * exits then the exit to the right would be at 90 degrees, the one straight ahead would be
     * at 180 degrees, the one to the left would at 270 degrees and the one used by the driver to
     * join the roundabout would be at 360 degrees.
     *
     * <p>The angle can also be set for irregular roundabouts. For example a roundabout with three
     * exits at 90, 270 and 360 degrees could also have the desired exit angle specified.
     *
     * <p>Required with the type is a roundabout with an angle.
     */
    public int getRoundaboutExitAngle() {
        return mRoundaboutExitAngle;
    }

    /**
     * Returns the icon for the maneuver.
     *
     * <p>Optional field that when not set may be shown in the target display by a generic image
     * representing the specific maneuver.
     */
    @Nullable
    public CarIcon getIcon() {
        return mIcon;
    }

    @Override
    @NonNull
    public String toString() {
        return "[type: "
                + mType
                + ", exit #: "
                + mRoundaboutExitNumber
                + ", exit angle: "
                + mRoundaboutExitAngle
                + ", icon: "
                + mIcon
                + "]";
    }

    @Override
    public int hashCode() {
        return Objects.hash(mType, mRoundaboutExitNumber, mRoundaboutExitAngle, mIcon);
    }

    @Override
    public boolean equals(@Nullable Object other) {
        if (this == other) {
            return true;
        }
        if (!(other instanceof Maneuver)) {
            return false;
        }

        Maneuver otherManeuver = (Maneuver) other;
        return mType == otherManeuver.mType
                && mRoundaboutExitNumber == otherManeuver.mRoundaboutExitNumber
                && mRoundaboutExitAngle == otherManeuver.mRoundaboutExitAngle
                && Objects.equals(mIcon, otherManeuver.mIcon);
    }

    Maneuver(@Type int type, int roundaboutExitNumber, int roundaboutExitAngle,
            @Nullable CarIcon icon) {
        mType = type;
        mRoundaboutExitNumber = roundaboutExitNumber;
        mRoundaboutExitAngle = roundaboutExitAngle;
        CarIconConstraints.DEFAULT.validateOrThrow(icon);
        mIcon = icon;
    }

    /** Constructs an empty instance, used by serialization code. */
    private Maneuver() {
        mType = TYPE_UNKNOWN;
        mRoundaboutExitNumber = 0;
        mRoundaboutExitAngle = 0;
        mIcon = null;
    }

    static boolean isValidType(@Type int type) {
        return (type >= TYPE_UNKNOWN && type <= TYPE_FERRY_TRAIN_RIGHT);
    }

    static boolean isValidTypeWithExitNumber(@Type int type) {
        return (type == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW
                || type == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW
                || type == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE
                || type == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE);
    }

    static boolean isValidTypeWithExitAngle(@Type int type) {
        return (type == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE
                || type == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE);
    }

    static boolean isExitNumberRequired(@Type int type) {
        return (type == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW
                || type == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW);
    }

    /** A builder of {@link Maneuver}. */
    public static final class Builder {
        @Type
        private final int mType;
        private boolean mIsRoundaboutExitNumberSet;
        private int mRoundaboutExitNumber;
        private boolean mIsRoundaboutExitAngleSet;
        private int mRoundaboutExitAngle;
        @Nullable
        private CarIcon mIcon;

        /**
         * Constructs a new instance of a {@link Builder}.
         *
         * <p>The type should be chosen to reflect the closest semantic meaning of the maneuver.
         * In some cases, an exact type match is not possible, but choosing a similar or slightly
         * more general type is preferred. Using {@link #TYPE_UNKNOWN} is allowed, but some head
         * units will not display any information in that case.
         *
         * @param type one of the {@code TYPE_*} static constants defined in this class
         * @throws IllegalArgumentException if {@code type} is not a valid maneuver type
         */
        public Builder(@Type int type) {
            if (!isValidType(type)) {
                throw new IllegalArgumentException("Maneuver must have a valid type");
            }
            mType = type;
        }

        /**
         * Sets an image representing the maneuver.
         *
         * <h4>Icon Sizing Guidance</h4>
         *
         * To minimize scaling artifacts across a wide range of car screens, apps should provide
         * icons targeting a 128 x 128 dp bounding box. If the icon exceeds this maximum size in
         * either one of the dimensions, it will be scaled down to be centered inside the
         * bounding box while preserving its aspect ratio.
         *
         * <p>See {@link CarIcon} for more details related to providing icon and image resources
         * that work with different car screen pixel densities.
         *
         * @throws NullPointerException if {@code icon} is {@code null}
         */
        @NonNull
        public Builder setIcon(@NonNull CarIcon icon) {
            mIcon = requireNonNull(icon);
            return this;
        }

        /**
         * Sets an exit number for roundabout maneuvers.
         *
         * <p>Use for when {@code type} is {@link #TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW}, {@link
         * #TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW},
         * {@link #TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE} or
         * {@link #TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE}. The {@code
         * roundaboutExitNumber} starts from 1 to designate the first exit after joining the
         * roundabout, and increases in circulation order.
         *
         * <p>For example, if the driver is joining a counter-clockwise roundabout with 4 exits,
         * then the exit to the right would be exit #1, the one straight ahead would be exit #2,
         * the one to the left would be exit #3 and the one used by the driver to join the
         * roundabout would be exit #4.
         *
         * @throws IllegalArgumentException if {@code type} does not include a exit number, or
         *                                  if {@code roundaboutExitNumber} is not greater than
         *                                  zero
         */
        @NonNull
        public Builder setRoundaboutExitNumber(@IntRange(from = 1) int roundaboutExitNumber) {
            if (!isValidTypeWithExitNumber(mType)) {
                throw new IllegalArgumentException(
                        "Maneuver does not include roundaboutExitNumber");
            }
            if (roundaboutExitNumber < 1) {
                throw new IllegalArgumentException("Maneuver must include a valid exit number");
            }
            mIsRoundaboutExitNumberSet = true;
            mRoundaboutExitNumber = roundaboutExitNumber;
            return this;
        }

        /**
         * Sets an exit angle for roundabout maneuvers.
         *
         * <p>Use for when {@code type} is {@link #TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE} or
         * {@link #TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE}. The {@code roundaboutExitAngle}
         * represents the degrees traveled in circulation from the entrance to the exit.
         *
         * <p>For example, in a 4 exit example, if all the exits are equally spaced then exit 1
         * would be at 90 degrees, exit 2 at 180, exit 3 at 270 and exit 4 at 360. However if the
         * exits are irregular then a different angle could be provided.
         *
         * @throws IllegalArgumentException if {@code type} does not include a exit angle or if
         *                                  {@code roundaboutExitAngle} is not greater than zero
         *                                  and less than or equal to 360 degrees
         */
        @NonNull
        public Builder setRoundaboutExitAngle(
                @IntRange(from = 1, to = 360) int roundaboutExitAngle) {
            if (!isValidTypeWithExitAngle(mType)) {
                throw new IllegalArgumentException("Maneuver does not include roundaboutExitAngle");
            }
            if (roundaboutExitAngle < 1 || roundaboutExitAngle > 360) {
                throw new IllegalArgumentException("Maneuver must include a valid exit angle");
            }
            mIsRoundaboutExitAngleSet = true;
            mRoundaboutExitAngle = roundaboutExitAngle;
            return this;
        }

        /**
         * Constructs the {@link Maneuver} defined by this builder.
         *
         * @throws IllegalArgumentException if {@code type} includes an exit number and one has
         *                                  not been set, or if it includes an exit angle and one
         *                                  has not been set
         */
        @NonNull
        public Maneuver build() {
            if (isExitNumberRequired(mType) && !mIsRoundaboutExitNumberSet) {
                throw new IllegalArgumentException("Maneuver missing roundaboutExitNumber");
            }
            if (isValidTypeWithExitAngle(mType) && !mIsRoundaboutExitAngleSet) {
                throw new IllegalArgumentException("Maneuver missing roundaboutExitAngle");
            }
            return new Maneuver(mType, mRoundaboutExitNumber, mRoundaboutExitAngle, mIcon);
        }
    }
}