CarDrawerActivity.java revision f4a72c4f1aa2394c6c289ed89dcb95cde548f236
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;
22da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.os.Bundle;
23da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.os.Handler;
24da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.os.IBinder;
25da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.os.RemoteException;
26da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.support.annotation.LayoutRes;
27da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.support.car.app.CarActivity;
2803100f7264789a3f36713b0dd69363ce4785435aYao Chenimport android.support.v4.app.Fragment;
29da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.util.DisplayMetrics;
30da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.util.Log;
31da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.view.LayoutInflater;
32da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.view.View;
33da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport android.view.ViewGroup;
34da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
35da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
36da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.lang.ref.WeakReference;
37da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.util.ArrayList;
38da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.util.HashMap;
39da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.util.List;
40da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenimport java.util.Map;
41da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
42da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen/**
43da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen * Base class for a car app which wants to use a drawer.
44da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen */
45da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chenpublic abstract class CarDrawerActivity extends CarActivity{
46da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private static final String TAG = "CarDrawerActivity";
47da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private static final String KEY_DRAWERSHOWING =
48da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            "android.support.car.app.CarDrawerActivity.DRAWER_SHOWING";
49da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
50da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private final Handler mHandler = new Handler();
51da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
52da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private CarUiController mUiController;
53da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private CarMenuCallbacks mMenuCallbacks;
54da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private CarMenuCallbacksBinder mBinder;
55da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private boolean mDrawerShowing;
56da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private boolean mOnCreateCalled = false;
57da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
58da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public CarDrawerActivity(Proxy proxy, Context context) {
59da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        super(proxy, context);
60da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController = new CarUiController(this);
61da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
62da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
63da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    @Override
64da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setContentView(View view) {
65da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        ViewGroup parent = (ViewGroup) findViewById(mUiController.getFragmentContainerId());
66da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        parent.addView(view);
67da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
68da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
69da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    @Override
70da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setContentView(@LayoutRes int resourceId) {
71da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        ViewGroup parent = (ViewGroup) findViewById(mUiController.getFragmentContainerId());
72da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        LayoutInflater inflater = getLayoutInflater();
73da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        inflater.inflate(resourceId, parent, true);
74da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
75da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
76da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setContentFragment(Fragment fragment) {
77da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        super.setContentFragment(fragment, mUiController.getFragmentContainerId());
78da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
79da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
8003100f7264789a3f36713b0dd69363ce4785435aYao Chen    @Override
8103100f7264789a3f36713b0dd69363ce4785435aYao Chen    public View findViewById(@LayoutRes int id) {
8203100f7264789a3f36713b0dd69363ce4785435aYao Chen        return super.findViewById(mUiController.getFragmentContainerId()).findViewById(id);
8303100f7264789a3f36713b0dd69363ce4785435aYao Chen    }
8403100f7264789a3f36713b0dd69363ce4785435aYao Chen
859d3fdf2eed6187804c78df5952e7290f5ed15fc3Yao Chen    public int getFragmentContainerId() {
869d3fdf2eed6187804c78df5952e7290f5ed15fc3Yao Chen        return mUiController.getFragmentContainerId();
879d3fdf2eed6187804c78df5952e7290f5ed15fc3Yao Chen    }
889d3fdf2eed6187804c78df5952e7290f5ed15fc3Yao Chen
89da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public interface OnMenuClickListener {
90da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        /**
91da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen         * Called when the menu button is clicked.
92da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen         *
93da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen         * @return True if event was handled. This will prevent the drawer from executing its
94da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen         *         default action (opening/closing/going back). False if the event was not handled
95da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen         *         so the drawer will execute the default action.
96da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen         */
97da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        boolean onClicked();
98da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
99da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
100da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setCarMenuCallbacks(final CarMenuCallbacks callbacks) {
101da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        if (mOnCreateCalled) {
102da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            throw new IllegalStateException(
103da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    "Cannot call setCarMenuCallbacks after onCreate has been called.");
104da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
105da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mMenuCallbacks = callbacks;
106da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
107da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
108da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    /**
109da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * Listener that listens for when the menu button is pressed.
110da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     *
111da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * @param listener {@link OnMenuClickListener} that will listen for menu button clicks.
112da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     */
113da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setOnMenuClickedListener(OnMenuClickListener listener) {
114da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mBinder.setOnMenuClickedListener(listener);
115da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
116da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
117f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell    /**
118f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell     * Restore the menu button drawable
119f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell     */
120f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell    public void restoreMenuButtonDrawable() {
121f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell        mUiController.restoreMenuButtonDrawable();
122f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell    }
123f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell
124f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell    /**
125f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell     * Sets the menu button bitmap
126f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell     *
127f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell     * @param bitmap Bitmap to the menu button to.
128f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell     */
129f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell    public void setMenuButtonBitmap(Bitmap bitmap) {
130f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell        mUiController.setMenuButtonBitmap(bitmap);
131f4a72c4f1aa2394c6c289ed89dcb95cde548f236Aidan Snoswell    }
132da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
133da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    /**
134da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * Set the title of the menu.
135da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     */
136da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setTitle(CharSequence title) {
137da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.setTitle(title);
138da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
139da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
140da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    /**
141da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * Set the System UI to be light.
142da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     */
143da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setLightMode() {
144da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.setLightMode();
145da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
146da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
147da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    /**
148da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * Set the System UI to be dark.
149da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     */
150da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setDarkMode() {
151da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.setDarkMode();
152da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
153da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
154da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    /**
155da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * Set the System UI to be dark during day mode and light during night mode.
156da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     */
157da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setAutoLightDarkMode() {
158da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.setAutoLightDarkMode();
159da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
160da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
161da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    /**
162da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * Sets the application background to the given {@link android.graphics.Bitmap}.
163da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     *
164da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * @param bitmap to use as background.
165da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     */
166da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setBackground(Bitmap bitmap) {
167da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.setBackground(bitmap);
168da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
169da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
170da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    /**
171da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * Sets the background to a given resource.
172da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * The resource should refer to a Drawable object or 0 to remove the background.
173da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     *
174da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * @param resId The identifier of the resource.
175da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     */
176da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setBackgroundResource(int resId) {
177da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.setBackgroundResource(resId);
178da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
179da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
180da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void setScrimColor(int color) {
181da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.setScrimColor(color);
182da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
183da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
184da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    /**
185da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * Show the menu associated with the given id in the drawer.
186da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     *
187da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * @param id Id of the menu to link to.
188da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     * @param title Title that should be displayed.
189da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen     */
190da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void showMenu(String id, String title) {
191da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.showMenu(id, title);
192da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
193da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
194da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private void registerCarMenuCallbacks(IBinder callbacks) {
195da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.registerCarMenuCallbacks(callbacks);
196da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
197da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
198da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private final CarMenuCallbacks.OnChildrenChangedListener mMenuListener =
199da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            new CarMenuCallbacks.OnChildrenChangedListener() {
200da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                @Override
201da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                public void onChildrenChanged(String parentId) {
202da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    if (mOnCreateCalled) {
203da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        mBinder.onChildrenChanged(parentId);
204da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    }
205da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                }
206da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
207da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                @Override
208da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                public void onChildChanged(String parentId, Bundle item,
209da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                           Drawable leftIcon, Drawable rightIcon) {
210da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    DisplayMetrics metrics = getResources().getDisplayMetrics();
211da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    if (leftIcon != null) {
212da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        item.putParcelable(Constants.CarMenuConstants.KEY_LEFTICON,
213da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                Utils.snapshot(metrics, leftIcon));
214da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    }
215da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
216da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    if (rightIcon != null) {
217da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        item.putParcelable(Constants.CarMenuConstants.KEY_RIGHTICON,
218da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                Utils.snapshot(metrics, rightIcon));
219da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    }
220da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    if (mOnCreateCalled) {
221da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        mBinder.onChildChanged(parentId, item);
222da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    }
223da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                }
224da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            };
225da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
226da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    protected void onCreate(Bundle savedInstanceState) {
227da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        super.onCreate(savedInstanceState);
228da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        super.setContentView(mUiController.getContentView());
229da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mBinder = new CarMenuCallbacksBinder(this);
230da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mHandler.post(new Runnable() {
231da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            @Override
232da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            public void run() {
233da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                registerCarMenuCallbacks(mBinder);
234da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                if (mMenuCallbacks != null) {
235da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    mMenuCallbacks.registerOnChildrenChangedListener(mMenuListener);
236da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                }
237da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                mOnCreateCalled = true;
238da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
239da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        });
240da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
241da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
242da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    protected void onDestroy() {
243da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        super.onDestroy();
244da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mHandler.post(new Runnable() {
245da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            @Override
246da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            public void run() {
247da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                if (mMenuCallbacks != null) {
248da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    mMenuCallbacks.unregisterOnChildrenChangedListener(mMenuListener);
249da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    mMenuCallbacks = null;
250da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                }
251da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
252da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        });
253da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
254da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
255da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    protected void onRestoreInstanceState(Bundle savedInstanceState) {
256da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        super.onRestoreInstanceState(savedInstanceState);
257da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mDrawerShowing = savedInstanceState.getBoolean(KEY_DRAWERSHOWING);
258da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.onRestoreInstanceState(savedInstanceState);
259da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
260da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
261da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    protected void onSaveInstanceState(Bundle outState) {
262da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        super.onSaveInstanceState(outState);
263da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        outState.putBoolean(KEY_DRAWERSHOWING, mDrawerShowing);
264da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.onSaveInstanceState(outState);
265da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
266da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
267da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void closeDrawer() {
268da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.closeDrawer();
269da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
270da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
271da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    public void openDrawer() {
272da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        mUiController.openDrawer();
273da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
274da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
275da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    private static class CarMenuCallbacksBinder extends ICarMenuCallbacks.Stub {
276da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        // Map of subscribed ids to their respective callbacks.
277da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        private final Map<String, List<ISubscriptionCallbacks>> mSubscriptionMap = new HashMap<>();
278da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        private OnMenuClickListener mMenuClickListener;
279da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        private final WeakReference<CarDrawerActivity> mActivity;
280da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
281da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        CarMenuCallbacksBinder(CarDrawerActivity activity) {
282da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            mActivity = new WeakReference<>(activity);
283da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
284da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
285da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
286da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public int getVersion() {
287da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            return 0;
288da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
289da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
290da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
291da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public Bundle getRoot() throws RemoteException {
292da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
293da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (activity != null && activity.mMenuCallbacks != null) {
294da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                Root root = activity.mMenuCallbacks.onGetRoot(null);
295da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                return root.getBundle();
296da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            } else {
297da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                return null;
298da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
299da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
300da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
301da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
302da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public synchronized void subscribe(final String parentId,
303da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                           final ISubscriptionCallbacks callbacks) throws RemoteException {
304da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (!mSubscriptionMap.containsKey(parentId)) {
305da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                mSubscriptionMap.put(parentId, new ArrayList<ISubscriptionCallbacks>());
306da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
307da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            mSubscriptionMap.get(parentId).add(callbacks);
308da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            loadResultsForClient(parentId, callbacks);
309da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
310da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
311da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
312da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public synchronized void unsubscribe(String id, ISubscriptionCallbacks callbacks)
313da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                throws RemoteException {
314da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            mSubscriptionMap.get(id).remove(callbacks);
315da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
316da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
317da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
318da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void onCarMenuOpened() throws RemoteException {
319da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
320da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (activity != null) {
321da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                activity.mDrawerShowing = true;
322da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                activity.mMenuCallbacks.onCarMenuOpened();
323da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
324da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
325da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
326da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
327da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
328da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void onCarMenuClosing() throws RemoteException {
329da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
330da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
331da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
332da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void onCarMenuClosed() throws RemoteException {
333da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
334da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            activity.mDrawerShowing = false;
335da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
336da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
337da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
338da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void onCarMenuOpening() throws RemoteException {
339da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
340da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            activity.mDrawerShowing = true;
341da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
342da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
343da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
344da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void onItemClicked(String id) throws RemoteException {
345da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
346da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (activity != null) {
347da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                activity.mMenuCallbacks.onItemClicked(id);
348da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                // TODO: Add support for IME
349da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                // activity.stopInput();
350da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
351da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
352da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
353da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
354da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public boolean onItemLongClicked(String id) throws RemoteException {
355da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
356da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (activity != null) {
357da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                return activity.mMenuCallbacks.onItemLongClicked(id);
358da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            } else {
359da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                return false;
360da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
361da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
362da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
363da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
364da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void onStateChanged(int newState) throws RemoteException {
365da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
366da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (activity != null) {
367da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                activity.mMenuCallbacks.onStateChanged(newState);
368da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
369da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
370da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
371da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void setOnMenuClickedListener(OnMenuClickListener listener) {
372da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            mMenuClickListener = listener;
373da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
374da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
375da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        @Override
376da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public boolean onMenuClicked() {
377da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
378da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (activity == null) {
379da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                return false;
380da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
381da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
382da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (mMenuClickListener != null) {
383da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                if (mMenuClickListener.onClicked()) {
384da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    return true;
385da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                }
386da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
387da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            return false;
388da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
389da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
390da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void onChildrenChanged(String parentId) {
391da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (mSubscriptionMap.containsKey(parentId)) {
392da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                loadResultsForAllClients(parentId);
393da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
394da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
395da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
396da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        public void reloadSubscribedMenus() {
397da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            for (String parentId : mSubscriptionMap.keySet()) {
398da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                loadResultsForAllClients(parentId);
399da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
400da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
401da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
402da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        private void loadResultsForClient(final String parentId,
403da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                          final ISubscriptionCallbacks callbacks) {
404da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
405da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (activity == null) {
406da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                return;
407da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
408da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
409da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            final CarMenu result = new CarMenu(activity.getResources().getDisplayMetrics()) {
410da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                @Override
411da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                protected void onResultReady(List<Bundle> list) {
412da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    synchronized (CarMenuCallbacksBinder.this) {
413da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        try {
414da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                            callbacks.onChildrenLoaded(parentId, list);
415da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        } catch (RemoteException e) {
416da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                            Log.e(TAG, "Error calling onChildrenLoaded: ", e);
417da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        }
418da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    }
419da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                }
420da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            };
421da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
422da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            activity.mMenuCallbacks.onLoadChildren(parentId, result);
423da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (!result.isDone()) {
424da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                throw new IllegalStateException("You must either call sendResult() or detach() " +
425da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        "before returning!");
426da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
427da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
428da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
429da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        private void loadResultsForAllClients(final String parentId) {
430da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            CarDrawerActivity activity = mActivity.get();
431da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (activity == null) {
432da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                return;
433da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
434da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
435da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            final CarMenu result = new CarMenu(activity.getResources().getDisplayMetrics()) {
436da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                @Override
437da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                protected void onResultReady(List<Bundle> list) {
438da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    synchronized (CarMenuCallbacksBinder.this) {
439da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        if (mSubscriptionMap.containsKey(parentId)) {
440da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                            try {
441da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                for (ISubscriptionCallbacks callbacks :
442da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                        mSubscriptionMap.get(parentId)) {
443da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                    callbacks.onChildrenLoaded(parentId, list);
444da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                }
445da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                            } catch (RemoteException e) {
446da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                                Log.e(TAG, "Error calling onChildrenLoaded: ", e);
447da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                            }
448da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        }
449da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    }
450da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                }
451da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            };
452da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
453da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            activity.mMenuCallbacks.onLoadChildren(parentId, result);
454da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
455da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen
456da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        private synchronized void onChildChanged(String parentId, Bundle item) {
457da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            if (mSubscriptionMap.containsKey(parentId)) {
458da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                for (ISubscriptionCallbacks callbacks : mSubscriptionMap.get(parentId)) {
459da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    try {
460da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        callbacks.onChildChanged(parentId, item);
461da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    } catch (RemoteException e) {
462da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                        Log.e(TAG, "Error calling onChildChanged: ", e);
463da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                    }
464da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen                }
465da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen            }
466da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen        }
467da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen    }
468da63b8de8a536a9e19c5443fcc3e2d4d2316f5eaYao Chen}
469