165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen/* 265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * Copyright (C) 2016 The Android Open Source Project 365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * 465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * Licensed under the Apache License, Version 2.0 (the "License"); 565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * you may not use this file except in compliance with the License. 665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * You may obtain a copy of the License at 765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * 865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * http://www.apache.org/licenses/LICENSE-2.0 965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * 1065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * Unless required by applicable law or agreed to in writing, software 1165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * distributed under the License is distributed on an "AS IS" BASIS, 1265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * See the License for the specific language governing permissions and 1465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen * limitations under the License. 1565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen */ 1665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenpackage android.support.car.app.menu.compat; 1765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 1865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport android.car.app.menu.RootMenu; 1965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport android.car.app.menu.SubscriptionCallbacks; 2065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport android.os.Bundle; 2165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport android.os.Handler; 2265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport android.support.annotation.NonNull; 2365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport android.support.car.app.menu.CarDrawerActivity; 2465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport android.support.car.app.menu.CarMenu; 2565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport android.support.car.app.menu.CarMenuCallbacks; 2665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 2765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport java.util.ArrayList; 2865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport java.util.HashMap; 2965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport java.util.List; 3065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenimport java.util.Map; 3165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 3265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chenpublic class EmbeddedCarMenuCallbacksCompat extends android.car.app.menu.CarMenuCallbacks { 3365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 3465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen private final CarMenuCallbacks mCallbacks; 3565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen private final CarDrawerActivity mActivity; 3665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 3765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen // Map of subscribed ids to their respective callbacks. 38fe15bd1c313e956181f8f2197a2b21c675c6a60dVitalii Tomkiv // @GuardedBy("this") 3965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen private final Map<String, List<SubscriptionCallbacks>> mSubscriptionMap = 4065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen new HashMap<String, List<SubscriptionCallbacks>>(); 4165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 4265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen private final Handler mHandler = new Handler(); 4365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 4465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public EmbeddedCarMenuCallbacksCompat(CarDrawerActivity activity, 4565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen CarMenuCallbacks callbacks) { 4665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mActivity = activity; 4765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mCallbacks = callbacks; 4865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 4965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 5065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 5165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public RootMenu getRootMenu(Bundle hint) { 5265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen android.support.car.app.menu.RootMenu rootMenu = mCallbacks.onGetRoot(hint); 5365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen return new RootMenu(rootMenu.getId(), rootMenu.getBundle()); 5465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 5565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 5665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 5765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void subscribe(String parentId, SubscriptionCallbacks callbacks) { 5865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen synchronized (this) { 5965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen if (!mSubscriptionMap.containsKey(parentId)) { 6065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mSubscriptionMap.put(parentId, new ArrayList<SubscriptionCallbacks>()); 6165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 6265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mSubscriptionMap.get(parentId).add(callbacks); 6365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen loadResultsForClient(parentId, callbacks); 6465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 6565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 6665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 6765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 6865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void unsubscribe(String parentId, SubscriptionCallbacks callbacks) { 6965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen synchronized (this) { 7065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mSubscriptionMap.get(parentId).remove(callbacks); 7165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 7265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 7365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 7465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 7565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void onCarMenuOpened() { 7665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mActivity.setDrawerShowing(true); 7765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mCallbacks.onCarMenuOpened(); 7865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 7965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 8065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 8165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void onCarMenuClosed() { 8265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mActivity.setDrawerShowing(false); 8365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mActivity.restoreSearchBox(); 8465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 8565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 8665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 8765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void onItemClicked(String id) { 8865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mCallbacks.onItemClicked(id); 8965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mActivity.stopInput(); 9065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 9165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 9265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 9365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public boolean onItemLongClicked(String id) { 9465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen return mCallbacks.onItemLongClicked(id); 9565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 9665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 9765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 9865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public boolean onMenuClicked() { 9965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 10065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen return mActivity.onMenuClicked(); 10165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 10265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 10365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 10465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void onCarMenuOpening() { 10565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mActivity.stopInput(); 10665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 10765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 10865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 10965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void onCarMenuClosing() { 11065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mActivity.restoreSearchBox(); 11165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 11265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 11365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void onChildrenChanged(final String parentId) { 11465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen synchronized (this) { 11565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen if (mSubscriptionMap.containsKey(parentId)) { 11665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen final List<SubscriptionCallbacks> callbacks = new ArrayList<>(); 11765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen callbacks.addAll(mSubscriptionMap.get(parentId)); 11865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mHandler.post(new Runnable() { 11965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 12065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void run() { 12165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen loadResultsForAllClients(parentId, callbacks); 12265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 12365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen }); 12465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 12565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 12665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 12765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 12865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void onChildChanged(final String parentId, final Bundle item) { 12965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen synchronized (this) { 13065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen if (mSubscriptionMap.containsKey(parentId)) { 13165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen final List<SubscriptionCallbacks> callbacks = new ArrayList<>(); 13265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen callbacks.addAll(mSubscriptionMap.get(parentId)); 13365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mHandler.post(new Runnable() { 13465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 13565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen public void run() { 13665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen for (SubscriptionCallbacks callback : callbacks) { 13765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen callback.onChildChanged(parentId, item); 13865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 13965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 14065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen }); 14165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 14265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 14365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 14465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 14565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 14665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen private void loadResultsForAllClients(final String parentId, 14765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @NonNull final List<SubscriptionCallbacks> callbacks) { 14865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen final CarMenu result = new CarMenu(mActivity.getResources().getDisplayMetrics()) { 14965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 15065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen protected void onResultReady(List<Bundle> list) { 15165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen for (SubscriptionCallbacks callback : callbacks) { 15265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen callback.onChildrenLoaded(parentId, list); 15365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 15465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 15565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen }; 15665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 15765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mCallbacks.onLoadChildren(parentId, result); 15865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen if (!result.isDone()) { 15965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen throw new IllegalStateException("You must either call sendResult() or detach() " + 16065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen "before returning!"); 16165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 16265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 16365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 16465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen private void loadResultsForClient(final String parentId, 16565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen final SubscriptionCallbacks callbacks) { 16665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen final CarMenu result = new CarMenu(mActivity.getResources().getDisplayMetrics()) { 16765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen @Override 16865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen protected void onResultReady(List<Bundle> list) { 16965de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen callbacks.onChildrenLoaded(parentId, list); 17065de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 17165de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen }; 17265de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen 17365de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen mCallbacks.onLoadChildren(parentId, result); 17465de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen if (!result.isDone()) { 17565de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen throw new IllegalStateException("You must either call sendResult() or detach() " + 17665de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen "before returning!"); 17765de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 17865de2039a94251f62d02a32e3136c0db4fc80d90Yao Chen } 179fe15bd1c313e956181f8f2197a2b21c675c6a60dVitalii Tomkiv} 180