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