Merge "Wrap ShortcutQuery in a parcelable wrapper object and pass it direcly through aidl." into rvc-dev am: 6991da300f

Change-Id: Ifbf033d65bde886048c52e66c30aeade82b964c0
This commit is contained in:
Mehdi Alizadeh
2020-04-04 00:27:39 +00:00
committed by Automerger Merge Worker
6 changed files with 315 additions and 24 deletions

View File

@@ -25,6 +25,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IOnAppsChangedListener;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutQueryWrapper;
import android.content.pm.IPackageInstallerCallback;
import android.content.pm.IShortcutChangeCallback;
import android.content.pm.PackageInstaller;
@@ -67,9 +68,8 @@ interface ILauncherApps {
LauncherApps.AppUsageLimit getAppUsageLimit(String callingPackage, String packageName,
in UserHandle user);
ParceledListSlice getShortcuts(String callingPackage, long changedSince, String packageName,
in List shortcutIds, in List<LocusId> locusIds, in ComponentName componentName,
int flags, in UserHandle user);
ParceledListSlice getShortcuts(String callingPackage, in ShortcutQueryWrapper query,
in UserHandle user);
void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
in UserHandle user);
boolean startShortcut(String callingPackage, String packageName, String featureId, String id,
@@ -93,9 +93,8 @@ interface ILauncherApps {
in IPackageInstallerCallback callback);
ParceledListSlice getAllSessions(String callingPackage);
void registerShortcutChangeCallback(String callingPackage, long changedSince,
String packageName, in List shortcutIds, in List<LocusId> locusIds,
in ComponentName componentName, int flags, in IShortcutChangeCallback callback);
void registerShortcutChangeCallback(String callingPackage, in ShortcutQueryWrapper query,
in IShortcutChangeCallback callback);
void unregisterShortcutChangeCallback(String callingPackage,
in IShortcutChangeCallback callback);

View File

@@ -1046,8 +1046,7 @@ public class LauncherApps {
// changed callback, but that only returns shortcuts with the "key" information, so
// that won't return disabled message.
return maybeUpdateDisabledMessage(mService.getShortcuts(mContext.getPackageName(),
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mLocusIds,
query.mActivity, query.mQueryFlags, user)
new ShortcutQueryWrapper(query), user)
.getList());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1826,8 +1825,7 @@ public class LauncherApps {
mShortcutChangeCallbacks.put(callback, new Pair<>(executor, proxy));
try {
mService.registerShortcutChangeCallback(mContext.getPackageName(),
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mLocusIds,
query.mActivity, query.mQueryFlags, proxy);
new ShortcutQueryWrapper(query), proxy);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -0,0 +1,20 @@
/**
* 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;
parcelable ShortcutQueryWrapper;

View File

@@ -0,0 +1,190 @@
/*
* 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.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.LocusId;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.DataClass;
import java.util.ArrayList;
import java.util.List;
/**
* @hide
*/
@DataClass(genParcelable = true, genToString = true)
public final class ShortcutQueryWrapper extends LauncherApps.ShortcutQuery implements Parcelable {
public ShortcutQueryWrapper(LauncherApps.ShortcutQuery query) {
this();
mChangedSince = query.mChangedSince;
mPackage = query.mPackage;
mLocusIds = query.mLocusIds;
mShortcutIds = query.mShortcutIds;
mActivity = query.mActivity;
mQueryFlags = query.mQueryFlags;
}
public long getChangedSince() {
return mChangedSince;
}
@Nullable
public String getPackage() {
return mPackage;
}
@Nullable
public List<LocusId> getLocusIds() {
return mLocusIds;
}
@Nullable
public List<String> getShortcutIds() {
return mShortcutIds;
}
@Nullable
public ComponentName getActivity() {
return mActivity;
}
public int getQueryFlags() {
return mQueryFlags;
}
// Code below generated by codegen v1.0.14.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
//
// To regenerate run:
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/ShortcutQueryWrapper.java
//
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
// Settings > Editor > Code Style > Formatter Control
//@formatter:off
@DataClass.Generated.Member
public ShortcutQueryWrapper() {
// onConstructed(); // You can define this method to get a callback
}
@Override
@DataClass.Generated.Member
public String toString() {
// You can override field toString logic by defining methods like:
// String fieldNameToString() { ... }
return "ShortcutQueryWrapper { " +
" }";
}
@Override
@DataClass.Generated.Member
public void writeToParcel(@NonNull Parcel dest, int flags) {
// You can override field parcelling by defining methods like:
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
if (mPackage != null) flg |= 0x2;
if (mShortcutIds != null) flg |= 0x4;
if (mLocusIds != null) flg |= 0x8;
if (mActivity != null) flg |= 0x10;
dest.writeByte(flg);
dest.writeLong(mChangedSince);
if (mPackage != null) dest.writeString(mPackage);
if (mShortcutIds != null) dest.writeStringList(mShortcutIds);
if (mLocusIds != null) dest.writeParcelableList(mLocusIds, flags);
if (mActivity != null) dest.writeTypedObject(mActivity, flags);
dest.writeInt(mQueryFlags);
}
@Override
@DataClass.Generated.Member
public int describeContents() { return 0; }
/** @hide */
@SuppressWarnings({"unchecked", "RedundantCast"})
@DataClass.Generated.Member
/* package-private */ ShortcutQueryWrapper(@NonNull Parcel in) {
// You can override field unparcelling by defining methods like:
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
long changedSince = in.readLong();
String pkg = (flg & 0x2) == 0 ? null : in.readString();
List<String> shortcutIds = null;
if ((flg & 0x4) != 0) {
shortcutIds = new ArrayList<>();
in.readStringList(shortcutIds);
}
List<LocusId> locusIds = null;
if ((flg & 0x8) != 0) {
locusIds = new ArrayList<>();
in.readParcelableList(locusIds, LocusId.class.getClassLoader());
}
ComponentName activity = (flg & 0x10) == 0 ? null
: (ComponentName) in.readTypedObject(ComponentName.CREATOR);
int queryFlags = in.readInt();
this.mChangedSince = changedSince;
this.mPackage = pkg;
this.mShortcutIds = shortcutIds;
this.mLocusIds = locusIds;
this.mActivity = activity;
this.mQueryFlags = queryFlags;
com.android.internal.util.AnnotationValidations.validate(
QueryFlags.class, null, mQueryFlags);
// onConstructed(); // You can define this method to get a callback
}
@DataClass.Generated.Member
public static final @NonNull Parcelable.Creator<ShortcutQueryWrapper> CREATOR
= new Parcelable.Creator<ShortcutQueryWrapper>() {
@Override
public ShortcutQueryWrapper[] newArray(int size) {
return new ShortcutQueryWrapper[size];
}
@Override
public ShortcutQueryWrapper createFromParcel(@NonNull Parcel in) {
return new ShortcutQueryWrapper(in);
}
};
@DataClass.Generated(
time = 1582049937960L,
codegenVersion = "1.0.14",
sourceFile = "frameworks/base/core/java/android/content/pm/ShortcutQueryWrapper.java",
inputSignatures = "public long getChangedSince()\npublic @android.annotation.Nullable java.lang.String getPackage()\npublic @android.annotation.Nullable java.util.List<android.content.LocusId> getLocusIds()\npublic @android.annotation.Nullable java.util.List<java.lang.String> getShortcutIds()\npublic @android.annotation.Nullable android.content.ComponentName getActivity()\npublic int getQueryFlags()\nclass ShortcutQueryWrapper extends android.content.pm.LauncherApps.ShortcutQuery implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genToString=true)")
@Deprecated
private void __metadata() {}
//@formatter:on
// End of generated code
}

View File

@@ -0,0 +1,77 @@
/*
* 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 static org.junit.Assert.assertEquals;
import android.content.ComponentName;
import android.content.LocusId;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
import androidx.test.runner.AndroidJUnit4;
import com.google.android.collect.Lists;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
@Presubmit
public class ShortcutQueryWrapperTest {
private static final long CHANGED_SINCE = TimeUnit.SECONDS.toMillis(1);
private static final String PACKAGE_NAME = "com.android.test";
private static final List<String> SHORTCUT_IDS = Lists.newArrayList("s1", "s2", "s3");
private static final List<LocusId> LOCUS_IDS = Lists.newArrayList(
new LocusId("id1"), new LocusId("id2"), new LocusId("id3"));
private static final ComponentName COMPONENT_NAME = new ComponentName(
PACKAGE_NAME, "ShortcutQueryTest");
private static final int QUERY_FLAG = LauncherApps.ShortcutQuery.FLAG_MATCH_ALL_KINDS;
private ShortcutQueryWrapper mShortcutQuery;
@Before
public void setUp() throws Exception {
mShortcutQuery = new ShortcutQueryWrapper(new LauncherApps.ShortcutQuery()
.setChangedSince(CHANGED_SINCE)
.setPackage(PACKAGE_NAME)
.setShortcutIds(SHORTCUT_IDS)
.setLocusIds(LOCUS_IDS)
.setActivity(COMPONENT_NAME)
.setQueryFlags(QUERY_FLAG));
}
@Test
public void testWriteAndReadFromParcel() {
Parcel p = Parcel.obtain();
mShortcutQuery.writeToParcel(p, 0);
p.setDataPosition(0);
ShortcutQueryWrapper q = ShortcutQueryWrapper.CREATOR.createFromParcel(p);
assertEquals("Changed since doesn't match!", CHANGED_SINCE, q.getChangedSince());
assertEquals("Package name doesn't match!", PACKAGE_NAME, q.getPackage());
assertEquals("Shortcut ids doesn't match", SHORTCUT_IDS, q.getShortcutIds());
assertEquals("Locus ids doesn't match", LOCUS_IDS, q.getLocusIds());
assertEquals("Component name doesn't match", COMPONENT_NAME, q.getActivity());
assertEquals("Query flag doesn't match", QUERY_FLAG, q.getQueryFlags());
p.recycle();
}
}

View File

@@ -47,6 +47,7 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutQueryWrapper;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
import android.content.pm.UserInfo;
@@ -698,13 +699,19 @@ public class LauncherAppsService extends SystemService {
}
@Override
public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
String packageName, List shortcutIds, List<LocusId> locusIds,
ComponentName componentName, int flags, UserHandle targetUser) {
public ParceledListSlice getShortcuts(@NonNull final String callingPackage,
@NonNull final ShortcutQueryWrapper query, @NonNull final UserHandle targetUser) {
ensureShortcutPermission(callingPackage);
if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) {
return new ParceledListSlice<>(Collections.EMPTY_LIST);
}
final long changedSince = query.getChangedSince();
final String packageName = query.getPackage();
final List<String> shortcutIds = query.getShortcutIds();
final List<LocusId> locusIds = query.getLocusIds();
final ComponentName componentName = query.getActivity();
final int flags = query.getQueryFlags();
if (shortcutIds != null && packageName == null) {
throw new IllegalArgumentException(
"To query by shortcut ID, package name must also be set");
@@ -723,16 +730,17 @@ public class LauncherAppsService extends SystemService {
}
@Override
public void registerShortcutChangeCallback(String callingPackage, long changedSince,
String packageName, List shortcutIds, List<LocusId> locusIds,
ComponentName componentName, int flags, IShortcutChangeCallback callback) {
public void registerShortcutChangeCallback(@NonNull final String callingPackage,
@NonNull final ShortcutQueryWrapper query,
@NonNull final IShortcutChangeCallback callback) {
ensureShortcutPermission(callingPackage);
if (shortcutIds != null && packageName == null) {
if (query.getShortcutIds() != null && query.getPackage() == null) {
throw new IllegalArgumentException(
"To query by shortcut ID, package name must also be set");
}
if (locusIds != null && packageName == null) {
if (query.getLocusIds() != null && query.getPackage() == null) {
throw new IllegalArgumentException(
"To query by locus ID, package name must also be set");
}
@@ -744,10 +752,7 @@ public class LauncherAppsService extends SystemService {
user = null;
}
// TODO: When ShortcutQueryWrapper (ag/10323729) is available, pass that directly.
ShortcutChangeHandler.QueryInfo query = new ShortcutChangeHandler.QueryInfo(
changedSince, packageName, shortcutIds, locusIds, componentName, flags, user);
mShortcutChangeHandler.addShortcutChangeCallback(callback, query);
mShortcutChangeHandler.addShortcutChangeCallback(callback, query, user);
}
@Override
@@ -1081,9 +1086,11 @@ public class LauncherAppsService extends SystemService {
new RemoteCallbackList<>();
public synchronized void addShortcutChangeCallback(IShortcutChangeCallback callback,
QueryInfo query) {
ShortcutQueryWrapper query, UserHandle user) {
mCallbacks.unregister(callback);
mCallbacks.register(callback, query);
mCallbacks.register(callback, new QueryInfo(query.getChangedSince(),
query.getPackage(), query.getShortcutIds(), query.getLocusIds(),
query.getActivity(), query.getQueryFlags(), user));
}
public synchronized void removeShortcutChangeCallback(