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