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