InstrumentClusterFragment.java revision 9aaf8b91bdef693f555632c9ca491423e457efa1
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 */ 16package com.google.android.car.kitchensink.cluster; 17 18import android.app.AlertDialog; 19import android.content.ComponentName; 20import android.os.Bundle; 21import android.support.annotation.Nullable; 22import android.support.car.Car; 23import android.support.car.CarAppFocusManager; 24import android.support.car.CarAppFocusManager.AppFocusChangeListener; 25import android.support.car.CarAppFocusManager.AppFocusOwnershipChangeListener; 26import android.support.car.CarNotConnectedException; 27import android.support.car.CarNotSupportedException; 28import android.support.car.ServiceConnectionCallbacks; 29import android.support.car.navigation.CarNavigationStatusManager; 30import android.support.v4.app.Fragment; 31import android.util.Log; 32import android.view.LayoutInflater; 33import android.view.View; 34import android.view.ViewGroup; 35 36import com.google.android.car.kitchensink.R; 37 38/** 39 * Contains functions to test instrument cluster API. 40 */ 41public class InstrumentClusterFragment extends Fragment { 42 private static final String TAG = InstrumentClusterFragment.class.getSimpleName(); 43 44 private CarNavigationStatusManager mCarNavigationStatusManager; 45 private CarAppFocusManager mCarAppFocusManager; 46 private Car mCarApi; 47 48 private final ServiceConnectionCallbacks mServiceConnectionCallbacks = 49 new ServiceConnectionCallbacks() { 50 @Override 51 public void onServiceConnected(ComponentName name) { 52 Log.d(TAG, "Connected to Car Service"); 53 try { 54 mCarNavigationStatusManager = (CarNavigationStatusManager) mCarApi.getCarManager( 55 android.car.Car.CAR_NAVIGATION_SERVICE); 56 mCarAppFocusManager = 57 (CarAppFocusManager) mCarApi.getCarManager(Car.APP_FOCUS_SERVICE); 58 } catch (CarNotConnectedException e) { 59 Log.e(TAG, "Car is not connected!", e); 60 } 61 } 62 63 @Override 64 public void onServiceDisconnected(ComponentName name) { 65 Log.d(TAG, "Disconnect from Car Service"); 66 } 67 68 @Override 69 public void onServiceSuspended(int cause) { 70 Log.d(TAG, "Car Service connection suspended"); 71 } 72 73 @Override 74 public void onServiceConnectionFailed(int cause) { 75 Log.d(TAG, "Car Service connection failed"); 76 } 77 }; 78 79 private void initCarApi() { 80 if (mCarApi != null && mCarApi.isConnected()) { 81 mCarApi.disconnect(); 82 mCarApi = null; 83 } 84 85 mCarApi = Car.createCar(getContext(), mServiceConnectionCallbacks); 86 mCarApi.connect(); 87 } 88 89 @Nullable 90 @Override 91 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 92 @Nullable Bundle savedInstanceState) { 93 View view = inflater.inflate(R.layout.instrument_cluster, container, false); 94 95 view.findViewById(R.id.cluster_start_button).setOnClickListener(v -> initCluster()); 96 view.findViewById(R.id.cluster_turn_left_button).setOnClickListener(v -> turnLeft()); 97 98 return view; 99 } 100 101 @Override 102 public void onCreate(@Nullable Bundle savedInstanceState) { 103 initCarApi(); 104 105 super.onCreate(savedInstanceState); 106 } 107 108 private void turnLeft() { 109 try { 110 mCarNavigationStatusManager 111 .sendNavigationTurnEvent(CarNavigationStatusManager.TURN_TURN, "Huff Ave", 90, 112 -1, null, CarNavigationStatusManager.TURN_SIDE_LEFT); 113 mCarNavigationStatusManager.sendNavigationTurnDistanceEvent(500, 10, 500, 114 CarNavigationStatusManager.DISTANCE_METERS); 115 } catch (CarNotConnectedException e) { 116 e.printStackTrace(); 117 initCarApi(); // This might happen due to inst cluster renderer crash. 118 } 119 } 120 121 private void initCluster() { 122 try { 123 mCarAppFocusManager.registerFocusListener(new AppFocusChangeListener() { 124 @Override 125 public void onAppFocusChange(int appType, boolean active) { 126 Log.d(TAG, "onAppFocusChange, appType: " + appType + " active: " + active); 127 } 128 }, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); 129 } catch (CarNotConnectedException e) { 130 Log.e(TAG, "Failed to register focus listener", e); 131 } 132 133 AppFocusOwnershipChangeListener focusListener = new AppFocusOwnershipChangeListener() { 134 @Override 135 public void onAppFocusOwnershipLoss(int focus) { 136 Log.w(TAG, "onAppFocusOwnershipLoss, focus: " + focus); 137 new AlertDialog.Builder(getContext()) 138 .setTitle(getContext().getApplicationInfo().name) 139 .setMessage(R.string.cluster_nav_app_context_loss) 140 .show(); 141 } 142 }; 143 try { 144 mCarAppFocusManager.requestAppFocus(focusListener, 145 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); 146 } catch (CarNotConnectedException e) { 147 Log.e(TAG, "Failed to set active focus", e); 148 } 149 150 try { 151 boolean ownsFocus = mCarAppFocusManager.isOwningFocus(focusListener, 152 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); 153 Log.d(TAG, "Owns APP_FOCUS_TYPE_NAVIGATION: " + ownsFocus); 154 if (!ownsFocus) { 155 throw new RuntimeException("Focus was not acquired."); 156 } 157 } catch (CarNotConnectedException e) { 158 Log.e(TAG, "Failed to get owned focus", e); 159 } 160 161 try { 162 mCarNavigationStatusManager 163 .sendNavigationStatus(CarNavigationStatusManager.STATUS_ACTIVE); 164 } catch (CarNotConnectedException e) { 165 Log.e(TAG, "Failed to set navigation status, reconnecting to the car", e); 166 initCarApi(); // This might happen due to inst cluster renderer crash. 167 } 168 } 169} 170