Loading core/java/android/appwidget/AppWidgetHost.java +76 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -45,6 +46,7 @@ import com.android.internal.appwidget.IAppWidgetHost; import com.android.internal.appwidget.IAppWidgetService; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -286,6 +288,7 @@ public class AppWidgetHost { catch (RemoteException e) { throw new RuntimeException("system server dead?", e); } reportAllWidgetEvents(); } /** Loading Loading @@ -384,6 +387,7 @@ public class AppWidgetHost { } catch (RemoteException e) { throw new RuntimeException("System server dead?", e); } reportAllWidgetEvents(); } /** Loading Loading @@ -554,6 +558,16 @@ public class AppWidgetHost { * @hide */ void onViewDataChanged(int viewId); /** * This function returns the current set of widget event data being tracked by this widget. * * @hide */ @Nullable default PersistableBundle collectWidgetEvent() { return null; } } void dispatchOnAppWidgetRemoved(int appWidgetId) { Loading Loading @@ -604,6 +618,7 @@ public class AppWidgetHost { * @hide */ public void removeListener(int appWidgetId) { reportEventForWidget(appWidgetId); synchronized (mListeners) { mListeners.remove(appWidgetId); } Loading Loading @@ -636,10 +651,71 @@ public class AppWidgetHost { * Clear the list of Views that have been created by this AppWidgetHost. */ protected void clearViews() { reportAllWidgetEvents(); synchronized (mListeners) { mListeners.clear(); } } /** * Report any pending widget event data to the AppWidgetService. * * @hide */ public void reportAllWidgetEvents() { if (sService == null) { return; } List<PersistableBundle> eventList = new ArrayList<>(); synchronized (mListeners) { for (int i = 0; i < mListeners.size(); i++) { PersistableBundle event = mListeners.valueAt(i).collectWidgetEvent(); if (event != null) { eventList.add(event); } } } if (eventList.isEmpty()) { return; } PersistableBundle[] events = new PersistableBundle[eventList.size()]; for (int i = 0; i < events.length; i++) { events[i] = eventList.get(i); } try { sService.reportWidgetEvents(mContextOpPackageName, events); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Report a pending widget event to the AppWidgetService. * * @hide */ public void reportEventForWidget(int appWidgetId) { if (sService == null) { return; } AppWidgetHostListener listener = getListener(appWidgetId); if (listener == null) { return; } PersistableBundle event = listener.collectWidgetEvent(); if (event == null) { return; } PersistableBundle[] events = {event}; try { sService.reportWidgetEvents(mContextOpPackageName, events); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } core/java/android/appwidget/AppWidgetHostView.java +43 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcelable; import android.os.PersistableBundle; import android.os.SystemClock; import android.util.ArraySet; import android.util.AttributeSet; Loading Loading @@ -1041,6 +1042,17 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW } } /** * This function returns the current set of widget event data being tracked by this widget. The * tracked data is cleared is returned here. * * @hide */ @Override public PersistableBundle collectWidgetEvent() { return mInteractionLogger.collectWidgetEvent(); } /** * This class is used to track user interactions with this widget. * @hide Loading @@ -1052,10 +1064,10 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW private static final long UPDATE_VISIBILITY_DELAY_MS = 1000L; // Clicked views @NonNull private final Set<Integer> mClickedIds = new ArraySet<>(MAX_NUM_ITEMS); private final ArraySet<Integer> mClickedIds = new ArraySet<>(MAX_NUM_ITEMS); // Scrolled views @NonNull private final Set<Integer> mScrolledIds = new ArraySet<>(MAX_NUM_ITEMS); private final ArraySet<Integer> mScrolledIds = new ArraySet<>(MAX_NUM_ITEMS); @Nullable private RemoteViews.InteractionHandler mInteractionHandler = null; // Last position this widget was laid out in Loading Loading @@ -1229,6 +1241,35 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW return view.isAggregatedVisible() && view.getGlobalVisibleRect(new Rect()) && view.getAlpha() != 0; } @Nullable private PersistableBundle collectWidgetEvent() { if (mIsVisible) { // If the widget is currently visible, add the current duration to the event data. updateVisibility(false); } if (mAppWidgetId <= 0 || mDurationMs == 0L) { return null; } PersistableBundle event = AppWidgetManager.createWidgetInteractionEvent(mAppWidgetId, mDurationMs, mPosition, toIntArray(mClickedIds), toIntArray(mScrolledIds)); mClickedIds.clear(); mScrolledIds.clear(); mDurationMs = 0; mPosition = null; return event; } private static int[] toIntArray(ArraySet<Integer> set) { if (set.isEmpty()) return null; int[] array = new int[set.size()]; for (int i = 0; i < array.length; i++) { array[i] = set.valueAt(i); } return array; } } } core/java/android/appwidget/AppWidgetManager.java +0 −1 Original line number Diff line number Diff line Loading @@ -1626,7 +1626,6 @@ public class AppWidgetManager { return extras; } @UiThread private static @NonNull Executor createUpdateExecutorIfNull() { if (sUpdateExecutor == null) { Loading core/java/com/android/internal/appwidget/IAppWidgetService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.pm.ParceledListSlice; import android.appwidget.AppWidgetProviderInfo; import com.android.internal.appwidget.IAppWidgetHost; import android.os.Bundle; import android.os.PersistableBundle; import android.os.IBinder; import android.widget.RemoteViews; import android.app.IApplicationThread; Loading Loading @@ -86,5 +87,6 @@ interface IAppWidgetService { @nullable RemoteViews getWidgetPreview(in String callingPackage, in ComponentName providerComponent, in int profileId, in int widgetCategory); void removeWidgetPreview(in ComponentName providerComponent, in int widgetCategories); oneway void reportWidgetEvents(in String callingPackage, in PersistableBundle[] events); } core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +6 −0 Original line number Diff line number Diff line Loading @@ -579,6 +579,12 @@ public final class SystemUiDeviceConfigFlags { public static final String GENERATED_PREVIEW_API_MAX_PROVIDERS = "generated_preview_api_max_providers"; /** * (long) The bucket interval for reporting widget interaction events to UsageStatsManager. */ public static final String WIDGET_EVENTS_REPORT_INTERVAL_MS = "widget_events_report_interval_ms"; private SystemUiDeviceConfigFlags() { } } Loading
core/java/android/appwidget/AppWidgetHost.java +76 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -45,6 +46,7 @@ import com.android.internal.appwidget.IAppWidgetHost; import com.android.internal.appwidget.IAppWidgetService; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -286,6 +288,7 @@ public class AppWidgetHost { catch (RemoteException e) { throw new RuntimeException("system server dead?", e); } reportAllWidgetEvents(); } /** Loading Loading @@ -384,6 +387,7 @@ public class AppWidgetHost { } catch (RemoteException e) { throw new RuntimeException("System server dead?", e); } reportAllWidgetEvents(); } /** Loading Loading @@ -554,6 +558,16 @@ public class AppWidgetHost { * @hide */ void onViewDataChanged(int viewId); /** * This function returns the current set of widget event data being tracked by this widget. * * @hide */ @Nullable default PersistableBundle collectWidgetEvent() { return null; } } void dispatchOnAppWidgetRemoved(int appWidgetId) { Loading Loading @@ -604,6 +618,7 @@ public class AppWidgetHost { * @hide */ public void removeListener(int appWidgetId) { reportEventForWidget(appWidgetId); synchronized (mListeners) { mListeners.remove(appWidgetId); } Loading Loading @@ -636,10 +651,71 @@ public class AppWidgetHost { * Clear the list of Views that have been created by this AppWidgetHost. */ protected void clearViews() { reportAllWidgetEvents(); synchronized (mListeners) { mListeners.clear(); } } /** * Report any pending widget event data to the AppWidgetService. * * @hide */ public void reportAllWidgetEvents() { if (sService == null) { return; } List<PersistableBundle> eventList = new ArrayList<>(); synchronized (mListeners) { for (int i = 0; i < mListeners.size(); i++) { PersistableBundle event = mListeners.valueAt(i).collectWidgetEvent(); if (event != null) { eventList.add(event); } } } if (eventList.isEmpty()) { return; } PersistableBundle[] events = new PersistableBundle[eventList.size()]; for (int i = 0; i < events.length; i++) { events[i] = eventList.get(i); } try { sService.reportWidgetEvents(mContextOpPackageName, events); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Report a pending widget event to the AppWidgetService. * * @hide */ public void reportEventForWidget(int appWidgetId) { if (sService == null) { return; } AppWidgetHostListener listener = getListener(appWidgetId); if (listener == null) { return; } PersistableBundle event = listener.collectWidgetEvent(); if (event == null) { return; } PersistableBundle[] events = {event}; try { sService.reportWidgetEvents(mContextOpPackageName, events); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }
core/java/android/appwidget/AppWidgetHostView.java +43 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcelable; import android.os.PersistableBundle; import android.os.SystemClock; import android.util.ArraySet; import android.util.AttributeSet; Loading Loading @@ -1041,6 +1042,17 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW } } /** * This function returns the current set of widget event data being tracked by this widget. The * tracked data is cleared is returned here. * * @hide */ @Override public PersistableBundle collectWidgetEvent() { return mInteractionLogger.collectWidgetEvent(); } /** * This class is used to track user interactions with this widget. * @hide Loading @@ -1052,10 +1064,10 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW private static final long UPDATE_VISIBILITY_DELAY_MS = 1000L; // Clicked views @NonNull private final Set<Integer> mClickedIds = new ArraySet<>(MAX_NUM_ITEMS); private final ArraySet<Integer> mClickedIds = new ArraySet<>(MAX_NUM_ITEMS); // Scrolled views @NonNull private final Set<Integer> mScrolledIds = new ArraySet<>(MAX_NUM_ITEMS); private final ArraySet<Integer> mScrolledIds = new ArraySet<>(MAX_NUM_ITEMS); @Nullable private RemoteViews.InteractionHandler mInteractionHandler = null; // Last position this widget was laid out in Loading Loading @@ -1229,6 +1241,35 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW return view.isAggregatedVisible() && view.getGlobalVisibleRect(new Rect()) && view.getAlpha() != 0; } @Nullable private PersistableBundle collectWidgetEvent() { if (mIsVisible) { // If the widget is currently visible, add the current duration to the event data. updateVisibility(false); } if (mAppWidgetId <= 0 || mDurationMs == 0L) { return null; } PersistableBundle event = AppWidgetManager.createWidgetInteractionEvent(mAppWidgetId, mDurationMs, mPosition, toIntArray(mClickedIds), toIntArray(mScrolledIds)); mClickedIds.clear(); mScrolledIds.clear(); mDurationMs = 0; mPosition = null; return event; } private static int[] toIntArray(ArraySet<Integer> set) { if (set.isEmpty()) return null; int[] array = new int[set.size()]; for (int i = 0; i < array.length; i++) { array[i] = set.valueAt(i); } return array; } } }
core/java/android/appwidget/AppWidgetManager.java +0 −1 Original line number Diff line number Diff line Loading @@ -1626,7 +1626,6 @@ public class AppWidgetManager { return extras; } @UiThread private static @NonNull Executor createUpdateExecutorIfNull() { if (sUpdateExecutor == null) { Loading
core/java/com/android/internal/appwidget/IAppWidgetService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.pm.ParceledListSlice; import android.appwidget.AppWidgetProviderInfo; import com.android.internal.appwidget.IAppWidgetHost; import android.os.Bundle; import android.os.PersistableBundle; import android.os.IBinder; import android.widget.RemoteViews; import android.app.IApplicationThread; Loading Loading @@ -86,5 +87,6 @@ interface IAppWidgetService { @nullable RemoteViews getWidgetPreview(in String callingPackage, in ComponentName providerComponent, in int profileId, in int widgetCategory); void removeWidgetPreview(in ComponentName providerComponent, in int widgetCategories); oneway void reportWidgetEvents(in String callingPackage, in PersistableBundle[] events); }
core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +6 −0 Original line number Diff line number Diff line Loading @@ -579,6 +579,12 @@ public final class SystemUiDeviceConfigFlags { public static final String GENERATED_PREVIEW_API_MAX_PROVIDERS = "generated_preview_api_max_providers"; /** * (long) The bucket interval for reporting widget interaction events to UsageStatsManager. */ public static final String WIDGET_EVENTS_REPORT_INTERVAL_MS = "widget_events_report_interval_ms"; private SystemUiDeviceConfigFlags() { } }