<commit_before>/* Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.
 */
// Copyright 2020 Google LLC
//
// 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 com.google.mapsplatform.transportation.sample;

import static com.google.mapsplatform.transportation.sample.state.AppStates.INITIALIZED;
import static com.google.mapsplatform.transportation.sample.state.AppStates.JOURNEY_SHARING;
import static com.google.mapsplatform.transportation.sample.state.AppStates.SELECTING_DROPOFF;
import static com.google.mapsplatform.transportation.sample.state.AppStates.SELECTING_PICKUP;
import static com.google.mapsplatform.transportation.sample.state.AppStates.UNINITIALIZED;
import static java.util.Objects.requireNonNull;

import android.Manifest.permission;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.lifecycle.ViewModelProviders;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.tasks.Task;
import com.google.android.libraries.mapsplatform.transportation.consumer.ConsumerApi;
import com.google.android.libraries.mapsplatform.transportation.consumer.auth.AuthTokenContext;
import com.google.android.libraries.mapsplatform.transportation.consumer.auth.AuthTokenFactory;
import com.google.android.libraries.mapsplatform.transportation.consumer.managers.TripModel;
import com.google.android.libraries.mapsplatform.transportation.consumer.managers.TripModelManager;
import com.google.android.libraries.mapsplatform.transportation.consumer.model.TerminalLocation;
import com.google.android.libraries.mapsplatform.transportation.consumer.model.Trip.TripStatus;
import com.google.android.libraries.mapsplatform.transportation.consumer.model.TripInfo;
import com.google.android.libraries.mapsplatform.transportation.consumer.sessions.JourneySharingSession;
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerController;
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerGoogleMap;
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerGoogleMap.ConsumerMapReadyCallback;
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapView;
import com.google.mapsplatform.transportation.sample.provider.ProviderUtils;
import com.google.mapsplatform.transportation.sample.provider.model.TripData;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;

/** Main activity for the sample application. */
public class SampleAppActivity extends AppCompatActivity implements ConsumerViewModel.JourneySharingListener {

  private static final String TAG = "SampleAppActivity";

  private static final long MINUTE_IN_MILLIS = 1000 * 60;
  private static final int REQUEST_LOCATION_PERMISSION_CODE = 99;
  /** Default zoom of initial map state. */
  private static final int DEFAULT_ZOOM = 16;
  /** Default Map location if failed to receive FLP location. Defaulted to Google MTV. */
  private static final LatLng DEFAULT_MAP_LOCATION = new LatLng(37.423061, -122.084051);

  // The current journey sharing trip status.
  private TextView tripStatusView;
  // Displays the users trip id.
  private TextView tripIdView;
  // Displays the users vehicle id.
  private TextView vehicleIdView;
  // Indicates the Eta to the next waypoint in minutes.
  private TextView etaView;
  // Indicates the remaining distance to the next waypoint.
  private TextView remainingDistanceView;
  // Indicates the cost of the route.
  private TextView customRouteCostView;
  // The ridesharing map.
  private ConsumerMapView consumerMapView;
  // Request trip button to send a request to provider.
  private Button requestTripButton;
  // Dropoff pin in the center of the map.
  private View dropoffPin;
  // Pickup pin in the center of the map.
  private View pickupPin;
  // The reference to the map that is being displayed.
  @MonotonicNonNull private ConsumerGoogleMap googleMap;
  // The last location of the device.
  @Nullable private LatLng lastLocation;
  // Map of markers on google map to indicate pickup and dropoff.
  private final Map<Integer, Marker> mapMarkers = new HashMap<>();

  // ViewModel for the consumer sample app.
  private ConsumerViewModel consumerViewModel;

  @MonotonicNonNull private TripModelManager consumerTripManager;
  @MonotonicNonNull private ConsumerController consumerController;

  // Session monitoring the current active trip.
  @Nullable private JourneySharingSession journeySharingSession;

  @MonotonicNonNull private String consumerToken;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    initViews();

    // Get the ViewModel.
    consumerViewModel = ViewModelProviders.of(this).get(ConsumerViewModel.class);
    consumerViewModel.setJourneySharingListener(this);

    showStartupLocation();

    // If the permission is granted, then continue to initialize. Otherwise wait until
    // the permission is granted in onRequestPermissionResult().
    if (hasRequiredPermissions()) {
      initializeSdk();
    } else {
      // Permissions are granted, initialize the application.
      ActivityCompat.requestPermissions(
          this, new String[] {permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION_CODE);
    }
  }

  /**
   * Start the asynchronous call to get the map api and subsequently the consumer controller. The
   * ConsumerGoogleMap is returned, is used to access the ConsumerController. Observers are created
   * that update the UI based on observed trip data.
   */
  private void initializeSdk() {
    consumerMapView.getConsumerGoogleMapAsync(
        new ConsumerMapReadyCallback() {
          @Override
          public void onConsumerMapReady(ConsumerGoogleMap consumerGoogleMap) {
            // Safe to do so as controller will only be nullified during consumerMap's onDestroy()
            consumerController = requireNonNull(consumerGoogleMap.getConsumerController());
            Task<ConsumerApi> consumerApiTask =
                ConsumerApi.initialize(
                    SampleAppActivity.this,
                    ProviderUtils.getProviderId(SampleAppActivity.this),
                    new TripAuthTokenFactory());
            consumerApiTask.addOnSuccessListener(
                consumerApi ->
                    consumerTripManager = requireNonNull(consumerApi.getTripModelManager()));
            consumerApiTask.addOnFailureListener(
                task -> Log.e(TAG, "ConsumerApi Initialization Error:\n" + task.getMessage()));
            ConsumerMarkerUtils.setCustomMarkers(
                requireNonNull(consumerController), SampleAppActivity.this);
            setupViewBindings();
            googleMap = consumerGoogleMap;
            centerCamera();
            setupMapListener();
          }
        },
        /* fragmentActivity= */ this,
        /* googleMapOptions= */ null);
  }

  @Override
  public TripModel startJourneySharing(TripData tripData) {
    consumerToken = tripData.token();
    TripModel trip = requireNonNull(consumerTripManager).getTripModel(tripData.tripName());
    journeySharingSession = JourneySharingSession.createInstance(trip);
    requireNonNull(consumerController).showSession(journeySharingSession);
    return trip;
  }

  @Override
  public void stopJourneySharing() {
    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
    journeySharingSession = null;
    requireNonNull(consumerController).hideAllSessions();
  }

  /** Center the camera to the last location of the device. */
  private void centerCamera() {
    if (lastLocation != null) {
      requireNonNull(googleMap)
          .moveCamera(CameraUpdateFactory.newLatLngZoom(lastLocation, DEFAULT_ZOOM));
    }
  }

  @Override
  public void updateCurrentLocation(LatLng latLang) {
    lastLocation = latLang;
  }

  @SuppressLint("MissingPermission")
  private void showStartupLocation() {
    FusedLocationProviderClient fusedLocationProviderClient =
        LocationServices.getFusedLocationProviderClient(this);
    fusedLocationProviderClient
        .getLastLocation()
        .addOnCompleteListener(
            task -> {
              if (task.isSuccessful() && task.getResult() != null) {
                Location location = task.getResult();
                lastLocation = new LatLng(location.getLatitude(), location.getLongitude());
              } else {
                lastLocation = DEFAULT_MAP_LOCATION;
              }
              centerCamera();
            });
  }

  /** Setting up map idle listeners to select pickup and dropoff locations. */
  private void setupMapListener() {
    requireNonNull(googleMap)
        .setOnCameraIdleListener(
            () -> {
              CameraPosition cameraPosition = requireNonNull(googleMap).getCameraPosition();
              if (cameraPosition == null) {
                return;
              }
              int state = consumerViewModel.getAppState().getValue();
              LatLng cameraLocation = cameraPosition.target;
              if (state == SELECTING_DROPOFF) {
                consumerViewModel.setDropoffLocation(cameraLocation);
                updateMarker(
                    ConsumerMarkerType.DROPOFF_POINT,
                    TerminalLocation.builder(cameraLocation).build());
              } else if (state == SELECTING_PICKUP) {
                consumerViewModel.setPickupLocation(cameraLocation);
                updateMarker(
                    ConsumerMarkerType.PICKUP_POINT,
                    TerminalLocation.builder(cameraLocation).build());
                consumerViewModel.getCustomRouteCost();
              }
            });
  }

  /** Update marker on the map based on camera location. */
  private void updateMarker(@ConsumerMarkerType Integer markerType, TerminalLocation location) {<commit_msg>Fix consumer sample app crash on first launch<commit_after>/* Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.
 */
// Copyright 2020 Google LLC
//
// 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 com.google.mapsplatform.transportation.sample;

import static com.google.mapsplatform.transportation.sample.state.AppStates.INITIALIZED;
import static com.google.mapsplatform.transportation.sample.state.AppStates.JOURNEY_SHARING;
import static com.google.mapsplatform.transportation.sample.state.AppStates.SELECTING_DROPOFF;
import static com.google.mapsplatform.transportation.sample.state.AppStates.SELECTING_PICKUP;
import static com.google.mapsplatform.transportation.sample.state.AppStates.UNINITIALIZED;
import static java.util.Objects.requireNonNull;

import android.Manifest.permission;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.lifecycle.ViewModelProviders;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.tasks.Task;
import com.google.android.libraries.mapsplatform.transportation.consumer.ConsumerApi;
import com.google.android.libraries.mapsplatform.transportation.consumer.auth.AuthTokenContext;
import com.google.android.libraries.mapsplatform.transportation.consumer.auth.AuthTokenFactory;
import com.google.android.libraries.mapsplatform.transportation.consumer.managers.TripModel;
import com.google.android.libraries.mapsplatform.transportation.consumer.managers.TripModelManager;
import com.google.android.libraries.mapsplatform.transportation.consumer.model.TerminalLocation;
import com.google.android.libraries.mapsplatform.transportation.consumer.model.Trip.TripStatus;
import com.google.android.libraries.mapsplatform.transportation.consumer.model.TripInfo;
import com.google.android.libraries.mapsplatform.transportation.consumer.sessions.JourneySharingSession;
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerController;
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerGoogleMap;
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerGoogleMap.ConsumerMapReadyCallback;
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapView;
import com.google.mapsplatform.transportation.sample.provider.ProviderUtils;
import com.google.mapsplatform.transportation.sample.provider.model.TripData;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;

/** Main activity for the sample application. */
public class SampleAppActivity extends AppCompatActivity implements ConsumerViewModel.JourneySharingListener {

  private static final String TAG = "SampleAppActivity";

  private static final long MINUTE_IN_MILLIS = 1000 * 60;
  private static final int REQUEST_LOCATION_PERMISSION_CODE = 99;
  /** Default zoom of initial map state. */
  private static final int DEFAULT_ZOOM = 16;
  /** Default Map location if failed to receive FLP location. Defaulted to Google MTV. */
  private static final LatLng DEFAULT_MAP_LOCATION = new LatLng(37.423061, -122.084051);

  // The current journey sharing trip status.
  private TextView tripStatusView;
  // Displays the users trip id.
  private TextView tripIdView;
  // Displays the users vehicle id.
  private TextView vehicleIdView;
  // Indicates the Eta to the next waypoint in minutes.
  private TextView etaView;
  // Indicates the remaining distance to the next waypoint.
  private TextView remainingDistanceView;
  // Indicates the cost of the route.
  private TextView customRouteCostView;
  // The ridesharing map.
  private ConsumerMapView consumerMapView;
  // Request trip button to send a request to provider.
  private Button requestTripButton;
  // Dropoff pin in the center of the map.
  private View dropoffPin;
  // Pickup pin in the center of the map.
  private View pickupPin;
  // The reference to the map that is being displayed.
  @MonotonicNonNull private ConsumerGoogleMap googleMap;
  // The last location of the device.
  @Nullable private LatLng lastLocation;
  // Map of markers on google map to indicate pickup and dropoff.
  private final Map<Integer, Marker> mapMarkers = new HashMap<>();

  // ViewModel for the consumer sample app.
  private ConsumerViewModel consumerViewModel;

  @MonotonicNonNull private TripModelManager consumerTripManager;
  @MonotonicNonNull private ConsumerController consumerController;

  // Session monitoring the current active trip.
  @Nullable private JourneySharingSession journeySharingSession;

  @MonotonicNonNull private String consumerToken;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    initViews();

    // Get the ViewModel.
    consumerViewModel = ViewModelProviders.of(this).get(ConsumerViewModel.class);
    consumerViewModel.setJourneySharingListener(this);

    // If the permission is granted, then continue to initialize. Otherwise wait until
    // the permission is granted in onRequestPermissionResult().
    if (hasRequiredPermissions()) {
      initializeSdk();
    } else {
      // Permissions are granted, initialize the application.
      ActivityCompat.requestPermissions(
          this, new String[] {permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION_CODE);
    }
  }

  /**
   * Start the asynchronous call to get the map api and subsequently the consumer controller. The
   * ConsumerGoogleMap is returned, is used to access the ConsumerController. Observers are created
   * that update the UI based on observed trip data.
   */
  private void initializeSdk() {
    showStartupLocation();

    consumerMapView.getConsumerGoogleMapAsync(
        new ConsumerMapReadyCallback() {
          @Override
          public void onConsumerMapReady(ConsumerGoogleMap consumerGoogleMap) {
            // Safe to do so as controller will only be nullified during consumerMap's onDestroy()
            consumerController = requireNonNull(consumerGoogleMap.getConsumerController());
            Task<ConsumerApi> consumerApiTask =
                ConsumerApi.initialize(
                    SampleAppActivity.this,
                    ProviderUtils.getProviderId(SampleAppActivity.this),
                    new TripAuthTokenFactory());
            consumerApiTask.addOnSuccessListener(
                consumerApi ->
                    consumerTripManager = requireNonNull(consumerApi.getTripModelManager()));
            consumerApiTask.addOnFailureListener(
                task -> Log.e(TAG, "ConsumerApi Initialization Error:\n" + task.getMessage()));
            ConsumerMarkerUtils.setCustomMarkers(
                requireNonNull(consumerController), SampleAppActivity.this);
            setupViewBindings();
            googleMap = consumerGoogleMap;
            centerCamera();
            setupMapListener();
          }
        },
        /* fragmentActivity= */ this,
        /* googleMapOptions= */ null);
  }

  @Override
  public TripModel startJourneySharing(TripData tripData) {
    consumerToken = tripData.token();
    TripModel trip = requireNonNull(consumerTripManager).getTripModel(tripData.tripName());
    journeySharingSession = JourneySharingSession.createInstance(trip);
    requireNonNull(consumerController).showSession(journeySharingSession);
    return trip;
  }

  @Override
  public void stopJourneySharing() {
    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
    journeySharingSession = null;
    requireNonNull(consumerController).hideAllSessions();
  }

  /** Center the camera to the last location of the device. */
  private void centerCamera() {
    if (lastLocation != null) {
      requireNonNull(googleMap)
          .moveCamera(CameraUpdateFactory.newLatLngZoom(lastLocation, DEFAULT_ZOOM));
    }
  }

  @Override
  public void updateCurrentLocation(LatLng latLang) {
    lastLocation = latLang;
  }

  @SuppressLint("MissingPermission")
  private void showStartupLocation() {
    FusedLocationProviderClient fusedLocationProviderClient =
        LocationServices.getFusedLocationProviderClient(this);
    fusedLocationProviderClient
        .getLastLocation()
        .addOnCompleteListener(
            task -> {
              if (task.isSuccessful() && task.getResult() != null) {
                Location location = task.getResult();
                lastLocation = new LatLng(location.getLatitude(), location.getLongitude());
              } else {
                lastLocation = DEFAULT_MAP_LOCATION;
              }
              if (googleMap != null) {
                centerCamera();
              }
            });
  }

  /** Setting up map idle listeners to select pickup and dropoff locations. */
  private void setupMapListener() {
    requireNonNull(googleMap)
        .setOnCameraIdleListener(
            () -> {
              CameraPosition cameraPosition = requireNonNull(googleMap).getCameraPosition();
              if (cameraPosition == null) {
                return;
              }
              int state = consumerViewModel.getAppState().getValue();
              LatLng cameraLocation = cameraPosition.target;
              if (state == SELECTING_DROPOFF) {
                consumerViewModel.setDropoffLocation(cameraLocation);
                updateMarker(
                    ConsumerMarkerType.DROPOFF_POINT,
                    TerminalLocation.builder(cameraLocation).build());
              } else if (state == SELECTING_PICKUP) {
                consumerViewModel.setPickupLocation(cameraLocation);
                updateMarker(
                    ConsumerMarkerType.PICKUP_POINT,
                    TerminalLocation.builder(cameraLocation).build());
                consumerViewModel.getCustomRouteCost();
              }
            });
  }

  /** Update marker on the map based on camera location. */
  private void updateMarker(@ConsumerMarkerType Integer markerType, TerminalLocation location) {
{'fraction_non_alphanumeric': 0.08069212914116902, 'fraction_numerical': 0.003629457691496096, 'mean_word_length': 3.6408147277712497, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4049892', 'n_tokens_mistral': 6198, 'n_tokens_neox': 5954, 'n_words': 1580}