Alienating QSB
> Moving all QSB widget handling code in a separate package > QSB is handled on a separate host, independent of the main host. This allows us to safely reset either of the two hosts > Also removing the logic around closeSystemDialog: Launcher does not use any panels which need closing System sends an onActivityResult(RESULT_CANCELLED), we do not need special handling for waitingForResult > Fixing bug when auto-generated qsb widget id was not being saved Change-Id: I2d889b7b1c80b14785d14f35624142a4b78452de
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.launcher3.QsbBlockerView
|
||||
<com.android.launcher3.qsb.QsbBlockerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
@@ -14,7 +14,7 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.launcher3.QsbContainerView
|
||||
<com.android.launcher3.qsb.QsbContainerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
@@ -23,8 +23,8 @@
|
||||
android:padding="0dp" >
|
||||
|
||||
<fragment
|
||||
android:name="com.android.launcher3.QsbContainerView$QsbFragment"
|
||||
android:name="com.android.launcher3.qsb.QsbContainerView$QsbFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:tag="qsb_view"
|
||||
android:layout_height="match_parent"/>
|
||||
</com.android.launcher3.QsbContainerView>
|
||||
</com.android.launcher3.qsb.QsbContainerView>
|
||||
@@ -69,7 +69,6 @@ import android.view.Menu;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
@@ -173,9 +172,6 @@ public class Launcher extends Activity
|
||||
static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =
|
||||
"com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";
|
||||
|
||||
public static final String ACTION_APPWIDGET_HOST_RESET =
|
||||
"com.android.launcher3.intent.ACTION_APPWIDGET_HOST_RESET";
|
||||
|
||||
// Type: int
|
||||
private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
|
||||
// Type: int
|
||||
@@ -206,18 +202,6 @@ public class Launcher extends Activity
|
||||
private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
|
||||
@Thunk static int NEW_APPS_ANIMATION_DELAY = 500;
|
||||
|
||||
private final BroadcastReceiver mUiBroadcastReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (ACTION_APPWIDGET_HOST_RESET.equals(intent.getAction())) {
|
||||
if (mAppWidgetHost != null) {
|
||||
mAppWidgetHost.startListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Thunk Workspace mWorkspace;
|
||||
private View mLauncherView;
|
||||
@Thunk DragLayer mDragLayer;
|
||||
@@ -441,9 +425,6 @@ public class Launcher extends Activity
|
||||
mDefaultKeySsb = new SpannableStringBuilder();
|
||||
Selection.setSelection(mDefaultKeySsb, 0);
|
||||
|
||||
IntentFilter filter = new IntentFilter(ACTION_APPWIDGET_HOST_RESET);
|
||||
registerReceiver(mUiBroadcastReceiver, filter);
|
||||
|
||||
mRotationEnabled = getResources().getBoolean(R.bool.allow_rotation);
|
||||
// In case we are on a device with locked rotation, we should look at preferences to check
|
||||
// if the user has specifically allowed rotation.
|
||||
@@ -467,6 +448,13 @@ public class Launcher extends Activity
|
||||
loadExtractedColorsAndColorItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppWidgetHostReset() {
|
||||
if (mAppWidgetHost != null) {
|
||||
mAppWidgetHost.startListening();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadExtractedColorsAndColorItems() {
|
||||
// TODO: do this in pre-N as well, once the extraction part is complete.
|
||||
if (Utilities.isNycOrAbove()) {
|
||||
@@ -570,7 +558,7 @@ public class Launcher extends Activity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLauncherProviderChange() {
|
||||
public void onLauncherProviderChanged() {
|
||||
if (mLauncherCallbacks != null) {
|
||||
mLauncherCallbacks.onLauncherProviderChange();
|
||||
}
|
||||
@@ -1665,13 +1653,6 @@ public class Launcher extends Activity
|
||||
return mDeviceProfile;
|
||||
}
|
||||
|
||||
public void closeSystemDialogs() {
|
||||
getWindow().closeAllPanels();
|
||||
|
||||
// Whatever we were doing is hereby canceled.
|
||||
setWaitingForResult(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
long startTime = 0;
|
||||
@@ -1690,9 +1671,6 @@ public class Launcher extends Activity
|
||||
|
||||
boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
|
||||
if (isActionMain) {
|
||||
// also will cancel mWaitingForResult.
|
||||
closeSystemDialogs();
|
||||
|
||||
if (mWorkspace == null) {
|
||||
// Can be cases where mWorkspace is null, this prevents a NPE
|
||||
return;
|
||||
@@ -1830,8 +1808,6 @@ public class Launcher extends Activity
|
||||
((AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE))
|
||||
.removeAccessibilityStateChangeListener(this);
|
||||
|
||||
unregisterReceiver(mUiBroadcastReceiver);
|
||||
|
||||
LauncherAnimUtils.onDestroyActivity();
|
||||
|
||||
if (mLauncherCallbacks != null) {
|
||||
|
||||
@@ -63,8 +63,6 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc
|
||||
@ViewDebug.ExportedProperty(category = "launcher")
|
||||
private boolean mChildrenFocused;
|
||||
|
||||
protected int mErrorViewId = R.layout.appwidget_error;
|
||||
|
||||
private boolean mIsAttachedToWindow;
|
||||
private boolean mIsAutoAdvanceRegistered;
|
||||
private Runnable mAutoAdvanceRunnable;
|
||||
@@ -81,7 +79,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc
|
||||
|
||||
@Override
|
||||
protected View getErrorView() {
|
||||
return mInflater.inflate(mErrorViewId, this, false);
|
||||
return mInflater.inflate(R.layout.appwidget_error, this, false);
|
||||
}
|
||||
|
||||
public void updateLastInflationOrientation() {
|
||||
|
||||
@@ -649,11 +649,8 @@ public class LauncherProvider extends ContentProvider {
|
||||
// Database was just created, so wipe any previous widgets
|
||||
if (mWidgetHostResetHandler != null) {
|
||||
new AppWidgetHost(mContext, Launcher.APPWIDGET_HOST_ID).deleteHost();
|
||||
mWidgetHostResetHandler.sendMessage(Message.obtain(
|
||||
mWidgetHostResetHandler,
|
||||
ChangeListenerWrapper.MSG_APP_WIDGET_HOST_RESET,
|
||||
mContext
|
||||
));
|
||||
mWidgetHostResetHandler.sendEmptyMessage(
|
||||
ChangeListenerWrapper.MSG_EXTRACTED_COLORS_CHANGED);
|
||||
}
|
||||
|
||||
// Set the flag for empty DB
|
||||
@@ -1136,17 +1133,13 @@ public class LauncherProvider extends ContentProvider {
|
||||
if (mListener != null) {
|
||||
switch (msg.what) {
|
||||
case MSG_LAUNCHER_PROVIDER_CHANGED:
|
||||
mListener.onLauncherProviderChange();
|
||||
mListener.onLauncherProviderChanged();
|
||||
break;
|
||||
case MSG_EXTRACTED_COLORS_CHANGED:
|
||||
mListener.onExtractedColorsChanged();
|
||||
break;
|
||||
case MSG_APP_WIDGET_HOST_RESET:
|
||||
Context context = (Context) msg.obj;
|
||||
if (context != null) {
|
||||
context.sendBroadcast(new Intent(Launcher.ACTION_APPWIDGET_HOST_RESET)
|
||||
.setPackage(context.getPackageName()));
|
||||
}
|
||||
mListener.onAppWidgetHostReset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ package com.android.launcher3;
|
||||
*/
|
||||
public interface LauncherProviderChangeListener {
|
||||
|
||||
public void onLauncherProviderChange();
|
||||
void onLauncherProviderChanged();
|
||||
|
||||
public void onExtractedColorsChanged();
|
||||
void onExtractedColorsChanged();
|
||||
|
||||
void onAppWidgetHostReset();
|
||||
}
|
||||
|
||||
+5
-2
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
package com.android.launcher3.qsb;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
@@ -27,12 +27,15 @@ import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.Workspace.OnStateChangeListener;
|
||||
import com.android.launcher3.Workspace.State;
|
||||
|
||||
/**
|
||||
* A simple view used to show the region blocked by QSB during drag and drop.
|
||||
*/
|
||||
public class QsbBlockerView extends View implements Workspace.OnStateChangeListener {
|
||||
public class QsbBlockerView extends View implements OnStateChangeListener {
|
||||
|
||||
private static final int VISIBLE_ALPHA = 100;
|
||||
|
||||
+68
-85
@@ -14,19 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
package com.android.launcher3.qsb;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.SearchManager;
|
||||
import android.appwidget.AppWidgetHost;
|
||||
import android.appwidget.AppWidgetHostView;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
@@ -35,6 +34,11 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.launcher3.AppWidgetResizeFrame;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.compat.AppWidgetManagerCompat;
|
||||
|
||||
/**
|
||||
@@ -68,25 +72,14 @@ public class QsbContainerView extends FrameLayout {
|
||||
private static final int REQUEST_BIND_QSB = 1;
|
||||
private static final String QSB_WIDGET_ID = "qsb_widget_id";
|
||||
|
||||
private static int sSavedWidgetId = -1;
|
||||
|
||||
private QsbWidgetHost mQsbWidgetHost;
|
||||
private AppWidgetProviderInfo mWidgetInfo;
|
||||
private LauncherAppWidgetHostView mQsb;
|
||||
|
||||
private BroadcastReceiver mRebindReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
rebindFragment();
|
||||
}
|
||||
};
|
||||
private QsbWidgetHostView mQsb;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
IntentFilter filter = new IntentFilter(Launcher.ACTION_APPWIDGET_HOST_RESET);
|
||||
filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
|
||||
getActivity().registerReceiver(mRebindReceiver, filter);
|
||||
mQsbWidgetHost = new QsbWidgetHost(getActivity());
|
||||
}
|
||||
|
||||
private FrameLayout mWrapper;
|
||||
@@ -95,110 +88,96 @@ public class QsbContainerView extends FrameLayout {
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
sSavedWidgetId = savedInstanceState.getInt(QSB_WIDGET_ID, -1);
|
||||
}
|
||||
mWrapper = new FrameLayout(getActivity());
|
||||
mWrapper.addView(createQsb(inflater, mWrapper));
|
||||
mWrapper.addView(createQsb(mWrapper));
|
||||
return mWrapper;
|
||||
}
|
||||
|
||||
private View createQsb(LayoutInflater inflater, ViewGroup container) {
|
||||
Launcher launcher = Launcher.getLauncher(getActivity());
|
||||
mWidgetInfo = getSearchWidgetProvider(launcher);
|
||||
private View createQsb(ViewGroup container) {
|
||||
Activity activity = getActivity();
|
||||
mWidgetInfo = getSearchWidgetProvider(activity);
|
||||
if (mWidgetInfo == null) {
|
||||
// There is no search provider, just show the default widget.
|
||||
return getDefaultView(inflater, container, false);
|
||||
} else {
|
||||
mWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(launcher, mWidgetInfo);
|
||||
return QsbWidgetHostView.getDefaultView(container);
|
||||
}
|
||||
|
||||
SharedPreferences prefs = Utilities.getPrefs(launcher);
|
||||
AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(launcher);
|
||||
LauncherAppWidgetHost widgetHost = launcher.getAppWidgetHost();
|
||||
AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(activity);
|
||||
InvariantDeviceProfile idp = LauncherAppState.getInstance().getInvariantDeviceProfile();
|
||||
|
||||
Bundle opts = new Bundle();
|
||||
Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(launcher, idp.numColumns, 1, null);
|
||||
Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(activity, idp.numColumns, 1, null);
|
||||
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, size.left);
|
||||
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, size.top);
|
||||
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, size.right);
|
||||
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, size.bottom);
|
||||
|
||||
int widgetId = prefs.getInt(QSB_WIDGET_ID, -1);
|
||||
int widgetId = Utilities.getPrefs(activity).getInt(QSB_WIDGET_ID, -1);
|
||||
AppWidgetProviderInfo widgetInfo = widgetManager.getAppWidgetInfo(widgetId);
|
||||
boolean isWidgetBound = (widgetInfo != null) &&
|
||||
widgetInfo.provider.equals(mWidgetInfo.provider);
|
||||
|
||||
int oldWidgetId = widgetId;
|
||||
if (!isWidgetBound) {
|
||||
// widgetId is already bound and its not the correct provider.
|
||||
// Delete the widget id.
|
||||
if (widgetId > -1) {
|
||||
widgetHost.deleteAppWidgetId(widgetId);
|
||||
// widgetId is already bound and its not the correct provider. reset host.
|
||||
mQsbWidgetHost.deleteHost();
|
||||
}
|
||||
|
||||
widgetId = mQsbWidgetHost.allocateAppWidgetId();
|
||||
isWidgetBound = widgetManager.bindAppWidgetIdIfAllowed(widgetId, mWidgetInfo, opts);
|
||||
if (!isWidgetBound) {
|
||||
mQsbWidgetHost.deleteAppWidgetId(widgetId);
|
||||
widgetId = -1;
|
||||
}
|
||||
|
||||
widgetId = widgetHost.allocateAppWidgetId();
|
||||
isWidgetBound = widgetManager.bindAppWidgetIdIfAllowed(widgetId, mWidgetInfo, opts);
|
||||
if (!isWidgetBound) {
|
||||
widgetHost.deleteAppWidgetId(widgetId);
|
||||
widgetId = -1;
|
||||
if (oldWidgetId != widgetId) {
|
||||
saveWidgetId(widgetId);
|
||||
}
|
||||
}
|
||||
|
||||
if (isWidgetBound) {
|
||||
mQsb = (LauncherAppWidgetHostView)
|
||||
widgetHost.createView(launcher, widgetId, mWidgetInfo);
|
||||
mQsb = (QsbWidgetHostView) mQsbWidgetHost.createView(activity, widgetId, mWidgetInfo);
|
||||
mQsb.setId(R.id.qsb_widget);
|
||||
mQsb.mErrorViewId = R.layout.qsb_default_view;
|
||||
|
||||
if (!Utilities.containsAll(AppWidgetManager.getInstance(launcher)
|
||||
if (!Utilities.containsAll(AppWidgetManager.getInstance(activity)
|
||||
.getAppWidgetOptions(widgetId), opts)) {
|
||||
mQsb.updateAppWidgetOptions(opts);
|
||||
}
|
||||
mQsb.setPadding(0, 0, 0, 0);
|
||||
mQsbWidgetHost.startListening();
|
||||
return mQsb;
|
||||
}
|
||||
|
||||
// Return a default widget with setup icon.
|
||||
return getDefaultView(inflater, container, true);
|
||||
View v = QsbWidgetHostView.getDefaultView(container);
|
||||
View setupButton = v.findViewById(R.id.btn_qsb_setup);
|
||||
setupButton.setVisibility(View.VISIBLE);
|
||||
setupButton.setOnClickListener(this);
|
||||
return v;
|
||||
}
|
||||
|
||||
private void saveWidgetId(int widgetId) {
|
||||
Utilities.getPrefs(getActivity()).edit().putInt(QSB_WIDGET_ID, widgetId).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (view.getId() == R.id.btn_qsb_search) {
|
||||
getActivity().startSearch("", false, null, true);
|
||||
} else if (view.getId() == R.id.btn_qsb_setup) {
|
||||
// Allocate a new widget id for QSB
|
||||
sSavedWidgetId = Launcher.getLauncher(getActivity())
|
||||
.getAppWidgetHost().allocateAppWidgetId();
|
||||
// Start intent for bind the widget
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, sSavedWidgetId);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, mWidgetInfo.provider);
|
||||
startActivityForResult(intent, REQUEST_BIND_QSB);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt(QSB_WIDGET_ID, sSavedWidgetId);
|
||||
// Start intent for bind the widget
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
|
||||
// Allocate a new widget id for QSB
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mQsbWidgetHost.allocateAppWidgetId());
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, mWidgetInfo.provider);
|
||||
startActivityForResult(intent, REQUEST_BIND_QSB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == REQUEST_BIND_QSB) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
int widgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
sSavedWidgetId);
|
||||
Utilities.getPrefs(getActivity()).edit().putInt(QSB_WIDGET_ID, widgetId).apply();
|
||||
sSavedWidgetId = -1;
|
||||
saveWidgetId(data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1));
|
||||
rebindFragment();
|
||||
} else if (sSavedWidgetId != -1) {
|
||||
Launcher.getLauncher(getActivity()).getAppWidgetHost()
|
||||
.deleteAppWidgetId(sSavedWidgetId);
|
||||
sSavedWidgetId = -1;
|
||||
} else {
|
||||
mQsbWidgetHost.deleteHost();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,27 +192,16 @@ public class QsbContainerView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
getActivity().unregisterReceiver(mRebindReceiver);
|
||||
mQsbWidgetHost.stopListening();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void rebindFragment() {
|
||||
if (mWrapper != null && getActivity() != null) {
|
||||
mWrapper.removeAllViews();
|
||||
mWrapper.addView(createQsb(getActivity().getLayoutInflater(), mWrapper));
|
||||
mWrapper.addView(createQsb(mWrapper));
|
||||
}
|
||||
}
|
||||
|
||||
private View getDefaultView(LayoutInflater inflater, ViewGroup parent, boolean showSetup) {
|
||||
View v = inflater.inflate(R.layout.qsb_default_view, parent, false);
|
||||
if (showSetup) {
|
||||
View setupButton = v.findViewById(R.id.btn_qsb_setup);
|
||||
setupButton.setVisibility(View.VISIBLE);
|
||||
setupButton.setOnClickListener(this);
|
||||
}
|
||||
v.findViewById(R.id.btn_qsb_search).setOnClickListener(this);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,4 +231,19 @@ public class QsbContainerView extends FrameLayout {
|
||||
}
|
||||
return defaultWidgetForSearchPackage;
|
||||
}
|
||||
|
||||
private static class QsbWidgetHost extends AppWidgetHost {
|
||||
|
||||
private static final int QSB_WIDGET_HOST_ID = 1026;
|
||||
|
||||
public QsbWidgetHost(Context context) {
|
||||
super(context, QSB_WIDGET_HOST_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AppWidgetHostView onCreateView(
|
||||
Context context, int appWidgetId, AppWidgetProviderInfo appWidget) {
|
||||
return new QsbWidgetHostView(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.qsb;
|
||||
|
||||
import android.appwidget.AppWidgetHostView;
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewDebug;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
|
||||
/**
|
||||
* Appwidget host view with QSB specific logic.
|
||||
*/
|
||||
public class QsbWidgetHostView extends AppWidgetHostView {
|
||||
|
||||
@ViewDebug.ExportedProperty(category = "launcher")
|
||||
private int mPreviousOrientation;
|
||||
|
||||
public QsbWidgetHostView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAppWidget(RemoteViews remoteViews) {
|
||||
// Store the orientation in which the widget was inflated
|
||||
mPreviousOrientation = getResources().getConfiguration().orientation;
|
||||
super.updateAppWidget(remoteViews);
|
||||
}
|
||||
|
||||
|
||||
public boolean isReinflateRequired() {
|
||||
// Re-inflate is required if the orientation has changed since last inflation.
|
||||
return mPreviousOrientation != getResources().getConfiguration().orientation;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
try {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
} catch (final RuntimeException e) {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Update the widget with 0 Layout id, to reset the view to error view.
|
||||
updateAppWidget(new RemoteViews(getAppWidgetInfo().provider.getPackageName(), 0));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View getErrorView() {
|
||||
return getDefaultView(this);
|
||||
}
|
||||
|
||||
public static View getDefaultView(ViewGroup parent) {
|
||||
View v = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.qsb_default_view, parent, false);
|
||||
v.findViewById(R.id.btn_qsb_search).setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Launcher.getLauncher(view.getContext()).startSearch("", false, null, true);
|
||||
}
|
||||
});
|
||||
return v;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user