Home | History | Annotate | Download | only in cluster
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.google.android.car.kitchensink.cluster;
     17 
     18 import android.app.AlertDialog;
     19 import android.car.cluster.CarInstrumentClusterManager;
     20 import android.content.Intent;
     21 import android.content.pm.PackageManager;
     22 import android.os.Bundle;
     23 import android.support.annotation.Nullable;
     24 import android.support.car.Car;
     25 import android.support.car.CarAppFocusManager;
     26 import android.support.car.CarConnectionCallback;
     27 import android.support.car.CarNotConnectedException;
     28 import android.support.car.navigation.CarNavigationStatusManager;
     29 import android.support.v4.app.Fragment;
     30 import android.util.Log;
     31 import android.view.LayoutInflater;
     32 import android.view.View;
     33 import android.view.ViewGroup;
     34 import android.widget.Toast;
     35 
     36 import com.google.android.car.kitchensink.R;
     37 
     38 /**
     39  * Contains functions to test instrument cluster API.
     40  */
     41 public class InstrumentClusterFragment extends Fragment {
     42     private static final String TAG = InstrumentClusterFragment.class.getSimpleName();
     43 
     44     private static final int DISPLAY_IN_CLUSTER_PERMISSION_REQUEST = 1;
     45 
     46     private CarNavigationStatusManager mCarNavigationStatusManager;
     47     private CarAppFocusManager mCarAppFocusManager;
     48     private Car mCarApi;
     49 
     50     private final CarConnectionCallback mCarConnectionCallback = new CarConnectionCallback() {
     51             @Override
     52             public void onConnected(Car car) {
     53                 Log.d(TAG, "Connected to Car Service");
     54                 try {
     55                     mCarNavigationStatusManager =
     56                             mCarApi.getCarManager(CarNavigationStatusManager.class);
     57                     mCarAppFocusManager = mCarApi.getCarManager(CarAppFocusManager.class);
     58                 } catch (CarNotConnectedException e) {
     59                     Log.e(TAG, "Car is not connected!", e);
     60                 }
     61             }
     62 
     63             @Override
     64             public void onDisconnected(Car car) {
     65             Log.d(TAG, "Disconnect from Car Service");
     66         }
     67     };
     68 
     69     private void initCarApi() {
     70         if (mCarApi != null && mCarApi.isConnected()) {
     71             mCarApi.disconnect();
     72             mCarApi = null;
     73         }
     74 
     75         mCarApi = Car.createCar(getContext(), mCarConnectionCallback);
     76         mCarApi.connect();
     77     }
     78 
     79     @Nullable
     80     @Override
     81     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
     82             @Nullable Bundle savedInstanceState) {
     83         View view = inflater.inflate(R.layout.instrument_cluster, container, false);
     84 
     85         view.findViewById(R.id.cluster_start_button).setOnClickListener(v -> initCluster());
     86         view.findViewById(R.id.cluster_turn_left_button).setOnClickListener(v -> turnLeft());
     87         view.findViewById(R.id.cluster_start_activity).setOnClickListener(v -> startNavActivity());
     88 
     89         return view;
     90     }
     91 
     92     @Override
     93     public void onCreate(@Nullable Bundle savedInstanceState) {
     94         initCarApi();
     95 
     96         super.onCreate(savedInstanceState);
     97     }
     98 
     99     private void startNavActivity() {
    100         CarInstrumentClusterManager clusterManager;
    101         try {
    102             clusterManager = (CarInstrumentClusterManager) mCarApi.getCarManager(
    103                     android.car.Car.CAR_INSTRUMENT_CLUSTER_SERVICE);
    104         } catch (CarNotConnectedException e) {
    105             Log.e(TAG, "Failed to get CarInstrumentClusterManager", e);
    106             Toast.makeText(getContext(), "Failed to get CarInstrumentClusterManager",
    107                     Toast.LENGTH_LONG).show();
    108             return;
    109         }
    110 
    111         // Implicit intent
    112         Intent intent = new Intent(Intent.ACTION_MAIN);
    113         intent.addCategory(CarInstrumentClusterManager.CATEGORY_NAVIGATION);
    114         try {
    115             clusterManager.startActivity(intent);
    116         } catch (android.car.CarNotConnectedException e) {
    117             Log.e(TAG, "Failed to startActivity in cluster", e);
    118             Toast.makeText(getContext(), "Failed to start activity in cluster",
    119                     Toast.LENGTH_LONG).show();
    120             return;
    121         }
    122     }
    123 
    124     private void turnLeft() {
    125         try {
    126             mCarNavigationStatusManager
    127                     .sendNavigationTurnEvent(CarNavigationStatusManager.TURN_TURN, "Huff Ave", 90,
    128                             -1, null, CarNavigationStatusManager.TURN_SIDE_LEFT);
    129             mCarNavigationStatusManager.sendNavigationTurnDistanceEvent(500, 10, 500,
    130                     CarNavigationStatusManager.DISTANCE_METERS);
    131         } catch (CarNotConnectedException e) {
    132             e.printStackTrace();
    133         }
    134     }
    135 
    136     private void initCluster() {
    137         try {
    138             mCarAppFocusManager
    139                     .addFocusListener(new CarAppFocusManager.OnAppFocusChangedListener() {
    140                         @Override
    141                         public void onAppFocusChanged(CarAppFocusManager manager, int appType,
    142                                 boolean active) {
    143                             Log.d(TAG, "onAppFocusChanged, appType: " + appType + " active: "
    144                                     + active);
    145                         }
    146                     }, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
    147         } catch (CarNotConnectedException e) {
    148             Log.e(TAG, "Failed to register focus listener", e);
    149         }
    150 
    151         CarAppFocusManager.OnAppFocusOwnershipCallback
    152                 focusCallback = new CarAppFocusManager.OnAppFocusOwnershipCallback() {
    153             @Override
    154             public void onAppFocusOwnershipLost(CarAppFocusManager manager, int focus) {
    155                 Log.w(TAG, "onAppFocusOwnershipLost, focus: " + focus);
    156                 new AlertDialog.Builder(getContext())
    157                         .setTitle(getContext().getApplicationInfo().name)
    158                         .setMessage(R.string.cluster_nav_app_context_loss)
    159                         .show();
    160             }
    161 
    162             @Override
    163             public void onAppFocusOwnershipGranted(CarAppFocusManager manager, int focus) {
    164                 Log.w(TAG, "onAppFocusOwnershipGranted, focus: " + focus);
    165             }
    166 
    167         };
    168         try {
    169             mCarAppFocusManager.requestAppFocus(CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION,
    170                     focusCallback);
    171         } catch (CarNotConnectedException e) {
    172             Log.e(TAG, "Failed to set active focus", e);
    173         }
    174 
    175         try {
    176             boolean ownsFocus = mCarAppFocusManager.isOwningFocus(
    177                     CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, focusCallback);
    178             Log.d(TAG, "Owns APP_FOCUS_TYPE_NAVIGATION: " + ownsFocus);
    179             if (!ownsFocus) {
    180                 throw new RuntimeException("Focus was not acquired.");
    181             }
    182         } catch (CarNotConnectedException e) {
    183             Log.e(TAG, "Failed to get owned focus", e);
    184         }
    185 
    186         try {
    187             mCarNavigationStatusManager
    188                     .sendNavigationStatus(CarNavigationStatusManager.STATUS_ACTIVE);
    189         } catch (CarNotConnectedException e) {
    190             Log.e(TAG, "Failed to set navigation status, reconnecting to the car", e);
    191         }
    192     }
    193 
    194     @Override
    195     public void onResume() {
    196         super.onResume();
    197         Log.i(TAG, "onResume!");
    198         if (getActivity().checkSelfPermission(android.car.Car.PERMISSION_CAR_DISPLAY_IN_CLUSTER)
    199                 != PackageManager.PERMISSION_GRANTED) {
    200             Log.i(TAG, "Requesting: " + android.car.Car.PERMISSION_CAR_DISPLAY_IN_CLUSTER);
    201 
    202             requestPermissions(new String[] {android.car.Car.PERMISSION_CAR_DISPLAY_IN_CLUSTER},
    203                     DISPLAY_IN_CLUSTER_PERMISSION_REQUEST);
    204         } else {
    205             Log.i(TAG, "All required permissions granted");
    206         }
    207     }
    208 
    209     @Override
    210     public void onRequestPermissionsResult(int requestCode, String[] permissions,
    211             int[] grantResults) {
    212         if (DISPLAY_IN_CLUSTER_PERMISSION_REQUEST == requestCode) {
    213             for (int i = 0; i < permissions.length; i++) {
    214                 boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
    215                 Log.i(TAG, "onRequestPermissionsResult, requestCode: " + requestCode
    216                         + ", permission: " + permissions[i] + ", granted: " + granted);
    217             }
    218         }
    219     }
    220 }
    221