Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08396cb1 authored by Pinyao Ting's avatar Pinyao Ting
Browse files

Use RemoteCompose to render previews for Conversation Widget

Bug: 286130467
Flag: aconfig android.appwidget.flags.draw_data_parcel TRUNK_FOOD
Flag: aconfig android.appwidget.flags.generated_previews TRUNK_FOOD
Test: manual
Change-Id: I092fe7adf087fdd138be7018fe15d1235af205fb
parent 83fbe2e2
Loading
Loading
Loading
Loading
+62.8 KiB

File added.

No diff preview for this file type.

+47 −2
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN;
import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN;
import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
import static android.appwidget.flags.Flags.drawDataParcel;
import static android.appwidget.flags.Flags.generatedPreviews;
import static android.appwidget.flags.Flags.generatedPreviews;
import static android.content.Intent.ACTION_BOOT_COMPLETED;
import static android.content.Intent.ACTION_BOOT_COMPLETED;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
@@ -71,6 +72,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutInfo;
import android.graphics.drawable.Icon;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
@@ -111,6 +113,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.bubbles.Bubbles;


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
@@ -1452,13 +1456,54 @@ public class PeopleSpaceWidgetManager implements Dumpable {
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, "Updating People Space widget preview for user " + user.getIdentifier());
            Log.d(TAG, "Updating People Space widget preview for user " + user.getIdentifier());
        }
        }
        boolean success = mAppWidgetManager.setWidgetPreview(
        if (!drawDataParcel() || (!Build.IS_USERDEBUG && !Build.IS_ENG)) {
                provider, WIDGET_CATEGORY_HOME_SCREEN | WIDGET_CATEGORY_KEYGUARD,
            updateGeneratedPreviewForUserInternal(provider, user,
                    new RemoteViews(mContext.getPackageName(),
                    new RemoteViews(mContext.getPackageName(),
                        R.layout.people_space_placeholder_layout));
                        R.layout.people_space_placeholder_layout));
        } else {
            mBgExecutor.execute(updateGeneratedPreviewFromDrawInstructionsForUser(provider, user));
        }
    }

    private void updateGeneratedPreviewForUserInternal(@NonNull final ComponentName provider,
            @NonNull final UserHandle user, @NonNull final RemoteViews rv) {
        boolean success = mAppWidgetManager.setWidgetPreview(
                provider, WIDGET_CATEGORY_HOME_SCREEN | WIDGET_CATEGORY_KEYGUARD,
                rv);
        if (DEBUG && !success) {
        if (DEBUG && !success) {
            Log.d(TAG, "Failed to update generated preview for user " + user.getIdentifier());
            Log.d(TAG, "Failed to update generated preview for user " + user.getIdentifier());
        }
        }
        mUpdatedPreviews.put(user.getIdentifier(), success);
        mUpdatedPreviews.put(user.getIdentifier(), success);
    }
    }

    private Runnable updateGeneratedPreviewFromDrawInstructionsForUser(
            @NonNull final ComponentName provider, @NonNull final UserHandle user) {
        return () -> {
            if (DEBUG) {
                Log.d(TAG, "Parsing People Space widget preview from binary for user "
                        + user.getIdentifier());
            }
            if (!generatedPreviews() || mUpdatedPreviews.get(user.getIdentifier())
                    || !mUserManager.isUserUnlocked(user)) {
                // Conditions may have changed given this is called from background thread
                return;
            }
            try (InputStream is = mContext.getResources().openRawResource(R.raw.widget)
            ) {
                final byte[] preview = new byte[(int) is.available()];
                final int result = is.read(preview);
                if (DEBUG && result == -1) {
                    Log.d(TAG, "Failed parsing previews from binary for user "
                            + user.getIdentifier());
                }
                updateGeneratedPreviewForUserInternal(provider, user, new RemoteViews(
                        new RemoteViews.DrawInstructions.Builder(
                                Collections.singletonList(preview)).build()));
            } catch (IOException e) {
                if (DEBUG) {
                    Log.e(TAG, "Failed to generate preview for people widget", e);
                }
            }
        };
    }
}
}
+54 −0
Original line number Original line Diff line number Diff line
@@ -138,6 +138,8 @@ import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Optional;
import java.util.Optional;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Collectors;


@SmallTest
@SmallTest
@@ -1576,6 +1578,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    @Test
    @Test
    public void testUpdateGeneratedPreview_flagDisabled() {
    public void testUpdateGeneratedPreview_flagDisabled() {
        mSetFlagsRule.disableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.disableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.disableFlags(android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL);
        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
        verify(mAppWidgetManager, times(0)).setWidgetPreview(any(), anyInt(), any());
        verify(mAppWidgetManager, times(0)).setWidgetPreview(any(), anyInt(), any());
    }
    }
@@ -1583,6 +1586,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    @Test
    @Test
    public void testUpdateGeneratedPreview_userLocked() {
    public void testUpdateGeneratedPreview_userLocked() {
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.disableFlags(android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(false);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(false);


        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
@@ -1592,6 +1596,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    @Test
    @Test
    public void testUpdateGeneratedPreview_userUnlocked() {
    public void testUpdateGeneratedPreview_userUnlocked() {
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.disableFlags(android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
        when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);
        when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);


@@ -1602,6 +1607,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    @Test
    @Test
    public void testUpdateGeneratedPreview_doesNotSetTwice() {
    public void testUpdateGeneratedPreview_doesNotSetTwice() {
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.disableFlags(android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
        when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);
        when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);


@@ -1610,6 +1616,54 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
        verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
        verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
    }
    }


    @Test
    public void testUpdateGeneratedPreviewWithDataParcel_userLocked() throws InterruptedException {
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(false);

        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
        assertThat(waitForBackgroundJob()).isTrue();
        verify(mAppWidgetManager, times(0)).setWidgetPreview(any(), anyInt(), any());
    }

    @Test
    public void testUpdateGeneratedPreviewWithDataParcel_userUnlocked()
            throws InterruptedException {
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
        when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);

        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
        assertThat(waitForBackgroundJob()).isTrue();
        verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
    }

    @Test
    public void testUpdateGeneratedPreviewWithDataParcel_doesNotSetTwice()
            throws InterruptedException {
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
        mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL);
        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
        when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);

        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
        assertThat(waitForBackgroundJob()).isTrue();
        verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
    }

    private boolean waitForBackgroundJob() throws InterruptedException {
        final CountDownLatch latch = new CountDownLatch(1);
        mFakeExecutor.execute(latch::countDown);
        mFakeExecutor.runAllReady();
        mFakeExecutor.advanceClockToNext();
        mFakeExecutor.runAllReady();
        return latch.await(30000, TimeUnit.MILLISECONDS);

    }

    private void setFinalField(String fieldName, int value) {
    private void setFinalField(String fieldName, int value) {
        try {
        try {
            Field field = NotificationManager.Policy.class.getDeclaredField(fieldName);
            Field field = NotificationManager.Policy.class.getDeclaredField(fieldName);