com.waz.zclient.pages.main.conversation.LocationFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.waz.zclient.pages.main.conversation.LocationFragment.java

Source

/**
 * Wire
 * Copyright (C) 2016 Wire Swiss GmbH
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.waz.zclient.pages.main.conversation;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.waz.api.ConversationsList;
import com.waz.api.IConversation;
import com.waz.api.MessageContent;
import com.waz.api.SyncState;
import com.waz.api.Verification;
import com.waz.zclient.OnBackPressedListener;
import com.waz.zclient.R;
import com.waz.zclient.controllers.accentcolor.AccentColorObserver;
import com.waz.zclient.controllers.permission.RequestPermissionsObserver;
import com.waz.zclient.controllers.userpreferences.IUserPreferencesController;
import com.waz.zclient.core.stores.conversation.ConversationChangeRequester;
import com.waz.zclient.core.stores.conversation.ConversationStoreObserver;
import com.waz.zclient.pages.BaseFragment;
import com.waz.zclient.ui.text.GlyphTextView;
import com.waz.zclient.ui.views.TouchRegisteringFrameLayout;
import com.waz.zclient.utils.LayoutSpec;
import com.waz.zclient.utils.PermissionUtils;
import com.waz.zclient.utils.StringUtils;
import com.waz.zclient.utils.TrackingUtils;
import com.waz.zclient.utils.ViewUtils;
import timber.log.Timber;

import java.util.List;
import java.util.Locale;

public class LocationFragment extends BaseFragment<LocationFragment.Container>
        implements com.google.android.gms.location.LocationListener, LocationListener,
        TouchRegisteringFrameLayout.TouchCallback, GoogleMap.OnCameraChangeListener,
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, OnMapReadyCallback,
        ConversationStoreObserver, RequestPermissionsObserver, OnBackPressedListener, AccentColorObserver,
        View.OnClickListener {

    public static final String TAG = LocationFragment.class.getName();

    private static final String[] LOCATION_PERMISSIONS = new String[] { Manifest.permission.ACCESS_FINE_LOCATION };
    private static final int LOCATION_PERMISSION_REQUEST_ID = 532;
    private static final float DEFAULT_MAP_ZOOM_LEVEL = 15F;
    private static final float DEFAULT_MIMIMUM_CAMERA_MOVEMENT = 2F;
    private static final int LOCATION_REQUEST_TIMEOUT_MS = 1500;
    private static final String MAP_VIEW_SAVE_STATE = "mapViewSaveState";

    private Toolbar toolbar;
    private MapView mapView;
    private View selectedLocationBackground;
    private GlyphTextView selectedLocationPin;
    private LinearLayout selectedLocationDetails;
    private TextView selectedLocationAddress;
    private TouchRegisteringFrameLayout touchRegisteringFrameLayout;
    private TextView requestCurrentLocationButton;
    private TextView sendCurrentLocationButton;
    private TextView toolbarTitle;
    private Bitmap marker;

    private GoogleMap map;
    private LocationManager locationManager;
    private Location currentLocation;

    private GoogleApiClient googleApiClient;
    private LocationRequest locationRequest;

    private String currentLocationCountryName;
    private String currentLocationLocality;
    private String currentLocationSubLocality;
    private String currentLocationFirstAddressLine;
    private String currentLocationName;
    private LatLng currentLatLng;

    private boolean animateTocurrentLocation;
    private boolean zoom;
    private boolean animating;
    private boolean checkIfLocationServicesEnabled;
    private Handler mainHandler;
    private Handler backgroundHandler;
    private HandlerThread handlerThread;
    private Geocoder geocoder;

    private final Runnable updateCurrentLocationBubbleRunnable = new Runnable() {
        @Override
        public void run() {
            if (getActivity() == null || getContainer() == null) {
                return;
            }
            updateCurrentLocationName((int) map.getCameraPosition().zoom);
            setTextAddressBubble(currentLocationName);
        }
    };

    private final Runnable retrieveCurrentLocationNameRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                final List<Address> addresses = geocoder.getFromLocation(currentLatLng.latitude,
                        currentLatLng.longitude, 1);
                if (addresses != null && addresses.size() > 0) {
                    Address adr = addresses.get(0);
                    if (adr.getMaxAddressLineIndex() >= 0) {
                        currentLocationFirstAddressLine = adr.getAddressLine(0);
                    } else {
                        currentLocationFirstAddressLine = "";
                    }
                    currentLocationCountryName = adr.getCountryName();
                    currentLocationLocality = adr.getLocality();
                    currentLocationSubLocality = adr.getSubLocality();
                } else {
                    currentLocationFirstAddressLine = "";
                    currentLocationCountryName = "";
                    currentLocationLocality = "";
                    currentLocationSubLocality = "";
                }

            } catch (Exception e) {
                currentLocationFirstAddressLine = "";
                currentLocationCountryName = "";
                currentLocationLocality = "";
                currentLocationSubLocality = "";
                Timber.i(e, "Unable to retrieve location name");
            }
            mainHandler.removeCallbacksAndMessages(null);
            mainHandler.post(updateCurrentLocationBubbleRunnable);
        }
    };

    public static LocationFragment newInstance() {
        return new LocationFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (isGooglePlayServicesAvailable()) {
            googleApiClient = new GoogleApiClient.Builder(getContext()).addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
        } else {
            locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
        }
        mainHandler = new Handler();
        handlerThread = new HandlerThread("Background handler");
        handlerThread.start();
        backgroundHandler = new Handler(handlerThread.getLooper());
        geocoder = new Geocoder(getContext(), Locale.getDefault());
        zoom = true;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup viewGroup,
            @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_location, viewGroup, false);

        toolbar = ViewUtils.getView(view, R.id.t_location_toolbar);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (getActivity() == null) {
                    return;
                }
                getControllerFactory().getLocationController().hideShareLocation(null);
            }
        });
        if (LayoutSpec.isTablet(getContext())) {
            toolbar.setNavigationIcon(R.drawable.action_back_dark);
        }

        toolbarTitle = ViewUtils.getView(view, R.id.tv__location_toolbar__title);

        selectedLocationBackground = ViewUtils.getView(view, R.id.iv__selected_location__background);
        selectedLocationPin = ViewUtils.getView(view, R.id.gtv__selected_location__pin);

        selectedLocationDetails = ViewUtils.getView(view, R.id.ll_selected_location_details);
        selectedLocationDetails.setVisibility(View.INVISIBLE);

        touchRegisteringFrameLayout = ViewUtils.getView(view, R.id.trfl_location_touch_registerer);
        touchRegisteringFrameLayout.setTouchCallback(this);

        requestCurrentLocationButton = ViewUtils.getView(view, R.id.gtv__location__current__button);
        requestCurrentLocationButton.setOnClickListener(this);

        sendCurrentLocationButton = ViewUtils.getView(view, R.id.ttv__location_send_button);
        sendCurrentLocationButton.setOnClickListener(this);

        selectedLocationAddress = ViewUtils.getView(view, R.id.ttv__location_address);

        final Bundle mapViewSavedInstanceState = savedInstanceState != null
                ? savedInstanceState.getBundle(MAP_VIEW_SAVE_STATE)
                : null;
        mapView = ViewUtils.getView(view, R.id.mv_map);
        mapView.onCreate(mapViewSavedInstanceState);
        mapView.getMapAsync(this);

        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        // Dirty hack to avoid crash in MapView
        // See https://code.google.com/p/gmaps-api-issues/issues/detail?id=6237#c9
        final Bundle mapViewSaveState = new Bundle(outState);
        mapView.onSaveInstanceState(mapViewSaveState);
        outState.putBundle(MAP_VIEW_SAVE_STATE, mapViewSaveState);

        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    @Override
    public void onStart() {
        super.onStart();
        getControllerFactory().getAccentColorController().addAccentColorObserver(this);
        getControllerFactory().getRequestPermissionsController().addObserver(this);
        getStoreFactory().getConversationStore().addConversationStoreObserver(this);
        if (PermissionUtils.hasSelfPermissions(getActivity(), LOCATION_PERMISSIONS)) {
            updateLastKnownLocation();
            if (!isLocationServicesEnabled()) {
                showLocationServicesDialog();
            }
            requestCurrentLocationButton.setVisibility(View.VISIBLE);
        } else {
            ActivityCompat.requestPermissions(getActivity(), LOCATION_PERMISSIONS, LOCATION_PERMISSION_REQUEST_ID);
            checkIfLocationServicesEnabled = true;
            requestCurrentLocationButton.setVisibility(View.GONE);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
        IConversation currentConversation = getStoreFactory().getConversationStore().getCurrentConversation();
        if (currentConversation != null) {
            toolbarTitle.setText(currentConversation.getName());
        }
        if (!getControllerFactory().getUserPreferencesController()
                .hasPerformedAction(IUserPreferencesController.SEND_LOCATION_MESSAGE)) {
            getControllerFactory().getUserPreferencesController()
                    .setPerformedAction(IUserPreferencesController.SEND_LOCATION_MESSAGE);
            Toast.makeText(getContext(), R.string.location_sharing__tip, Toast.LENGTH_LONG).show();
        }
        if (PermissionUtils.hasSelfPermissions(getActivity(), LOCATION_PERMISSIONS)) {
            if (googleApiClient != null) {
                googleApiClient.connect();
            } else if (locationManager != null) {
                startLocationManagerListeningForCurrentLocation();
            }
        }
    }

    @Override
    public void onPause() {
        stopLocationManagerListeningForCurrentLocation();
        stopPlayServicesListeningForCurrentLocation();
        if (googleApiClient != null) {
            googleApiClient.disconnect();
        }
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onStop() {
        getStoreFactory().getConversationStore().removeConversationStoreObserver(this);
        getControllerFactory().getRequestPermissionsController().removeObserver(this);
        getControllerFactory().getAccentColorController().removeAccentColorObserver(this);
        super.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    private boolean isGooglePlayServicesAvailable() {
        return ConnectionResult.SUCCESS == GooglePlayServicesUtil.isGooglePlayServicesAvailable(getContext());
    }

    @SuppressWarnings("ResourceType")
    @SuppressLint("MissingPermission")
    private void startLocationManagerListeningForCurrentLocation() {
        Timber.i("startLocationManagerListeningForCurrentLocation");
        if (locationManager != null && PermissionUtils.hasSelfPermissions(getContext(), LOCATION_PERMISSIONS)) {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
    }

    private void startPlayServicesListeningForCurrentLocation() {
        Timber.i("startPlayServicesListeningForCurrentLocation");
        if (locationRequest != null) {
            return;
        }
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(1000);
        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
        currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    }

    @SuppressWarnings("ResourceType")
    @SuppressLint("MissingPermission")
    private void stopLocationManagerListeningForCurrentLocation() {
        Timber.i("stopLocationManagerListeningForCurrentLocation");
        if (locationManager != null && PermissionUtils.hasSelfPermissions(getContext(), LOCATION_PERMISSIONS)) {
            locationManager.removeUpdates(this);
        }
    }

    private void stopPlayServicesListeningForCurrentLocation() {
        Timber.i("stopPlayServicesListeningForCurrentLocation");
        if (locationRequest == null) {
            return;
        }
        LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
        locationRequest = null;
    }

    private boolean isLocationServicesEnabled() {
        if (!PermissionUtils.hasSelfPermissions(getContext(), LOCATION_PERMISSIONS)) {
            return false;
        }
        // We are creating a local locationManager here, as it's not sure we already have one
        LocationManager locationManager = (LocationManager) getActivity()
                .getSystemService(Context.LOCATION_SERVICE);
        if (locationManager == null) {
            return false;
        }
        boolean gpsEnabled;
        boolean netEnabled;

        try {
            gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch (Exception e) {
            gpsEnabled = false;
        }

        try {
            netEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception e) {
            netEnabled = false;
        }
        return netEnabled || gpsEnabled;
    }

    private void showLocationServicesDialog() {
        ViewUtils.showAlertDialog(getContext(), R.string.location_sharing__enable_system_location__title,
                R.string.location_sharing__enable_system_location__message,
                R.string.location_sharing__enable_system_location__confirm,
                R.string.location_sharing__enable_system_location__cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        getContext().startActivity(myIntent);
                    }
                }, null);
    }

    private void updateCurrentLocationName(int zoom) {
        if (zoom >= 12) {
            // Local address
            if (!StringUtils.isBlank(currentLocationFirstAddressLine)) {
                currentLocationName = currentLocationFirstAddressLine;
            } else if (!StringUtils.isBlank(currentLocationSubLocality)) {
                currentLocationName = currentLocationSubLocality;
            } else if (!StringUtils.isBlank(currentLocationLocality)) {
                currentLocationName = currentLocationLocality;
            } else {
                currentLocationName = currentLocationCountryName;
            }
        } else if (zoom >= 6) {
            // City-ish
            if (!StringUtils.isBlank(currentLocationSubLocality)) {
                currentLocationName = currentLocationSubLocality;
            } else if (!StringUtils.isBlank(currentLocationLocality)) {
                currentLocationName = currentLocationLocality;
            } else {
                currentLocationName = currentLocationCountryName;
            }
        } else {
            // Country
            currentLocationName = currentLocationCountryName;
        }
    }

    @Override
    public void onInterceptTouchEvent(MotionEvent event) {
        animateTocurrentLocation = false;
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.gtv__location__current__button:
            animateTocurrentLocation = true;
            zoom = true;
            if (PermissionUtils.hasSelfPermissions(getActivity(), LOCATION_PERMISSIONS)) {
                updateLastKnownLocation();
            } else {
                ActivityCompat.requestPermissions(getActivity(), LOCATION_PERMISSIONS,
                        LOCATION_PERMISSION_REQUEST_ID);
            }
            break;
        case R.id.ttv__location_send_button:
            if (getStoreFactory() == null || getStoreFactory().isTornDown() || currentLatLng == null) {
                return;
            }
            MessageContent.Location location = new MessageContent.Location((float) currentLatLng.longitude,
                    (float) currentLatLng.latitude, currentLocationName, (int) map.getCameraPosition().zoom);
            getControllerFactory().getLocationController().hideShareLocation(location);
            TrackingUtils.onSentLocationMessage(getControllerFactory().getTrackingController(),
                    getStoreFactory().getConversationStore().getCurrentConversation());
            break;
        }
    }

    @SuppressWarnings("ResourceType")
    @SuppressLint("MissingPermission")
    private void updateLastKnownLocation() {
        if (locationManager != null) {
            currentLocation = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
        } else if (googleApiClient != null && locationRequest != null) {
            currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
        }
        if (currentLocation != null) {
            onLocationChanged(currentLocation);
        }
    }

    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        Timber.i("onCameraChange");
        animating = false;
        currentLatLng = cameraPosition.target;
        currentLocationName = "";

        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                selectedLocationAddress.setVisibility(View.INVISIBLE);
            }
        }, LOCATION_REQUEST_TIMEOUT_MS);
        backgroundHandler.removeCallbacksAndMessages(null);
        backgroundHandler.post(retrieveCurrentLocationNameRunnable);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        Timber.i("onMapReady");
        map = googleMap;
        map.getUiSettings().setMyLocationButtonEnabled(false);
        map.setMyLocationEnabled(false);
        if (currentLocation != null) {
            map.animateCamera(CameraUpdateFactory.newLatLngZoom(
                    new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),
                    DEFAULT_MAP_ZOOM_LEVEL));
            animateTocurrentLocation = false;
            onLocationChanged(currentLocation);
        }
        map.setOnCameraChangeListener(this);
    }

    @Override
    public void onLocationChanged(Location location) {
        Timber.i("onLocationChanged, lat=%f, lon=%f, accuracy=%f, distanceToCurrent=%f", location.getLatitude(),
                location.getLongitude(), location.getAccuracy(),
                (currentLocation == null) ? 0 : location.distanceTo(currentLocation));

        float distanceFromCenterOfScreen = Float.MAX_VALUE;
        if (currentLatLng != null) {
            float[] distance = new float[1];
            Location.distanceBetween(currentLatLng.latitude, currentLatLng.longitude, location.getLatitude(),
                    location.getLongitude(), distance);
            distanceFromCenterOfScreen = distance[0];
            Timber.i("current location distance from map center %f", distance[0]);
        }

        currentLocation = location;
        if (map != null) {
            map.clear();
            LatLng position = new LatLng(location.getLatitude(), location.getLongitude());
            map.addMarker(new MarkerOptions().position(position)
                    .icon(BitmapDescriptorFactory.fromBitmap(getMarker())).anchor(0.5f, 0.5f));
            if (animateTocurrentLocation && distanceFromCenterOfScreen > DEFAULT_MIMIMUM_CAMERA_MOVEMENT) {
                if (zoom || animating) {
                    map.animateCamera(CameraUpdateFactory.newLatLngZoom(
                            new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),
                            DEFAULT_MAP_ZOOM_LEVEL));
                    animating = true;
                    zoom = false;
                } else {
                    map.animateCamera(CameraUpdateFactory
                            .newLatLng(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude())));
                }
            }
        }
    }

    private void setTextAddressBubble(String name) {
        if (StringUtils.isBlank(name)) {
            selectedLocationDetails.setVisibility(View.INVISIBLE);
            selectedLocationBackground.setVisibility(View.VISIBLE);
            selectedLocationPin.setVisibility(View.VISIBLE);
        } else {
            selectedLocationAddress.setText(name);
            selectedLocationAddress.setVisibility(View.VISIBLE);
            selectedLocationDetails.requestLayout();
            selectedLocationDetails.setVisibility(View.VISIBLE);
            selectedLocationBackground.setVisibility(View.INVISIBLE);
            selectedLocationPin.setVisibility(View.INVISIBLE);
        }
    }

    private Bitmap getMarker() {
        if (marker != null) {
            return marker;
        }
        int size = getResources().getDimensionPixelSize(R.dimen.share_location__current_location_marker__size);
        int outerCircleRadius = getResources()
                .getDimensionPixelSize(R.dimen.share_location__current_location_marker__outer_ring_radius);
        int midCircleRadius = getResources()
                .getDimensionPixelSize(R.dimen.share_location__current_location_marker__mid_ring_radius);
        int innerCircleRadius = getResources()
                .getDimensionPixelSize(R.dimen.share_location__current_location_marker__inner_ring_radius);

        Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        Paint paint = new Paint();
        paint.setColor(getControllerFactory().getAccentColorController().getColor());
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        paint.setAlpha(
                getResources().getInteger(R.integer.share_location__current_location_marker__outer_ring_alpha));
        canvas.drawCircle(size / 2, size / 2, outerCircleRadius, paint);
        paint.setAlpha(
                getResources().getInteger(R.integer.share_location__current_location_marker__mid_ring_alpha));
        canvas.drawCircle(size / 2, size / 2, midCircleRadius, paint);
        paint.setAlpha(
                getResources().getInteger(R.integer.share_location__current_location_marker__inner_ring_alpha));
        canvas.drawCircle(size / 2, size / 2, innerCircleRadius, paint);
        marker = bitmap;
        return marker;
    }

    @Override
    public void onConversationListUpdated(@NonNull ConversationsList conversationsList) {

    }

    @Override
    public void onConversationListStateHasChanged(ConversationsList.ConversationsListState state) {

    }

    @Override
    public void onCurrentConversationHasChanged(IConversation fromConversation, IConversation toConversation,
            ConversationChangeRequester conversationChangerSender) {
        if (toConversation != null) {
            toolbarTitle.setText(toConversation.getName());
        }
    }

    @Override
    public void onConversationSyncingStateHasChanged(SyncState syncState) {

    }

    @Override
    public void onMenuConversationHasChanged(IConversation fromConversation) {

    }

    @Override
    public void onVerificationStateChanged(String conversationId, Verification previousVerification,
            Verification currentVerification) {

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, int[] grantResults) {
        if (getActivity() == null) {
            return;
        }
        switch (requestCode) {
        case LOCATION_PERMISSION_REQUEST_ID:
            if (PermissionUtils.verifyPermissions(grantResults)) {
                requestCurrentLocationButton.setVisibility(View.VISIBLE);
                zoom = true;
                updateLastKnownLocation();
                if (googleApiClient != null && googleApiClient.isConnected()) {
                    startPlayServicesListeningForCurrentLocation();
                } else if (locationManager != null) {
                    startLocationManagerListeningForCurrentLocation();
                }
                if (checkIfLocationServicesEnabled) {
                    checkIfLocationServicesEnabled = false;
                    if (!isLocationServicesEnabled()) {
                        showLocationServicesDialog();
                    }
                }
            } else {
                Toast.makeText(getContext(), R.string.location_sharing__permission_error, Toast.LENGTH_SHORT)
                        .show();
            }
            break;
        }
    }

    @Override
    public boolean onBackPressed() {
        if (getControllerFactory() == null || getControllerFactory().isTornDown()) {
            return false;
        }
        getControllerFactory().getLocationController().hideShareLocation(null);
        return true;
    }

    @Override
    public void onAccentColorHasChanged(Object sender, int color) {
        selectedLocationPin.setTextColor(color);
        marker = null;
    }

    @Override
    public void onConnected(Bundle bundle) {
        Timber.i("onConnected");
        if (PermissionUtils.hasSelfPermissions(getActivity(), LOCATION_PERMISSIONS)) {
            animateTocurrentLocation = true;
            startPlayServicesListeningForCurrentLocation();
        } else {
            ActivityCompat.requestPermissions(getActivity(), LOCATION_PERMISSIONS, LOCATION_PERMISSION_REQUEST_ID);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        Timber.i("onConnectionSuspended");
        // goodbye
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // fallback to LocationManager
        Timber.e("Google API Client connection failed");
        googleApiClient.unregisterConnectionFailedListener(this);
        googleApiClient.unregisterConnectionCallbacks(this);
        googleApiClient = null;
        locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
        if (PermissionUtils.hasSelfPermissions(getActivity(), LOCATION_PERMISSIONS)) {
            startLocationManagerListeningForCurrentLocation();
        } else {
            ActivityCompat.requestPermissions(getActivity(), LOCATION_PERMISSIONS, LOCATION_PERMISSION_REQUEST_ID);
        }
    }

    public interface Container {

    }
}