SearchPanelView.java revision 9a720f5eb6c67b581df22f4ecb498cebb459babe
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2012 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1768f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrookpackage com.android.systemui; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 198bcbebd4178b2e9aca9ee3bd9e1e12c42e74c8dbAdam Powellimport android.animation.LayoutTransition; 208bcbebd4178b2e9aca9ee3bd9e1e12c42e74c8dbAdam Powellimport android.app.ActivityOptions; 21206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.app.SearchManager; 22206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.content.ActivityNotFoundException; 23206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.content.ComponentName; 24206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.content.Context; 25206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.content.Intent; 2668f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrookimport android.content.pm.PackageManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 28206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.util.Slog; 29206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.view.MotionEvent; 30206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.view.View; 31206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.view.ViewGroup; 32206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport android.view.ViewTreeObserver; 3350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganovimport android.view.ViewTreeObserver.OnPreDrawListener; 34e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport android.widget.FrameLayout; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.widget.multiwaveview.MultiWaveView; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.widget.multiwaveview.MultiWaveView.OnTriggerListener; 38206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport com.android.systemui.R; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.systemui.recent.StatusBarTouchProxy; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.systemui.statusbar.BaseStatusBar; 41206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport com.android.systemui.statusbar.CommandQueue; 42206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport com.android.systemui.statusbar.phone.PhoneStatusBar; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.systemui.statusbar.tablet.StatusBarPanel; 44206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganovimport com.android.systemui.statusbar.tablet.TabletStatusBar; 45206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SearchPanelView extends FrameLayout implements 47206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov StatusBarPanel { 48e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final int SEARCH_PANEL_HOLD_DURATION = 500; 49206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov static final String TAG = "SearchPanelView"; 50206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 5268f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook private BaseStatusBar mBar; 534bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov private StatusBarTouchProxy mStatusBarTouchProxy; 544bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov 554bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov private boolean mShowing; 564bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov private View mSearchTargetsContainer; 574bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov private MultiWaveView mMultiWaveView; 584bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov 594bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov public SearchPanelView(Context context, AttributeSet attrs) { 604bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov this(context, attrs, 0); 614bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov } 624bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov 634bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov public SearchPanelView(Context context, AttributeSet attrs, int defStyle) { 644bfd794475e6fb34c9dfa83d4302e9db365a3709Svetoslav Ganov super(context, attrs, defStyle); 6568f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook mContext = context; 6668f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); 6768f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook if (mSearchManager == null) { 68fdf6db6748b32f620a7f68b13a67c38b4e59e5edTom Taylor Slog.w(TAG, "Search manager not available"); 6968f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook } 70e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 71e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 72e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private SearchManager mSearchManager; 73e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 74e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // This code should be the same as that used in LockScreen.java 75206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public boolean isAssistantAvailable() { 7668f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook Intent intent = getAssistIntent(); 77206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return intent == null ? false 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mContext.getPackageManager().queryIntentActivities(intent, 7968f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook PackageManager.MATCH_DEFAULT_ONLY).size() > 0; 80206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 8168f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook 82206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov private Intent getAssistIntent() { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = null; 84206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov SearchManager searchManager = getSearchManager(); 85206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (searchManager != null) { 86206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity(); 87206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (globalSearchActivity != null) { 88fdf6db6748b32f620a7f68b13a67c38b4e59e5edTom Taylor intent = new Intent(Intent.ACTION_ASSIST); 89206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov intent.setPackage(globalSearchActivity.getPackageName()); 90206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } else { 91206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov Slog.w(TAG, "No global search activity"); 92206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 93206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } else { 94206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov Slog.w(TAG, "No SearchManager"); 95206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 96206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return intent; 97206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 98206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 99206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov private SearchManager getSearchManager() { 100206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (mSearchManager == null) { 101206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); 102206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 103206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return mSearchManager; 104206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 105206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 106206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov private void startAssistActivity() { 107206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // Close Recent Apps if needed 108206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL); 109206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // Launch Assist 110206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov Intent intent = getAssistIntent(); 111206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov try { 112206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, 113206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov R.anim.search_launch_enter, R.anim.search_launch_exit); 114206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 115206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mContext.startActivity(intent, opts.toBundle()); 116206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } catch (ActivityNotFoundException e) { 117206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov Slog.w(TAG, "Activity not found for " + intent.getAction()); 118206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 119206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 120206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 121206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov final MultiWaveView.OnTriggerListener mMultiWaveViewListener 122206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov = new MultiWaveView.OnTriggerListener() { 123e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 124e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private boolean mWaitingForLaunch; 125206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 126206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public void onGrabbed(View v, int handle) { 127206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 128206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 129f0ef665299d795df7905897e1c337e37891dafefJean-Baptiste Queru public void onReleased(View v, int handle) { 130206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 131206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 132206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public void onGrabbedStateChange(View v, int handle) { 133e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (!mWaitingForLaunch && OnTriggerListener.NO_HANDLE == handle) { 134206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mBar.hideSearchPanel(); 135206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 136206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 137206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onTrigger(View v, final int target) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int resId = mMultiWaveView.getResourceIdForTarget(target); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (resId) { 141206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov case com.android.internal.R.drawable.ic_lockscreen_search: 142206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mWaitingForLaunch = true; 143206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov startAssistActivity(); 144206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov postDelayed(new Runnable() { 145206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public void run() { 146206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mWaitingForLaunch = false; 147206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mBar.hideSearchPanel(); 148206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 149206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov }, SEARCH_PANEL_HOLD_DURATION); 150206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov break; 151206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 152206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 153206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 154206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public void onFinishFinalAnimation() { 155206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 156206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov }; 157206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 158206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov @Override 159206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov protected void onFinishInflate() { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onFinishInflate(); 161206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 162206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mSearchTargetsContainer = findViewById(R.id.search_panel_container); 163206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: fetch views 16568f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook mMultiWaveView = (MultiWaveView) findViewById(R.id.multi_wave_view); 16668f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook mMultiWaveView.setOnTriggerListener(mMultiWaveViewListener); 16768f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook } 16868f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook 169e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private boolean pointInside(int x, int y, View v) { 17068f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook final int l = v.getLeft(); 17168f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook final int r = v.getRight(); 17268f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook final int t = v.getTop(); 17368f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook final int b = v.getBottom(); 174e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return x >= l && x < r && y >= t && y < b; 17568f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook } 17668f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook 17768f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook public boolean isInContentArea(int x, int y) { 17868f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook if (pointInside(x, y, mSearchTargetsContainer)) { 179e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return true; 18068f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook } else if (mStatusBarTouchProxy != null && 18168f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook pointInside(x, y, mStatusBarTouchProxy)) { 182206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return true; 18368f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook } else { 184cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganov return false; 18550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 18650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 18750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 18850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final OnPreDrawListener mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() { 18950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public boolean onPreDraw() { 190206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov getViewTreeObserver().removeOnPreDrawListener(this); 191206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mMultiWaveView.resumeAnimations(); 192206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return false; 193206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 195fdf6db6748b32f620a7f68b13a67c38b4e59e5edTom Taylor 196206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public void show(final boolean show, boolean animate) { 197206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (!show) { 198206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov final LayoutTransition transitioner = animate ? createLayoutTransitioner() : null; 199e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov ((ViewGroup)mSearchTargetsContainer).setLayoutTransition(transitioner); 200fdf6db6748b32f620a7f68b13a67c38b4e59e5edTom Taylor } 20168f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrook mShowing = show; 202206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (show) { 203206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (getVisibility() != View.VISIBLE) { 204206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov setVisibility(View.VISIBLE); 205206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // Don't start the animation until we've created the layer, which is done 206206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // right before we are drawn 207206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mMultiWaveView.suspendAnimations(); 208206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov getViewTreeObserver().addOnPreDrawListener(mPreDrawListener); 209206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 210206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov setFocusable(true); 211206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov setFocusableInTouchMode(true); 212206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov requestFocus(); 213206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } else { 214206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov setVisibility(View.INVISIBLE); 215206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 216206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 217206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 218206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public void hide(boolean animate) { 219206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (mBar != null) { 220206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // This will indirectly cause show(false, ...) to get called 221206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE); 222206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } else { 223206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov setVisibility(View.INVISIBLE); 224206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 225206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 226206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 227206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov /** 228206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov * We need to be aligned at the bottom. LinearLayout can't do this, so instead, 229206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov * let LinearLayout do all the hard work, and then shift everything down to the bottom. 230206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov */ 231206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov @Override 232206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov protected void onLayout(boolean changed, int l, int t, int r, int b) { 233206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov super.onLayout(changed, l, t, r, b); 234206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // setPanelHeight(mSearchTargetsContainer.getHeight()); 235206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 236206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 237206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov @Override 238206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public boolean dispatchHoverEvent(MotionEvent event) { 239206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // Ignore hover events outside of this panel bounds since such events 240206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // generate spurious accessibility events with the panel content when 241206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov // tapping outside of it, thus confusing the user. 242206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov final int x = (int) event.getX(); 243206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov final int y = (int) event.getY(); 244206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { 245206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return super.dispatchHoverEvent(event); 246206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 247206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return true; 248206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 249206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 250206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov /** 251206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov * Whether the panel is showing, or, if it's animating, whether it will be 252206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov * when the animation is done. 253206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov */ 254206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public boolean isShowing() { 255206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return mShowing; 256206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 257206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 258206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public void setBar(BaseStatusBar bar) { 259206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mBar = bar; 260206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 261206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 262206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov public void setStatusBarView(final View statusBarView) { 263206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov if (mStatusBarTouchProxy != null) { 264206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov mStatusBarTouchProxy.setStatusBar(statusBarView); 265206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov// mMultiWaveView.setOnTouchListener(new OnTouchListener() { 266206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov// public boolean onTouch(View v, MotionEvent event) { 267206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov// return statusBarView.onTouchEvent(event); 268206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov// } 269206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov// }); 270206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 271206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 272206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov 273206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov private LayoutTransition createLayoutTransitioner() { 274206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov LayoutTransition transitioner = new LayoutTransition(); 275206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov transitioner.setDuration(200); 276206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0); 277206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov transitioner.setAnimator(LayoutTransition.DISAPPEARING, null); 278206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov return transitioner; 279206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov } 280206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov} 281206316a61f904ea0a6b106137dd7715a2c246d4cSvetoslav Ganov