CarDrawerActivity.java revision 13df550560fd8e7e6287603a112659cca244eeee
1da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen/* 2da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Copyright (C) 2015 The Android Open Source Project 3da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * 4da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * you may not use this file except in compliance with the License. 6da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * You may obtain a copy of the License at 7da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * 8da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * http://www.apache.org/licenses/LICENSE-2.0 9da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * 10da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Unless required by applicable law or agreed to in writing, software 11da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * distributed under the License is distributed on an "AS IS" BASIS, 12da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * See the License for the specific language governing permissions and 14da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * limitations under the License. 15da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 16da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 17da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenpackage android.support.car.app.menu; 18da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 19da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.content.Context; 20da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.graphics.Bitmap; 21da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.graphics.drawable.Drawable; 2270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.hardware.input.InputManager; 23da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.os.Bundle; 24da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.os.Handler; 25da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.os.IBinder; 26da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.os.RemoteException; 27da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.support.annotation.LayoutRes; 2813df550560fd8e7e6287603a112659cca244eeeeYao Chenimport android.support.car.Car; 29868f9e6e890eeaf3281e55475f102cb677d6032aYao Chenimport android.support.car.app.CarFragmentActivity; 3070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.support.car.input.CarEditable; 3170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.support.car.input.CarEditableListener; 3270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.support.car.input.CarInputManager; 3370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.support.car.input.CarRestrictedEditText; 3403100f7264789a3f36713b0dd69363ce4785435aYao Chenimport android.support.v4.app.Fragment; 35da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.util.DisplayMetrics; 36da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.util.Log; 37da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.view.LayoutInflater; 38da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.view.View; 39da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.view.ViewGroup; 4070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.view.WindowManager; 4170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.view.inputmethod.EditorInfo; 4270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.view.inputmethod.InputConnection; 4370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.view.inputmethod.InputConnectionWrapper; 4470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.view.inputmethod.InputMethodManager; 4570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chenimport android.widget.EditText; 46da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 47da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 48da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.lang.ref.WeakReference; 49da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.util.ArrayList; 50da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.util.HashMap; 51da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.util.List; 52da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.util.Map; 53da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 54da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen/** 55da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Base class for a car app which wants to use a drawer. 56da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 57868f9e6e890eeaf3281e55475f102cb677d6032aYao Chenpublic abstract class CarDrawerActivity extends CarFragmentActivity { 58da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private static final String TAG = "CarDrawerActivity"; 59da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private static final String KEY_DRAWERSHOWING = 60da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen "android.support.car.app.CarDrawerActivity.DRAWER_SHOWING"; 6170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private static final String KEY_INPUTSHOWING = 6270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen "android.support.car.app.CarDrawerActivity.INPUT_SHOWING"; 6370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private static final String KEY_SEARCHBOXENABLED = 6470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen "android.support.car.app.CarDrawerActivity.SEARCH_BOX_ENABLED"; 65da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 66da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private final Handler mHandler = new Handler(); 6770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private final CarUiController mUiController; 68da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 69da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private CarMenuCallbacks mMenuCallbacks; 70da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private CarMenuCallbacksBinder mBinder; 71da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private boolean mDrawerShowing; 7270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private boolean mShowingSearchBox; 7370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private boolean mSearchBoxEnabled; 74da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private boolean mOnCreateCalled = false; 7570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private View.OnClickListener mSearchBoxOnClickListener; 7670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 7770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private CarInputManager mInputManager; 7870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private EditText mSearchBoxView; 7970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 8070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen /** 8170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * Simple interface to listen for keyboard events. 8270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen */ 8370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public interface SearchBoxEditListener { 8470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen /** 8570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * The user hit enter on the keyboard. 8670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen */ 8770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen void onSearch(String text); 8870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 8970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen /** 9070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * The user changed the text in the search box with the keyboard. 9170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen */ 9270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen void onEdit(String text); 9370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 94da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 9513df550560fd8e7e6287603a112659cca244eeeeYao Chen public CarDrawerActivity(Proxy proxy, Context context, Car car) { 9613df550560fd8e7e6287603a112659cca244eeeeYao Chen super(proxy, context, car); 97da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController = new CarUiController(this); 98da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 99da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 100da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 101da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setContentView(View view) { 102da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen ViewGroup parent = (ViewGroup) findViewById(mUiController.getFragmentContainerId()); 103da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen parent.addView(view); 104da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 105da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 106da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 107da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setContentView(@LayoutRes int resourceId) { 108da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen ViewGroup parent = (ViewGroup) findViewById(mUiController.getFragmentContainerId()); 109da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen LayoutInflater inflater = getLayoutInflater(); 110da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen inflater.inflate(resourceId, parent, true); 111da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 112da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 113da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setContentFragment(Fragment fragment) { 114da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen super.setContentFragment(fragment, mUiController.getFragmentContainerId()); 115da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 116da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 11703100f7264789a3f36713b0dd69363ce4785435aYao Chen @Override 11803100f7264789a3f36713b0dd69363ce4785435aYao Chen public View findViewById(@LayoutRes int id) { 11903100f7264789a3f36713b0dd69363ce4785435aYao Chen return super.findViewById(mUiController.getFragmentContainerId()).findViewById(id); 12003100f7264789a3f36713b0dd69363ce4785435aYao Chen } 12103100f7264789a3f36713b0dd69363ce4785435aYao Chen 122d33cc25ece71923740ebc87be2048475b452cf0bYao Chen @Override 123d33cc25ece71923740ebc87be2048475b452cf0bYao Chen protected void onStart() { 124d33cc25ece71923740ebc87be2048475b452cf0bYao Chen super.onStart(); 12570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 126d33cc25ece71923740ebc87be2048475b452cf0bYao Chen mUiController.onStart(); 127d33cc25ece71923740ebc87be2048475b452cf0bYao Chen } 128d33cc25ece71923740ebc87be2048475b452cf0bYao Chen 129d33cc25ece71923740ebc87be2048475b452cf0bYao Chen @Override 130d33cc25ece71923740ebc87be2048475b452cf0bYao Chen protected void onResume() { 131d33cc25ece71923740ebc87be2048475b452cf0bYao Chen super.onResume(); 132d33cc25ece71923740ebc87be2048475b452cf0bYao Chen mUiController.onResume(); 133d33cc25ece71923740ebc87be2048475b452cf0bYao Chen } 134d33cc25ece71923740ebc87be2048475b452cf0bYao Chen 135d33cc25ece71923740ebc87be2048475b452cf0bYao Chen @Override 136d33cc25ece71923740ebc87be2048475b452cf0bYao Chen protected void onPause() { 137d33cc25ece71923740ebc87be2048475b452cf0bYao Chen super.onPause(); 138d33cc25ece71923740ebc87be2048475b452cf0bYao Chen mUiController.onPause(); 139d33cc25ece71923740ebc87be2048475b452cf0bYao Chen } 140d33cc25ece71923740ebc87be2048475b452cf0bYao Chen 141d33cc25ece71923740ebc87be2048475b452cf0bYao Chen @Override 142d33cc25ece71923740ebc87be2048475b452cf0bYao Chen protected void onStop() { 143d33cc25ece71923740ebc87be2048475b452cf0bYao Chen super.onStop(); 144d33cc25ece71923740ebc87be2048475b452cf0bYao Chen mUiController.onStop(); 145d33cc25ece71923740ebc87be2048475b452cf0bYao Chen } 146d33cc25ece71923740ebc87be2048475b452cf0bYao Chen 1479d3fdf2eed6187804c78df5952e7290f5ed15fc3Yao Chen public int getFragmentContainerId() { 1489d3fdf2eed6187804c78df5952e7290f5ed15fc3Yao Chen return mUiController.getFragmentContainerId(); 1499d3fdf2eed6187804c78df5952e7290f5ed15fc3Yao Chen } 1509d3fdf2eed6187804c78df5952e7290f5ed15fc3Yao Chen 151da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public interface OnMenuClickListener { 152da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 153da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Called when the menu button is clicked. 154da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * 155da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * @return True if event was handled. This will prevent the drawer from executing its 156da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * default action (opening/closing/going back). False if the event was not handled 157da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * so the drawer will execute the default action. 158da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 159da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen boolean onClicked(); 160da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 161da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 162da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setCarMenuCallbacks(final CarMenuCallbacks callbacks) { 163da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mOnCreateCalled) { 164da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen throw new IllegalStateException( 165da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen "Cannot call setCarMenuCallbacks after onCreate has been called."); 166da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 167da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mMenuCallbacks = callbacks; 168da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 169da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 170da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 171da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Listener that listens for when the menu button is pressed. 172da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * 173da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * @param listener {@link OnMenuClickListener} that will listen for menu button clicks. 174da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 175da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setOnMenuClickedListener(OnMenuClickListener listener) { 176da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mBinder.setOnMenuClickedListener(listener); 177da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 178da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 179f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell /** 180f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell * Restore the menu button drawable 181f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell */ 182f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell public void restoreMenuButtonDrawable() { 183f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell mUiController.restoreMenuButtonDrawable(); 184f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell } 185f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell 186f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell /** 187f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell * Sets the menu button bitmap 188f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell * 189f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell * @param bitmap Bitmap to the menu button to. 190f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell */ 191f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell public void setMenuButtonBitmap(Bitmap bitmap) { 192f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell mUiController.setMenuButtonBitmap(bitmap); 193f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell } 194da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 195da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 196da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Set the title of the menu. 197da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 198da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setTitle(CharSequence title) { 199da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.setTitle(title); 200da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 201da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 202da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 203da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Set the System UI to be light. 204da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 205da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setLightMode() { 206da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.setLightMode(); 207da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 208da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 209da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 210da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Set the System UI to be dark. 211da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 212da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setDarkMode() { 213da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.setDarkMode(); 214da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 215da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 216da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 217da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Set the System UI to be dark during day mode and light during night mode. 218da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 219da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setAutoLightDarkMode() { 220da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.setAutoLightDarkMode(); 221da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 222da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 223da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 224da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Sets the application background to the given {@link android.graphics.Bitmap}. 225da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * 226da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * @param bitmap to use as background. 227da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 228da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setBackground(Bitmap bitmap) { 229da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.setBackground(bitmap); 230da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 231da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 232da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 233da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Sets the background to a given resource. 234da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * The resource should refer to a Drawable object or 0 to remove the background. 235da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * 236da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * @param resId The identifier of the resource. 237da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 238da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setBackgroundResource(int resId) { 239da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.setBackgroundResource(resId); 240da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 241da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 242da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setScrimColor(int color) { 243da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.setScrimColor(color); 244da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 245da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 246da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen /** 247da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Show the menu associated with the given id in the drawer. 248da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * 249da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * @param id Id of the menu to link to. 250da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * @param title Title that should be displayed. 251da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */ 252da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void showMenu(String id, String title) { 253da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.showMenu(id, title); 254da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 255da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 256da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private void registerCarMenuCallbacks(IBinder callbacks) { 257da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.registerCarMenuCallbacks(callbacks); 258da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 259da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 260da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private final CarMenuCallbacks.OnChildrenChangedListener mMenuListener = 261da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen new CarMenuCallbacks.OnChildrenChangedListener() { 262da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 263da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onChildrenChanged(String parentId) { 264da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mOnCreateCalled) { 265da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mBinder.onChildrenChanged(parentId); 266da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 267da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 268da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 269da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 270da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onChildChanged(String parentId, Bundle item, 271da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen Drawable leftIcon, Drawable rightIcon) { 272da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen DisplayMetrics metrics = getResources().getDisplayMetrics(); 273da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (leftIcon != null) { 274da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen item.putParcelable(Constants.CarMenuConstants.KEY_LEFTICON, 275da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen Utils.snapshot(metrics, leftIcon)); 276da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 277da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 278da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (rightIcon != null) { 279da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen item.putParcelable(Constants.CarMenuConstants.KEY_RIGHTICON, 280da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen Utils.snapshot(metrics, rightIcon)); 281da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 282da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mOnCreateCalled) { 283da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mBinder.onChildChanged(parentId, item); 284da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 285da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 286da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen }; 287da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 288da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen protected void onCreate(Bundle savedInstanceState) { 289da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen super.onCreate(savedInstanceState); 290da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen super.setContentView(mUiController.getContentView()); 291da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mBinder = new CarMenuCallbacksBinder(this); 29270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mInputManager = getInputManager(); 293da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mHandler.post(new Runnable() { 294da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 295da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void run() { 296da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen registerCarMenuCallbacks(mBinder); 297da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mMenuCallbacks != null) { 298da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mMenuCallbacks.registerOnChildrenChangedListener(mMenuListener); 299da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 300da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mOnCreateCalled = true; 301da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 302da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen }); 303da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 304da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 305da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen protected void onDestroy() { 306da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen super.onDestroy(); 307da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mHandler.post(new Runnable() { 308da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 309da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void run() { 310da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mMenuCallbacks != null) { 311da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mMenuCallbacks.unregisterOnChildrenChangedListener(mMenuListener); 312da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mMenuCallbacks = null; 313da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 314da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 315da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen }); 316da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 317da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 318da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen protected void onRestoreInstanceState(Bundle savedInstanceState) { 319da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen super.onRestoreInstanceState(savedInstanceState); 320da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mDrawerShowing = savedInstanceState.getBoolean(KEY_DRAWERSHOWING); 321da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.onRestoreInstanceState(savedInstanceState); 322da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 323da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 324da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen protected void onSaveInstanceState(Bundle outState) { 325da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen super.onSaveInstanceState(outState); 326da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen outState.putBoolean(KEY_DRAWERSHOWING, mDrawerShowing); 327da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.onSaveInstanceState(outState); 328da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 329da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 330da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void closeDrawer() { 331da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.closeDrawer(); 332da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 333da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 334da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void openDrawer() { 335da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mUiController.openDrawer(); 336da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 337da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 33870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public boolean isDrawerShowing() { 33970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen return mDrawerShowing; 34070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 34170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 34270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen /** 34370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * Shows a small clickable {@link android.widget.EditText}. 34470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * 34570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * {@link View} will be {@code null} in {@link View.OnClickListener#onClick(View)}. 34670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * 34770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * @param listener {@link View.OnClickListener} that is called when user selects the 34870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * {@link android.widget.EditText}. 34970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen */ 35070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void showSearchBox(View.OnClickListener listener) { 35170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (!isDrawerShowing()) { 35270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mUiController.showSearchBox(listener); 35370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mShowingSearchBox = true; 35470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 35570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mSearchBoxEnabled = true; 35670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mSearchBoxOnClickListener = listener; 35770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 35870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 35970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void hideSearchBox() { 36070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (isShowingSearchBox()) { 36170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen stopInput(); 36270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 36370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mSearchBoxEnabled = false; 36470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 36570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 36670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public boolean isShowingSearchBox() { 36770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen return mShowingSearchBox; 36870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 36970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 37070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void setSearchBoxEditListener(SearchBoxEditListener listener) { 37170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mUiController.setSearchBoxEditListener(new SearchBoxEditListenerBinder(listener)); 37270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 37370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 37470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void stopInput() { 37570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen // STOPSHIP: sometimes focus is lost and we are not able to hide the keyboard. 37670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen // properly fix this before we ship. 37770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (mSearchBoxView != null) { 37870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mSearchBoxView.requestFocusFromTouch(); 37970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 38070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mUiController.stopInput(); 38170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mInputManager.stopInput(); 38270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mShowingSearchBox = false; 38370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 38470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 38570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen /** 38670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * Start input on the search box that is provided by a car ui provider. 38770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * TODO: Migrate to use the new input/search api once it becomes stable (b/27108311). 38870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * @param hint Search hint 38970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen */ 39070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void startInput(String hint) { 39170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen startInput(hint, mSearchBoxOnClickListener); 39270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 39370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 39470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen /** 39570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * Start input on the search box that is provided by a car ui provider. 39670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * TODO: Migrate to use the new input/search api once it becomes stable (b/27108311). 39770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * @param hint Search hint 39870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen * @param onClickListener Listener for the search box clicks. 39970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen */ 40070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void startInput(final String hint, final View.OnClickListener onClickListener) { 40170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mInputManager = getInputManager(); 40270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen EditText inputView = mUiController.startSearchInput(hint, onClickListener); 40370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen getInputManager().startInput(inputView); 40470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mSearchBoxView = inputView; 40570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mShowingSearchBox = true; 40670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 40770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 40870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void setSearchBoxColors(int backgroundColor, int googleLogoColor, int textColor, 40970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen int hintTextColor) { 41070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mUiController.setSearchBoxColors(backgroundColor, googleLogoColor, textColor, hintTextColor); 41170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 41270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 41370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void setSearchBoxEndView(View endView) { 41470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mUiController.setSearchBoxEndView(endView); 41570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 41670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 41770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void showToast(String text, int duration) { 41870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 41970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 42070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private static class SearchBoxEditListenerBinder extends ISearchBoxEditListener.Stub { 42170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen private final SearchBoxEditListener mListener; 42270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 42370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public SearchBoxEditListenerBinder(SearchBoxEditListener listener) { 42470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (listener == null) { 42570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen throw new IllegalArgumentException("Listener cannot be null"); 42670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 42770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mListener = listener; 42870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 42970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 43070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen @Override 43170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void onSearch(String text) { 43270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mListener.onSearch(text); 43370f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 43470f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 43570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen @Override 43670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen public void onEdit(String text) { 43770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen mListener.onEdit(text); 43870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 43970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 44070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen 441da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private static class CarMenuCallbacksBinder extends ICarMenuCallbacks.Stub { 442da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen // Map of subscribed ids to their respective callbacks. 443da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private final Map<String, List<ISubscriptionCallbacks>> mSubscriptionMap = new HashMap<>(); 444da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private OnMenuClickListener mMenuClickListener; 445da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private final WeakReference<CarDrawerActivity> mActivity; 446da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 447da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarMenuCallbacksBinder(CarDrawerActivity activity) { 448da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mActivity = new WeakReference<>(activity); 449da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 450da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 451da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 452da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public int getVersion() { 453da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return 0; 454da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 455da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 456da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 457da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public Bundle getRoot() throws RemoteException { 458da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 459da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (activity != null && activity.mMenuCallbacks != null) { 460da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen Root root = activity.mMenuCallbacks.onGetRoot(null); 461da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return root.getBundle(); 462da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } else { 463da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return null; 464da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 465da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 466da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 467da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 468da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public synchronized void subscribe(final String parentId, 469da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen final ISubscriptionCallbacks callbacks) throws RemoteException { 470da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (!mSubscriptionMap.containsKey(parentId)) { 471da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mSubscriptionMap.put(parentId, new ArrayList<ISubscriptionCallbacks>()); 472da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 473da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mSubscriptionMap.get(parentId).add(callbacks); 474da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen loadResultsForClient(parentId, callbacks); 475da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 476da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 477da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 478da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public synchronized void unsubscribe(String id, ISubscriptionCallbacks callbacks) 479da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen throws RemoteException { 480da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mSubscriptionMap.get(id).remove(callbacks); 481da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 482da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 483da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 484da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onCarMenuOpened() throws RemoteException { 485da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 486da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (activity != null) { 487da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen activity.mDrawerShowing = true; 488da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen activity.mMenuCallbacks.onCarMenuOpened(); 489da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 490da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 491da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 492da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 493da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 494da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onCarMenuClosing() throws RemoteException { 49570f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen CarDrawerActivity activity = mActivity.get(); 49670f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (activity != null) { 49770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (activity.mSearchBoxEnabled) { 49870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen activity.mUiController.showSearchBox(activity.mSearchBoxOnClickListener); 49970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen activity.mShowingSearchBox = true; 50070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 50170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 502da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 503da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 504da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 505da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onCarMenuClosed() throws RemoteException { 506da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 50770f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (activity != null) { 50870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen activity.mDrawerShowing = false; 50970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (activity.mSearchBoxEnabled && !activity.mShowingSearchBox) { 51070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen activity.showSearchBox(activity.mSearchBoxOnClickListener); 51170f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 51270f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 513da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 514da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 515da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 516da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onCarMenuOpening() throws RemoteException { 517da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 51870f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen if (activity != null) { 51970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen activity.stopInput(); 52070f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen } 521da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 522da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 523da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 524da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onItemClicked(String id) throws RemoteException { 525da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 526da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (activity != null) { 527da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen activity.mMenuCallbacks.onItemClicked(id); 528da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen // TODO: Add support for IME 52970f6a63ea01a15f33f282edcf31948a35b789aa7Yao Chen activity.stopInput(); 530da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 531da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 532da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 533da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 534da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public boolean onItemLongClicked(String id) throws RemoteException { 535da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 536da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (activity != null) { 537da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return activity.mMenuCallbacks.onItemLongClicked(id); 538da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } else { 539da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return false; 540da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 541da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 542da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 543da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 544da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onStateChanged(int newState) throws RemoteException { 545da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 546da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (activity != null) { 547da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen activity.mMenuCallbacks.onStateChanged(newState); 548da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 549da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 550da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 551da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void setOnMenuClickedListener(OnMenuClickListener listener) { 552da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mMenuClickListener = listener; 553da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 554da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 555da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 556da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public boolean onMenuClicked() { 557da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 558da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (activity == null) { 559da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return false; 560da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 561da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 562da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mMenuClickListener != null) { 563da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mMenuClickListener.onClicked()) { 564da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return true; 565da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 566da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 567da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return false; 568da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 569da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 570da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void onChildrenChanged(String parentId) { 571da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mSubscriptionMap.containsKey(parentId)) { 572da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen loadResultsForAllClients(parentId); 573da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 574da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 575da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 576da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen public void reloadSubscribedMenus() { 577da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen for (String parentId : mSubscriptionMap.keySet()) { 578da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen loadResultsForAllClients(parentId); 579da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 580da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 581da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 582da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private void loadResultsForClient(final String parentId, 583da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen final ISubscriptionCallbacks callbacks) { 584da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 585da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (activity == null) { 586da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return; 587da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 588da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 589da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen final CarMenu result = new CarMenu(activity.getResources().getDisplayMetrics()) { 590da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 591da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen protected void onResultReady(List<Bundle> list) { 592da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen synchronized (CarMenuCallbacksBinder.this) { 593da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen try { 594da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen callbacks.onChildrenLoaded(parentId, list); 595da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } catch (RemoteException e) { 596da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen Log.e(TAG, "Error calling onChildrenLoaded: ", e); 597da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 598da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 599da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 600da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen }; 601da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 602da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen activity.mMenuCallbacks.onLoadChildren(parentId, result); 603da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (!result.isDone()) { 604da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen throw new IllegalStateException("You must either call sendResult() or detach() " + 605da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen "before returning!"); 606da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 607da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 608da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 609da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private void loadResultsForAllClients(final String parentId) { 610da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen CarDrawerActivity activity = mActivity.get(); 611da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (activity == null) { 612da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen return; 613da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 614da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 615da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen final CarMenu result = new CarMenu(activity.getResources().getDisplayMetrics()) { 616da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen @Override 617da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen protected void onResultReady(List<Bundle> list) { 618da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen synchronized (CarMenuCallbacksBinder.this) { 619da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mSubscriptionMap.containsKey(parentId)) { 620da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen try { 621da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen for (ISubscriptionCallbacks callbacks : 622da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen mSubscriptionMap.get(parentId)) { 623da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen callbacks.onChildrenLoaded(parentId, list); 624da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 625da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } catch (RemoteException e) { 626da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen Log.e(TAG, "Error calling onChildrenLoaded: ", e); 627da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 628da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 629da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 630da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 631da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen }; 632da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 633da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen activity.mMenuCallbacks.onLoadChildren(parentId, result); 634da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 635da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen 636da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen private synchronized void onChildChanged(String parentId, Bundle item) { 637da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen if (mSubscriptionMap.containsKey(parentId)) { 638da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen for (ISubscriptionCallbacks callbacks : mSubscriptionMap.get(parentId)) { 639da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen try { 640da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen callbacks.onChildChanged(parentId, item); 641da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } catch (RemoteException e) { 642da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen Log.e(TAG, "Error calling onChildChanged: ", e); 643da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 644da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 645da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 646da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 647da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen } 648da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen} 649