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

Commit 90a789e1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Give VoiceInteractionService access to shortcuts."

parents a779b40e c160fa4c
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -671,9 +671,13 @@ public class LauncherApps {
    }

    /**
     * Returns whether the caller can access the shortcut information.
     * Returns whether the caller can access the shortcut information.  Access is currently
     * available to:
     *
     * <p>Only the default launcher can access the shortcut information.
     * <ul>
     *     <li>The current launcher (or default launcher if there is no set current launcher).</li>
     *     <li>The currently active voice interaction service.</li>
     * </ul>
     *
     * <p>Note when this method returns {@code false}, it may be a temporary situation because
     * the user is trying a new launcher application.  The user may decide to change the default
+3 −0
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ public abstract class ShortcutServiceInternal {
    public abstract boolean hasShortcutHostPermission(int launcherUserId,
            @NonNull String callingPackage, int callingPid, int callingUid);

    public abstract void setShortcutHostPackage(@NonNull String type, @Nullable String packageName,
            int userId);

    public abstract boolean requestPinAppWidget(@NonNull String callingPackage,
            @NonNull AppWidgetProviderInfo appWidget, @Nullable Bundle extras,
            @Nullable IntentSender resultIntent, int userId);
+20 −0
Original line number Diff line number Diff line
@@ -2262,6 +2262,10 @@ public class ShortcutService extends IShortcutService.Stub {

            final ShortcutUser user = getUserShortcutsLocked(userId);

            if (user.hasHostPackage(packageName)) {
                return true;
            }

            // Always trust the cached component.
            final ComponentName cached = user.getCachedLauncher();
            if (cached != null) {
@@ -2361,6 +2365,16 @@ public class ShortcutService extends IShortcutService.Stub {
        }
    }

    public void setShortcutHostPackage(@NonNull String type, @Nullable String packageName,
            int userId) {
        synchronized (mLock) {
            throwIfUserLockedL(userId);

            final ShortcutUser user = getUserShortcutsLocked(userId);
            user.setShortcutHostPackage(type, packageName);
        }
    }

    // === House keeping ===

    private void cleanUpPackageForAllLoadedUsers(String packageName, @UserIdInt int packageUserId,
@@ -2696,6 +2710,12 @@ public class ShortcutService extends IShortcutService.Stub {
                    callingPid, callingUid);
        }

        @Override
        public void setShortcutHostPackage(@NonNull String type, @Nullable String packageName,
                int userId) {
            ShortcutService.this.setShortcutHostPackage(type, packageName, userId);
        }

        @Override
        public boolean requestPinAppWidget(@NonNull String callingPackage,
                @NonNull AppWidgetProviderInfo appWidget, @Nullable Bundle extras,
+44 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.pm.ShortcutManager;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;

@@ -123,6 +124,20 @@ class ShortcutUser {
    /** In-memory-cached default launcher. */
    private ComponentName mCachedLauncher;

    /**
     * Keep track of additional packages that other parts of the system have said are
     * allowed to access shortcuts.  The key is the part of the system it came from,
     * the value is the package name that has access.  We don't persist these because
     * at boot all relevant system services will push this data back to us they do their
     * normal evaluation of the state of the world.
     */
    private final ArrayMap<String, String> mHostPackages = new ArrayMap<>();

    /**
     * Set of package name values from above.
     */
    private final ArraySet<String> mHostPackageSet = new ArraySet<>();

    private String mKnownLocales;

    private long mLastAppScanTime;
@@ -467,6 +482,23 @@ class ShortcutUser {
        return mCachedLauncher;
    }

    public void setShortcutHostPackage(@NonNull String type, @Nullable String packageName) {
        if (packageName != null) {
            mHostPackages.put(type, packageName);
        } else {
            mHostPackages.remove(type);
        }

        mHostPackageSet.clear();
        for (int i = 0; i < mHostPackages.size(); i++) {
            mHostPackageSet.add(mHostPackages.valueAt(i));
        }
    }

    public boolean hasHostPackage(@NonNull String packageName) {
        return mHostPackageSet.contains(packageName);
    }

    public void resetThrottling() {
        for (int i = mPackages.size() - 1; i >= 0; i--) {
            mPackages.valueAt(i).resetThrottling();
@@ -555,6 +587,18 @@ class ShortcutUser {
            pw.print("Last known launcher: ");
            pw.print(mLastKnownLauncher);
            pw.println();

            if (mHostPackages.size() > 0) {
                pw.print(prefix);
                pw.println("Host packages:");
                for (int i = 0; i < mHostPackages.size(); i++) {
                    pw.print(prefix);
                    pw.print("  ");
                    pw.print(mHostPackages.keyAt(i));
                    pw.print(": ");
                    pw.println(mHostPackages.valueAt(i));
                }
            }
        }

        for (int i = 0; i < mLaunchers.size(); i++) {
+32 −7
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.ShortcutServiceInternal;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
@@ -44,6 +45,7 @@ import android.os.Parcel;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.voice.IVoiceInteractionService;
import android.service.voice.IVoiceInteractionSession;
@@ -53,6 +55,7 @@ import android.service.voice.VoiceInteractionServiceInfo;
import android.service.voice.VoiceInteractionSession;
import android.speech.RecognitionService;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;

@@ -63,6 +66,7 @@ import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.UiThread;
@@ -84,7 +88,9 @@ public class VoiceInteractionManagerService extends SystemService {
    final ContentResolver mResolver;
    final DatabaseHelper mDbHelper;
    final ActivityManagerInternal mAmInternal;
    final TreeSet<Integer> mLoadedKeyphraseIds;
    final UserManager mUserManager;
    final ArraySet<Integer> mLoadedKeyphraseIds = new ArraySet<>();
    ShortcutServiceInternal mShortcutServiceInternal;
    SoundTriggerInternal mSoundTriggerInternal;

    private final RemoteCallbackList<IVoiceInteractionSessionListener>
@@ -96,8 +102,10 @@ public class VoiceInteractionManagerService extends SystemService {
        mResolver = context.getContentResolver();
        mDbHelper = new DatabaseHelper(context);
        mServiceStub = new VoiceInteractionManagerServiceStub();
        mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
        mLoadedKeyphraseIds = new TreeSet<Integer>();
        mAmInternal = Preconditions.checkNotNull(
                LocalServices.getService(ActivityManagerInternal.class));
        mUserManager = Preconditions.checkNotNull(
                context.getSystemService(UserManager.class));

        PackageManagerInternal packageManagerInternal = LocalServices.getService(
                PackageManagerInternal.class);
@@ -124,6 +132,8 @@ public class VoiceInteractionManagerService extends SystemService {
    @Override
    public void onBootPhase(int phase) {
        if (PHASE_SYSTEM_SERVICES_READY == phase) {
            mShortcutServiceInternal = Preconditions.checkNotNull(
                    LocalServices.getService(ShortcutServiceInternal.class));
            mSoundTriggerInternal = LocalServices.getService(SoundTriggerInternal.class);
        } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
            mServiceStub.systemRunning(isSafeMode());
@@ -180,6 +190,7 @@ public class VoiceInteractionManagerService extends SystemService {

        private boolean mSafeMode;
        private int mCurUser;
        private boolean mCurUserUnlocked;
        private final boolean mEnableService;

        VoiceInteractionManagerServiceStub() {
@@ -381,6 +392,7 @@ public class VoiceInteractionManagerService extends SystemService {
        public void switchUser(int userHandle) {
            synchronized (this) {
                mCurUser = userHandle;
                mCurUserUnlocked = false;
                switchImplementationIfNeededLocked(false);
            }
        }
@@ -409,13 +421,24 @@ public class VoiceInteractionManagerService extends SystemService {
                    }
                }

                final boolean hasComponent = serviceComponent != null && serviceInfo != null;

                if (mUserManager.isUserUnlockingOrUnlocked(mCurUser)) {
                    if (hasComponent) {
                        mShortcutServiceInternal.setShortcutHostPackage(TAG,
                                serviceComponent.getPackageName(), mCurUser);
                    } else {
                        mShortcutServiceInternal.setShortcutHostPackage(TAG, null, mCurUser);
                    }
                }

                if (force || mImpl == null || mImpl.mUser != mCurUser
                        || !mImpl.mComponent.equals(serviceComponent)) {
                    unloadAllKeyphraseModels();
                    if (mImpl != null) {
                        mImpl.shutdownLocked();
                    }
                    if (serviceComponent != null && serviceInfo != null) {
                    if (hasComponent) {
                        mImpl = new VoiceInteractionManagerServiceImpl(mContext,
                                UiThread.getHandler(), this, mCurUser, serviceComponent);
                        mImpl.startLocked();
@@ -953,12 +976,14 @@ public class VoiceInteractionManagerService extends SystemService {
        }

        private synchronized void unloadAllKeyphraseModels() {
            for (int keyphraseId : mLoadedKeyphraseIds) {
            for (int i = 0; i < mLoadedKeyphraseIds.size(); i++) {
                final long caller = Binder.clearCallingIdentity();
                try {
                    int status = mSoundTriggerInternal.unloadKeyphraseModel(keyphraseId);
                    int status = mSoundTriggerInternal.unloadKeyphraseModel(
                            mLoadedKeyphraseIds.valueAt(i));
                    if (status != SoundTriggerInternal.STATUS_OK) {
                        Slog.w(TAG, "Failed to unload keyphrase " + keyphraseId + ":" + status);
                        Slog.w(TAG, "Failed to unload keyphrase " + mLoadedKeyphraseIds.valueAt(i)
                                + ":" + status);
                    }
                } finally {
                    Binder.restoreCallingIdentity(caller);