diff options
| author | 2019-01-30 18:37:17 +0000 | |
|---|---|---|
| committer | 2019-01-30 18:37:17 +0000 | |
| commit | 26447bc85c85564ca5b797e52e8087f2f08b5b4b (patch) | |
| tree | b6ce7387b533dc5d64660567fc31c485245c9de6 | |
| parent | 415c74155caaf001a76adeb9aee6f4767e22237c (diff) | |
| parent | 5208cbee8db43014c5156237c792ed0c237da58d (diff) | |
Merge "Ensure some calls are available for testing"
| -rw-r--r-- | api/system-current.txt | 4 | ||||
| -rw-r--r-- | api/test-current.txt | 103 | ||||
| -rw-r--r-- | core/java/android/app/prediction/AppPredictionContext.java | 18 | ||||
| -rw-r--r-- | core/java/android/app/prediction/AppPredictionManager.java | 2 | ||||
| -rw-r--r-- | core/java/android/app/prediction/AppPredictionSessionId.java | 2 | ||||
| -rw-r--r-- | core/java/android/app/prediction/AppPredictor.java | 38 | ||||
| -rw-r--r-- | core/java/android/app/prediction/AppTarget.java | 40 | ||||
| -rw-r--r-- | core/java/android/app/prediction/AppTargetEvent.java | 13 | ||||
| -rw-r--r-- | core/java/android/app/prediction/AppTargetId.java | 6 | ||||
| -rw-r--r-- | core/java/android/service/appprediction/AppPredictionService.java | 4 |
10 files changed, 225 insertions, 5 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 1fd849550639..d061d01ac9b4 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -990,6 +990,7 @@ package android.app.prediction { } public static final class AppPredictionContext.Builder { + ctor public AppPredictionContext.Builder(@NonNull android.content.Context); method public android.app.prediction.AppPredictionContext build(); method public android.app.prediction.AppPredictionContext.Builder setExtras(@Nullable android.os.Bundle); method public android.app.prediction.AppPredictionContext.Builder setPredictedTargetCount(int); @@ -1021,6 +1022,8 @@ package android.app.prediction { } public final class AppTarget implements android.os.Parcelable { + ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull String, @Nullable String, @NonNull android.os.UserHandle); + ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull android.content.pm.ShortcutInfo, @Nullable String); method public int describeContents(); method @Nullable public String getClassName(); method @NonNull public android.app.prediction.AppTargetId getId(); @@ -1051,6 +1054,7 @@ package android.app.prediction { } public final class AppTargetId implements android.os.Parcelable { + ctor public AppTargetId(@NonNull String); method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.prediction.AppTargetId> CREATOR; diff --git a/api/test-current.txt b/api/test-current.txt index 91d00191a543..76261ddfc191 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -332,6 +332,91 @@ package android.app.backup { } +package android.app.prediction { + + public final class AppPredictionContext implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public android.os.Bundle getExtras(); + method @NonNull public String getPackageName(); + method public int getPredictedTargetCount(); + method public String getUiSurface(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.prediction.AppPredictionContext> CREATOR; + } + + public static final class AppPredictionContext.Builder { + ctor public AppPredictionContext.Builder(@NonNull android.content.Context); + method public android.app.prediction.AppPredictionContext build(); + method public android.app.prediction.AppPredictionContext.Builder setExtras(@Nullable android.os.Bundle); + method public android.app.prediction.AppPredictionContext.Builder setPredictedTargetCount(int); + method public android.app.prediction.AppPredictionContext.Builder setUiSurface(@Nullable String); + } + + public final class AppPredictionManager { + method public android.app.prediction.AppPredictor createAppPredictionSession(@NonNull android.app.prediction.AppPredictionContext); + } + + public final class AppPredictionSessionId implements android.os.Parcelable { + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.prediction.AppPredictionSessionId> CREATOR; + } + + public final class AppPredictor { + method public void destroy(); + method public android.app.prediction.AppPredictionSessionId getSessionId(); + method public void notifyAppTargetEvent(@NonNull android.app.prediction.AppTargetEvent); + method public void notifyLocationShown(@NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); + method public void registerPredictionUpdates(@NonNull java.util.concurrent.Executor, @NonNull android.app.prediction.AppPredictor.Callback); + method public void requestPredictionUpdate(); + method @Nullable public void sortTargets(@NonNull java.util.List<android.app.prediction.AppTarget>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.prediction.AppTarget>>); + method public void unregisterPredictionUpdates(@NonNull android.app.prediction.AppPredictor.Callback); + } + + public static interface AppPredictor.Callback { + method public void onTargetsAvailable(@NonNull java.util.List<android.app.prediction.AppTarget>); + } + + public final class AppTarget implements android.os.Parcelable { + ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull String, @Nullable String, @NonNull android.os.UserHandle); + method public int describeContents(); + method @Nullable public String getClassName(); + method @NonNull public android.app.prediction.AppTargetId getId(); + method @NonNull public String getPackageName(); + method public int getRank(); + method @Nullable public android.content.pm.ShortcutInfo getShortcutInfo(); + method @NonNull public android.os.UserHandle getUser(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.prediction.AppTarget> CREATOR; + } + + public final class AppTargetEvent implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public int getAction(); + method @NonNull public String getLaunchLocation(); + method @Nullable public android.app.prediction.AppTarget getTarget(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int ACTION_DISMISS = 2; // 0x2 + field public static final int ACTION_LAUNCH = 1; // 0x1 + field public static final int ACTION_PIN = 3; // 0x3 + field public static final android.os.Parcelable.Creator<android.app.prediction.AppTargetEvent> CREATOR; + } + + public static final class AppTargetEvent.Builder { + ctor public AppTargetEvent.Builder(@Nullable android.app.prediction.AppTarget, int); + method public android.app.prediction.AppTargetEvent build(); + method public android.app.prediction.AppTargetEvent.Builder setLaunchLocation(String); + } + + public final class AppTargetId implements android.os.Parcelable { + ctor public AppTargetId(@NonNull String); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.prediction.AppTargetId> CREATOR; + } + +} + package android.app.role { public final class RoleManager { @@ -1774,6 +1859,24 @@ package android.security.keystore { } +package android.service.appprediction { + + public abstract class AppPredictionService extends android.app.Service { + ctor public AppPredictionService(); + method @MainThread public abstract void onAppTargetEvent(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull android.app.prediction.AppTargetEvent); + method public final android.os.IBinder onBind(android.content.Intent); + method public void onCreatePredictionSession(@NonNull android.app.prediction.AppPredictionContext, @NonNull android.app.prediction.AppPredictionSessionId); + method @MainThread public void onDestroyPredictionSession(@NonNull android.app.prediction.AppPredictionSessionId); + method @MainThread public abstract void onLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List<android.app.prediction.AppTargetId>); + method @MainThread public abstract void onRequestPredictionUpdate(@NonNull android.app.prediction.AppPredictionSessionId); + method @MainThread public abstract void onSortAppTargets(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull java.util.List<android.app.prediction.AppTarget>, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<java.util.List<android.app.prediction.AppTarget>>); + method @MainThread public void onStartPredictionUpdates(); + method @MainThread public void onStopPredictionUpdates(); + method public final void updatePredictions(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull java.util.List<android.app.prediction.AppTarget>); + } + +} + package android.service.autofill { public abstract class AutofillFieldClassificationService extends android.app.Service { diff --git a/core/java/android/app/prediction/AppPredictionContext.java b/core/java/android/app/prediction/AppPredictionContext.java index 87ccb660e5bd..2fbe6e360085 100644 --- a/core/java/android/app/prediction/AppPredictionContext.java +++ b/core/java/android/app/prediction/AppPredictionContext.java @@ -18,6 +18,7 @@ package android.app.prediction; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.content.Context; import android.os.Bundle; import android.os.Parcel; @@ -29,6 +30,7 @@ import android.os.Parcelable; * @hide */ @SystemApi +@TestApi public final class AppPredictionContext implements Parcelable { private final int mPredictedTargetCount; @@ -73,6 +75,17 @@ public final class AppPredictionContext implements Parcelable { } @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!getClass().equals(o != null ? o.getClass() : null)) return false; + + AppPredictionContext other = (AppPredictionContext) o; + return mPredictedTargetCount == other.mPredictedTargetCount + && mUiSurface.equals(other.mUiSurface) + && mPackageName.equals(other.mPackageName); + } + + @Override public int describeContents() { return 0; } @@ -104,6 +117,7 @@ public final class AppPredictionContext implements Parcelable { * @hide */ @SystemApi + @TestApi public static final class Builder { @NonNull @@ -116,8 +130,12 @@ public final class AppPredictionContext implements Parcelable { private Bundle mExtras; /** + * TODO(b/123591863): Add java docs + * * @hide */ + @SystemApi + @TestApi public Builder(@NonNull Context context) { mPackageName = context.getPackageName(); } diff --git a/core/java/android/app/prediction/AppPredictionManager.java b/core/java/android/app/prediction/AppPredictionManager.java index f8578d4533ef..99f78f1957b9 100644 --- a/core/java/android/app/prediction/AppPredictionManager.java +++ b/core/java/android/app/prediction/AppPredictionManager.java @@ -17,6 +17,7 @@ package android.app.prediction; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.content.Context; import com.android.internal.util.Preconditions; @@ -26,6 +27,7 @@ import com.android.internal.util.Preconditions; * @hide */ @SystemApi +@TestApi public final class AppPredictionManager { private final Context mContext; diff --git a/core/java/android/app/prediction/AppPredictionSessionId.java b/core/java/android/app/prediction/AppPredictionSessionId.java index 1d7308ec2404..1e76c241f8e9 100644 --- a/core/java/android/app/prediction/AppPredictionSessionId.java +++ b/core/java/android/app/prediction/AppPredictionSessionId.java @@ -17,6 +17,7 @@ package android.app.prediction; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -26,6 +27,7 @@ import android.os.Parcelable; * @hide */ @SystemApi +@TestApi public final class AppPredictionSessionId implements Parcelable { private final String mId; diff --git a/core/java/android/app/prediction/AppPredictor.java b/core/java/android/app/prediction/AppPredictor.java index 2ddbd08c7477..12d6ce3c5b90 100644 --- a/core/java/android/app/prediction/AppPredictor.java +++ b/core/java/android/app/prediction/AppPredictor.java @@ -19,6 +19,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.app.prediction.IPredictionCallback.Stub; import android.content.Context; import android.content.pm.ParceledListSlice; @@ -63,6 +64,7 @@ import java.util.function.Consumer; * @hide */ @SystemApi +@TestApi public final class AppPredictor { private static final String TAG = AppPredictor.class.getSimpleName(); @@ -102,6 +104,10 @@ public final class AppPredictor { * Notifies the prediction service of an app target event. */ public void notifyAppTargetEvent(@NonNull AppTargetEvent event) { + if (mIsClosed.get()) { + throw new IllegalStateException("This client has already been destroyed."); + } + try { mPredictionManager.notifyAppTargetEvent(mSessionId, event); } catch (RemoteException e) { @@ -114,6 +120,10 @@ public final class AppPredictor { */ public void notifyLocationShown(@NonNull String launchLocation, @NonNull List<AppTargetId> targetIds) { + if (mIsClosed.get()) { + throw new IllegalStateException("This client has already been destroyed."); + } + try { mPredictionManager.notifyLocationShown(mSessionId, launchLocation, new ParceledListSlice<>(targetIds)); @@ -130,6 +140,10 @@ public final class AppPredictor { */ public void registerPredictionUpdates(@NonNull @CallbackExecutor Executor callbackExecutor, @NonNull AppPredictor.Callback callback) { + if (mIsClosed.get()) { + throw new IllegalStateException("This client has already been destroyed."); + } + if (mRegisteredCallbacks.containsKey(callback)) { // Skip if this callback is already registered return; @@ -149,6 +163,10 @@ public final class AppPredictor { * callback until the callback is re-registered. */ public void unregisterPredictionUpdates(@NonNull AppPredictor.Callback callback) { + if (mIsClosed.get()) { + throw new IllegalStateException("This client has already been destroyed."); + } + if (!mRegisteredCallbacks.containsKey(callback)) { // Skip if this callback was never registered return; @@ -168,6 +186,10 @@ public final class AppPredictor { * @see Callback#onTargetsAvailable(List) */ public void requestPredictionUpdate() { + if (mIsClosed.get()) { + throw new IllegalStateException("This client has already been destroyed."); + } + try { mPredictionManager.requestPredictionUpdate(mSessionId); } catch (RemoteException e) { @@ -182,6 +204,10 @@ public final class AppPredictor { @Nullable public void sortTargets(@NonNull List<AppTarget> targets, @NonNull Executor callbackExecutor, @NonNull Consumer<List<AppTarget>> callback) { + if (mIsClosed.get()) { + throw new IllegalStateException("This client has already been destroyed."); + } + try { mPredictionManager.sortAppTargets(mSessionId, new ParceledListSlice(targets), new CallbackWrapper(callbackExecutor, callback)); @@ -206,6 +232,8 @@ public final class AppPredictor { } catch (RemoteException e) { Log.e(TAG, "Failed to notify app target event", e); } + } else { + throw new IllegalStateException("This client has already been destroyed."); } } @@ -222,6 +250,16 @@ public final class AppPredictor { } /** + * TODO(b/123591863): Add java docs + * + * @hide + */ + @TestApi + public AppPredictionSessionId getSessionId() { + return mSessionId; + } + + /** * Callback for receiving prediction updates. */ public interface Callback { diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java index 99c1c44866fe..b924cec63823 100644 --- a/core/java/android/app/prediction/AppTarget.java +++ b/core/java/android/app/prediction/AppTarget.java @@ -18,6 +18,7 @@ package android.app.prediction; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.content.pm.ShortcutInfo; import android.os.Parcel; import android.os.Parcelable; @@ -30,6 +31,7 @@ import com.android.internal.util.Preconditions; * @hide */ @SystemApi +@TestApi public final class AppTarget implements Parcelable { private final AppTargetId mId; @@ -42,8 +44,12 @@ public final class AppTarget implements Parcelable { private int mRank; /** + * TODO(b/123591863): Add java docs + * * @hide */ + @SystemApi + @TestApi public AppTarget(@NonNull AppTargetId id, @NonNull String packageName, @Nullable String className, @NonNull UserHandle user) { mId = id; @@ -55,15 +61,19 @@ public final class AppTarget implements Parcelable { } /** + * TODO(b/123591863): Add java docs + * * @hide */ - public AppTarget(@NonNull AppTargetId id, @NonNull ShortcutInfo shortcutInfo) { + @SystemApi + public AppTarget(@NonNull AppTargetId id, @NonNull ShortcutInfo shortcutInfo, + @Nullable String className) { mId = id; mShortcutInfo = Preconditions.checkNotNull(shortcutInfo); mPackageName = mShortcutInfo.getPackage(); mUser = mShortcutInfo.getUserHandle(); - mClassName = null; + mClassName = className; } private AppTarget(Parcel parcel) { @@ -71,13 +81,12 @@ public final class AppTarget implements Parcelable { mShortcutInfo = parcel.readTypedObject(ShortcutInfo.CREATOR); if (mShortcutInfo == null) { mPackageName = parcel.readString(); - mClassName = parcel.readString(); mUser = UserHandle.of(parcel.readInt()); } else { mPackageName = mShortcutInfo.getPackage(); mUser = mShortcutInfo.getUserHandle(); - mClassName = null; } + mClassName = parcel.readString(); mRank = parcel.readInt(); } @@ -129,11 +138,32 @@ public final class AppTarget implements Parcelable { mRank = rank; } + /** + * Returns the rank for the target. + */ public int getRank() { return mRank; } @Override + public boolean equals(Object o) { + if (!getClass().equals(o != null ? o.getClass() : null)) return false; + + AppTarget other = (AppTarget) o; + boolean sameClassName = (mClassName == null && other.mClassName == null) + || (mClassName != null && mClassName.equals(other.mClassName)); + boolean sameShortcutInfo = (mShortcutInfo == null && other.mShortcutInfo == null) + || (mShortcutInfo != null && other.mShortcutInfo != null + && mShortcutInfo.getId() == other.mShortcutInfo.getId()); + return mId.equals(other.mId) + && mPackageName.equals(other.mPackageName) + && sameClassName + && mUser.equals(other.mUser) + && sameShortcutInfo + && mRank == other.mRank; + } + + @Override public int describeContents() { return 0; } @@ -144,9 +174,9 @@ public final class AppTarget implements Parcelable { dest.writeTypedObject(mShortcutInfo, flags); if (mShortcutInfo == null) { dest.writeString(mPackageName); - dest.writeString(mClassName); dest.writeInt(mUser.getIdentifier()); } + dest.writeString(mClassName); dest.writeInt(mRank); } diff --git a/core/java/android/app/prediction/AppTargetEvent.java b/core/java/android/app/prediction/AppTargetEvent.java index 18317e1bf99d..37e41deba544 100644 --- a/core/java/android/app/prediction/AppTargetEvent.java +++ b/core/java/android/app/prediction/AppTargetEvent.java @@ -19,6 +19,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -30,6 +31,7 @@ import java.lang.annotation.RetentionPolicy; * @hide */ @SystemApi +@TestApi public final class AppTargetEvent implements Parcelable { /** @@ -96,6 +98,16 @@ public final class AppTargetEvent implements Parcelable { } @Override + public boolean equals(Object o) { + if (!getClass().equals(o != null ? o.getClass() : null)) return false; + + AppTargetEvent other = (AppTargetEvent) o; + return mTarget.equals(other.mTarget) + && mLocation.equals(other.mLocation) + && mAction == other.mAction; + } + + @Override public int describeContents() { return 0; } @@ -126,6 +138,7 @@ public final class AppTargetEvent implements Parcelable { * @hide */ @SystemApi + @TestApi public static final class Builder { private AppTarget mTarget; private String mLocation; diff --git a/core/java/android/app/prediction/AppTargetId.java b/core/java/android/app/prediction/AppTargetId.java index 0b8fb47377d2..639ba78f76f5 100644 --- a/core/java/android/app/prediction/AppTargetId.java +++ b/core/java/android/app/prediction/AppTargetId.java @@ -17,6 +17,7 @@ package android.app.prediction; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -25,14 +26,19 @@ import android.os.Parcelable; * @hide */ @SystemApi +@TestApi public final class AppTargetId implements Parcelable { @NonNull private final String mId; /** + * TODO(b/123591863): Add java docs + * * @hide */ + @SystemApi + @TestApi public AppTargetId(@NonNull String id) { mId = id; } diff --git a/core/java/android/service/appprediction/AppPredictionService.java b/core/java/android/service/appprediction/AppPredictionService.java index b77405affaec..d0128514d3e7 100644 --- a/core/java/android/service/appprediction/AppPredictionService.java +++ b/core/java/android/service/appprediction/AppPredictionService.java @@ -21,6 +21,7 @@ import android.annotation.CallSuper; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.app.Service; import android.app.prediction.AppPredictionContext; import android.app.prediction.AppPredictionSessionId; @@ -49,6 +50,7 @@ import java.util.function.Consumer; * @hide */ @SystemApi +@TestApi public abstract class AppPredictionService extends Service { private static final String TAG = "AppPredictionService"; @@ -140,6 +142,7 @@ public abstract class AppPredictionService extends Service { @Override public final IBinder onBind(Intent intent) { + // TODO(b/111701043): Verify that the action is valid return mInterface.asBinder(); } @@ -228,6 +231,7 @@ public abstract class AppPredictionService extends Service { public void onStopPredictionUpdates() {} private void doRequestPredictionUpdate(@NonNull AppPredictionSessionId sessionId) { + // Just an optimization, if there are no callbacks, then don't bother notifying the service final ArrayList<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId); if (callbacks != null && !callbacks.isEmpty()) { onRequestPredictionUpdate(sessionId); |