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

Commit d9b11089 authored by Pinyao Ting's avatar Pinyao Ting Committed by Android (Google) Code Review
Browse files

Merge "Implement Device Flag for shortcut integration with AppSearch" into sc-dev

parents 1027fb5c 8b875d24
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -483,6 +483,12 @@ public final class SystemUiDeviceConfigFlags {
    public static final String HOME_BUTTON_LONG_PRESS_DURATION_MS =
            "home_button_long_press_duration_ms";

    /**
     * (boolean) Whether shortcut integration over app search service is enabled.
     */
    public static final String SHORTCUT_APPSEARCH_INTEGRATION =
            "shortcut_appsearch_integration";

    private SystemUiDeviceConfigFlags() {
    }
}
+68 −15
Original line number Diff line number Diff line
@@ -219,10 +219,12 @@ class ShortcutPackage extends ShortcutPackageItem {
                getPackageName(), getPackageUserId());
    }

    private boolean isAppSearchEnabled() {
        return mShortcutUser.mService.isAppSearchEnabled();
    }

    public int getShortcutCount() {
        final int[] count = new int[1];
        forEachShortcut(si -> count[0]++);
        return count[0];
        return mShortcuts.size();
    }

    @Override
@@ -442,15 +444,18 @@ class ShortcutPackage extends ShortcutPackageItem {
        }

        forceReplaceShortcutInner(newShortcut);
        if (isAppSearchEnabled()) {
            mShortcutUser.mService.injectPostToHandler(() -> awaitInAppSearch("reportUsage",
                    session -> {
                        final AndroidFuture<Boolean> future = new AndroidFuture<>();
                        session.reportUsage(
                                new ReportUsageRequest.Builder(getPackageName())
                                        .setUri(newShortcut.getId()).build(),
                            mShortcutUser.mExecutor, result -> future.complete(result.isSuccess()));
                                mShortcutUser.mExecutor,
                                result -> future.complete(result.isSuccess()));
                        return future;
                    }));
        }
        return deleted;
    }

@@ -960,7 +965,7 @@ class ShortcutPackage extends ShortcutPackageItem {
     * the app's Xml resource.
     */
    int getSharingShortcutCount() {
        if (getShortcutCount() == 0 || mShareTargets.isEmpty()) {
        if (mShareTargets.isEmpty()) {
            return 0;
        }

@@ -1700,7 +1705,7 @@ class ShortcutPackage extends ShortcutPackageItem {
        final int size = mShortcuts.size();
        final int shareTargetSize = mShareTargets.size();

        if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0 && getShortcutCount() == 0) {
        if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0) {
            return; // nothing to write.
        }

@@ -2254,6 +2259,9 @@ class ShortcutPackage extends ShortcutPackageItem {
    }

    void updateVisibility(String packageName, byte[] certificate, boolean visible) {
        if (!isAppSearchEnabled()) {
            return;
        }
        if (visible) {
            mPackageIdentifiers.put(packageName, new PackageIdentifier(packageName, certificate));
        } else {
@@ -2287,6 +2295,14 @@ class ShortcutPackage extends ShortcutPackageItem {

    private void saveShortcut(@NonNull final Collection<ShortcutInfo> shortcuts) {
        Objects.requireNonNull(shortcuts);
        if (!isAppSearchEnabled()) {
            // If AppSearch isn't enabled, save it in memory and we are done.
            for (ShortcutInfo si : shortcuts) {
                mShortcuts.put(si.getId(), si);
            }
            return;
        }
        // Otherwise, save pinned shortcuts in memory.
        shortcuts.forEach(si -> {
            if (si.isPinned()) {
                mShortcuts.put(si.getId(), si);
@@ -2294,12 +2310,13 @@ class ShortcutPackage extends ShortcutPackageItem {
                mShortcuts.remove(si.getId());
            }
        });
        // Then proceed to app search.
        saveToAppSearch(shortcuts);
    }

    private void saveToAppSearch(@NonNull final Collection<ShortcutInfo> shortcuts) {
        Objects.requireNonNull(shortcuts);
        if (shortcuts.isEmpty()) {
        if (!isAppSearchEnabled() || shortcuts.isEmpty()) {
            // No need to invoke AppSearch when there's nothing to save.
            return;
        }
@@ -2335,6 +2352,9 @@ class ShortcutPackage extends ShortcutPackageItem {
     * Removes shortcuts from AppSearch.
     */
    void removeShortcuts() {
        if (!isAppSearchEnabled()) {
            return;
        }
        awaitInAppSearch("Removing all shortcuts from " + getPackageName(), session -> {
            final AndroidFuture<Boolean> future = new AndroidFuture<>();
            session.remove("", getSearchSpec(), mShortcutUser.mExecutor, result -> {
@@ -2352,6 +2372,9 @@ class ShortcutPackage extends ShortcutPackageItem {
    private void removeShortcut(@NonNull final String id) {
        Objects.requireNonNull(id);
        mShortcuts.remove(id);
        if (!isAppSearchEnabled()) {
            return;
        }
        awaitInAppSearch("Removing shortcut with id=" + id, session -> {
            final AndroidFuture<Boolean> future = new AndroidFuture<>();
            session.remove(new RemoveByUriRequest.Builder(getPackageName()).addUris(id).build(),
@@ -2381,6 +2404,16 @@ class ShortcutPackage extends ShortcutPackageItem {
                shortcutIds.add(id);
            }
        }
        if (!isAppSearchEnabled()) {
            final List<ShortcutInfo> ret = new ArrayList<>(1);
            for (int i = mShortcuts.size() - 1; i >= 0; i--) {
                ShortcutInfo si = mShortcuts.valueAt(i);
                if (shortcutIds.contains(si.getId())) {
                    ret.add(si);
                }
            }
            return ret;
        }
        if (ShortcutService.DEBUG_REBOOT) {
            Slog.d(TAG, "Getting shortcuts for user=" + mShortcutUser.getUserId()
                    + " pkg=" + getPackageName() + " ids: [" + String.join(",", ids) + "]");
@@ -2429,6 +2462,13 @@ class ShortcutPackage extends ShortcutPackageItem {

    private void forEachShortcutMutateIf(@NonNull final String query,
            @NonNull final Function<ShortcutInfo, Boolean> cb) {
        if (!isAppSearchEnabled()) {
            for (int i = mShortcuts.size() - 1; i >= 0; i--) {
                ShortcutInfo si = mShortcuts.valueAt(i);
                cb.apply(si);
            }
            return;
        }
        if (ShortcutService.DEBUG_REBOOT) {
            Slog.d(TAG, "Changing shortcuts for user=" + mShortcutUser.getUserId()
                    + " pkg=" + getPackageName());
@@ -2454,6 +2494,15 @@ class ShortcutPackage extends ShortcutPackageItem {

    private void forEachShortcutStopWhen(
            @NonNull final String query, @NonNull final Function<ShortcutInfo, Boolean> cb) {
        if (!isAppSearchEnabled()) {
            for (int i = mShortcuts.size() - 1; i >= 0; i--) {
                final ShortcutInfo si = mShortcuts.valueAt(i);
                if (cb.apply(si)) {
                    return;
                }
            }
            return;
        }
        if (ShortcutService.DEBUG_REBOOT) {
            Slog.d(TAG, "Iterating shortcuts for user=" + mShortcutUser.getUserId()
                    + " pkg=" + getPackageName());
@@ -2517,6 +2566,10 @@ class ShortcutPackage extends ShortcutPackageItem {
            final boolean forceReset,
            @NonNull final String description,
            @NonNull final Function<AppSearchSession, CompletableFuture<T>> cb) {
        if (!isAppSearchEnabled()) {
            throw new IllegalStateException(
                    "awaitInAppSearch called when app search integration is disabled");
        }
        synchronized (mLock) {
            final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
            final long callingIdentity = Binder.clearCallingIdentity();
+12 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.server.pm;

import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;

import android.Manifest.permission;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -85,6 +87,7 @@ import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.text.format.TimeMigrationUtils;
import android.util.ArraySet;
@@ -104,6 +107,7 @@ import android.view.IWindowManager;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.BackgroundThread;
@@ -447,6 +451,8 @@ public class ShortcutService extends IShortcutService.Stub {
    @GuardedBy("mLock")
    private final MetricsLogger mMetricsLogger = new MetricsLogger();

    private final boolean mIsAppSearchEnabled;

    static class InvalidFileFormatException extends Exception {
        public InvalidFileFormatException(String message, Throwable cause) {
            super(message, cause);
@@ -481,6 +487,8 @@ public class ShortcutService extends IShortcutService.Stub {
        mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock);
        mShortcutBitmapSaver = new ShortcutBitmapSaver(this);
        mShortcutDumpFiles = new ShortcutDumpFiles(this);
        mIsAppSearchEnabled = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
                SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, false);

        if (onlyForPackageManagerApis) {
            return; // Don't do anything further.  For unit tests only.
@@ -518,6 +526,10 @@ public class ShortcutService extends IShortcutService.Stub {
        injectRegisterRoleHoldersListener(mOnRoleHoldersChangedListener);
    }

    boolean isAppSearchEnabled() {
        return mIsAppSearchEnabled;
    }

    long getStatStartTime() {
        return mStatLogger.getTime();
    }
+1 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@
            android:action="action"
            android:data="http://www/"
            android:targetPackage="abc"
            android:targetClass=".xyz"
            android:targetClass="abc.xyz"
            android:mimeType="foo/bar"
            >
            <categories android:name="cat1" />
+11 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.server.pm;

import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;

import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;

import android.app.PendingIntent;
@@ -22,6 +24,9 @@ import android.app.appsearch.PackageIdentifier;
import android.content.pm.AppSearchShortcutInfo;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.DeviceConfig;

import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;

import java.util.Random;

@@ -33,7 +38,12 @@ import java.util.Random;
public class ShortcutManagerTest12 extends BaseShortcutManagerTest {

    public void testUpdateShortcutVisibility_updatesShortcutSchema() {

        if (!DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
                SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED,
                false)) {
            // no-op if app-search integration is disabled.
            return;
        }
        final byte[] cert = new byte[20];
        new Random().nextBytes(cert);