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