3737import androidx .lifecycle .LifecycleOwner ;
3838import com .facebook .proguard .annotations .DoNotStrip ;
3939import com .facebook .react .bridge .ReadableMap ;
40+ import com .facebook .react .bridge .UiThreadUtil ;
4041import com .google .android .gms .maps .CameraUpdate ;
4142import com .google .android .gms .maps .CameraUpdateFactory ;
4243import com .google .android .gms .maps .GoogleMap ;
43- import com .google .android .libraries .navigation .NavigationViewForAuto ;
44+ import com .google .android .gms .maps .GoogleMapOptions ;
45+ import com .google .android .libraries .navigation .NavigationView ;
4446import com .google .android .libraries .navigation .StylingOptions ;
4547import org .json .JSONObject ;
4648
@@ -56,16 +58,17 @@ public abstract class AndroidAutoBaseScreen extends Screen
5658 implements SurfaceCallback , INavigationViewController {
5759 private static final String VIRTUAL_DISPLAY_NAME = "AndroidAutoNavScreen" ;
5860
59- private NavigationViewForAuto mNavigationView ;
61+ private NavigationView mNavigationView ;
6062 private VirtualDisplay mVirtualDisplay ;
6163 private Presentation mPresentation ;
6264 protected GoogleMap mGoogleMap ;
63- protected boolean mNavigationInitialized = false ;
65+ protected volatile boolean mNavigationInitialized = false ;
6466 private MapViewController mMapViewController ;
67+ private boolean mIsSurfaceDestroyed = true ;
6568
6669 private boolean mAndroidAutoModuleInitialized = false ;
6770 private boolean mNavModuleInitialized = false ;
68- private final AndroidAutoBaseScreen screenInstance = this ;
71+ private final NavModule . NavigationReadyListener mNavigationReadyListener = this :: onSessionAttached ;
6972
7073 @ Override
7174 public void setStylingOptions (StylingOptions stylingOptions ) {
@@ -78,26 +81,33 @@ public void setStylingOptions(StylingOptions stylingOptions) {
7881 */
7982 private void onSessionAttached (boolean ready ) {
8083 mNavigationInitialized = ready ;
84+ updateNavigationUiEnabled (ready );
8185 onNavigationReady (ready );
8286 }
8387
88+ private void updateNavigationUiEnabled (boolean ready ) {
89+ UiThreadUtil .runOnUiThread (
90+ () -> {
91+ NavigationView navigationView = mNavigationView ;
92+ if (!mIsSurfaceDestroyed && navigationView != null ) {
93+ navigationView .setNavigationUiEnabled (ready );
94+ }
95+ });
96+ }
97+
8498 /**
8599 * Called when the navigation session state changes. Override this method in your subclass to
86100 * handle navigation ready state changes.
87101 *
88- * <p><b>Note:</b> Navigation UI controls like setHeaderEnabled, setFooterEnabled,
89- * setSpeedometerEnabled, etc. are NOT supported on Android Auto's NavigationViewForAuto. These
90- * controls are automatically managed by the Android Auto navigation template.
102+ * <p>The Android Auto map view disables phone-oriented navigation UI controls so that the
103+ * Android Auto navigation template remains the sole provider of navigation UI.
91104 *
92105 * <p>The navigation state ({@code mNavigationInitialized}) is already updated before this method
93106 * is called.
94107 *
95108 * @param ready true when navigation session is ready, false when it's no longer available.
96109 */
97110 protected void onNavigationReady (boolean ready ) {
98- // NavigationViewForAuto does not support direct UI control settings like
99- // setHeaderEnabled, setFooterEnabled, setTrafficPromptsEnabled, etc.
100- // These are automatically managed by the Android Auto navigation template.
101111 // Override this method in your subclass if you need custom behavior.
102112 }
103113
@@ -115,7 +125,7 @@ public AndroidAutoBaseScreen(@NonNull CarContext carContext) {
115125 () -> {
116126 mNavModuleInitialized = true ;
117127 try {
118- NavModule .getInstance ().registerNavigationReadyListener (this :: onSessionAttached );
128+ NavModule .getInstance ().registerNavigationReadyListener (mNavigationReadyListener );
119129 } catch (IllegalStateException e ) {
120130 // NavModule not yet initialized, will be registered later
121131 }
@@ -134,7 +144,7 @@ public void onDestroy(@NonNull LifecycleOwner lifecycleOwner) {
134144 if (mNavModuleInitialized ) {
135145 try {
136146 NavModule .getInstance ()
137- .unRegisterNavigationReadyListener (screenInstance :: onSessionAttached );
147+ .unRegisterNavigationReadyListener (mNavigationReadyListener );
138148 } catch (Exception e ) {
139149 // Module may have been destroyed, safe to ignore.
140150 }
@@ -175,6 +185,7 @@ public void onSurfaceAvailable(@NonNull SurfaceContainer surfaceContainer) {
175185 if (!isSurfaceReady (surfaceContainer )) {
176186 return ;
177187 }
188+ mIsSurfaceDestroyed = false ;
178189 mVirtualDisplay =
179190 getCarContext ()
180191 .getSystemService (DisplayManager .class )
@@ -187,16 +198,31 @@ public void onSurfaceAvailable(@NonNull SurfaceContainer surfaceContainer) {
187198 DisplayManager .VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY );
188199 mPresentation = new Presentation (getCarContext (), mVirtualDisplay .getDisplay ());
189200
190- mNavigationView = new NavigationViewForAuto (getCarContext ());
201+ GoogleMapOptions googleMapOptions = new GoogleMapOptions ().compassEnabled (false );
202+ mNavigationView = new NavigationView (getCarContext (), googleMapOptions );
191203 mNavigationView .onCreate (null );
192204 mNavigationView .onStart ();
193205 mNavigationView .onResume ();
206+ mNavigationView .setHeaderEnabled (false );
207+ mNavigationView .setRecenterButtonEnabled (false );
208+ mNavigationView .setEtaCardEnabled (false );
209+ mNavigationView .setSpeedometerEnabled (false );
210+ mNavigationView .setTripProgressBarEnabled (false );
211+ mNavigationView .setReportIncidentButtonEnabled (false );
212+ mNavigationView .setNavigationUiEnabled (mNavigationInitialized );
194213
195214 mPresentation .setContentView (mNavigationView );
196215 mPresentation .show ();
197216
198- mNavigationView .getMapAsync (
217+ NavigationView navigationView = mNavigationView ;
218+ navigationView .getMapAsync (
199219 (GoogleMap googleMap ) -> {
220+ if (mIsSurfaceDestroyed || navigationView != mNavigationView ) {
221+ return ;
222+ }
223+
224+ googleMap .getUiSettings ().setIndoorLevelPickerEnabled (false );
225+ googleMap .getUiSettings ().setMyLocationButtonEnabled (false );
200226 mGoogleMap = googleMap ;
201227 mMapViewController = new MapViewController ();
202228 mMapViewController .initialize (googleMap , () -> null );
@@ -210,27 +236,35 @@ public void onSurfaceAvailable(@NonNull SurfaceContainer surfaceContainer) {
210236 * Called when the map view has been loaded and is ready. Override this method in your subclass to
211237 * configure map settings.
212238 *
213- * <p><b>Note:</b> Navigation UI controls like setSpeedometerEnabled, setSpeedLimitIconEnabled,
214- * etc. are NOT supported on Android Auto's NavigationViewForAuto. These controls are
215- * automatically managed by the Android Auto navigation template.
239+ * <p>Phone-oriented navigation UI controls are disabled on the map view to avoid overlapping
240+ * the Android Auto navigation template.
216241 */
217242 protected void onMapViewReady () {
218- // NavigationViewForAuto does not support direct UI control settings like
219- // setSpeedometerEnabled, setSpeedLimitIconEnabled, etc.
220- // These are automatically managed by the Android Auto navigation template.
221243 // Override this method in your subclass if you need custom behavior.
222244 }
223245
224246 @ Override
225247 public void onSurfaceDestroyed (@ NonNull SurfaceContainer surfaceContainer ) {
248+ mIsSurfaceDestroyed = true ;
226249 unRegisterControllersForAndroidAutoModule ();
227- mNavigationView .onPause ();
228- mNavigationView .onStop ();
229- mNavigationView .onDestroy ();
250+ mMapViewController = null ;
251+
252+ if (mNavigationView != null ) {
253+ mNavigationView .onPause ();
254+ mNavigationView .onStop ();
255+ mNavigationView .onDestroy ();
256+ mNavigationView = null ;
257+ }
230258 mGoogleMap = null ;
231259
232- mPresentation .dismiss ();
233- mVirtualDisplay .release ();
260+ if (mPresentation != null ) {
261+ mPresentation .dismiss ();
262+ mPresentation = null ;
263+ }
264+ if (mVirtualDisplay != null ) {
265+ mVirtualDisplay .release ();
266+ mVirtualDisplay = null ;
267+ }
234268 }
235269
236270 @ Override
0 commit comments