migrate custom widgets in comply with plugin framework

Bug: 139888225
Change-Id: I8a3d0fe2689ad5ba24b19309728bbad0b6287f71
This commit is contained in:
Pinyao Ting
2019-08-26 14:36:02 -07:00
parent 19b15701ce
commit c7a6c2979c
13 changed files with 286 additions and 235 deletions
-15
View File
@@ -152,21 +152,6 @@
<attr name="canThumbDetach" format="boolean" />
</declare-styleable>
<declare-styleable name="CustomAppWidgetProviderInfo">
<attr name="providerId" format="integer" />
<attr name="android:label" />
<attr name="android:initialLayout" />
<attr name="android:icon" />
<attr name="android:previewImage" />
<attr name="android:resizeMode" />
<attr name="numRows" />
<attr name="numColumns" />
<attr name="numMinRows" format="integer" />
<attr name="numMinColumns" format="integer" />
</declare-styleable>
<declare-styleable name="PreviewFragment">
<attr name="android:name" />
<attr name="android:id" />
-31
View File
@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 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.
-->
<widgets>
<!-- Sample widget definition
<widget
android:label="My custom widget"
android:initialLayout="@layout/sample_widget_layout"
android:icon="@drawable/ic_launcher_home"
android:resizeMode="horizontal|vertical"
launcher:numRows="2"
launcher:numColumns="3"
launcher:numMinRows="1"
launcher:numMinColumns="2"
launcher:providerId="1" />
-->
</widgets>
+4 -5
View File
@@ -147,7 +147,7 @@ import com.android.launcher3.widget.WidgetAddFlowHandler;
import com.android.launcher3.widget.WidgetHostViewLoader;
import com.android.launcher3.widget.WidgetListRowEntry;
import com.android.launcher3.widget.WidgetsFullSheet;
import com.android.launcher3.widget.custom.CustomWidgetParser;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -1657,10 +1657,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
} else {
// In this case, we either need to start an activity to get permission to bind
// the widget, or we need to start an activity to configure the widget, or both.
if (FeatureFlags.ENABLE_CUSTOM_WIDGETS &&
info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET) {
appWidgetId = CustomWidgetParser.getWidgetIdForCustomProvider(
this, info.componentName);
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET) {
appWidgetId = CustomWidgetManager.INSTANCE.get(this).getWidgetIdForCustomProvider(
info.componentName);
} else {
appWidgetId = getAppWidgetHost().allocateAppWidgetId();
}
@@ -37,6 +37,7 @@ import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.SecureSettingsObserver;
import com.android.launcher3.widget.custom.CustomWidgetManager;
public class LauncherAppState {
@@ -148,6 +149,8 @@ public class LauncherAppState {
LauncherModel setLauncher(Launcher launcher) {
getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);
mModel.initialize(launcher);
CustomWidgetManager.INSTANCE.get(launcher)
.setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
return mModel;
}
@@ -27,12 +27,12 @@ import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.widget.Toast;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.widget.DeferredAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.ArrayList;
@@ -180,10 +180,8 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
LauncherAppWidgetProviderInfo appWidget) {
if (appWidget.isCustomWidget()) {
LauncherAppWidgetHostView lahv = new LauncherAppWidgetHostView(context);
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(appWidget.initialLayout, lahv);
lahv.setAppWidget(0, appWidget);
CustomWidgetManager.INSTANCE.get(context).onViewCreated(lahv);
return lahv;
} else if ((mFlags & FLAG_LISTENING) == 0) {
DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context);
@@ -523,5 +523,4 @@ public class LauncherModel extends BroadcastReceiver
public Callbacks getCallback() {
return mCallbacks != null ? mCallbacks.get() : null;
}
}
@@ -23,19 +23,18 @@ import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.custom.CustomWidgetParser;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.HashMap;
import java.util.List;
import androidx.annotation.Nullable;
public abstract class AppWidgetManagerCompat {
private static final Object sInstanceLock = new Object();
@@ -63,11 +62,9 @@ public abstract class AppWidgetManagerCompat {
}
public LauncherAppWidgetProviderInfo getLauncherAppWidgetInfo(int appWidgetId) {
if (FeatureFlags.ENABLE_CUSTOM_WIDGETS
&& appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
return CustomWidgetParser.getWidgetProvider(mContext, appWidgetId);
if (appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
return CustomWidgetManager.INSTANCE.get(mContext).getWidgetProvider(appWidgetId);
}
AppWidgetProviderInfo info = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
return info == null ? null : LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
}
@@ -24,12 +24,15 @@ import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.custom.CustomWidgetParser;
import com.android.launcher3.widget.custom.CustomAppWidgetProviderInfo;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.ArrayList;
import java.util.Collections;
@@ -37,8 +40,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import androidx.annotation.Nullable;
class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
private final UserManager mUserManager;
@@ -54,14 +55,11 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
return Collections.emptyList();
}
if (packageUser == null) {
ArrayList<AppWidgetProviderInfo> providers = new ArrayList<AppWidgetProviderInfo>();
ArrayList<AppWidgetProviderInfo> providers = new ArrayList<>();
for (UserHandle user : mUserManager.getUserProfiles()) {
providers.addAll(mAppWidgetManager.getInstalledProvidersForProfile(user));
}
if (FeatureFlags.ENABLE_CUSTOM_WIDGETS) {
providers.addAll(CustomWidgetParser.getCustomWidgets(mContext));
}
providers.addAll(getCustomWidgets());
return providers;
}
// Only get providers for the given package/user.
@@ -74,9 +72,9 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
}
}
if (FeatureFlags.ENABLE_CUSTOM_WIDGETS && Process.myUserHandle().equals(packageUser.mUser)
if (Process.myUserHandle().equals(packageUser.mUser)
&& mContext.getPackageName().equals(packageUser.mPackageName)) {
providers.addAll(CustomWidgetParser.getCustomWidgets(mContext));
providers.addAll(getCustomWidgets());
}
return providers;
}
@@ -87,9 +85,7 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
if (FeatureFlags.GO_DISABLE_WIDGETS) {
return false;
}
if (FeatureFlags.ENABLE_CUSTOM_WIDGETS
&& appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
if (appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
return true;
}
return mAppWidgetManager.bindAppWidgetIdIfAllowed(
@@ -108,9 +104,8 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
}
}
if (FeatureFlags.ENABLE_CUSTOM_WIDGETS && Process.myUserHandle().equals(user)) {
for (LauncherAppWidgetProviderInfo info :
CustomWidgetParser.getCustomWidgets(mContext)) {
if (Process.myUserHandle().equals(user)) {
for (LauncherAppWidgetProviderInfo info : getCustomWidgets()) {
if (info.provider.equals(provider)) {
return info;
}
@@ -131,13 +126,13 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
result.put(new ComponentKey(info.provider, user), info);
}
}
if (FeatureFlags.ENABLE_CUSTOM_WIDGETS) {
for (LauncherAppWidgetProviderInfo info :
CustomWidgetParser.getCustomWidgets(mContext)) {
result.put(new ComponentKey(info.provider, info.getProfile()), info);
}
for (LauncherAppWidgetProviderInfo info : getCustomWidgets()) {
result.put(new ComponentKey(info.provider, info.getProfile()), info);
}
return result;
}
List<CustomAppWidgetProviderInfo> getCustomWidgets() {
return CustomWidgetManager.INSTANCE.get(mContext).getCustomWidgets();
}
}
@@ -19,14 +19,14 @@ package com.android.launcher3.compat;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import androidx.annotation.Nullable;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.PackageUserKey;
import java.util.Collections;
import java.util.List;
import androidx.annotation.Nullable;
class AppWidgetManagerCompatVO extends AppWidgetManagerCompatVL {
AppWidgetManagerCompatVO(Context context) {
@@ -23,11 +23,11 @@ import android.content.SharedPreferences;
import androidx.annotation.GuardedBy;
import androidx.annotation.Keep;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.Utilities;
import com.android.launcher3.Utilities;
import com.android.launcher3.uioverrides.TogglableFlag;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
@@ -74,9 +74,6 @@ public abstract class BaseFlags {
//Feature flag to enable pulling down navigation shade from workspace.
public static final boolean PULL_DOWN_STATUS_BAR = true;
// When true, custom widgets are loaded using CustomWidgetParser.
public static final boolean ENABLE_CUSTOM_WIDGETS = false;
// Features to control Launcher3Go behavior
public static final boolean GO_DISABLE_WIDGETS = false;
@@ -0,0 +1,163 @@
/*
* Copyright (C) 2019 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.widget.custom;
import static com.android.launcher3.LauncherAppWidgetProviderInfo.CLS_CUSTOM_WIDGET_PREFIX;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.os.Parcel;
import android.os.Process;
import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.systemui.plugins.CustomWidgetPlugin;
import com.android.systemui.plugins.PluginListener;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/**
* CustomWidgetManager handles custom widgets implemented as a plugin.
*/
public class CustomWidgetManager implements PluginListener<CustomWidgetPlugin> {
public static final MainThreadInitializedObject<CustomWidgetManager> INSTANCE =
new MainThreadInitializedObject<>(CustomWidgetManager::new);
private final List<CustomWidgetPlugin> mPlugins;
private final List<CustomAppWidgetProviderInfo> mCustomWidgets;
private final SparseArray<ComponentName> mWidgetsIdMap;
private Consumer<PackageUserKey> mWidgetRefreshCallback;
private CustomWidgetManager(Context context) {
mPlugins = new ArrayList<>();
mCustomWidgets = new ArrayList<>();
mWidgetsIdMap = new SparseArray<>();
PluginManagerWrapper.INSTANCE.get(context)
.addPluginListener(this, CustomWidgetPlugin.class, true);
}
@Override
public void onPluginConnected(CustomWidgetPlugin plugin, Context context) {
mPlugins.add(plugin);
List<AppWidgetProviderInfo> providers = AppWidgetManager.getInstance(context)
.getInstalledProvidersForProfile(Process.myUserHandle());
if (providers.isEmpty()) return;
Parcel parcel = Parcel.obtain();
providers.get(0).writeToParcel(parcel, 0);
parcel.setDataPosition(0);
CustomAppWidgetProviderInfo info = newInfo(plugin, parcel, context);
parcel.recycle();
mCustomWidgets.add(info);
mWidgetsIdMap.put(plugin.getProviderId(), info.provider);
mWidgetRefreshCallback.accept(null);
}
@Override
public void onPluginDisconnected(CustomWidgetPlugin plugin) {
mPlugins.remove(plugin);
mCustomWidgets.remove(getWidgetProvider(plugin.getProviderId()));
mWidgetsIdMap.remove(plugin.getProviderId());
}
/**
* Inject a callback function to refresh the widgets.
*/
public void setWidgetRefreshCallback(Consumer<PackageUserKey> cb) {
mWidgetRefreshCallback = cb;
}
/**
* Callback method to inform a plugin it's corresponding widget has been created.
*/
public void onViewCreated(LauncherAppWidgetHostView view) {
CustomAppWidgetProviderInfo info = (CustomAppWidgetProviderInfo) view.getAppWidgetInfo();
CustomWidgetPlugin plugin = findPlugin(info.providerId);
if (plugin == null) return;
plugin.onViewCreated(view);
}
/**
* Returns the list of custom widgets.
*/
@NonNull
public List<CustomAppWidgetProviderInfo> getCustomWidgets() {
return mCustomWidgets;
}
/**
* Returns the widget id for a specific provider.
*/
public int getWidgetIdForCustomProvider(@NonNull ComponentName provider) {
int index = mWidgetsIdMap.indexOfValue(provider);
if (index >= 0) {
return LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - mWidgetsIdMap.keyAt(index);
} else {
return AppWidgetManager.INVALID_APPWIDGET_ID;
}
}
/**
* Returns the widget provider in respect to given widget id.
*/
@Nullable
public LauncherAppWidgetProviderInfo getWidgetProvider(int widgetId) {
ComponentName cn = mWidgetsIdMap.get(LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - widgetId);
for (LauncherAppWidgetProviderInfo info : mCustomWidgets) {
if (info.provider.equals(cn)) return info;
}
return null;
}
private static CustomAppWidgetProviderInfo newInfo(
CustomWidgetPlugin plugin, Parcel parcel, Context context) {
int providerId = plugin.getProviderId();
CustomAppWidgetProviderInfo info = new CustomAppWidgetProviderInfo(
parcel, false, providerId);
info.provider = new ComponentName(
context.getPackageName(), CLS_CUSTOM_WIDGET_PREFIX + providerId);
info.label = plugin.getLabel();
info.icon = plugin.getIcon();
info.previewImage = plugin.getPreviewImage();
info.resizeMode = plugin.getResizeMode();
info.spanX = plugin.getSpanX();
info.spanY = plugin.getSpanY();
info.minSpanX = plugin.getMinSpanX();
info.minSpanY = plugin.getMinSpanY();
return info;
}
@Nullable
private CustomWidgetPlugin findPlugin(int providerId) {
return mPlugins.stream().filter((p) -> p.getProviderId() == providerId).findFirst()
.orElse(null);
}
}
@@ -1,142 +0,0 @@
/*
* Copyright (C) 2017 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.widget.custom;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Parcel;
import android.os.Process;
import android.util.SparseArray;
import android.util.Xml;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static com.android.launcher3.LauncherAppWidgetProviderInfo.CLS_CUSTOM_WIDGET_PREFIX;
/**
* Utility class to parse {@ink CustomAppWidgetProviderInfo} definitions from xml
*/
public class CustomWidgetParser {
private static List<LauncherAppWidgetProviderInfo> sCustomWidgets;
private static SparseArray<ComponentName> sWidgetsIdMap;
public static List<LauncherAppWidgetProviderInfo> getCustomWidgets(Context context) {
if (sCustomWidgets == null) {
// Synchronization not needed as it it safe to load multiple times
parseCustomWidgets(context);
}
return sCustomWidgets;
}
public static int getWidgetIdForCustomProvider(Context context, ComponentName provider) {
if (sWidgetsIdMap == null) {
parseCustomWidgets(context);
}
int index = sWidgetsIdMap.indexOfValue(provider);
if (index >= 0) {
return LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - sWidgetsIdMap.keyAt(index);
} else {
return AppWidgetManager.INVALID_APPWIDGET_ID;
}
}
public static LauncherAppWidgetProviderInfo getWidgetProvider(Context context, int widgetId) {
if (sWidgetsIdMap == null || sCustomWidgets == null) {
parseCustomWidgets(context);
}
ComponentName cn = sWidgetsIdMap.get(LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - widgetId);
for (LauncherAppWidgetProviderInfo info : sCustomWidgets) {
if (info.provider.equals(cn)) {
return info;
}
}
return null;
}
private static void parseCustomWidgets(Context context) {
ArrayList<LauncherAppWidgetProviderInfo> widgets = new ArrayList<>();
SparseArray<ComponentName> idMap = new SparseArray<>();
List<AppWidgetProviderInfo> providers = AppWidgetManager.getInstance(context)
.getInstalledProvidersForProfile(Process.myUserHandle());
if (providers.isEmpty()) {
sCustomWidgets = widgets;
sWidgetsIdMap = idMap;
return;
}
Parcel parcel = Parcel.obtain();
providers.get(0).writeToParcel(parcel, 0);
try (XmlResourceParser parser = context.getResources().getXml(R.xml.custom_widgets)) {
final int depth = parser.getDepth();
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG) && "widget".equals(parser.getName())) {
TypedArray a = context.obtainStyledAttributes(
Xml.asAttributeSet(parser), R.styleable.CustomAppWidgetProviderInfo);
parcel.setDataPosition(0);
CustomAppWidgetProviderInfo info = newInfo(a, parcel, context);
widgets.add(info);
a.recycle();
idMap.put(info.providerId, info.provider);
}
}
} catch (IOException | XmlPullParserException e) {
throw new RuntimeException(e);
}
parcel.recycle();
sCustomWidgets = widgets;
sWidgetsIdMap = idMap;
}
private static CustomAppWidgetProviderInfo newInfo(TypedArray a, Parcel parcel, Context context) {
int providerId = a.getInt(R.styleable.CustomAppWidgetProviderInfo_providerId, 0);
CustomAppWidgetProviderInfo info = new CustomAppWidgetProviderInfo(parcel, false, providerId);
info.provider = new ComponentName(context.getPackageName(), CLS_CUSTOM_WIDGET_PREFIX + providerId);
info.label = a.getString(R.styleable.CustomAppWidgetProviderInfo_android_label);
info.initialLayout = a.getResourceId(R.styleable.CustomAppWidgetProviderInfo_android_initialLayout, 0);
info.icon = a.getResourceId(R.styleable.CustomAppWidgetProviderInfo_android_icon, 0);
info.previewImage = a.getResourceId(R.styleable.CustomAppWidgetProviderInfo_android_previewImage, 0);
info.resizeMode = a.getInt(R.styleable.CustomAppWidgetProviderInfo_android_resizeMode, 0);
info.spanX = a.getInt(R.styleable.CustomAppWidgetProviderInfo_numColumns, 1);
info.spanY = a.getInt(R.styleable.CustomAppWidgetProviderInfo_numRows, 1);
info.minSpanX = a.getInt(R.styleable.CustomAppWidgetProviderInfo_numMinColumns, 1);
info.minSpanY = a.getInt(R.styleable.CustomAppWidgetProviderInfo_numMinRows, 1);
return info;
}
}
@@ -0,0 +1,88 @@
/*
* Copyright (C) 2019 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.plugins;
import android.appwidget.AppWidgetHostView;
import com.android.systemui.plugins.annotations.ProvidesInterface;
/**
* Implement this plugin interface to add a custom widget.
*/
@ProvidesInterface(action = CustomWidgetPlugin.ACTION, version = CustomWidgetPlugin.VERSION)
public interface CustomWidgetPlugin extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_CUSTOM_WIDGET";
int VERSION = 1;
/**
* An unique identifier for this widget. Must be a non-negative integer.
*/
int getProviderId();
/**
* The label to display to the user in the AppWidget picker.
*/
String getLabel();
/**
* A preview of what the AppWidget will look like after it's configured.
* If not supplied, the AppWidget's icon will be used.
*/
int getPreviewImage();
/**
* The icon to display for this AppWidget in the AppWidget picker. If not supplied in the
* xml, the application icon will be used.
*/
int getIcon();
/**
* The default width of the widget when added to a host, in dp. The widget will get
* at least this width, and will often be given more, depending on the host.
*/
int getSpanX();
/**
* The default height of the widget when added to a host, in dp. The widget will get
* at least this height, and will often be given more, depending on the host.
*/
int getSpanY();
/**
* Minimum width (in dp) which the widget can be resized to. This field has no effect if it
* is greater than minWidth or if horizontal resizing isn't enabled.
*/
int getMinSpanX();
/**
* Minimum height (in dp) which the widget can be resized to. This field has no effect if it
* is greater than minHeight or if vertical resizing isn't enabled.
*/
int getMinSpanY();
/**
* The rules by which a widget can be resized.
*/
int getResizeMode();
/**
* Notify the plugin that container of the widget has been rendered, where the custom widget
* can be attached to.
*/
void onViewCreated(AppWidgetHostView parent);
}