Skip to content

Commit 793d8fd

Browse files
feat: switch android auto screen to use regular navigation view
1 parent 0b1819c commit 793d8fd

1 file changed

Lines changed: 59 additions & 25 deletions

File tree

android/src/main/java/com/google/android/react/navsdk/AndroidAutoBaseScreen.java

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737
import androidx.lifecycle.LifecycleOwner;
3838
import com.facebook.proguard.annotations.DoNotStrip;
3939
import com.facebook.react.bridge.ReadableMap;
40+
import com.facebook.react.bridge.UiThreadUtil;
4041
import com.google.android.gms.maps.CameraUpdate;
4142
import com.google.android.gms.maps.CameraUpdateFactory;
4243
import 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;
4446
import com.google.android.libraries.navigation.StylingOptions;
4547
import 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

Comments
 (0)