Loading cmds/pm/src/com/android/commands/pm/Pm.java +19 −2 Original line number Diff line number Diff line Loading @@ -30,14 +30,15 @@ import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.res.AssetManager; import android.content.res.Resources; import android.net.Uri; import android.os.Parcel; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import java.io.File; import java.lang.reflect.Field; Loading Loading @@ -223,7 +224,7 @@ public final class Pm { String filter = nextArg(); try { List<PackageInfo> packages = mPm.getInstalledPackages(getFlags); final List<PackageInfo> packages = getInstalledPackages(mPm, getFlags); int count = packages.size(); for (int p = 0 ; p < count ; p++) { Loading @@ -247,6 +248,22 @@ public final class Pm { } } @SuppressWarnings("unchecked") private List<PackageInfo> getInstalledPackages(IPackageManager pm, int flags) throws RemoteException { final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); PackageInfo lastItem = null; ParceledListSlice<PackageInfo> slice; do { final String lastKey = lastItem != null ? lastItem.packageName : null; slice = pm.getInstalledPackages(flags, lastKey); lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); } while (!slice.isLastSlice()); return packageInfos; } /** * Lists all of the features supported by the current device. * Loading core/java/android/app/ContextImpl.java +26 −2 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.content.pm.IPackageStatsObserver; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; Loading Loading @@ -83,6 +84,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.IPowerManager; import android.os.Looper; import android.os.Parcel; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; Loading Loading @@ -1998,19 +2000,41 @@ class ContextImpl extends Context { throw new NameNotFoundException("No shared userid for user:"+sharedUserName); } @SuppressWarnings("unchecked") @Override public List<PackageInfo> getInstalledPackages(int flags) { try { return mPM.getInstalledPackages(flags); final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); PackageInfo lastItem = null; ParceledListSlice<PackageInfo> slice; do { final String lastKey = lastItem != null ? lastItem.packageName : null; slice = mPM.getInstalledPackages(flags, lastKey); lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); } while (!slice.isLastSlice()); return packageInfos; } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } } @SuppressWarnings("unchecked") @Override public List<ApplicationInfo> getInstalledApplications(int flags) { try { return mPM.getInstalledApplications(flags); final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>(); ApplicationInfo lastItem = null; ParceledListSlice<ApplicationInfo> slice; do { final String lastKey = lastItem != null ? lastItem.packageName : null; slice = mPM.getInstalledApplications(flags, lastKey); lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR); } while (!slice.isLastSlice()); return applicationInfos; } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } Loading core/java/android/content/pm/IPackageManager.aidl +15 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.ParceledListSlice; import android.content.pm.ProviderInfo; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; Loading Loading @@ -109,9 +110,21 @@ interface IPackageManager { List<ResolveInfo> queryIntentServices(in Intent intent, String resolvedType, int flags); List<PackageInfo> getInstalledPackages(int flags); /** * This implements getInstalledPackages via a "last returned row" * mechanism that is not exposed in the API. This is to get around the IPC * limit that kicks in when flags are included that bloat up the data * returned. */ ParceledListSlice getInstalledPackages(int flags, in String lastRead); List<ApplicationInfo> getInstalledApplications(int flags); /** * This implements getInstalledApplications via a "last returned row" * mechanism that is not exposed in the API. This is to get around the IPC * limit that kicks in when flags are included that bloat up the data * returned. */ ParceledListSlice getInstalledApplications(int flags, in String lastRead); /** * Retrieve all applications that are marked as persistent. Loading core/java/android/content/pm/ParceledListSlice.aidl 0 → 100755 +19 −0 Original line number Diff line number Diff line /* * Copyright 2011, 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 ParceledListSlice; core/java/android/content/pm/ParceledListSlice.java 0 → 100644 +170 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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.os.Parcel; import android.os.Parcelable; import java.util.List; /** * Builds up a parcel that is discarded when written to another parcel or * written to a list. This is useful for API that sends huge lists across a * Binder that may be larger than the IPC limit. * * @hide */ public class ParceledListSlice<T extends Parcelable> implements Parcelable { /* * TODO get this number from somewhere else. For now set it to a quarter of * the 1MB limit. */ private static final int MAX_IPC_SIZE = 256 * 1024; private Parcel mParcel; private int mNumItems; private boolean mIsLastSlice; public ParceledListSlice() { mParcel = Parcel.obtain(); } private ParceledListSlice(Parcel p, int numItems, boolean lastSlice) { mParcel = p; mNumItems = numItems; mIsLastSlice = lastSlice; } @Override public int describeContents() { return 0; } /** * Write this to another Parcel. Note that this discards the internal Parcel * and should not be used anymore. This is so we can pass this to a Binder * where we won't have a chance to call recycle on this. */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mNumItems); dest.writeInt(mIsLastSlice ? 1 : 0); if (mNumItems > 0) { final int parcelSize = mParcel.dataSize(); dest.writeInt(parcelSize); dest.appendFrom(mParcel, 0, parcelSize); } mNumItems = 0; mParcel.recycle(); mParcel = null; } /** * Appends a parcel to this list slice. * * @param item Parcelable item to append to this list slice * @return true when the list slice is full and should not be appended to * anymore */ public boolean append(T item) { if (mParcel == null) { throw new IllegalStateException("ParceledListSlice has already been recycled"); } item.writeToParcel(mParcel, PARCELABLE_WRITE_RETURN_VALUE); mNumItems++; return mParcel.dataSize() > MAX_IPC_SIZE; } /** * Populates a list and discards the internal state of the * ParceledListSlice in the process. The instance should * not be used anymore. * * @param list list to insert items from this slice. * @param creator creator that knows how to unparcel the * target object type. * @return the last item inserted into the list or null if none. */ public T populateList(List<T> list, Creator<T> creator) { mParcel.setDataPosition(0); T item = null; for (int i = 0; i < mNumItems; i++) { item = creator.createFromParcel(mParcel); list.add(item); } mParcel.recycle(); mParcel = null; return item; } /** * Sets whether this is the last list slice in the series. * * @param lastSlice */ public void setLastSlice(boolean lastSlice) { mIsLastSlice = lastSlice; } /** * Returns whether this is the last slice in a series of slices. * * @return true if this is the last slice in the series. */ public boolean isLastSlice() { return mIsLastSlice; } @SuppressWarnings("unchecked") public static final Parcelable.Creator<ParceledListSlice> CREATOR = new Parcelable.Creator<ParceledListSlice>() { public ParceledListSlice createFromParcel(Parcel in) { final int numItems = in.readInt(); final boolean lastSlice = in.readInt() == 1; if (numItems > 0) { final int parcelSize = in.readInt(); // Advance within this Parcel int offset = in.dataPosition(); in.setDataPosition(offset + parcelSize); Parcel p = Parcel.obtain(); p.setDataPosition(0); p.appendFrom(in, offset, parcelSize); p.setDataPosition(0); return new ParceledListSlice(p, numItems, lastSlice); } else { return new ParceledListSlice(); } } public ParceledListSlice[] newArray(int size) { return new ParceledListSlice[size]; } }; } Loading
cmds/pm/src/com/android/commands/pm/Pm.java +19 −2 Original line number Diff line number Diff line Loading @@ -30,14 +30,15 @@ import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.res.AssetManager; import android.content.res.Resources; import android.net.Uri; import android.os.Parcel; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import java.io.File; import java.lang.reflect.Field; Loading Loading @@ -223,7 +224,7 @@ public final class Pm { String filter = nextArg(); try { List<PackageInfo> packages = mPm.getInstalledPackages(getFlags); final List<PackageInfo> packages = getInstalledPackages(mPm, getFlags); int count = packages.size(); for (int p = 0 ; p < count ; p++) { Loading @@ -247,6 +248,22 @@ public final class Pm { } } @SuppressWarnings("unchecked") private List<PackageInfo> getInstalledPackages(IPackageManager pm, int flags) throws RemoteException { final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); PackageInfo lastItem = null; ParceledListSlice<PackageInfo> slice; do { final String lastKey = lastItem != null ? lastItem.packageName : null; slice = pm.getInstalledPackages(flags, lastKey); lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); } while (!slice.isLastSlice()); return packageInfos; } /** * Lists all of the features supported by the current device. * Loading
core/java/android/app/ContextImpl.java +26 −2 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.content.pm.IPackageStatsObserver; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; Loading Loading @@ -83,6 +84,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.IPowerManager; import android.os.Looper; import android.os.Parcel; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; Loading Loading @@ -1998,19 +2000,41 @@ class ContextImpl extends Context { throw new NameNotFoundException("No shared userid for user:"+sharedUserName); } @SuppressWarnings("unchecked") @Override public List<PackageInfo> getInstalledPackages(int flags) { try { return mPM.getInstalledPackages(flags); final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); PackageInfo lastItem = null; ParceledListSlice<PackageInfo> slice; do { final String lastKey = lastItem != null ? lastItem.packageName : null; slice = mPM.getInstalledPackages(flags, lastKey); lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); } while (!slice.isLastSlice()); return packageInfos; } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } } @SuppressWarnings("unchecked") @Override public List<ApplicationInfo> getInstalledApplications(int flags) { try { return mPM.getInstalledApplications(flags); final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>(); ApplicationInfo lastItem = null; ParceledListSlice<ApplicationInfo> slice; do { final String lastKey = lastItem != null ? lastItem.packageName : null; slice = mPM.getInstalledApplications(flags, lastKey); lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR); } while (!slice.isLastSlice()); return applicationInfos; } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } Loading
core/java/android/content/pm/IPackageManager.aidl +15 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.ParceledListSlice; import android.content.pm.ProviderInfo; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; Loading Loading @@ -109,9 +110,21 @@ interface IPackageManager { List<ResolveInfo> queryIntentServices(in Intent intent, String resolvedType, int flags); List<PackageInfo> getInstalledPackages(int flags); /** * This implements getInstalledPackages via a "last returned row" * mechanism that is not exposed in the API. This is to get around the IPC * limit that kicks in when flags are included that bloat up the data * returned. */ ParceledListSlice getInstalledPackages(int flags, in String lastRead); List<ApplicationInfo> getInstalledApplications(int flags); /** * This implements getInstalledApplications via a "last returned row" * mechanism that is not exposed in the API. This is to get around the IPC * limit that kicks in when flags are included that bloat up the data * returned. */ ParceledListSlice getInstalledApplications(int flags, in String lastRead); /** * Retrieve all applications that are marked as persistent. Loading
core/java/android/content/pm/ParceledListSlice.aidl 0 → 100755 +19 −0 Original line number Diff line number Diff line /* * Copyright 2011, 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 ParceledListSlice;
core/java/android/content/pm/ParceledListSlice.java 0 → 100644 +170 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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.os.Parcel; import android.os.Parcelable; import java.util.List; /** * Builds up a parcel that is discarded when written to another parcel or * written to a list. This is useful for API that sends huge lists across a * Binder that may be larger than the IPC limit. * * @hide */ public class ParceledListSlice<T extends Parcelable> implements Parcelable { /* * TODO get this number from somewhere else. For now set it to a quarter of * the 1MB limit. */ private static final int MAX_IPC_SIZE = 256 * 1024; private Parcel mParcel; private int mNumItems; private boolean mIsLastSlice; public ParceledListSlice() { mParcel = Parcel.obtain(); } private ParceledListSlice(Parcel p, int numItems, boolean lastSlice) { mParcel = p; mNumItems = numItems; mIsLastSlice = lastSlice; } @Override public int describeContents() { return 0; } /** * Write this to another Parcel. Note that this discards the internal Parcel * and should not be used anymore. This is so we can pass this to a Binder * where we won't have a chance to call recycle on this. */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mNumItems); dest.writeInt(mIsLastSlice ? 1 : 0); if (mNumItems > 0) { final int parcelSize = mParcel.dataSize(); dest.writeInt(parcelSize); dest.appendFrom(mParcel, 0, parcelSize); } mNumItems = 0; mParcel.recycle(); mParcel = null; } /** * Appends a parcel to this list slice. * * @param item Parcelable item to append to this list slice * @return true when the list slice is full and should not be appended to * anymore */ public boolean append(T item) { if (mParcel == null) { throw new IllegalStateException("ParceledListSlice has already been recycled"); } item.writeToParcel(mParcel, PARCELABLE_WRITE_RETURN_VALUE); mNumItems++; return mParcel.dataSize() > MAX_IPC_SIZE; } /** * Populates a list and discards the internal state of the * ParceledListSlice in the process. The instance should * not be used anymore. * * @param list list to insert items from this slice. * @param creator creator that knows how to unparcel the * target object type. * @return the last item inserted into the list or null if none. */ public T populateList(List<T> list, Creator<T> creator) { mParcel.setDataPosition(0); T item = null; for (int i = 0; i < mNumItems; i++) { item = creator.createFromParcel(mParcel); list.add(item); } mParcel.recycle(); mParcel = null; return item; } /** * Sets whether this is the last list slice in the series. * * @param lastSlice */ public void setLastSlice(boolean lastSlice) { mIsLastSlice = lastSlice; } /** * Returns whether this is the last slice in a series of slices. * * @return true if this is the last slice in the series. */ public boolean isLastSlice() { return mIsLastSlice; } @SuppressWarnings("unchecked") public static final Parcelable.Creator<ParceledListSlice> CREATOR = new Parcelable.Creator<ParceledListSlice>() { public ParceledListSlice createFromParcel(Parcel in) { final int numItems = in.readInt(); final boolean lastSlice = in.readInt() == 1; if (numItems > 0) { final int parcelSize = in.readInt(); // Advance within this Parcel int offset = in.dataPosition(); in.setDataPosition(offset + parcelSize); Parcel p = Parcel.obtain(); p.setDataPosition(0); p.appendFrom(in, offset, parcelSize); p.setDataPosition(0); return new ParceledListSlice(p, numItems, lastSlice); } else { return new ParceledListSlice(); } } public ParceledListSlice[] newArray(int size) { return new ParceledListSlice[size]; } }; }