1905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev/*
2905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * Copyright (C) 2017 The Android Open Source Project
3905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev *
4905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * Licensed under the Apache License, Version 2.0 (the "License");
5905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * you may not use this file except in compliance with the License.
6905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * You may obtain a copy of the License at
7905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev *
8905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev *      http://www.apache.org/licenses/LICENSE-2.0
9905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev *
10905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * Unless required by applicable law or agreed to in writing, software
11905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * distributed under the License is distributed on an "AS IS" BASIS,
12905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * See the License for the specific language governing permissions and
14905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * limitations under the License.
15905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev */
16905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevpackage android.car.cluster.sample;
17905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
18905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
19905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport static java.lang.Integer.parseInt;
20905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
21905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.app.ActivityOptions;
22905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.car.CarNotConnectedException;
23905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.car.cluster.ClusterActivityState;
24905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.car.cluster.renderer.InstrumentClusterRenderingService;
25905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.car.cluster.renderer.NavigationRenderer;
26905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.car.navigation.CarNavigationInstrumentCluster;
27905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.content.Context;
28905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.content.Intent;
29905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.graphics.Bitmap;
30905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.graphics.Rect;
31905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.hardware.display.DisplayManager;
32905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.os.Binder;
33905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.os.IBinder;
34905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.os.SystemClock;
35905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.provider.Settings;
36905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.provider.Settings.Global;
37905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.util.Log;
38905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.view.Display;
39905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.view.InputDevice;
40905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport android.view.KeyEvent;
41905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
42905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport java.io.FileDescriptor;
43905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport java.io.PrintWriter;
44905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevimport java.util.Arrays;
45905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
46905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev/**
47905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev * Dummy implementation of {@link SampleClusterServiceImpl} to log all interaction.
48905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev */
49905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsevpublic class SampleClusterServiceImpl extends InstrumentClusterRenderingService {
50905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
51905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    private static final String TAG = SampleClusterServiceImpl.class.getSimpleName();
52905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
53905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    private Listener mListener;
54905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    private final Binder mLocalBinder = new LocalBinder();
55905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    static final String LOCAL_BINDING_ACTION = "local";
56905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
57905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    @Override
58905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    public IBinder onBind(Intent intent) {
59905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Log.i(TAG, "onBind, intent: " + intent);
60905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        return (LOCAL_BINDING_ACTION.equals(intent.getAction()))
61905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                ? mLocalBinder : super.onBind(intent);
62905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
63905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
64905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    @Override
65905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    public void onCreate() {
66905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        super.onCreate();
67905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Log.i(TAG, "onCreate");
68905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
69905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Display clusterDisplay = getInstrumentClusterDisplay(this);
70905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        if (clusterDisplay == null) {
71905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            Log.e(TAG, "Unable to find instrument cluster display");
72905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            return;
73905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        }
74905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
75905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        ActivityOptions options = ActivityOptions.makeBasic();
76905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        options.setLaunchDisplayId(clusterDisplay.getDisplayId());
77905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Intent intent = new Intent(this, MainClusterActivity.class);
78905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
79905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        startActivity(intent, options.toBundle());
80905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
81905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
82905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    @Override
83905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    protected void onKeyEvent(KeyEvent keyEvent) {
84905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Log.i(TAG, "onKeyEvent, keyEvent: " + keyEvent + ", listener: " + mListener);
85905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        if (mListener != null) {
86905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            mListener.onKeyEvent(keyEvent);
87905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        }
88905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
89905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
90905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    void registerListener(Listener listener) {
91905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        mListener = listener;
92905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
93905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
94905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    void unregisterListener() {
95905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        mListener = null;
96905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
97905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
98905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    @Override
99905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    protected NavigationRenderer getNavigationRenderer() {
100905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        NavigationRenderer navigationRenderer = new NavigationRenderer() {
101905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            @Override
102905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            public CarNavigationInstrumentCluster getNavigationProperties() {
103905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                Log.i(TAG, "getNavigationProperties");
104905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                CarNavigationInstrumentCluster config =
105905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                        CarNavigationInstrumentCluster.createCluster(1000);
106905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                Log.i(TAG, "getNavigationProperties, returns: " + config);
107905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                return config;
108905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
109905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
110905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            @Override
111905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            public void onStartNavigation() {
112905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                Log.i(TAG, "onStartNavigation");
113905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
114905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
115905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            @Override
116905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            public void onStopNavigation() {
117905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                Log.i(TAG, "onStopNavigation");
118905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
119905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
120905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            @Override
121905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            public void onNextTurnChanged(int event, CharSequence eventName, int turnAngle,
122905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    int turnNumber, Bitmap image, int turnSide) {
123905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                Log.i(TAG, "event: " + event + ", eventName: " + eventName +
124905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                        ", turnAngle: " + turnAngle + ", turnNumber: " + turnNumber +
125905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                        ", image: " + image + ", turnSide: " + turnSide);
126905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                mListener.onShowToast("Next turn: " + eventName);
127905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
128905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
129905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            @Override
130905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            public void onNextTurnDistanceChanged(int distanceMeters, int timeSeconds,
131905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    int displayDistanceMillis, int displayDistanceUnit) {
132905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                Log.i(TAG, "onNextTurnDistanceChanged, distanceMeters: " + distanceMeters
133905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                        + ", timeSeconds: " + timeSeconds
134905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                        + ", displayDistanceMillis: " + displayDistanceMillis
135905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                        + ", displayDistanceUnit: " + displayDistanceUnit);
136905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                mListener.onShowToast("Next turn distance: " + distanceMeters + " meters.");
137905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
138905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        };
139905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
140905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Log.i(TAG, "createNavigationRenderer, returns: " + navigationRenderer);
141905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        return navigationRenderer;
142905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
143905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
144905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    class LocalBinder extends Binder {
145905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        SampleClusterServiceImpl getService() {
146905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            // Return this instance of LocalService so clients can call public methods
147905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            return SampleClusterServiceImpl.this;
148905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        }
149905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
150905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
151905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    interface Listener {
152905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        void onKeyEvent(KeyEvent event);
153905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        void onShowToast(String text);
154905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
155905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
156905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    @Override
157905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
158905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        if (args != null && args.length > 0) {
159905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            execShellCommand(args);
160905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        }
161905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
162905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
163905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    private void doKeyEvent(int keyCode) {
164905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Log.i(TAG, "doKeyEvent, keyCode: " + keyCode);
165905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        long downTime = SystemClock.uptimeMillis();
166905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        long eventTime = SystemClock.uptimeMillis();
167905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        KeyEvent event = obtainKeyEvent(keyCode, downTime, eventTime, KeyEvent.ACTION_DOWN);
168905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        onKeyEvent(event);
169905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
170905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        eventTime = SystemClock.uptimeMillis();
171905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        event = obtainKeyEvent(keyCode, downTime, eventTime, KeyEvent.ACTION_UP);
172905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        onKeyEvent(event);
173905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
174905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
175905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    private KeyEvent obtainKeyEvent(int keyCode, long downTime, long eventTime, int action) {
176905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        int scanCode = 0;
177905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
178905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            scanCode = 108;
179905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
180905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            scanCode = 106;
181905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        }
182905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        return KeyEvent.obtain(
183905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    downTime,
184905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    eventTime,
185905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    action,
186905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    keyCode,
187905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    0 /* repeat */,
188905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    0 /* meta state */,
189905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    0 /* deviceId*/,
190905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    scanCode /* scancode */,
191905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    KeyEvent.FLAG_FROM_SYSTEM /* flags */,
192905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    InputDevice.SOURCE_KEYBOARD,
193905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    null /* characters */);
194905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
195905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
196905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    private void execShellCommand(String[] args) {
197905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Log.i(TAG, "execShellCommand, args: " + Arrays.toString(args));
198905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
199905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        String command = args[0];
200905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
201905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        switch (command) {
202905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            case "injectKey": {
203905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                if (args.length > 1) {
204905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    doKeyEvent(parseInt(args[1]));
205905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                } else {
206905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    Log.i(TAG, "Not enough arguments");
207905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                }
208905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                break;
209905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
210905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            case "destroyOverlayDisplay": {
211905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                Settings.Global.putString(getContentResolver(),
212905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    Global.OVERLAY_DISPLAY_DEVICES, "");
213905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                break;
214905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
215905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
216905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            case "createOverlayDisplay": {
217905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                if (args.length > 1) {
218905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    Settings.Global.putString(getContentResolver(),
219905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                            Global.OVERLAY_DISPLAY_DEVICES, args[1]);
220905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                } else {
221905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    Log.i(TAG, "Not enough arguments, expected 2");
222905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                }
223905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                break;
224905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
225905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
226905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            case "setUnobscuredArea": {
227905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                if (args.length > 5) {
228905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    Rect unobscuredArea = new Rect(parseInt(args[2]), parseInt(args[3]),
229905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                            parseInt(args[4]), parseInt(args[5]));
230905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    try {
231905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                        setClusterActivityState(args[1],
232905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                                ClusterActivityState.create(true, unobscuredArea).toBundle());
233905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    } catch (CarNotConnectedException e) {
234905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                        Log.i(TAG, "Failed to set activity state.", e);
235905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    }
236905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                } else {
237905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                    Log.i(TAG, "wrong format, expected: category left top right bottom");
238905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev                }
239905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            }
240905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        }
241905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
242905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
243905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    private static Display getInstrumentClusterDisplay(Context context) {
244905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        DisplayManager displayManager = context.getSystemService(DisplayManager.class);
245905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Display[] displays = displayManager.getDisplays();
246905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
247905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        Log.d(TAG, "There are currently " + displays.length + " displays connected.");
248905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        for (Display display : displays) {
249905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            Log.d(TAG, "  " + display);
250905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        }
251905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
252905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        if (displays.length > 1) {
253905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            // TODO: assuming that secondary display is instrument cluster. Put this into settings?
254905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev            return displays[1];
255905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        }
256905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev        return null;
257905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev    }
258905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev
259905968cf95d4c8608d6d9351b5dd10fe994a1220Pavel Maltsev}
260