Loading core/java/android/appwidget/AppWidgetHost.java +34 −29 Original line number Diff line number Diff line Loading @@ -50,7 +50,6 @@ import com.android.internal.appwidget.IAppWidgetService; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Loading Loading @@ -82,6 +81,7 @@ public class AppWidgetHost { private final Callbacks mCallbacks; private final SparseArray<AppWidgetHostListener> mListeners = new SparseArray<>(); private InteractionHandler mInteractionHandler; private final Handler mMainHandler; static class Callbacks extends IAppWidgetHost.Stub { private final WeakReference<Handler> mWeakHandler; Loading Loading @@ -214,6 +214,7 @@ public class AppWidgetHost { mHandler = new UpdateHandler(looper); mCallbacks = new Callbacks(mHandler); mDisplayMetrics = context.getResources().getDisplayMetrics(); mMainHandler = new Handler(Looper.getMainLooper()); bindService(context); } Loading Loading @@ -673,6 +674,7 @@ public class AppWidgetHost { } List<AppWidgetEvent> eventList = new ArrayList<>(); mMainHandler.post(() -> { synchronized (mListeners) { for (int i = 0; i < mListeners.size(); i++) { AppWidgetEvent event = mListeners.valueAt(i).collectWidgetEvent(); Loading @@ -694,6 +696,7 @@ public class AppWidgetHost { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }); } /** Loading @@ -709,6 +712,7 @@ public class AppWidgetHost { if (listener == null) { return; } mMainHandler.post(() -> { AppWidgetEvent event = listener.collectWidgetEvent(); if (event == null) { return; Loading @@ -720,6 +724,7 @@ public class AppWidgetHost { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }); } } Loading core/java/android/appwidget/AppWidgetHostView.java +6 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Looper; import android.os.Parcelable; import android.os.SystemClock; import android.util.AttributeSet; Loading Loading @@ -1043,11 +1044,16 @@ 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. * * This should always be called on the main thread. * * @hide */ @FlaggedApi(FLAG_ENGAGEMENT_METRICS) @Override public AppWidgetEvent collectWidgetEvent() { if (!Looper.getMainLooper().isCurrentThread()) { throw new IllegalStateException("collectWidgetEvent must be called from main thread"); } return mInteractionLogger.collectWidgetEvent(); } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceTest.kt +14 −1 Original line number Diff line number Diff line Loading @@ -45,8 +45,10 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doAnswer import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.never Loading Loading @@ -143,7 +145,15 @@ class GlanceableHubWidgetManagerServiceTest : SysuiTestCase() { val service = IGlanceableHubWidgetManagerService.Stub.asInterface(binder) // Set listener val listener = mock<IGlanceableHubWidgetManagerService.IAppWidgetHostListener>() val listener = mock<IGlanceableHubWidgetManagerService.IAppWidgetHostListener> { on { collectWidgetEvent(any()) } doAnswer { (it.arguments[0] as IGlanceableHubWidgetManagerService.IAppWidgetEventCallback) .onResult(null) } } service.setAppWidgetHostListener(1, listener) // Verify a listener is set on the host Loading @@ -164,6 +174,9 @@ class GlanceableHubWidgetManagerServiceTest : SysuiTestCase() { appWidgetHostListener.onViewDataChanged(1) verify(listener).onViewDataChanged(1) appWidgetHostListener.collectWidgetEvent() verify(listener).collectWidgetEvent(any()) } @Test Loading packages/SystemUI/src/com/android/systemui/communal/widgets/AppWidgetHostListenerDelegate.kt +19 −0 Original line number Diff line number Diff line Loading @@ -16,14 +16,17 @@ package com.android.systemui.communal.widgets import android.appwidget.AppWidgetEvent import android.appwidget.AppWidgetHost.AppWidgetHostListener import android.appwidget.AppWidgetProviderInfo import android.os.Looper import android.widget.RemoteViews import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.dagger.qualifiers.Application import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.util.concurrent.CompletableFuture import kotlinx.coroutines.CoroutineScope /** Loading Loading @@ -55,4 +58,20 @@ constructor( override fun onViewDataChanged(viewId: Int) { mainScope.launchTraced("$tag#onViewDataChanged") { listener.onViewDataChanged(viewId) } } override fun collectWidgetEvent(): AppWidgetEvent? { if (!android.appwidget.flags.Flags.engagementMetrics()) { return null } if (Looper.getMainLooper().isCurrentThread()) { return listener.collectWidgetEvent() } val future = CompletableFuture<AppWidgetEvent?>() mainScope.launchTraced("$tag#collectWidgetEvent") { future.complete(listener.collectWidgetEvent()) } return future.get() } } packages/SystemUI/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManager.kt +5 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import com.android.server.servicewatcher.ServiceWatcher import com.android.server.servicewatcher.ServiceWatcher.ServiceListener import com.android.systemui.communal.shared.model.CommunalWidgetContentModel import com.android.systemui.communal.shared.model.GlanceableHubMultiUserHelper import com.android.systemui.communal.widgets.IGlanceableHubWidgetManagerService.IAppWidgetEventCallback import com.android.systemui.communal.widgets.IGlanceableHubWidgetManagerService.IAppWidgetHostListener import com.android.systemui.communal.widgets.IGlanceableHubWidgetManagerService.IConfigureWidgetCallback import com.android.systemui.communal.widgets.IGlanceableHubWidgetManagerService.IGlanceableHubWidgetsListener Loading Loading @@ -212,6 +213,10 @@ constructor( override fun onViewDataChanged(viewId: Int) { listener.onViewDataChanged(viewId) } override fun collectWidgetEvent(callback: IAppWidgetEventCallback) { callback.onResult(listener.collectWidgetEvent()) } } } Loading Loading
core/java/android/appwidget/AppWidgetHost.java +34 −29 Original line number Diff line number Diff line Loading @@ -50,7 +50,6 @@ import com.android.internal.appwidget.IAppWidgetService; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Loading Loading @@ -82,6 +81,7 @@ public class AppWidgetHost { private final Callbacks mCallbacks; private final SparseArray<AppWidgetHostListener> mListeners = new SparseArray<>(); private InteractionHandler mInteractionHandler; private final Handler mMainHandler; static class Callbacks extends IAppWidgetHost.Stub { private final WeakReference<Handler> mWeakHandler; Loading Loading @@ -214,6 +214,7 @@ public class AppWidgetHost { mHandler = new UpdateHandler(looper); mCallbacks = new Callbacks(mHandler); mDisplayMetrics = context.getResources().getDisplayMetrics(); mMainHandler = new Handler(Looper.getMainLooper()); bindService(context); } Loading Loading @@ -673,6 +674,7 @@ public class AppWidgetHost { } List<AppWidgetEvent> eventList = new ArrayList<>(); mMainHandler.post(() -> { synchronized (mListeners) { for (int i = 0; i < mListeners.size(); i++) { AppWidgetEvent event = mListeners.valueAt(i).collectWidgetEvent(); Loading @@ -694,6 +696,7 @@ public class AppWidgetHost { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }); } /** Loading @@ -709,6 +712,7 @@ public class AppWidgetHost { if (listener == null) { return; } mMainHandler.post(() -> { AppWidgetEvent event = listener.collectWidgetEvent(); if (event == null) { return; Loading @@ -720,6 +724,7 @@ public class AppWidgetHost { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }); } } Loading
core/java/android/appwidget/AppWidgetHostView.java +6 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Looper; import android.os.Parcelable; import android.os.SystemClock; import android.util.AttributeSet; Loading Loading @@ -1043,11 +1044,16 @@ 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. * * This should always be called on the main thread. * * @hide */ @FlaggedApi(FLAG_ENGAGEMENT_METRICS) @Override public AppWidgetEvent collectWidgetEvent() { if (!Looper.getMainLooper().isCurrentThread()) { throw new IllegalStateException("collectWidgetEvent must be called from main thread"); } return mInteractionLogger.collectWidgetEvent(); } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceTest.kt +14 −1 Original line number Diff line number Diff line Loading @@ -45,8 +45,10 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doAnswer import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.never Loading Loading @@ -143,7 +145,15 @@ class GlanceableHubWidgetManagerServiceTest : SysuiTestCase() { val service = IGlanceableHubWidgetManagerService.Stub.asInterface(binder) // Set listener val listener = mock<IGlanceableHubWidgetManagerService.IAppWidgetHostListener>() val listener = mock<IGlanceableHubWidgetManagerService.IAppWidgetHostListener> { on { collectWidgetEvent(any()) } doAnswer { (it.arguments[0] as IGlanceableHubWidgetManagerService.IAppWidgetEventCallback) .onResult(null) } } service.setAppWidgetHostListener(1, listener) // Verify a listener is set on the host Loading @@ -164,6 +174,9 @@ class GlanceableHubWidgetManagerServiceTest : SysuiTestCase() { appWidgetHostListener.onViewDataChanged(1) verify(listener).onViewDataChanged(1) appWidgetHostListener.collectWidgetEvent() verify(listener).collectWidgetEvent(any()) } @Test Loading
packages/SystemUI/src/com/android/systemui/communal/widgets/AppWidgetHostListenerDelegate.kt +19 −0 Original line number Diff line number Diff line Loading @@ -16,14 +16,17 @@ package com.android.systemui.communal.widgets import android.appwidget.AppWidgetEvent import android.appwidget.AppWidgetHost.AppWidgetHostListener import android.appwidget.AppWidgetProviderInfo import android.os.Looper import android.widget.RemoteViews import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.dagger.qualifiers.Application import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.util.concurrent.CompletableFuture import kotlinx.coroutines.CoroutineScope /** Loading Loading @@ -55,4 +58,20 @@ constructor( override fun onViewDataChanged(viewId: Int) { mainScope.launchTraced("$tag#onViewDataChanged") { listener.onViewDataChanged(viewId) } } override fun collectWidgetEvent(): AppWidgetEvent? { if (!android.appwidget.flags.Flags.engagementMetrics()) { return null } if (Looper.getMainLooper().isCurrentThread()) { return listener.collectWidgetEvent() } val future = CompletableFuture<AppWidgetEvent?>() mainScope.launchTraced("$tag#collectWidgetEvent") { future.complete(listener.collectWidgetEvent()) } return future.get() } }
packages/SystemUI/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManager.kt +5 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import com.android.server.servicewatcher.ServiceWatcher import com.android.server.servicewatcher.ServiceWatcher.ServiceListener import com.android.systemui.communal.shared.model.CommunalWidgetContentModel import com.android.systemui.communal.shared.model.GlanceableHubMultiUserHelper import com.android.systemui.communal.widgets.IGlanceableHubWidgetManagerService.IAppWidgetEventCallback import com.android.systemui.communal.widgets.IGlanceableHubWidgetManagerService.IAppWidgetHostListener import com.android.systemui.communal.widgets.IGlanceableHubWidgetManagerService.IConfigureWidgetCallback import com.android.systemui.communal.widgets.IGlanceableHubWidgetManagerService.IGlanceableHubWidgetsListener Loading Loading @@ -212,6 +213,10 @@ constructor( override fun onViewDataChanged(viewId: Int) { listener.onViewDataChanged(viewId) } override fun collectWidgetEvent(callback: IAppWidgetEventCallback) { callback.onResult(listener.collectWidgetEvent()) } } } Loading