diff options
author | Jim Miller <jaggies@google.com> | 2012-04-24 18:32:37 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-04-24 18:32:37 -0700 |
commit | e4cd3b0d9529a1ef8d388ece83a101227e206cc3 (patch) | |
tree | f32f5b5c2d8efdd2dca343ec704fb986363f02dd | |
parent | 97c03cac4d9a73b75096e1fa1d8927263dce39e1 (diff) | |
parent | e898ac59db04d8ab0762180ca8ec7cea1347aa09 (diff) | |
download | frameworks_base-e4cd3b0d9529a1ef8d388ece83a101227e206cc3.zip frameworks_base-e4cd3b0d9529a1ef8d388ece83a101227e206cc3.tar.gz frameworks_base-e4cd3b0d9529a1ef8d388ece83a101227e206cc3.tar.bz2 |
Merge "Fix 6299832: Add search target swipe action to navigation bar on phones"
32 files changed, 885 insertions, 33 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index bc310b0..d62f513 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -429,6 +429,12 @@ public interface WindowManager extends ViewManager { public static final int TYPE_DREAM = FIRST_SYSTEM_WINDOW+23; /** + * Window type: Navigation bar panel (when navigation bar is distinct from status bar) + * @hide + */ + public static final int TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW+24; + + /** * End of types of system windows. */ public static final int LAST_SYSTEM_WINDOW = 2999; diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java index f2b6e45..624dea8 100644 --- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java +++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java @@ -27,7 +27,6 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.RectF; -import android.graphics.drawable.Drawable; import android.os.Vibrator; import android.text.TextUtils; import android.util.AttributeSet; @@ -142,6 +141,7 @@ public class MultiWaveView extends View { private int mTargetResourceId; private int mTargetDescriptionsResourceId; private int mDirectionDescriptionsResourceId; + private boolean mAlwaysTrackFinger; public MultiWaveView(Context context) { this(context, null); @@ -168,6 +168,7 @@ public class MultiWaveView extends View { mTapRadius = mHandleDrawable.getWidth()/2; mOuterRing = new TargetDrawable(res, a.peekValue(R.styleable.MultiWaveView_waveDrawable).resourceId); + mAlwaysTrackFinger = a.getBoolean(R.styleable.MultiWaveView_alwaysTrackFinger, false); // Read chevron animation drawables final int chevrons[] = { R.styleable.MultiWaveView_leftChevronDrawable, @@ -634,7 +635,6 @@ public class MultiWaveView extends View { @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getAction(); - boolean handled = false; switch (action) { case MotionEvent.ACTION_DOWN: @@ -805,7 +805,7 @@ public class MultiWaveView extends View { final float y = event.getY(); final float dx = x - mWaveCenterX; final float dy = y - mWaveCenterY; - if (dist2(dx,dy) <= getScaledTapRadiusSquared()) { + if (mAlwaysTrackFinger || dist2(dx,dy) <= getScaledTapRadiusSquared()) { if (DEBUG) Log.v(TAG, "** Handle HIT"); switchToState(STATE_FIRST_TOUCH, x, y); moveHandleTo(x, y, false); diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png Binary files differnew file mode 100644 index 0000000..2c4847c --- /dev/null +++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png Binary files differnew file mode 100644 index 0000000..d98557d --- /dev/null +++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png Binary files differnew file mode 100644 index 0000000..656f3ba --- /dev/null +++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png Binary files differnew file mode 100644 index 0000000..32a68e0 --- /dev/null +++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png Binary files differnew file mode 100644 index 0000000..3f96d03 --- /dev/null +++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png Binary files differnew file mode 100644 index 0000000..2f7efcf --- /dev/null +++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png Binary files differnew file mode 100644 index 0000000..d643f83 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png Binary files differnew file mode 100644 index 0000000..51863f4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png Binary files differnew file mode 100644 index 0000000..9a9bf68 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png Binary files differdeleted file mode 100644 index c625a36..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png Binary files differdeleted file mode 100644 index c625a36..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png +++ /dev/null diff --git a/core/res/res/drawable/ic_lockscreen_search.xml b/core/res/res/drawable/ic_lockscreen_search.xml index b103922..2c0091a 100644 --- a/core/res/res/drawable/ic_lockscreen_search.xml +++ b/core/res/res/drawable/ic_lockscreen_search.xml @@ -19,12 +19,12 @@ android:state_enabled="true" android:state_active="false" android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_search_normal" /> + android:drawable="@drawable/ic_lockscreen_google_normal" /> <item android:state_enabled="true" android:state_active="true" android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_search_activated" /> + android:drawable="@drawable/ic_lockscreen_google_activated" /> </selector> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 0ac381d..9fa666e 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -5383,6 +5383,9 @@ <!-- Used to shift center of pattern horizontally. --> <attr name="horizontalOffset" format="dimension" /> + + <!-- Used when the handle shouldn't wait to be hit before following the finger --> + <attr name="alwaysTrackFinger" format="boolean" /> </declare-styleable> <!-- =============================== --> diff --git a/packages/SystemUI/res/drawable/navbar_search_bg_scrim.png b/packages/SystemUI/res/drawable/navbar_search_bg_scrim.png Binary files differnew file mode 100644 index 0000000..d595ed2 --- /dev/null +++ b/packages/SystemUI/res/drawable/navbar_search_bg_scrim.png diff --git a/packages/SystemUI/res/drawable/navbar_search_handle.xml b/packages/SystemUI/res/drawable/navbar_search_handle.xml new file mode 100644 index 0000000..e40fa2c --- /dev/null +++ b/packages/SystemUI/res/drawable/navbar_search_handle.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item + android:state_enabled="true" + android:state_active="false" + android:state_focused="false" + android:drawable="@*android:drawable/ic_lockscreen_handle_pressed" /> + + <item + android:state_enabled="true" + android:state_active="true" + android:state_focused="false" + android:drawable="@*android:drawable/ic_lockscreen_handle_pressed" /> + +</selector> diff --git a/packages/SystemUI/res/drawable/navbar_search_outerring.xml b/packages/SystemUI/res/drawable/navbar_search_outerring.xml new file mode 100644 index 0000000..37b6c1c --- /dev/null +++ b/packages/SystemUI/res/drawable/navbar_search_outerring.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> + <size android:height="@dimen/navbar_search_outerring_diameter" + android:width="@dimen/navbar_search_outerring_diameter" /> + <solid android:color="#00000000" /> + <stroke android:color="#1affffff" android:width="2dp" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml new file mode 100644 index 0000000..2adee33 --- /dev/null +++ b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<com.android.systemui.SearchPanelView + xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android" + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/search_panel_container" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:paddingBottom="0dip"> + + <RelativeLayout + android:id="@+id/search_bg_protect" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginBottom="0dip"> + + <RelativeLayout + android:id="@+id/search_panel_container" + android:layout_width="230dip" + android:layout_height="match_parent" + android:layout_alignParentRight="true"> + + <com.android.internal.widget.multiwaveview.MultiWaveView + android:id="@+id/multi_wave_view" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentBottom="true" + android:background="@drawable/navbar_search_bg_scrim" + + prvandroid:targetDrawables="@array/navbar_search_targets" + prvandroid:targetDescriptions="@array/navbar_search_target_descriptions" + prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions" + prvandroid:handleDrawable="@drawable/navbar_search_handle" + prvandroid:waveDrawable="@drawable/navbar_search_outerring" + prvandroid:outerRadius="@dimen/navbar_search_target_placement_radius" + prvandroid:snapMargin="@dimen/navbar_search_snap_margin" + prvandroid:hitRadius="@dimen/navbar_search_hit_radius" + prvandroid:verticalOffset="0dip" + prvandroid:horizontalOffset="60dip" + prvandroid:feedbackCount="0" + prvandroid:vibrationDuration="0" + prvandroid:alwaysTrackFinger="true"/> + + </RelativeLayout> + + </RelativeLayout> + +</com.android.systemui.SearchPanelView> diff --git a/packages/SystemUI/res/layout-port/status_bar_search_panel.xml b/packages/SystemUI/res/layout-port/status_bar_search_panel.xml new file mode 100644 index 0000000..463fa04 --- /dev/null +++ b/packages/SystemUI/res/layout-port/status_bar_search_panel.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<com.android.systemui.SearchPanelView + xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android" + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/search_panel_container" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:paddingBottom="0dip"> + + <RelativeLayout + android:id="@+id/search_bg_protect" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginBottom="0dip"> + + <RelativeLayout + android:id="@+id/search_panel_container" + android:layout_width="match_parent" + android:layout_height="230dip" + android:layout_alignParentBottom="true"> + + <com.android.internal.widget.multiwaveview.MultiWaveView + android:id="@+id/multi_wave_view" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentBottom="true" + android:background="@drawable/navbar_search_bg_scrim" + + prvandroid:targetDrawables="@array/navbar_search_targets" + prvandroid:targetDescriptions="@array/navbar_search_target_descriptions" + prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions" + prvandroid:handleDrawable="@drawable/navbar_search_handle" + prvandroid:waveDrawable="@drawable/navbar_search_outerring" + prvandroid:outerRadius="@dimen/navbar_search_target_placement_radius" + prvandroid:snapMargin="@dimen/navbar_search_snap_margin" + prvandroid:hitRadius="@dimen/navbar_search_hit_radius" + prvandroid:horizontalOffset="0dip" + prvandroid:verticalOffset="60dip" + prvandroid:feedbackCount="0" + prvandroid:vibrationDuration="0" + prvandroid:alwaysTrackFinger="true"/> + + </RelativeLayout> + + </RelativeLayout> + +</com.android.systemui.SearchPanelView> diff --git a/packages/SystemUI/res/values-land/arrays.xml b/packages/SystemUI/res/values-land/arrays.xml new file mode 100644 index 0000000..53f374d --- /dev/null +++ b/packages/SystemUI/res/values-land/arrays.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/colors.xml +** +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <array name="navbar_search_targets"> + <item>@null</item> + <item>@null</item> + <item>@*android:drawable/ic_lockscreen_search</item> + <item>@null</item> + </array> + + <array name="navbar_search_target_descriptions"> + <item>@null</item> + <item>@null</item> + <item>@*android:string/description_target_search</item> + <item>@null</item> + </array> + + <array name="navbar_search_direction_descriptions"> + <item>@null</item> + <item>@null</item> + <item>@*android:string/description_direction_left</item> + <item>@null</item> + </array> + +</resources> diff --git a/packages/SystemUI/res/values-port/arrays.xml b/packages/SystemUI/res/values-port/arrays.xml new file mode 100644 index 0000000..f8b1620 --- /dev/null +++ b/packages/SystemUI/res/values-port/arrays.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/colors.xml +** +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <array name="navbar_search_targets"> + <item>@null</item> + <item>@*android:drawable/ic_lockscreen_search</item> + <item>@null</item> + <item>@null</item> + </array> + + <array name="navbar_search_target_descriptions"> + <item>@null</item> + <item>@*android:string/description_target_search</item> + <item>@null</item> + <item>@null</item> + </array> + + <array name="navbar_search_direction_descriptions"> + <item>@null</item> + <item>@*android:string/description_direction_up</item> + <item>@null</item> + <item>@null</item> + </array> + +</resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index b8e8fe4..531f154 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -105,4 +105,17 @@ <!-- The width of the view containing the menu status bar icon --> <dimen name="navigation_menu_key_width">40dip</dimen> + + <!-- Default target placement radius for navigation bar search target --> + <dimen name="navbar_search_target_placement_radius">150dip</dimen> + + <!-- Default distance beyond which snaps to the target radius --> + <dimen name="navbar_search_snap_margin">20dip</dimen> + + <!-- Default distance from each snap target considers a "hit" --> + <dimen name="navbar_search_hit_radius">60dip</dimen> + + <!-- Diameter of outer shape drawable shown in navbar search--> + <dimen name="navbar_search_outerring_diameter">300dip</dimen> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java new file mode 100644 index 0000000..369a093 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui; + +import android.animation.Animator; +import android.animation.LayoutTransition; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.speech.RecognizerIntent; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import com.android.internal.widget.multiwaveview.MultiWaveView; +import com.android.internal.widget.multiwaveview.MultiWaveView.OnTriggerListener; +import com.android.systemui.R; +import com.android.systemui.recent.StatusBarTouchProxy; +import com.android.systemui.statusbar.BaseStatusBar; +import com.android.systemui.statusbar.phone.PhoneStatusBar; +import com.android.systemui.statusbar.tablet.StatusBarPanel; +import com.android.systemui.statusbar.tablet.TabletStatusBar; + +public class SearchPanelView extends FrameLayout implements + StatusBarPanel, Animator.AnimatorListener { + static final String TAG = "SearchPanelView"; + static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false; + private Context mContext; + private BaseStatusBar mBar; + private StatusBarTouchProxy mStatusBarTouchProxy; + + private boolean mShowing; + private View mSearchTargetsContainer; + private MultiWaveView mMultiWaveView; + + + public SearchPanelView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SearchPanelView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mContext = context; + } + + final MultiWaveView.OnTriggerListener mMultiWaveViewListener + = new MultiWaveView.OnTriggerListener() { + + public void onGrabbed(View v, int handle) { + } + + public void onReleased(View v, int handle) { + } + + public void onGrabbedStateChange(View v, int handle) { + if (OnTriggerListener.NO_HANDLE == handle) { + mBar.hideSearchPanel(); + } + } + + public void onTrigger(View v, int target) { + final int resId = mMultiWaveView.getResourceIdForTarget(target); + switch (resId) { + case com.android.internal.R.drawable.ic_lockscreen_search: + Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH); + intent.setFlags( + Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_SINGLE_TOP + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + try { + mContext.startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.w(TAG, "Application not found for action " + intent.getAction()); + } + mBar.hideSearchPanel(); + break; + } + } + }; + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + mSearchTargetsContainer = (ViewGroup) findViewById(R.id.search_panel_container); + mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy); + // TODO: fetch views + mMultiWaveView = (MultiWaveView) findViewById(R.id.multi_wave_view); + mMultiWaveView.setOnTriggerListener(mMultiWaveViewListener); + } + + private boolean pointInside(int x, int y, View v) { + final int l = v.getLeft(); + final int r = v.getRight(); + final int t = v.getTop(); + final int b = v.getBottom(); + return x >= l && x < r && y >= t && y < b; + } + + public boolean isInContentArea(int x, int y) { + if (pointInside(x, y, mSearchTargetsContainer)) { + return true; + } else if (mStatusBarTouchProxy != null && + pointInside(x, y, mStatusBarTouchProxy)) { + return true; + } else { + return false; + } + } + + public void show(boolean show, boolean animate) { + if (animate) { + if (mShowing != show) { + mShowing = show; + // TODO: start animating ring + } + } else { + mShowing = show; + onAnimationEnd(null); + } + setVisibility(show ? View.VISIBLE : View.GONE); + if (show) { + setFocusable(true); + setFocusableInTouchMode(true); + requestFocus(); + } + } + + public void hide(boolean animate) { + if (!animate) { + setVisibility(View.GONE); + } + if (mBar != null) { + // This will indirectly cause show(false, ...) to get called + mBar.animateCollapse(); + } + } + + public void onAnimationCancel(Animator animation) { + } + + public void onAnimationEnd(Animator animation) { + if (mShowing) { + final LayoutTransition transitioner = new LayoutTransition(); + ((ViewGroup)mSearchTargetsContainer).setLayoutTransition(transitioner); + createCustomAnimations(transitioner); + } else { + ((ViewGroup)mSearchTargetsContainer).setLayoutTransition(null); + } + } + + public void onAnimationRepeat(Animator animation) { + } + + public void onAnimationStart(Animator animation) { + } + + /** + * We need to be aligned at the bottom. LinearLayout can't do this, so instead, + * let LinearLayout do all the hard work, and then shift everything down to the bottom. + */ + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + // setPanelHeight(mSearchTargetsContainer.getHeight()); + } + + @Override + public boolean dispatchHoverEvent(MotionEvent event) { + // Ignore hover events outside of this panel bounds since such events + // generate spurious accessibility events with the panel content when + // tapping outside of it, thus confusing the user. + final int x = (int) event.getX(); + final int y = (int) event.getY(); + if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { + return super.dispatchHoverEvent(event); + } + return true; + } + + /** + * Whether the panel is showing, or, if it's animating, whether it will be + * when the animation is done. + */ + public boolean isShowing() { + return mShowing; + } + + public void setBar(BaseStatusBar bar) { + mBar = bar; + } + + public void setStatusBarView(final View statusBarView) { + if (mStatusBarTouchProxy != null) { + mStatusBarTouchProxy.setStatusBar(statusBarView); +// mMultiWaveView.setOnTouchListener(new OnTouchListener() { +// public boolean onTouch(View v, MotionEvent event) { +// return statusBarView.onTouchEvent(event); +// } +// }); + } + } + + private void createCustomAnimations(LayoutTransition transitioner) { + transitioner.setDuration(200); + transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0); + transitioner.setAnimator(LayoutTransition.DISAPPEARING, null); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 19306a9..4dd96fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -55,6 +55,7 @@ import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIconList; import com.android.internal.statusbar.StatusBarNotification; import com.android.internal.widget.SizeAdaptiveLayout; +import com.android.systemui.SearchPanelView; import com.android.systemui.SystemUI; import com.android.systemui.recent.RecentsPanelView; import com.android.systemui.recent.RecentTasksLoader; @@ -73,6 +74,8 @@ public abstract class BaseStatusBar extends SystemUI implements protected static final int MSG_CLOSE_RECENTS_PANEL = 1021; protected static final int MSG_PRELOAD_RECENT_APPS = 1022; protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023; + protected static final int MSG_OPEN_SEARCH_PANEL = 1024; + protected static final int MSG_CLOSE_SEARCH_PANEL = 1025; protected CommandQueue mCommandQueue; protected IStatusBarService mBarService; @@ -81,6 +84,9 @@ public abstract class BaseStatusBar extends SystemUI implements // used to notify status bar for suppressing notification LED protected boolean mPanelSlightlyVisible; + // Search panel + protected SearchPanelView mSearchPanelView; + // Recent apps protected RecentsPanelView mRecentsPanel; protected RecentTasksLoader mRecentTasksLoader; @@ -278,12 +284,29 @@ public abstract class BaseStatusBar extends SystemUI implements } @Override + public void showSearchPanel() { + int msg = MSG_OPEN_SEARCH_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + + @Override + public void hideSearchPanel() { + int msg = MSG_CLOSE_SEARCH_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + + @Override public void onRecentsPanelVisibilityChanged(boolean visible) { } protected abstract WindowManager.LayoutParams getRecentsLayoutParams( LayoutParams layoutParams); + protected abstract WindowManager.LayoutParams getSearchLayoutParams( + LayoutParams layoutParams); + protected void updateRecentsPanel(int recentsResId) { // Recents Panel boolean visible = false; @@ -319,6 +342,31 @@ public abstract class BaseStatusBar extends SystemUI implements } + protected void updateSearchPanel() { + // Search Panel + boolean visible = false; + if (mSearchPanelView != null) { + visible = mSearchPanelView.isShowing(); + WindowManagerImpl.getDefault().removeView(mSearchPanelView); + } + + // Provide SearchPanel with a temporary parent to allow layout params to work. + LinearLayout tmpRoot = new LinearLayout(mContext); + mSearchPanelView = (SearchPanelView) LayoutInflater.from(mContext).inflate( + R.layout.status_bar_search_panel, tmpRoot, false); + mSearchPanelView.setOnTouchListener( + new TouchOutsideListener(MSG_CLOSE_SEARCH_PANEL, mSearchPanelView)); + mSearchPanelView.setVisibility(View.GONE); + + WindowManager.LayoutParams lp = getSearchLayoutParams(mSearchPanelView.getLayoutParams()); + + WindowManagerImpl.getDefault().addView(mSearchPanelView, lp); + mSearchPanelView.setBar(this); + if (visible) { + mSearchPanelView.show(true, false); + } + } + protected H createHandler() { return new H(); } @@ -346,6 +394,18 @@ public abstract class BaseStatusBar extends SystemUI implements if (DEBUG) Slog.d(TAG, "cancel preloading recents"); mRecentsPanel.clearRecentTasksList(); break; + case MSG_OPEN_SEARCH_PANEL: + if (DEBUG) Slog.d(TAG, "opening search panel"); + if (mSearchPanelView != null) { + mSearchPanelView.show(true, true); + } + break; + case MSG_CLOSE_SEARCH_PANEL: + if (DEBUG) Slog.d(TAG, "closing search panel"); + if (mSearchPanelView != null && mSearchPanelView.isShowing()) { + mSearchPanelView.show(false, true); + } + break; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index f88a3cc..4209354 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -59,7 +59,7 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_TOP_APP_WINDOW_CHANGED = 8 << MSG_SHIFT; private static final int MSG_SHOW_IME_BUTTON = 9 << MSG_SHIFT; private static final int MSG_SET_HARD_KEYBOARD_STATUS = 10 << MSG_SHIFT; - + private static final int MSG_TOGGLE_RECENT_APPS = 11 << MSG_SHIFT; private static final int MSG_PRELOAD_RECENT_APPS = 12 << MSG_SHIFT; private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 13 << MSG_SHIFT; @@ -95,6 +95,8 @@ public class CommandQueue extends IStatusBar.Stub { public void setHardKeyboardStatus(boolean available, boolean enabled); public void toggleRecentApps(); public void preloadRecentApps(); + public void showSearchPanel(); + public void hideSearchPanel(); public void cancelPreloadRecentApps(); public void setNavigationIconHints(int hints); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java new file mode 100644 index 0000000..f725724 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar; + +import android.view.MotionEvent; +import android.view.Surface; +import android.view.VelocityTracker; +import android.view.View; + +public class DelegateViewHelper { + private static final int VELOCITY_THRESHOLD = 1000; + private VelocityTracker mVelocityTracker; + private View mDelegateView; + private View mSourceView; + private BaseStatusBar mBar; + private int[] mTempPoint = new int[2]; + private int mOrientation; + + public DelegateViewHelper(View sourceView) { + mSourceView = sourceView; + } + + public void setDelegateView(View view) { + mDelegateView = view; + } + + public void setBar(BaseStatusBar phoneStatusBar) { + mBar = phoneStatusBar; + } + + public void setOrientation(int orientation) { + mOrientation = orientation; + } + + public boolean onInterceptTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mVelocityTracker = VelocityTracker.obtain(); + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + mVelocityTracker.recycle(); + mVelocityTracker = null; + break; + } + if (mVelocityTracker != null) { + if (mDelegateView != null && mDelegateView.getVisibility() != View.VISIBLE) { + mVelocityTracker.addMovement(event); + mVelocityTracker.computeCurrentVelocity(1000); + final boolean isVertical = (mOrientation == Surface.ROTATION_90 + || mOrientation == Surface.ROTATION_270); + float velocity = isVertical ? - mVelocityTracker.getXVelocity() + : - mVelocityTracker.getYVelocity(); + if (velocity > VELOCITY_THRESHOLD) { + if (mDelegateView != null && mDelegateView.getVisibility() != View.VISIBLE) { + mBar.showSearchPanel(); + } + } + } + } + if (mDelegateView != null) { + mSourceView.getLocationOnScreen(mTempPoint); + float deltaX = mTempPoint[0]; + float deltaY = mTempPoint[1]; + + mDelegateView.getLocationOnScreen(mTempPoint); + deltaX -= mTempPoint[0]; + deltaY -= mTempPoint[1]; + + event.offsetLocation(deltaX, deltaY); + mDelegateView.dispatchTouchEvent(event); + event.offsetLocation(-deltaX, -deltaY); + } + return false; + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 11e067f..73c5d3a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -31,10 +31,12 @@ import android.util.Slog; import android.view.animation.AccelerateInterpolator; import android.view.Display; import android.view.MotionEvent; +import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; import android.view.Surface; import android.view.WindowManager; +import android.view.WindowManagerImpl; import android.widget.ImageView; import android.widget.LinearLayout; @@ -43,8 +45,9 @@ import java.io.PrintWriter; import java.lang.StringBuilder; import com.android.internal.statusbar.IStatusBarService; - import com.android.systemui.R; +import com.android.systemui.statusbar.BaseStatusBar; +import com.android.systemui.statusbar.DelegateViewHelper; public class NavigationBarView extends LinearLayout { final static boolean DEBUG = false; @@ -68,6 +71,8 @@ public class NavigationBarView extends LinearLayout { int mDisabledFlags = 0; int mNavigationIconHints = 0; + private DelegateViewHelper mDelegateHelper; + // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288) final static boolean WORKAROUND_INVALID_LAYOUT = true; final static int MSG_CHECK_INVALID_LAYOUT = 8686; @@ -95,6 +100,19 @@ public class NavigationBarView extends LinearLayout { } } + public void setDelegateView(View view) { + mDelegateHelper.setDelegateView(view); + } + + public void setBar(BaseStatusBar phoneStatusBar) { + mDelegateHelper.setBar(phoneStatusBar); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + return mDelegateHelper.onInterceptTouchEvent(event); + } + private H mHandler = new H(); public View getRecentsButton() { @@ -127,6 +145,7 @@ public class NavigationBarView extends LinearLayout { mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size); mVertical = false; mShowMenu = false; + mDelegateHelper = new DelegateViewHelper(this); } View.OnTouchListener mLightsOutListener = new View.OnTouchListener() { @@ -411,4 +430,5 @@ public class NavigationBarView extends LinearLayout { ); pw.println(" }"); } + } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 61500e9..80ee64f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -258,7 +258,7 @@ public class PhoneStatusBar extends BaseStatusBar { // ================================================================================ // Constructing the view // ================================================================================ - protected View makeStatusBarView() { + protected PhoneStatusBarView makeStatusBarView() { final Context context = mContext; Resources res = context.getResources(); @@ -294,6 +294,7 @@ public class PhoneStatusBar extends BaseStatusBar { (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null); mNavigationBarView.setDisabledFlags(mDisabled); + mNavigationBarView.setBar(this); } } catch (RemoteException ex) { // no window manager? good luck with that @@ -389,6 +390,32 @@ public class PhoneStatusBar extends BaseStatusBar { return lp; } + @Override + protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) { + boolean opaque = false; + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, + (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT)); + if (ActivityManager.isHighEndGfx(mDisplay)) { + lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; + } else { + lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND; + lp.dimAmount = 0.7f; + } + lp.gravity = Gravity.BOTTOM | Gravity.LEFT; + lp.setTitle("SearchPanel"); + // TODO: Define custom animation for Search panel + lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications; + lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED + | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; + return lp; + } + protected void updateRecentsPanel() { super.updateRecentsPanel(R.layout.status_bar_recent_panel); // Make .03 alpha the minimum so you always see the item a bit-- slightly below @@ -397,6 +424,33 @@ public class PhoneStatusBar extends BaseStatusBar { mRecentsPanel.setMinSwipeAlpha(0.03f); } + @Override + protected void updateSearchPanel() { + super.updateSearchPanel(); + mSearchPanelView.setStatusBarView(mStatusBarView); + mNavigationBarView.setDelegateView(mSearchPanelView); + } + + @Override + public void showSearchPanel() { + super.showSearchPanel(); + WindowManager.LayoutParams lp = + (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams(); + lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; + lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY; + WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp); + } + + @Override + public void hideSearchPanel() { + super.hideSearchPanel(); + WindowManager.LayoutParams lp = + (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams(); + lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; + lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY; + WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp); + } + protected int getStatusBarGravity() { return Gravity.TOP | Gravity.FILL_HORIZONTAL; } @@ -412,12 +466,30 @@ public class PhoneStatusBar extends BaseStatusBar { } }; private StatusBarNotification mCurrentlyIntrudingNotification; + View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() { + public boolean onTouch(View v, MotionEvent event) { + switch(event.getAction()) { + case MotionEvent.ACTION_DOWN: + Slog.d(TAG, "showing search panel"); + showSearchPanel(); + break; + + case MotionEvent.ACTION_UP: + Slog.d(TAG, "hiding search panel"); + hideSearchPanel(); + break; + } + return false; + } + }; private void prepareNavigationBarView() { mNavigationBarView.reorient(); mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener); mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel); + updateSearchPanel(); +// mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener); } // For small-screen devices (read: phones) that lack hardware navigation buttons @@ -528,7 +600,7 @@ public class PhoneStatusBar extends BaseStatusBar { Slog.d(TAG, "Presenting high-priority notification"); // special new transient ticker mode // 1. Populate mIntruderAlertView - + if (notification.notification.intruderView == null) { Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null"); return; @@ -544,7 +616,7 @@ public class PhoneStatusBar extends BaseStatusBar { mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener); mCurrentlyIntrudingNotification = notification; - + // 2. Animate mIntruderAlertView in mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER); @@ -698,7 +770,7 @@ public class PhoneStatusBar extends BaseStatusBar { // Recalculate the position of the sliding windows and the titles. updateExpandedViewPos(EXPANDED_LEAVE_ALONE); - + if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) { mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER); } @@ -1672,7 +1744,7 @@ public class PhoneStatusBar extends BaseStatusBar { addStatusBarWindow(); addExpandedWindow(); } - + private void addStatusBarWindow() { // Put up the view final int height = getStatusBarHeight(); @@ -1697,9 +1769,10 @@ public class PhoneStatusBar extends BaseStatusBar { lp.gravity = getStatusBarGravity(); lp.setTitle("StatusBar"); lp.packageName = mContext.getPackageName(); - WindowManagerImpl.getDefault().addView(makeStatusBarView(), lp); + mStatusBarView = makeStatusBarView(); + WindowManagerImpl.getDefault().addView(mStatusBarView, lp); } - + void addExpandedWindow() { WindowManager.LayoutParams lp; int pixelFormat; @@ -1780,11 +1853,11 @@ public class PhoneStatusBar extends BaseStatusBar { panelh = disph; } } - + // catch orientation changes and other peculiar cases if (panelh > disph || (panelh < disph && !mTracking && !mAnimating)) panelh = disph; - + mTrackingPosition = panelh; // XXX: this is all very WIP //mNotificationPanel.setY(panelh); @@ -1796,9 +1869,9 @@ public class PhoneStatusBar extends BaseStatusBar { final float frac = (float)panelh / disph; final int color = ((int)(0xB0 * frac * frac)) << 24; mExpandedWindowView.setBackgroundColor(color); - + // Slog.d(TAG, String.format("updateExpanded: pos=%d frac=%.2f col=0x%08x", pos, frac, color)); - + // if (mExpandedParams != null) { // if (mCloseView.getWindowVisibility() == View.VISIBLE) { // mCloseView.getLocationInWindow(mPositionTmp); @@ -2060,7 +2133,7 @@ public class PhoneStatusBar extends BaseStatusBar { // oh well } } - + /** * Reload some of our resources when the configuration changes. * diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 7b3b745..3bdefcb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.tablet; import android.animation.LayoutTransition; import android.animation.ObjectAnimator; +import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.Notification; import android.app.PendingIntent; @@ -174,7 +175,7 @@ public class TabletStatusBar extends BaseStatusBar implements KeyEvent mSpaceBarKeyEvent = null; View mCompatibilityHelpDialog = null; - + // for disabling the status bar int mDisabled = 0; @@ -192,7 +193,7 @@ public class TabletStatusBar extends BaseStatusBar implements addStatusBarWindow(); addPanelWindows(); } - + private void addStatusBarWindow() { final View sb = makeStatusBarView(); @@ -328,6 +329,10 @@ public class TabletStatusBar extends BaseStatusBar implements mRecentTasksLoader = new RecentTasksLoader(context); updateRecentsPanel(); + // Search Panel + mStatusBarView.setBar(this); + updateSearchPanel(); + // Input methods Panel mInputMethodsPanel = (InputMethodsPanel) View.inflate(context, R.layout.system_bar_input_methods_panel, null); @@ -350,7 +355,7 @@ public class TabletStatusBar extends BaseStatusBar implements lp.windowAnimations = R.style.Animation_RecentPanel; WindowManagerImpl.getDefault().addView(mInputMethodsPanel, lp); - + // Compatibility mode selector panel mCompatModePanel = (CompatModePanel) View.inflate(context, R.layout.system_bar_compat_mode_panel, null); @@ -373,7 +378,7 @@ public class TabletStatusBar extends BaseStatusBar implements lp.windowAnimations = android.R.style.Animation_Dialog; WindowManagerImpl.getDefault().addView(mCompatModePanel, lp); - + mRecentButton.setOnTouchListener(mRecentsPanel); mPile = (NotificationRowLayout)mNotificationPanel.findViewById(R.id.content); @@ -646,11 +651,64 @@ public class TabletStatusBar extends BaseStatusBar implements return lp; } + @Override + protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) { + boolean opaque = false; + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, + (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT)); + if (ActivityManager.isHighEndGfx(mDisplay)) { + lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; + } else { + lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND; + lp.dimAmount = 0.7f; + } + lp.gravity = Gravity.BOTTOM | Gravity.LEFT; + lp.setTitle("SearchPanel"); + // TODO: Define custom animation for Search panel + lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications; + lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED + | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; + return lp; + } + protected void updateRecentsPanel() { super.updateRecentsPanel(R.layout.system_bar_recent_panel); mRecentsPanel.setStatusBarView(mStatusBarView); } + @Override + protected void updateSearchPanel() { + super.updateSearchPanel(); + mSearchPanelView.setStatusBarView(mStatusBarView); + mStatusBarView.setDelegateView(mSearchPanelView); + } + + @Override + public void showSearchPanel() { + super.showSearchPanel(); + WindowManager.LayoutParams lp = + (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams(); + lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; + lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY; + WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp); + } + + @Override + public void hideSearchPanel() { + super.hideSearchPanel(); + WindowManager.LayoutParams lp = + (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams(); + lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; + lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY; + WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp); + } + public int getStatusBarHeight() { return mStatusBarView != null ? mStatusBarView.getHeight() : mContext.getResources().getDimensionPixelSize( @@ -1191,7 +1249,7 @@ public class TabletStatusBar extends BaseStatusBar implements if (mCompatibilityHelpDialog != null) { return; } - + mCompatibilityHelpDialog = View.inflate(mContext, R.layout.compat_mode_help, null); View button = mCompatibilityHelpDialog.findViewById(R.id.button); @@ -1227,7 +1285,7 @@ public class TabletStatusBar extends BaseStatusBar implements mCompatibilityHelpDialog = null; } } - + public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { mInputMethodSwitchButton.setImeWindowStatus(token, (vis & InputMethodService.IME_ACTIVE) != 0); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java index 877a40e..a6fc396 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.tablet; +import com.android.systemui.statusbar.BaseStatusBar; +import com.android.systemui.statusbar.DelegateViewHelper; + import android.content.Context; import android.os.Handler; import android.util.AttributeSet; @@ -31,13 +34,24 @@ public class TabletStatusBarView extends FrameLayout { private final View[] mIgnoreChildren = new View[MAX_PANELS]; private final View[] mPanels = new View[MAX_PANELS]; private final int[] mPos = new int[2]; + private DelegateViewHelper mDelegateHelper; public TabletStatusBarView(Context context) { super(context); + mDelegateHelper = new DelegateViewHelper(this); } public TabletStatusBarView(Context context, AttributeSet attrs) { super(context, attrs); + mDelegateHelper = new DelegateViewHelper(this); + } + + public void setDelegateView(View view) { + mDelegateHelper.setDelegateView(view); + } + + public void setBar(BaseStatusBar phoneStatusBar) { + mDelegateHelper.setBar(phoneStatusBar); } @Override @@ -72,6 +86,9 @@ public class TabletStatusBarView extends FrameLayout { if (TabletStatusBar.DEBUG) { Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event"); } + if (mDelegateHelper != null) { + return mDelegateHelper.onInterceptTouchEvent(ev); + } return super.onInterceptTouchEvent(ev); } @@ -97,7 +114,7 @@ public class TabletStatusBarView extends FrameLayout { /** * Let the status bar know that if you tap on ignore while panel is showing, don't do anything. - * + * * Debounces taps on, say, a popup's trigger when the popup is already showing. */ public void setIgnoreChildren(int index, View ignore, View panel) { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index cc663c2..5086325 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -131,6 +131,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.LayoutParams.TYPE_POINTER; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS; import android.view.WindowManagerImpl; import android.view.WindowManagerPolicy; @@ -216,16 +217,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int SYSTEM_OVERLAY_LAYER = 18; // the navigation bar, if available, shows atop most things static final int NAVIGATION_BAR_LAYER = 19; + // some panels (e.g. search) need to show on top of the navigation bar + static final int NAVIGATION_BAR_PANEL_LAYER = 20; // system-level error dialogs - static final int SYSTEM_ERROR_LAYER = 20; + static final int SYSTEM_ERROR_LAYER = 21; // the drag layer: input for drag-and-drop is associated with this window, // which sits above all other focusable windows - static final int DRAG_LAYER = 21; - static final int SECURE_SYSTEM_OVERLAY_LAYER = 22; - static final int BOOT_PROGRESS_LAYER = 23; + static final int DRAG_LAYER = 22; + static final int SECURE_SYSTEM_OVERLAY_LAYER = 23; + static final int BOOT_PROGRESS_LAYER = 24; // the (mouse) pointer layer - static final int POINTER_LAYER = 24; - static final int HIDDEN_NAV_CONSUMER_LAYER = 25; + static final int POINTER_LAYER = 25; + static final int HIDDEN_NAV_CONSUMER_LAYER = 26; static final int APPLICATION_MEDIA_SUBLAYER = -2; static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1; @@ -1335,6 +1338,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { return POINTER_LAYER; case TYPE_NAVIGATION_BAR: return NAVIGATION_BAR_LAYER; + case TYPE_NAVIGATION_BAR_PANEL: + return NAVIGATION_BAR_PANEL_LAYER; case TYPE_BOOT_PROGRESS: return BOOT_PROGRESS_LAYER; case TYPE_HIDDEN_NAV_CONSUMER: @@ -1577,6 +1582,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { mNavigationBar = win; if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar); break; + case TYPE_NAVIGATION_BAR_PANEL: + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.STATUS_BAR_SERVICE, + "PhoneWindowManager"); + break; case TYPE_STATUS_BAR_PANEL: mContext.enforceCallingOrSelfPermission( android.Manifest.permission.STATUS_BAR_SERVICE, @@ -2480,7 +2490,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)", pf.left, pf.top, pf.right, pf.bottom)); } - } else if (attrs.type == TYPE_NAVIGATION_BAR) { + } else if (attrs.type == TYPE_NAVIGATION_BAR + || attrs.type == TYPE_NAVIGATION_BAR_PANEL) { // The navigation bar has Real Ultimate Power. pf.left = df.left = mUnrestrictedScreenLeft; pf.top = df.top = mUnrestrictedScreenTop; |