Loading core/java/android/content/pm/LauncherApps.java +6 −2 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/android/content/pm/ShortcutServiceInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/core/java/com/android/server/pm/ShortcutService.java +20 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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, Loading Loading @@ -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, Loading services/core/java/com/android/server/pm/ShortcutUser.java +44 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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++) { Loading services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +32 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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> Loading @@ -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); Loading @@ -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()); Loading Loading @@ -180,6 +190,7 @@ public class VoiceInteractionManagerService extends SystemService { private boolean mSafeMode; private int mCurUser; private boolean mCurUserUnlocked; private final boolean mEnableService; VoiceInteractionManagerServiceStub() { Loading Loading @@ -381,6 +392,7 @@ public class VoiceInteractionManagerService extends SystemService { public void switchUser(int userHandle) { synchronized (this) { mCurUser = userHandle; mCurUserUnlocked = false; switchImplementationIfNeededLocked(false); } } Loading Loading @@ -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(); Loading Loading @@ -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); Loading Loading
core/java/android/content/pm/LauncherApps.java +6 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/content/pm/ShortcutServiceInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/core/java/com/android/server/pm/ShortcutService.java +20 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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, Loading Loading @@ -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, Loading
services/core/java/com/android/server/pm/ShortcutUser.java +44 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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++) { Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +32 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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> Loading @@ -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); Loading @@ -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()); Loading Loading @@ -180,6 +190,7 @@ public class VoiceInteractionManagerService extends SystemService { private boolean mSafeMode; private int mCurUser; private boolean mCurUserUnlocked; private final boolean mEnableService; VoiceInteractionManagerServiceStub() { Loading Loading @@ -381,6 +392,7 @@ public class VoiceInteractionManagerService extends SystemService { public void switchUser(int userHandle) { synchronized (this) { mCurUser = userHandle; mCurUserUnlocked = false; switchImplementationIfNeededLocked(false); } } Loading Loading @@ -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(); Loading Loading @@ -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); Loading