1 /*
2  * Copyright (C) 2016 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.printservice.recommendation;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.SystemApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.printservice.PrintService;
25 
26 import com.android.internal.util.Preconditions;
27 
28 import java.net.InetAddress;
29 import java.net.UnknownHostException;
30 import java.util.ArrayList;
31 import java.util.List;
32 
33 /**
34  * A recommendation to install a {@link PrintService print service}.
35  *
36  * @hide
37  */
38 @SystemApi
39 public final class RecommendationInfo implements Parcelable {
40     /** Package name of the print service. */
41     private @NonNull final CharSequence mPackageName;
42 
43     /** Display name of the print service. */
44     private @NonNull final CharSequence mName;
45 
46     /** Printers the print service would discover if installed. */
47     @NonNull private final List<InetAddress> mDiscoveredPrinters;
48 
49     /** If the service detects printer from multiple vendors. */
50     private final boolean mRecommendsMultiVendorService;
51 
52     /**
53      * Create a new recommendation.
54      *
55      * @param packageName                  Package name of the print service
56      * @param name                         Display name of the print service
57      * @param discoveredPrinters           The {@link InetAddress addresses} of the discovered
58      *                                     printers. Cannot be null or empty.
59      * @param recommendsMultiVendorService If the service detects printer from multiple vendor
60      */
RecommendationInfo(@onNull CharSequence packageName, @NonNull CharSequence name, @NonNull List<InetAddress> discoveredPrinters, boolean recommendsMultiVendorService)61     public RecommendationInfo(@NonNull CharSequence packageName, @NonNull CharSequence name,
62             @NonNull List<InetAddress> discoveredPrinters, boolean recommendsMultiVendorService) {
63         mPackageName = Preconditions.checkStringNotEmpty(packageName);
64         mName = Preconditions.checkStringNotEmpty(name);
65         mDiscoveredPrinters = Preconditions.checkCollectionElementsNotNull(discoveredPrinters,
66                     "discoveredPrinters");
67         mRecommendsMultiVendorService = recommendsMultiVendorService;
68     }
69 
70     /**
71      * Create a new recommendation.
72      *
73      * @param packageName                  Package name of the print service
74      * @param name                         Display name of the print service
75      * @param numDiscoveredPrinters        Number of printers the print service would discover if
76      *                                     installed
77      * @param recommendsMultiVendorService If the service detects printer from multiple vendor
78      *
79      * @deprecated Use {@link RecommendationInfo(String, String, List<InetAddress>, boolean)}
80      *             instead
81      */
82     @Deprecated
RecommendationInfo(@onNull CharSequence packageName, @NonNull CharSequence name, @IntRange(from = 0) int numDiscoveredPrinters, boolean recommendsMultiVendorService)83     public RecommendationInfo(@NonNull CharSequence packageName, @NonNull CharSequence name,
84             @IntRange(from = 0) int numDiscoveredPrinters, boolean recommendsMultiVendorService) {
85         throw new IllegalArgumentException("This constructor has been deprecated");
86     }
87 
88     /**
89      * Read a list of blobs from the parcel and return it as a list of {@link InetAddress
90      * addresses}.
91      *
92      * @param parcel the parcel to read the blobs from
93      *
94      * @return The list of {@link InetAddress addresses} or null if no printers were found.
95      *
96      * @see #writeToParcel(Parcel, int)
97      */
readDiscoveredPrinters(@onNull Parcel parcel)98     @NonNull private static ArrayList<InetAddress> readDiscoveredPrinters(@NonNull Parcel parcel) {
99         int numDiscoveredPrinters = parcel.readInt();
100         ArrayList<InetAddress> discoveredPrinters = new ArrayList<>(numDiscoveredPrinters);
101 
102         for (int i = 0; i < numDiscoveredPrinters; i++) {
103             try {
104                 discoveredPrinters.add(InetAddress.getByAddress(parcel.readBlob()));
105             } catch (UnknownHostException e) {
106                 throw new IllegalArgumentException(e);
107             }
108         }
109 
110         return discoveredPrinters;
111     }
112 
113     /**
114      * Create a new recommendation from a parcel.
115      *
116      * @param parcel The parcel containing the data
117      *
118      * @see #CREATOR
119      */
RecommendationInfo(@onNull Parcel parcel)120     private RecommendationInfo(@NonNull Parcel parcel) {
121         this(parcel.readCharSequence(), parcel.readCharSequence(), readDiscoveredPrinters(parcel),
122                 parcel.readByte() != 0);
123     }
124 
125     /**
126      * @return The package name the recommendations recommends.
127      */
getPackageName()128     public CharSequence getPackageName() {
129         return mPackageName;
130     }
131 
132     /**
133      * @return Whether the recommended print service detects printers of more than one vendor.
134      */
recommendsMultiVendorService()135     public boolean recommendsMultiVendorService() {
136         return mRecommendsMultiVendorService;
137     }
138 
139     /**
140      * @return The {@link InetAddress address} of the printers the print service would detect.
141      */
getDiscoveredPrinters()142     @NonNull public List<InetAddress> getDiscoveredPrinters() {
143         return mDiscoveredPrinters;
144     }
145 
146     /**
147      * @return The number of printer the print service would detect.
148      */
getNumDiscoveredPrinters()149     public int getNumDiscoveredPrinters() {
150         return mDiscoveredPrinters.size();
151     }
152 
153     /**
154      * @return The name of the recommended print service.
155      */
getName()156     public CharSequence getName() {
157         return mName;
158     }
159 
160     @Override
describeContents()161     public int describeContents() {
162         return 0;
163     }
164 
165     @Override
writeToParcel(Parcel dest, int flags)166     public void writeToParcel(Parcel dest, int flags) {
167         dest.writeCharSequence(mPackageName);
168         dest.writeCharSequence(mName);
169 
170         int numDiscoveredPrinters = mDiscoveredPrinters.size();
171         dest.writeInt(numDiscoveredPrinters);
172 
173         for (InetAddress printer : mDiscoveredPrinters) {
174             dest.writeBlob(printer.getAddress());
175         }
176 
177         dest.writeByte((byte) (mRecommendsMultiVendorService ? 1 : 0));
178     }
179 
180     /**
181      * Utility class used to create new print service recommendation objects from parcels.
182      *
183      * @see #RecommendationInfo(Parcel)
184      */
185     public static final @android.annotation.NonNull Creator<RecommendationInfo> CREATOR =
186             new Creator<RecommendationInfo>() {
187                 @Override
188                 public RecommendationInfo createFromParcel(Parcel in) {
189                     return new RecommendationInfo(in);
190                 }
191 
192                 @Override
193                 public RecommendationInfo[] newArray(int size) {
194                     return new RecommendationInfo[size];
195                 }
196     };
197 }
198