Using the default search widget in Launcher3

> Removing all logic related to search and voice overlays
from Launcher3
> Using the widget provided by global search provider on the
homescreen
> Removing VoiceButtonProxy, as it is not being used anymore

Change-Id: Ie8b09b44f7213c8fa11bce685914442e4884295d
This commit is contained in:
Sunny Goyal 2014-11-06 10:12:54 -08:00
parent 8dfe2da698
commit 594d76dc66
37 changed files with 104 additions and 1125 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,50 +0,0 @@
<?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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Global search icon -->
<com.android.launcher3.HolographicImageView
style="@style/SearchButton"
android:id="@+id/search_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:scaleType="center"
android:src="@drawable/ic_home_search_normal_holo"
android:adjustViewBounds="true"
android:onClick="onClickSearchButton"
android:focusable="true"
android:clickable="true"
android:contentDescription="@string/accessibility_search_button" />
<!-- Voice search icon -->
<com.android.launcher3.HolographicImageView
style="@style/SearchButton"
android:id="@+id/voice_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:scaleType="center"
android:src="@drawable/ic_home_voice_search_holo"
android:adjustViewBounds="true"
android:onClick="onClickVoiceButton"
android:focusable="true"
android:clickable="true"
android:contentDescription="@string/accessibility_voice_search_button" />
</LinearLayout>

View File

@ -66,18 +66,6 @@
android:id="@+id/search_drop_target_bar"
layout="@layout/search_drop_target_bar" />
<!-- This is the search bar voice button proxy view. It allows us to have a larger
touch target than the microphone constrained by the search bar bounds. -->
<com.android.launcher3.DrawableStateProxyView
android:id="@+id/voice_button_proxy"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="top|end"
android:clickable="true"
android:onClick="onClickVoiceButton"
android:importantForAccessibility="no"
launcher:sourceViewId="@+id/voice_button" />
<include layout="@layout/apps_customize_pane"
android:id="@+id/apps_customize_pane"
android:layout_width="match_parent"

View File

@ -1,72 +0,0 @@
<?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.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/search_frame">
<!-- Global search icon -->
<com.android.launcher3.HolographicLinearLayout
style="@style/SearchButton.WithPaddingStart"
launcher:sourceImageViewId="@+id/search_button"
android:id="@+id/search_button_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/voice_button_container"
android:onClick="onClickSearchButton"
android:focusable="true"
android:clickable="true"
android:contentDescription="@string/accessibility_search_button">
<ImageView
android:id="@+id/search_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:scaleType="fitCenter"
android:src="@drawable/ic_home_search_normal_holo"
android:adjustViewBounds="true" />
</com.android.launcher3.HolographicLinearLayout>
<!-- Voice search icon -->
<com.android.launcher3.HolographicLinearLayout
style="@style/SearchButton"
launcher:sourceImageViewId="@+id/voice_button"
android:id="@+id/voice_button_container"
android:layout_width="@dimen/app_icon_size"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:onClick="onClickVoiceButton"
android:focusable="true"
android:clickable="true"
android:contentDescription="@string/accessibility_voice_search_button">
<ImageView
android:id="@+id/voice_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="end"
android:scaleType="fitCenter"
android:src="@drawable/ic_home_voice_search_holo"
android:adjustViewBounds="true" />
</com.android.launcher3.HolographicLinearLayout>
</RelativeLayout>

View File

@ -66,16 +66,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<com.android.launcher3.DrawableStateProxyView
android:id="@+id/voice_button_proxy"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="top|end"
android:clickable="true"
android:onClick="onClickVoiceButton"
android:importantForAccessibility="no"
launcher:sourceViewId="@+id/voice_button" />
<include layout="@layout/apps_customize_pane"
android:id="@+id/apps_customize_pane"
android:layout_width="match_parent"

View File

@ -1,72 +0,0 @@
<?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.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/search_frame">
<!-- Global search icon -->
<com.android.launcher3.HolographicLinearLayout
style="@style/SearchButton.WithPaddingStart"
launcher:sourceImageViewId="@+id/search_button"
android:id="@+id/search_button_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/voice_button_container"
android:onClick="onClickSearchButton"
android:focusable="true"
android:clickable="true"
android:contentDescription="@string/accessibility_search_button">
<ImageView
android:id="@+id/search_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:scaleType="fitCenter"
android:src="@drawable/ic_home_search_normal_holo"
android:adjustViewBounds="true" />
</com.android.launcher3.HolographicLinearLayout>
<!-- Voice search icon -->
<com.android.launcher3.HolographicLinearLayout
style="@style/SearchButton"
launcher:sourceImageViewId="@+id/voice_button"
android:id="@+id/voice_button_container"
android:layout_width="@dimen/app_icon_size"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:onClick="onClickVoiceButton"
android:focusable="true"
android:clickable="true"
android:contentDescription="@string/accessibility_voice_search_button">
<ImageView
android:id="@+id/voice_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="end"
android:scaleType="fitCenter"
android:src="@drawable/ic_home_voice_search_holo"
android:adjustViewBounds="true" />
</com.android.launcher3.HolographicLinearLayout>
</RelativeLayout>

View File

@ -3,7 +3,4 @@
<style name="PagedViewWidgetImageView">
<item name="android:paddingStart">@dimen/app_widget_preview_padding_left</item>
</style>
<style name="SearchButton.WithPaddingStart">
<item name="android:paddingStart">8dp</item>
</style>
</resources>

View File

@ -18,13 +18,6 @@
<resources>
<!-- DrawableStateProxyView specific attributes. These attributes are used to customize
a DrawableStateProxyView view in XML files. -->
<declare-styleable name="DrawableStateProxyView">
<!-- The source view to delegate touch presses events to. -->
<attr name="sourceViewId" format="integer" />
</declare-styleable>
<!-- Page Indicator specific attributes. -->
<declare-styleable name="PageIndicator">
<attr name="windowSize" format="integer" />
@ -76,13 +69,6 @@
<attr name="strokeWidth" format="float" />
</declare-styleable>
<!-- HolographicLinearLayout specific attributes. -->
<declare-styleable name="HolographicLinearLayout">
<!-- The source view to generate and apply the drawable states to/from -->
<attr name="sourceImageViewId" format="integer" />
<attr name="stateHotwordOn" format="boolean" />
</declare-styleable>
<!-- PagedView specific attributes. These attributes are used to customize
a PagedView view in XML files. -->
<declare-styleable name="PagedView">

View File

@ -43,9 +43,6 @@
<!-- QSB -->
<dimen name="toolbar_button_vertical_padding">4dip</dimen>
<dimen name="toolbar_button_horizontal_padding">12dip</dimen>
<!-- External toolbar icon size (for bounds) -->
<dimen name="toolbar_external_icon_width">36dp</dimen>
<dimen name="toolbar_external_icon_height">36dp</dimen>
<!-- AllApps/Customize/AppsCustomize -->
<!-- The height of the tab bar - if this changes, we should update the

View File

@ -132,10 +132,6 @@ s -->
<!-- Label for the info icon. [CHAR_LIMIT=20] -->
<string name="info_target_label">App info</string>
<!-- Accessibility: Search button -->
<string name="accessibility_search_button">Search</string>
<!-- Accessibility: Voice Search button -->
<string name="accessibility_voice_search_button">Voice Search</string>
<!-- Accessibility: AllApps button -->
<string name="accessibility_all_apps_button">Apps</string>
<!-- Accessibility: Delete button -->

View File

@ -51,8 +51,6 @@
<item name="customShadows">false</item>
</style>
<style name="SearchDropTargetBar"></style>
<style name="SearchButton"></style>
<style name="DropTargetButtonContainer">
@ -97,8 +95,4 @@
<item name="android:paddingLeft">@dimen/app_widget_preview_padding_left</item>
</style>
<style name="SearchButton.WithPaddingStart">
<item name="android:paddingLeft">8dp</item>
</style>
</resources>

View File

@ -122,9 +122,7 @@ public class DeviceProfile {
int allAppsNumRows;
int allAppsNumCols;
int searchBarSpaceWidthPx;
int searchBarSpaceMaxWidthPx;
int searchBarSpaceHeightPx;
int searchBarHeightPx;
int pageIndicatorHeightPx;
int allAppsButtonVisualSize;
@ -372,10 +370,10 @@ public class DeviceProfile {
hotseatIconSizePx = (int) (DynamicGrid.pxFromDp(hotseatIconSize, dm) * scale);
// Search Bar
searchBarSpaceMaxWidthPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width);
searchBarHeightPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
searchBarSpaceWidthPx = Math.min(searchBarSpaceMaxWidthPx, widthPx);
searchBarSpaceHeightPx = searchBarHeightPx + getSearchBarTopOffset();
searchBarSpaceWidthPx = Math.min(widthPx,
resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width));
searchBarSpaceHeightPx = getSearchBarTopOffset()
+ resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
// Calculate the actual text height
Paint textPaint = new Paint();
@ -398,10 +396,6 @@ public class DeviceProfile {
folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
// All Apps
Rect padding = getWorkspacePadding(isLandscape ?
CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
int pageIndicatorOffset =
resources.getDimensionPixelSize(R.dimen.apps_customize_page_indicator_offset);
allAppsCellWidthPx = allAppsIconSizePx;
allAppsCellHeightPx = allAppsIconSizePx + drawablePadding + iconTextSizePx;
int maxLongEdgeCellCount =
@ -717,9 +711,6 @@ public class DeviceProfile {
lp.gravity = Gravity.TOP | Gravity.LEFT;
lp.width = searchBarSpaceHeightPx;
lp.height = LayoutParams.WRAP_CONTENT;
searchBar.setPadding(
0, 2 * edgeMarginPx, 0,
2 * edgeMarginPx);
LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar);
targets.setOrientation(LinearLayout.VERTICAL);
@ -728,27 +719,9 @@ public class DeviceProfile {
lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
lp.width = searchBarSpaceWidthPx;
lp.height = searchBarSpaceHeightPx;
searchBar.setPadding(
2 * edgeMarginPx,
getSearchBarTopOffset(),
2 * edgeMarginPx, 0);
}
searchBar.setLayoutParams(lp);
// Layout the voice proxy
View voiceButtonProxy = launcher.findViewById(R.id.voice_button_proxy);
if (voiceButtonProxy != null) {
if (hasVerticalBarLayout) {
// TODO: MOVE THIS INTO SEARCH BAR MEASURE
} else {
lp = (FrameLayout.LayoutParams) voiceButtonProxy.getLayoutParams();
lp.gravity = Gravity.TOP | Gravity.END;
lp.width = (widthPx - searchBarSpaceWidthPx) / 2 +
2 * iconSizePx;
lp.height = searchBarSpaceHeightPx;
}
}
// Layout the workspace
PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace);
lp = (FrameLayout.LayoutParams) workspace.getLayoutParams();

View File

@ -1,69 +0,0 @@
/*
* 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.launcher3;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
public class DrawableStateProxyView extends LinearLayout {
private View mView;
private int mViewId;
public DrawableStateProxyView(Context context) {
this(context, null);
}
public DrawableStateProxyView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DrawableStateProxyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DrawableStateProxyView,
defStyle, 0);
mViewId = a.getResourceId(R.styleable.DrawableStateProxyView_sourceViewId, -1);
a.recycle();
setFocusable(false);
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (mView == null) {
View parent = (View) getParent();
mView = parent.findViewById(mViewId);
}
if (mView != null) {
mView.setPressed(isPressed());
mView.setHovered(isHovered());
}
}
@Override
public boolean onHoverEvent(MotionEvent event) {
return false;
}
}

View File

@ -1,121 +0,0 @@
/*
* 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.
*/
package com.android.launcher3;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
public class HolographicImageView extends ImageView {
private final HolographicViewHelper mHolographicHelper;
private boolean mHotwordOn;
private boolean mIsPressed;
private boolean mIsFocused;
public HolographicImageView(Context context) {
this(context, null);
}
public HolographicImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HolographicImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mHolographicHelper = new HolographicViewHelper(context);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HolographicLinearLayout,
defStyle, 0);
mHotwordOn = a.getBoolean(R.styleable.HolographicLinearLayout_stateHotwordOn, false);
a.recycle();
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isPressed() != mIsPressed) {
mIsPressed = isPressed();
refreshDrawableState();
}
return false;
}
});
setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (isFocused() != mIsFocused) {
mIsFocused = isFocused();
refreshDrawableState();
}
}
});
}
void invalidatePressedFocusedStates() {
mHolographicHelper.invalidatePressedFocusedStates(this);
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
mHolographicHelper.generatePressedFocusedStates(this);
Drawable d = getDrawable();
if (d instanceof StateListDrawable) {
StateListDrawable sld = (StateListDrawable) d;
sld.setState(getDrawableState());
sld.invalidateSelf();
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// One time call to generate the pressed/focused state -- must be called after
// measure/layout
mHolographicHelper.generatePressedFocusedStates(this);
}
private boolean isHotwordOn() {
return mHotwordOn;
}
public void setHotwordState(boolean on) {
if (on == mHotwordOn) {
return;
}
mHotwordOn = on;
refreshDrawableState();
}
@Override
public int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isHotwordOn()) {
mergeDrawableStates(drawableState, new int[] {R.attr.stateHotwordOn});
}
return drawableState;
}
}

View File

@ -1,134 +0,0 @@
/*
* 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.
*/
package com.android.launcher3;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class HolographicLinearLayout extends LinearLayout {
private final HolographicViewHelper mHolographicHelper;
private ImageView mImageView;
private int mImageViewId;
private boolean mHotwordOn;
private boolean mIsPressed;
private boolean mIsFocused;
public HolographicLinearLayout(Context context) {
this(context, null);
}
public HolographicLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HolographicLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HolographicLinearLayout,
defStyle, 0);
mImageViewId = a.getResourceId(R.styleable.HolographicLinearLayout_sourceImageViewId, -1);
mHotwordOn = a.getBoolean(R.styleable.HolographicLinearLayout_stateHotwordOn, false);
a.recycle();
setWillNotDraw(false);
mHolographicHelper = new HolographicViewHelper(context);
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isPressed() != mIsPressed) {
mIsPressed = isPressed();
refreshDrawableState();
}
return false;
}
});
setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (isFocused() != mIsFocused) {
mIsFocused = isFocused();
refreshDrawableState();
}
}
});
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (mImageView != null) {
mHolographicHelper.generatePressedFocusedStates(mImageView);
Drawable d = mImageView.getDrawable();
if (d instanceof StateListDrawable) {
StateListDrawable sld = (StateListDrawable) d;
sld.setState(getDrawableState());
sld.invalidateSelf();
}
}
}
void invalidatePressedFocusedStates() {
mHolographicHelper.invalidatePressedFocusedStates(mImageView);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// One time call to generate the pressed/focused state -- must be called after
// measure/layout
if (mImageView == null) {
mImageView = (ImageView) findViewById(mImageViewId);
}
mHolographicHelper.generatePressedFocusedStates(mImageView);
}
private boolean isHotwordOn() {
return mHotwordOn;
}
public void setHotwordState(boolean on) {
if (on == mHotwordOn) {
return;
}
mHotwordOn = on;
refreshDrawableState();
}
@Override
public int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isHotwordOn()) {
mergeDrawableStates(drawableState, new int[] {R.attr.stateHotwordOn});
}
return drawableState;
}
}

View File

@ -1,109 +0,0 @@
/*
* 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.
*/
package com.android.launcher3;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.widget.ImageView;
public class HolographicViewHelper {
private final Canvas mTempCanvas = new Canvas();
private boolean mStatesUpdated;
private int mHighlightColor, mHotwordColor;
public HolographicViewHelper(Context context) {
Resources res = context.getResources();
mHighlightColor = res.getColor(android.R.color.holo_blue_light);
mHotwordColor = res.getColor(android.R.color.holo_green_light);
}
/**
* Generate the pressed/focused states if necessary.
*/
void generatePressedFocusedStates(ImageView v) {
if (!mStatesUpdated && v != null) {
mStatesUpdated = true;
Bitmap original = createOriginalImage(v, mTempCanvas);
Bitmap outline = createImageWithOverlay(v, mTempCanvas, mHighlightColor);
Bitmap hotword = createImageWithOverlay(v, mTempCanvas, mHotwordColor);
FastBitmapDrawable originalD = new FastBitmapDrawable(original);
FastBitmapDrawable outlineD = new FastBitmapDrawable(outline);
FastBitmapDrawable hotwordD = new FastBitmapDrawable(hotword);
StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed}, outlineD);
states.addState(new int[] {android.R.attr.state_focused}, outlineD);
states.addState(new int[] {R.attr.stateHotwordOn}, hotwordD);
states.addState(new int[] {}, originalD);
v.setImageDrawable(states);
}
}
/**
* Invalidates the pressed/focused states.
*/
void invalidatePressedFocusedStates(ImageView v) {
mStatesUpdated = false;
if (v != null) {
v.invalidate();
}
}
/**
* Creates a copy of the original image.
*/
private Bitmap createOriginalImage(ImageView v, Canvas canvas) {
final Drawable d = v.getDrawable();
final Bitmap b = Bitmap.createBitmap(
d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
canvas.setBitmap(b);
canvas.save();
d.draw(canvas);
canvas.restore();
canvas.setBitmap(null);
return b;
}
/**
* Creates a new press state image which is the old image with a blue overlay.
* Responsibility for the bitmap is transferred to the caller.
*/
private Bitmap createImageWithOverlay(ImageView v, Canvas canvas, int color) {
final Drawable d = v.getDrawable();
final Bitmap b = Bitmap.createBitmap(
d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
canvas.setBitmap(b);
canvas.save();
d.draw(canvas);
canvas.restore();
canvas.drawColor(color, PorterDuff.Mode.SRC_IN);
canvas.setBitmap(null);
return b;
}
}

View File

@ -66,7 +66,6 @@ import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.os.SystemClock;
import android.speech.RecognizerIntent;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@ -96,7 +95,6 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.Advanceable;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.launcher3.DropTarget.DragObject;
@ -210,15 +208,12 @@ public class Launcher extends Activity
static final String ACTION_FIRST_LOAD_COMPLETE =
"com.android.launcher3.action.FIRST_LOAD_COMPLETE";
private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";
private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =
"com.android.launcher.toolbar_search_icon";
private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =
"com.android.launcher.toolbar_voice_search_icon";
public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";
public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;
private static final String QSB_WIDGET_ID = "qsb_widget_id";
private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";
public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";
/** The different states that Launcher can be in. */
@ -282,7 +277,7 @@ public class Launcher extends Activity
private AppsCustomizeTabHost mAppsCustomizeTabHost;
private AppsCustomizePagedView mAppsCustomizeContent;
private boolean mAutoAdvanceRunning = false;
private View mQsb;
private AppWidgetHostView mQsb;
private Bundle mSavedState;
// We set the state in both onCreate and then onNewIntent in some cases, which causes both
@ -330,10 +325,6 @@ public class Launcher extends Activity
// match the sensor state.
private final int mRestoreScreenOrientationDelay = 500;
// External icons saved in case of resource changes, orientation, etc.
private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];
private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];
private Drawable mWorkspaceBackgroundDrawable;
private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();
@ -484,8 +475,6 @@ public class Launcher extends Activity
IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(mCloseSystemDialogsReceiver, filter);
updateGlobalIcons();
// On large interfaces, we want the screen to auto-rotate based on the current orientation
unlockScreenOrientation(true);
@ -567,28 +556,6 @@ public class Launcher extends Activity
}
}
private void updateGlobalIcons() {
boolean searchVisible = false;
boolean voiceVisible = false;
// If we have a saved version of these external icons, we load them up immediately
int coi = getCurrentOrientationIndexForGlobalIcons();
if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {
searchVisible = updateGlobalSearchIcon();
voiceVisible = updateVoiceSearchIcon(searchVisible);
}
if (sGlobalSearchIcon[coi] != null) {
updateGlobalSearchIcon(sGlobalSearchIcon[coi]);
searchVisible = true;
}
if (sVoiceSearchIcon[coi] != null) {
updateVoiceSearchIcon(sVoiceSearchIcon[coi]);
voiceVisible = true;
}
if (mSearchDropTargetBar != null) {
mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);
}
}
private void checkForLocaleChange() {
if (sLocaleConfiguration == null) {
new AsyncTask<Void, Void, LocaleConfiguration>() {
@ -1078,12 +1045,6 @@ public class Launcher extends Activity
// Process any items that were added while Launcher was away.
InstallShortcutReceiver.disableAndFlushInstallQueue(this);
// Update the voice search button proxy
updateVoiceButtonProxyVisible(false);
// Again, as with the above scenario, it's possible that one or more of the global icons
// were updated in the wrong orientation.
updateGlobalIcons();
if (DEBUG_RESUME_TIME) {
Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));
}
@ -1473,6 +1434,7 @@ public class Launcher extends Activity
dragController.addDropTarget(mWorkspace);
if (mSearchDropTargetBar != null) {
mSearchDropTargetBar.setup(this, dragController);
mSearchDropTargetBar.setQsbSearchBar(getQsbBar());
}
if (getResources().getBoolean(R.bool.debug_memory_enabled)) {
@ -2644,51 +2606,6 @@ public class Launcher extends Activity
}
}
/**
* Event handler for the search button
*
* @param v The view that was clicked.
*/
public void onClickSearchButton(View v) {
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
onSearchRequested();
}
/**
* Event handler for the voice button
*
* @param v The view that was clicked.
*/
public void onClickVoiceButton(View v) {
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
startVoice();
}
public void startVoice() {
if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
mLauncherCallbacks.startVoice();
return;
}
try {
final SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
ComponentName activityName = searchManager.getGlobalSearchActivity();
Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (activityName != null) {
intent.setPackage(activityName.getPackageName());
}
startActivity(null, intent, "onClickVoiceButton");
} catch (ActivityNotFoundException e) {
Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivitySafely(null, intent, "onClickVoiceButton");
}
}
/**
* Event handler for the "grid" button that appears on the home screen, which
* enters all apps mode.
@ -2967,10 +2884,8 @@ public class Launcher extends Activity
}
void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {
String packageName = componentName.getPackageName();
try {
LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);
UserManagerCompat userManager = UserManagerCompat.getInstance(this);
launcherApps.showAppDetailsForProfile(componentName, user);
} catch (SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
@ -3445,8 +3360,6 @@ public class Launcher extends Activity
final View page = content.getPageAt(content.getCurrentPage());
final View revealView = toView.findViewById(R.id.fake_page);
final float initialPanelAlpha = 1f;
final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;
if (isWidgetTray) {
revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));
@ -4032,137 +3945,8 @@ public class Launcher extends Activity
// TODO
}
/**
* Hides the hotseat area.
*/
void hideHotseat(boolean animated) {
if (!LauncherAppState.getInstance().isScreenLarge()) {
if (animated) {
if (mHotseat.getAlpha() != 0f) {
int duration = 0;
if (mSearchDropTargetBar != null) {
duration = mSearchDropTargetBar.getTransitionOutDuration();
}
mHotseat.animate().alpha(0f).setDuration(duration);
}
} else {
mHotseat.setAlpha(0f);
}
}
}
/**
* Add an item from all apps or customize onto the given workspace screen.
* If layout is null, add to the current screen.
*/
void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {
if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {
showOutOfSpaceMessage(isHotseatLayout(layout));
}
}
/** Maps the current orientation to an index for referencing orientation correct global icons */
private int getCurrentOrientationIndexForGlobalIcons() {
// default - 0, landscape - 1
switch (getResources().getConfiguration().orientation) {
case Configuration.ORIENTATION_LANDSCAPE:
return 1;
default:
return 0;
}
}
private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {
try {
PackageManager packageManager = getPackageManager();
// Look for the toolbar icon specified in the activity meta-data
Bundle metaData = packageManager.getActivityInfo(
activityName, PackageManager.GET_META_DATA).metaData;
if (metaData != null) {
int iconResId = metaData.getInt(resourceName);
if (iconResId != 0) {
Resources res = packageManager.getResourcesForActivity(activityName);
return res.getDrawable(iconResId);
}
}
} catch (NameNotFoundException e) {
// This can happen if the activity defines an invalid drawable
Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +
" not found", e);
} catch (Resources.NotFoundException nfe) {
// This can happen if the activity defines an invalid drawable
Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),
nfe);
}
return null;
}
// if successful in getting icon, return it; otherwise, set button to use default drawable
private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(
int buttonId, ComponentName activityName, int fallbackDrawableId,
String toolbarResourceName) {
Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);
Resources r = getResources();
int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);
int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);
TextView button = (TextView) findViewById(buttonId);
// If we were unable to find the icon via the meta-data, use a generic one
if (toolbarIcon == null) {
toolbarIcon = r.getDrawable(fallbackDrawableId);
toolbarIcon.setBounds(0, 0, w, h);
if (button != null) {
button.setCompoundDrawables(toolbarIcon, null, null, null);
}
return null;
} else {
toolbarIcon.setBounds(0, 0, w, h);
if (button != null) {
button.setCompoundDrawables(toolbarIcon, null, null, null);
}
return toolbarIcon.getConstantState();
}
}
// if successful in getting icon, return it; otherwise, set button to use default drawable
private Drawable.ConstantState updateButtonWithIconFromExternalActivity(
int buttonId, ComponentName activityName, int fallbackDrawableId,
String toolbarResourceName) {
ImageView button = (ImageView) findViewById(buttonId);
Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);
if (button != null) {
// If we were unable to find the icon via the meta-data, use a
// generic one
if (toolbarIcon == null) {
button.setImageResource(fallbackDrawableId);
} else {
button.setImageDrawable(toolbarIcon);
}
}
return toolbarIcon != null ? toolbarIcon.getConstantState() : null;
}
private void updateTextButtonWithDrawable(int buttonId, Drawable d) {
TextView button = (TextView) findViewById(buttonId);
button.setCompoundDrawables(d, null, null, null);
}
private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {
ImageView button = (ImageView) findViewById(buttonId);
button.setImageDrawable(d.newDrawable(getResources()));
}
private void invalidatePressedFocusedStates(View container, View button) {
if (container instanceof HolographicLinearLayout) {
HolographicLinearLayout layout = (HolographicLinearLayout) container;
layout.invalidatePressedFocusedStates();
} else if (button instanceof HolographicImageView) {
HolographicImageView view = (HolographicImageView) button;
view.invalidatePressedFocusedStates();
}
protected void disableVoiceButtonProxy(boolean disable) {
// NO-OP
}
public View getQsbBar() {
@ -4171,140 +3955,54 @@ public class Launcher extends Activity
}
if (mQsb == null) {
mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);
mSearchDropTargetBar.addView(mQsb);
AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);
if (searchProvider == null) {
return null;
}
Bundle opts = new Bundle();
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
SharedPreferences sp = getSharedPreferences(
LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);
int widgetId = sp.getInt(QSB_WIDGET_ID, -1);
if (!searchProvider.provider.flattenToString().equals(
sp.getString(QSB_WIDGET_PROVIDER, null))
|| (widgetId == -1)
|| !mAppWidgetManager.getAppWidgetInfo(widgetId).provider
.equals(searchProvider.provider)) {
// A valid widget is not already bound.
if (widgetId > -1) {
mAppWidgetHost.deleteAppWidgetId(widgetId);
widgetId = -1;
}
// Try to bind a new widget
widgetId = mAppWidgetHost.allocateAppWidgetId();
if (!AppWidgetManagerCompat.getInstance(this)
.bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {
mAppWidgetHost.deleteAppWidgetId(widgetId);
widgetId = -1;
}
sp.edit()
.putInt(QSB_WIDGET_ID, widgetId)
.putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())
.commit();
}
if (widgetId != -1) {
mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);
mQsb.updateAppWidgetOptions(opts);
mQsb.setPadding(0, 0, 0, 0);
mSearchDropTargetBar.addView(mQsb);
}
}
return mQsb;
}
protected boolean updateGlobalSearchIcon() {
if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
return true;
}
final View searchButtonContainer = findViewById(R.id.search_button_container);
final ImageView searchButton = (ImageView) findViewById(R.id.search_button);
final View voiceButtonContainer = findViewById(R.id.voice_button_container);
final View voiceButton = findViewById(R.id.voice_button);
final SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
ComponentName activityName = searchManager.getGlobalSearchActivity();
if (activityName != null) {
int coi = getCurrentOrientationIndexForGlobalIcons();
sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,
TOOLBAR_SEARCH_ICON_METADATA_NAME);
if (sGlobalSearchIcon[coi] == null) {
sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,
TOOLBAR_ICON_METADATA_NAME);
}
if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);
searchButton.setVisibility(View.VISIBLE);
invalidatePressedFocusedStates(searchButtonContainer, searchButton);
return true;
} else {
// We disable both search and voice search when there is no global search provider
if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);
if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
if (searchButton != null) searchButton.setVisibility(View.GONE);
if (voiceButton != null) voiceButton.setVisibility(View.GONE);
updateVoiceButtonProxyVisible(false);
return false;
}
}
protected void updateGlobalSearchIcon(Drawable.ConstantState d) {
if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) return;
final View searchButtonContainer = findViewById(R.id.search_button_container);
final View searchButton = (ImageView) findViewById(R.id.search_button);
updateButtonWithDrawable(R.id.search_button, d);
invalidatePressedFocusedStates(searchButtonContainer, searchButton);
}
protected boolean updateVoiceSearchIcon(boolean searchVisible) {
if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
return true;
}
final View voiceButtonContainer = findViewById(R.id.voice_button_container);
final View voiceButton = findViewById(R.id.voice_button);
// We only show/update the voice search icon if the search icon is enabled as well
final SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();
ComponentName activityName = null;
if (globalSearchActivity != null) {
// Check if the global search activity handles voice search
Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
intent.setPackage(globalSearchActivity.getPackageName());
activityName = intent.resolveActivity(getPackageManager());
}
if (activityName == null) {
// Fallback: check if an activity other than the global search activity
// resolves this
Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
activityName = intent.resolveActivity(getPackageManager());
}
if (searchVisible && activityName != null) {
int coi = getCurrentOrientationIndexForGlobalIcons();
sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,
TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);
if (sVoiceSearchIcon[coi] == null) {
sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,
TOOLBAR_ICON_METADATA_NAME);
}
if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);
voiceButton.setVisibility(View.VISIBLE);
updateVoiceButtonProxyVisible(false);
invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);
return true;
} else {
if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
if (voiceButton != null) voiceButton.setVisibility(View.GONE);
updateVoiceButtonProxyVisible(false);
return false;
}
}
protected void updateVoiceSearchIcon(Drawable.ConstantState d) {
if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
return;
}
final View voiceButtonContainer = findViewById(R.id.voice_button_container);
final View voiceButton = findViewById(R.id.voice_button);
updateButtonWithDrawable(R.id.voice_button, d);
invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);
}
public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {
if (mLauncherCallbacks != null) {
forceDisableVoiceButtonProxy |= mLauncherCallbacks.forceDisableVoiceButtonProxy();
}
final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);
if (voiceButtonProxy != null) {
boolean visible = !forceDisableVoiceButtonProxy &&
mWorkspace.shouldVoiceButtonProxyBeVisible();
voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);
voiceButtonProxy.bringToFront();
}
}
/**
* This is an overrid eot disable the voice button proxy. If disabled is true, then the voice button proxy
* will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.
*/
public void disableVoiceButtonProxy(boolean disabled) {
updateVoiceButtonProxyVisible(disabled);
}
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
final boolean result = super.dispatchPopulateAccessibilityEvent(event);
@ -4883,13 +4581,15 @@ public class Launcher extends Activity
getDeviceProfile().getSearchBarBounds();
}
@Override
public void bindSearchablesChanged() {
boolean searchVisible = updateGlobalSearchIcon();
boolean voiceVisible = updateVoiceSearchIcon(searchVisible);
if (mSearchDropTargetBar != null) {
mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);
if (mSearchDropTargetBar == null) {
return;
}
if (mQsb != null) {
mSearchDropTargetBar.removeView(mQsb);
mQsb = null;
}
mSearchDropTargetBar.setQsbSearchBar(getQsbBar());
}
/**

View File

@ -16,7 +16,6 @@
package com.android.launcher3;
import android.app.SearchManager;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@ -57,7 +56,6 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
public class LauncherProvider extends ContentProvider {
private static final String TAG = "Launcher.LauncherProvider";
@ -1342,29 +1340,8 @@ public class LauncherProvider extends ContentProvider {
}
private ComponentName getSearchWidgetProvider() {
SearchManager searchManager =
(SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
ComponentName searchComponent = searchManager.getGlobalSearchActivity();
if (searchComponent == null) return null;
return getProviderInPackage(searchComponent.getPackageName());
}
/**
* Gets an appwidget provider from the given package. If the package contains more than
* one appwidget provider, an arbitrary one is returned.
*/
private ComponentName getProviderInPackage(String packageName) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
List<AppWidgetProviderInfo> providers = appWidgetManager.getInstalledProviders();
if (providers == null) return null;
final int providerCount = providers.size();
for (int i = 0; i < providerCount; i++) {
ComponentName provider = providers.get(i).provider;
if (provider != null && provider.getPackageName().equals(packageName)) {
return provider;
}
}
return null;
AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(mContext);
return (searchProvider == null) ? null : searchProvider.provider;
}
private void migrateLauncher2Shortcuts(SQLiteDatabase db, Uri uri) {

View File

@ -22,7 +22,6 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
@ -50,7 +49,6 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
private int mBarHeight;
private boolean mDeferOnDragEnd = false;
private Drawable mPreviousBackground;
private boolean mEnableDropDownDropTargets;
public SearchDropTargetBar(Context context, AttributeSet attrs) {
@ -70,7 +68,10 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
mInfoDropTarget.setLauncher(launcher);
mDeleteDropTarget.setLauncher(launcher);
mQSBSearchBar = launcher.getQsbBar();
}
public void setQsbSearchBar(View qsb) {
mQSBSearchBar = qsb;
if (mQSBSearchBar != null) {
if (mEnableDropDownDropTargets) {
mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
@ -224,20 +225,6 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
}
}
public void onSearchPackagesChanged(boolean searchVisible, boolean voiceVisible) {
if (mQSBSearchBar != null) {
Drawable bg = mQSBSearchBar.getBackground();
if (bg != null && (!searchVisible && !voiceVisible)) {
// Save the background and disable it
mPreviousBackground = bg;
mQSBSearchBar.setBackgroundResource(0);
} else if (mPreviousBackground != null && (searchVisible || voiceVisible)) {
// Restore the background
mQSBSearchBar.setBackground(mPreviousBackground);
}
}
}
public Rect getSearchBarBounds() {
if (mQSBSearchBar != null) {
final int[] pos = new int[2];

View File

@ -18,6 +18,9 @@ package com.android.launcher3;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.SearchManager;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
@ -39,8 +42,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
@ -508,4 +509,37 @@ public final class Utilities {
return v.getKeyDispatcherState() != null;
}
}
/**
* Returns a widget with category {@link AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}
* provided by the same package which is set to be global search activity.
* If widgetCategory is not supported, or no such widget is found, returns the first widget
* provided by the package.
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static AppWidgetProviderInfo getSearchWidgetProvider(Context context) {
SearchManager searchManager =
(SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
ComponentName searchComponent = searchManager.getGlobalSearchActivity();
if (searchComponent == null) return null;
String providerPkg = searchComponent.getPackageName();
AppWidgetProviderInfo defaultWidgetForSearchPackage = null;
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
for (AppWidgetProviderInfo info : appWidgetManager.getInstalledProviders()) {
if (info.provider.getPackageName().equals(providerPkg)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if ((info.widgetCategory & AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX) != 0) {
return info;
} else if (defaultWidgetForSearchPackage == null) {
defaultWidgetForSearchPackage = info;
}
} else {
return info;
}
}
}
return defaultWidgetForSearchPackage;
}
}

View File

@ -1329,13 +1329,11 @@ public class Workspace extends SmoothPagedView
if (mCustomContentCallbacks != null) {
mCustomContentCallbacks.onShow(false);
mCustomContentShowTime = System.currentTimeMillis();
mLauncher.updateVoiceButtonProxyVisible(false);
}
} else if (hasCustomContent() && getNextPage() != 0 && mCustomContentShowing) {
mCustomContentShowing = false;
if (mCustomContentCallbacks != null) {
mCustomContentCallbacks.onHide();
mLauncher.updateVoiceButtonProxyVisible(false);
}
}
}
@ -2203,16 +2201,6 @@ public class Workspace extends SmoothPagedView
return -offsetFromTopEdge + mInsets.top + offsetToCenterInOverview;
}
boolean shouldVoiceButtonProxyBeVisible() {
if (isOnOrMovingToCustomContent()) {
return false;
}
if (mState != State.NORMAL) {
return false;
}
return true;
}
public void updateInteractionForState() {
if (mState != State.NORMAL) {
mLauncher.onInteractionBegin();
@ -2468,7 +2456,6 @@ public class Workspace extends SmoothPagedView
setScaleY(mNewScale);
setTranslationY(finalWorkspaceTranslationY);
}
mLauncher.updateVoiceButtonProxyVisible(false);
if (stateIsNormal) {
animateBackgroundGradient(0f, animated);