Loading core/java/android/content/pm/ILauncherApps.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IOnAppsChangedListener; import android.content.pm.LauncherApps; import android.content.pm.IPackageInstallerCallback; import android.content.pm.IShortcutChangeCallback; import android.content.pm.PackageInstaller; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; Loading Loading @@ -89,4 +90,9 @@ interface ILauncherApps { void registerPackageInstallerCallback(String callingPackage, in IPackageInstallerCallback callback); ParceledListSlice getAllSessions(String callingPackage); void registerShortcutChangeCallback(String callingPackage, long changedSince, String packageName, in List shortcutIds, in ComponentName componentName, int flags, in IShortcutChangeCallback callback, int callbackId); void unregisterShortcutChangeCallback(String callingPackage, int callbackId); } core/java/android/content/pm/IShortcutChangeCallback.aidl 0 → 100644 +37 −0 Original line number Diff line number Diff line /** * Copyright (c) 2020, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content.pm; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; import android.os.UserHandle; import java.util.List; /** * Interface for LauncherApps#ShortcutChangeCallbackProxy. * * @hide */ oneway interface IShortcutChangeCallback { void onShortcutsAddedOrUpdated(String packageName, in List<ShortcutInfo> shortcuts, in UserHandle user); void onShortcutsRemoved(String packageName, in List<ShortcutInfo> shortcuts, in UserHandle user); } No newline at end of file core/java/android/content/pm/LauncherApps.java +154 −0 Original line number Diff line number Diff line Loading @@ -61,15 +61,21 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.DisplayMetrics; import android.util.Log; import android.util.Pair; import com.android.internal.util.function.pooled.PooledLambda; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.Executor; Loading Loading @@ -152,6 +158,9 @@ public class LauncherApps { private final List<CallbackMessageHandler> mCallbacks = new ArrayList<>(); private final List<SessionCallbackDelegate> mDelegates = new ArrayList<>(); private final Map<Integer, Pair<Executor, ShortcutChangeCallback>> mShortcutChangeCallbacks = new HashMap<>(); /** * Callbacks for package changes to this and related managed profiles. */ Loading Loading @@ -469,6 +478,95 @@ public class LauncherApps { } } /** * Callbacks for shortcut changes to this and related managed profiles. * * @hide */ public interface ShortcutChangeCallback { /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been added or updated. * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. * * @param packageName The name of the package that has the shortcuts. * @param shortcuts Shortcuts from the package that have updated or added. Only "key" * information will be provided, as defined in {@link ShortcutInfo#hasKeyFieldsOnly()}. * @param user The UserHandle of the profile that generated the change. * * @see ShortcutManager */ default void onShortcutsAddedOrUpdated(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {} /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been removed. * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. * * @param packageName The name of the package that has the shortcuts. * @param shortcuts Shortcuts from the package that have been removed. Only "key" * information will be provided, as defined in {@link ShortcutInfo#hasKeyFieldsOnly()}. * @param user The UserHandle of the profile that generated the change. * * @see ShortcutManager */ default void onShortcutsRemoved(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {} } /** * Callback proxy class for {@link ShortcutChangeCallback} * * @hide */ private static class ShortcutChangeCallbackProxy extends android.content.pm.IShortcutChangeCallback.Stub { private final WeakReference<Pair<Executor, ShortcutChangeCallback>> mRemoteReferences; ShortcutChangeCallbackProxy(Pair<Executor, ShortcutChangeCallback> remoteReferences) { mRemoteReferences = new WeakReference<>(remoteReferences); } @Override public void onShortcutsAddedOrUpdated(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) { Pair<Executor, ShortcutChangeCallback> remoteReferences = mRemoteReferences.get(); if (remoteReferences == null) { // Binder is dead. return; } final Executor executor = remoteReferences.first; final ShortcutChangeCallback callback = remoteReferences.second; executor.execute( PooledLambda.obtainRunnable(ShortcutChangeCallback::onShortcutsAddedOrUpdated, callback, packageName, shortcuts, user).recycleOnUse()); } @Override public void onShortcutsRemoved(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) { Pair<Executor, ShortcutChangeCallback> remoteReferences = mRemoteReferences.get(); if (remoteReferences == null) { // Binder is dead. return; } final Executor executor = remoteReferences.first; final ShortcutChangeCallback callback = remoteReferences.second; executor.execute( PooledLambda.obtainRunnable(ShortcutChangeCallback::onShortcutsRemoved, callback, packageName, shortcuts, user).recycleOnUse()); } } /** @hide */ public LauncherApps(Context context, ILauncherApps service) { mContext = context; Loading Loading @@ -1559,6 +1657,62 @@ public class LauncherApps { } } /** * Register a callback to watch for shortcut change events in this user and managed profiles. * * @param callback The callback to register. * @param query {@link ShortcutQuery} to match and filter the shortcut events. Only matching * shortcuts will be returned by the callback. * @param executor {@link Executor} to handle the callbacks. To dispatch callbacks to the main * thread of your application, you can use {@link android.content.Context#getMainExecutor()}. * * @hide */ public void registerShortcutChangeCallback(@NonNull ShortcutChangeCallback callback, @NonNull ShortcutQuery query, @NonNull @CallbackExecutor Executor executor) { Objects.requireNonNull(callback, "Callback cannot be null"); Objects.requireNonNull(query, "Query cannot be null"); Objects.requireNonNull(executor, "Executor cannot be null"); synchronized (mShortcutChangeCallbacks) { final int callbackId = callback.hashCode(); final Pair<Executor, ShortcutChangeCallback> state = new Pair<>(executor, callback); mShortcutChangeCallbacks.put(callbackId, state); try { mService.registerShortcutChangeCallback(mContext.getPackageName(), query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity, query.mQueryFlags, new ShortcutChangeCallbackProxy(state), callbackId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Unregisters a callback that was previously registered. * @see #registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery, Executor) * * @param callback Callback to be unregistered. * * @hide */ public void unregisterShortcutChangeCallback(@NonNull ShortcutChangeCallback callback) { Objects.requireNonNull(callback, "Callback cannot be null"); synchronized (mShortcutChangeCallbacks) { final int callbackId = callback.hashCode(); if (mShortcutChangeCallbacks.containsKey(callbackId)) { mShortcutChangeCallbacks.remove(callbackId); try { mService.unregisterShortcutChangeCallback(mContext.getPackageName(), callbackId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } } /** * A helper method to extract a {@link PinItemRequest} set to * the {@link #EXTRA_PIN_ITEM_REQUEST} extra. Loading services/core/java/com/android/server/pm/LauncherAppsService.java +11 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.content.pm.ILauncherApps; import android.content.pm.IOnAppsChangedListener; import android.content.pm.IPackageInstallerCallback; import android.content.pm.IPackageManager; import android.content.pm.IShortcutChangeCallback; import android.content.pm.LauncherApps; import android.content.pm.LauncherApps.ShortcutQuery; import android.content.pm.PackageInfo; Loading Loading @@ -680,6 +681,16 @@ public class LauncherAppsService extends SystemService { injectBinderCallingPid(), injectBinderCallingUid())); } @Override public void registerShortcutChangeCallback(String callingPackage, long changedSince, String packageName, List shortcutIds, ComponentName componentName, int flags, IShortcutChangeCallback callback, int callbackId) { } @Override public void unregisterShortcutChangeCallback(String callingPackage, int callbackId) { } @Override public void pinShortcuts(String callingPackage, String packageName, List<String> ids, UserHandle targetUser) { Loading Loading
core/java/android/content/pm/ILauncherApps.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IOnAppsChangedListener; import android.content.pm.LauncherApps; import android.content.pm.IPackageInstallerCallback; import android.content.pm.IShortcutChangeCallback; import android.content.pm.PackageInstaller; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; Loading Loading @@ -89,4 +90,9 @@ interface ILauncherApps { void registerPackageInstallerCallback(String callingPackage, in IPackageInstallerCallback callback); ParceledListSlice getAllSessions(String callingPackage); void registerShortcutChangeCallback(String callingPackage, long changedSince, String packageName, in List shortcutIds, in ComponentName componentName, int flags, in IShortcutChangeCallback callback, int callbackId); void unregisterShortcutChangeCallback(String callingPackage, int callbackId); }
core/java/android/content/pm/IShortcutChangeCallback.aidl 0 → 100644 +37 −0 Original line number Diff line number Diff line /** * Copyright (c) 2020, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content.pm; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; import android.os.UserHandle; import java.util.List; /** * Interface for LauncherApps#ShortcutChangeCallbackProxy. * * @hide */ oneway interface IShortcutChangeCallback { void onShortcutsAddedOrUpdated(String packageName, in List<ShortcutInfo> shortcuts, in UserHandle user); void onShortcutsRemoved(String packageName, in List<ShortcutInfo> shortcuts, in UserHandle user); } No newline at end of file
core/java/android/content/pm/LauncherApps.java +154 −0 Original line number Diff line number Diff line Loading @@ -61,15 +61,21 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.DisplayMetrics; import android.util.Log; import android.util.Pair; import com.android.internal.util.function.pooled.PooledLambda; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.Executor; Loading Loading @@ -152,6 +158,9 @@ public class LauncherApps { private final List<CallbackMessageHandler> mCallbacks = new ArrayList<>(); private final List<SessionCallbackDelegate> mDelegates = new ArrayList<>(); private final Map<Integer, Pair<Executor, ShortcutChangeCallback>> mShortcutChangeCallbacks = new HashMap<>(); /** * Callbacks for package changes to this and related managed profiles. */ Loading Loading @@ -469,6 +478,95 @@ public class LauncherApps { } } /** * Callbacks for shortcut changes to this and related managed profiles. * * @hide */ public interface ShortcutChangeCallback { /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been added or updated. * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. * * @param packageName The name of the package that has the shortcuts. * @param shortcuts Shortcuts from the package that have updated or added. Only "key" * information will be provided, as defined in {@link ShortcutInfo#hasKeyFieldsOnly()}. * @param user The UserHandle of the profile that generated the change. * * @see ShortcutManager */ default void onShortcutsAddedOrUpdated(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {} /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been removed. * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. * * @param packageName The name of the package that has the shortcuts. * @param shortcuts Shortcuts from the package that have been removed. Only "key" * information will be provided, as defined in {@link ShortcutInfo#hasKeyFieldsOnly()}. * @param user The UserHandle of the profile that generated the change. * * @see ShortcutManager */ default void onShortcutsRemoved(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {} } /** * Callback proxy class for {@link ShortcutChangeCallback} * * @hide */ private static class ShortcutChangeCallbackProxy extends android.content.pm.IShortcutChangeCallback.Stub { private final WeakReference<Pair<Executor, ShortcutChangeCallback>> mRemoteReferences; ShortcutChangeCallbackProxy(Pair<Executor, ShortcutChangeCallback> remoteReferences) { mRemoteReferences = new WeakReference<>(remoteReferences); } @Override public void onShortcutsAddedOrUpdated(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) { Pair<Executor, ShortcutChangeCallback> remoteReferences = mRemoteReferences.get(); if (remoteReferences == null) { // Binder is dead. return; } final Executor executor = remoteReferences.first; final ShortcutChangeCallback callback = remoteReferences.second; executor.execute( PooledLambda.obtainRunnable(ShortcutChangeCallback::onShortcutsAddedOrUpdated, callback, packageName, shortcuts, user).recycleOnUse()); } @Override public void onShortcutsRemoved(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) { Pair<Executor, ShortcutChangeCallback> remoteReferences = mRemoteReferences.get(); if (remoteReferences == null) { // Binder is dead. return; } final Executor executor = remoteReferences.first; final ShortcutChangeCallback callback = remoteReferences.second; executor.execute( PooledLambda.obtainRunnable(ShortcutChangeCallback::onShortcutsRemoved, callback, packageName, shortcuts, user).recycleOnUse()); } } /** @hide */ public LauncherApps(Context context, ILauncherApps service) { mContext = context; Loading Loading @@ -1559,6 +1657,62 @@ public class LauncherApps { } } /** * Register a callback to watch for shortcut change events in this user and managed profiles. * * @param callback The callback to register. * @param query {@link ShortcutQuery} to match and filter the shortcut events. Only matching * shortcuts will be returned by the callback. * @param executor {@link Executor} to handle the callbacks. To dispatch callbacks to the main * thread of your application, you can use {@link android.content.Context#getMainExecutor()}. * * @hide */ public void registerShortcutChangeCallback(@NonNull ShortcutChangeCallback callback, @NonNull ShortcutQuery query, @NonNull @CallbackExecutor Executor executor) { Objects.requireNonNull(callback, "Callback cannot be null"); Objects.requireNonNull(query, "Query cannot be null"); Objects.requireNonNull(executor, "Executor cannot be null"); synchronized (mShortcutChangeCallbacks) { final int callbackId = callback.hashCode(); final Pair<Executor, ShortcutChangeCallback> state = new Pair<>(executor, callback); mShortcutChangeCallbacks.put(callbackId, state); try { mService.registerShortcutChangeCallback(mContext.getPackageName(), query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity, query.mQueryFlags, new ShortcutChangeCallbackProxy(state), callbackId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Unregisters a callback that was previously registered. * @see #registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery, Executor) * * @param callback Callback to be unregistered. * * @hide */ public void unregisterShortcutChangeCallback(@NonNull ShortcutChangeCallback callback) { Objects.requireNonNull(callback, "Callback cannot be null"); synchronized (mShortcutChangeCallbacks) { final int callbackId = callback.hashCode(); if (mShortcutChangeCallbacks.containsKey(callbackId)) { mShortcutChangeCallbacks.remove(callbackId); try { mService.unregisterShortcutChangeCallback(mContext.getPackageName(), callbackId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } } /** * A helper method to extract a {@link PinItemRequest} set to * the {@link #EXTRA_PIN_ITEM_REQUEST} extra. Loading
services/core/java/com/android/server/pm/LauncherAppsService.java +11 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.content.pm.ILauncherApps; import android.content.pm.IOnAppsChangedListener; import android.content.pm.IPackageInstallerCallback; import android.content.pm.IPackageManager; import android.content.pm.IShortcutChangeCallback; import android.content.pm.LauncherApps; import android.content.pm.LauncherApps.ShortcutQuery; import android.content.pm.PackageInfo; Loading Loading @@ -680,6 +681,16 @@ public class LauncherAppsService extends SystemService { injectBinderCallingPid(), injectBinderCallingUid())); } @Override public void registerShortcutChangeCallback(String callingPackage, long changedSince, String packageName, List shortcutIds, ComponentName componentName, int flags, IShortcutChangeCallback callback, int callbackId) { } @Override public void unregisterShortcutChangeCallback(String callingPackage, int callbackId) { } @Override public void pinShortcuts(String callingPackage, String packageName, List<String> ids, UserHandle targetUser) { Loading