1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.content.pm.parsing.component; 18 19 import android.annotation.Nullable; 20 import android.content.IntentFilter; 21 import android.os.Parcel; 22 import android.util.Pair; 23 24 import com.android.internal.util.Parcelling; 25 26 import java.util.ArrayList; 27 import java.util.List; 28 29 /** @hide **/ 30 public final class ParsedIntentInfo extends IntentFilter { 31 32 public static final Parceler PARCELER = new Parceler(); 33 34 public static class Parceler implements Parcelling<ParsedIntentInfo> { 35 36 @Override parcel(ParsedIntentInfo item, Parcel dest, int parcelFlags)37 public void parcel(ParsedIntentInfo item, Parcel dest, int parcelFlags) { 38 item.writeIntentInfoToParcel(dest, parcelFlags); 39 } 40 41 @Override unparcel(Parcel source)42 public ParsedIntentInfo unparcel(Parcel source) { 43 return new ParsedIntentInfo(source); 44 } 45 } 46 47 public static class ListParceler implements Parcelling<List<ParsedIntentInfo>> { 48 49 /** 50 * <p> 51 * Implementation note: The serialized form for the intent list also contains the name 52 * of the concrete class that's stored in the list, and assumes that every element of the 53 * list is of the same type. This is very similar to the original parcelable mechanism. 54 * We cannot use that directly because IntentInfo extends IntentFilter, which is parcelable 55 * and is public API. It also declares Parcelable related methods as final which means 56 * we can't extend them. The approach of using composition instead of inheritance leads to 57 * a large set of cascading changes in the PackageManagerService, which seem undesirable. 58 * 59 * <p> 60 * <b>WARNING: </b> The list of objects returned by this function might need to be fixed up 61 * to make sure their owner fields are consistent. See {@code fixupOwner}. 62 */ 63 @Override parcel(List<ParsedIntentInfo> item, Parcel dest, int parcelFlags)64 public void parcel(List<ParsedIntentInfo> item, Parcel dest, int parcelFlags) { 65 if (item == null) { 66 dest.writeInt(-1); 67 return; 68 } 69 70 final int size = item.size(); 71 dest.writeInt(size); 72 73 for (int index = 0; index < size; index++) { 74 PARCELER.parcel(item.get(index), dest, parcelFlags); 75 } 76 } 77 78 @Override unparcel(Parcel source)79 public List<ParsedIntentInfo> unparcel(Parcel source) { 80 int size = source.readInt(); 81 if (size == -1) { 82 return null; 83 } 84 85 if (size == 0) { 86 return new ArrayList<>(0); 87 } 88 89 final ArrayList<ParsedIntentInfo> intentsList = new ArrayList<>(size); 90 for (int i = 0; i < size; ++i) { 91 intentsList.add(PARCELER.unparcel(source)); 92 } 93 94 return intentsList; 95 } 96 } 97 98 public static class StringPairListParceler implements Parcelling<List<Pair<String, ParsedIntentInfo>>> { 99 100 @Override parcel(List<Pair<String, ParsedIntentInfo>> item, Parcel dest, int parcelFlags)101 public void parcel(List<Pair<String, ParsedIntentInfo>> item, Parcel dest, 102 int parcelFlags) { 103 if (item == null) { 104 dest.writeInt(-1); 105 return; 106 } 107 108 final int size = item.size(); 109 dest.writeInt(size); 110 111 for (int index = 0; index < size; index++) { 112 Pair<String, ParsedIntentInfo> pair = item.get(index); 113 dest.writeString(pair.first); 114 PARCELER.parcel(pair.second, dest, parcelFlags); 115 } 116 } 117 118 @Override unparcel(Parcel source)119 public List<Pair<String, ParsedIntentInfo>> unparcel(Parcel source) { 120 int size = source.readInt(); 121 if (size == -1) { 122 return null; 123 } 124 125 if (size == 0) { 126 return new ArrayList<>(0); 127 } 128 129 final List<Pair<String, ParsedIntentInfo>> list = new ArrayList<>(size); 130 for (int i = 0; i < size; ++i) { 131 list.add(Pair.create(source.readString(), PARCELER.unparcel(source))); 132 } 133 134 return list; 135 } 136 } 137 138 boolean hasDefault; 139 int labelRes; 140 @Nullable 141 CharSequence nonLocalizedLabel; 142 int icon; 143 ParsedIntentInfo()144 public ParsedIntentInfo() { 145 } 146 ParsedIntentInfo(Parcel in)147 public ParsedIntentInfo(Parcel in) { 148 super(in); 149 hasDefault = in.readBoolean(); 150 labelRes = in.readInt(); 151 nonLocalizedLabel = in.readCharSequence(); 152 icon = in.readInt(); 153 } 154 writeIntentInfoToParcel(Parcel dest, int flags)155 public void writeIntentInfoToParcel(Parcel dest, int flags) { 156 super.writeToParcel(dest, flags); 157 dest.writeBoolean(hasDefault); 158 dest.writeInt(labelRes); 159 dest.writeCharSequence(nonLocalizedLabel); 160 dest.writeInt(icon); 161 } 162 toString()163 public String toString() { 164 return "ParsedIntentInfo{" 165 + Integer.toHexString(System.identityHashCode(this)) 166 + '}'; 167 } 168 isHasDefault()169 public boolean isHasDefault() { 170 return hasDefault; 171 } 172 getLabelRes()173 public int getLabelRes() { 174 return labelRes; 175 } 176 177 @Nullable getNonLocalizedLabel()178 public CharSequence getNonLocalizedLabel() { 179 return nonLocalizedLabel; 180 } 181 getIcon()182 public int getIcon() { 183 return icon; 184 } 185 } 186