1c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito/*
2c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * Copyright (C) 2015 The Android Open Source Project
3c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito *
4c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * Licensed under the Apache License, Version 2.0 (the "License");
5c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * you may not use this file except in compliance with the License.
6c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * You may obtain a copy of the License at
7c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito *
8c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito *      http://www.apache.org/licenses/LICENSE-2.0
9c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito *
10c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * Unless required by applicable law or agreed to in writing, software
11c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * distributed under the License is distributed on an "AS IS" BASIS,
12c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * See the License for the specific language governing permissions and
14c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * limitations under the License.
15c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito */
16c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
17c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itopackage android.nfc.cardemulation;
18c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
19c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.content.ComponentName;
20c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.content.pm.PackageManager;
21c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.content.pm.ResolveInfo;
22c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.content.pm.ServiceInfo;
23c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.content.pm.PackageManager.NameNotFoundException;
24c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.content.res.Resources;
25c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.content.res.TypedArray;
26c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.content.res.XmlResourceParser;
27c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.graphics.drawable.Drawable;
28c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.os.Parcel;
29c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.os.Parcelable;
30c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.util.AttributeSet;
31c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.util.Log;
32c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport android.util.Xml;
33c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
34c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport org.xmlpull.v1.XmlPullParser;
35c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport org.xmlpull.v1.XmlPullParserException;
36c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
37c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport java.io.FileDescriptor;
38c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport java.io.IOException;
39c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itoimport java.io.PrintWriter;
40c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
41c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito/**
42c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito * @hide
43c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito */
44c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Itopublic final class NfcFServiceInfo implements Parcelable {
45c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    static final String TAG = "NfcFServiceInfo";
46c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
47c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    /**
48c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     * The service that implements this
49c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     */
50c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    final ResolveInfo mService;
51c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
52c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    /**
53c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     * Description of the service
54c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     */
55c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    final String mDescription;
56c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
57c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    /**
58c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     * System Code of the service
59c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     */
60c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    final String mSystemCode;
61c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
62c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    /**
63c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     * System Code of the service registered by API
64c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     */
65c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    String mDynamicSystemCode;
66c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
67c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    /**
68c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     * NFCID2 of the service
69c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     */
70c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    final String mNfcid2;
71c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
72c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    /**
73c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     * NFCID2 of the service registered by API
74c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     */
75c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    String mDynamicNfcid2;
76c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
77c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    /**
78c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     * The uid of the package the service belongs to
79c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     */
80c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    final int mUid;
81c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
82c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    /**
83c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     * @hide
84c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito     */
85c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public NfcFServiceInfo(ResolveInfo info, String description,
86c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String systemCode, String dynamicSystemCode, String nfcid2, String dynamicNfcid2,
87c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            int uid) {
88c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        this.mService = info;
89c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        this.mDescription = description;
90c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        this.mSystemCode = systemCode;
91c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        this.mDynamicSystemCode = dynamicSystemCode;
92c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        this.mNfcid2 = nfcid2;
93c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        this.mDynamicNfcid2 = dynamicNfcid2;
94c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        this.mUid = uid;
95c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
96c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
97c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public NfcFServiceInfo(PackageManager pm, ResolveInfo info)
98c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            throws XmlPullParserException, IOException {
99c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        ServiceInfo si = info.serviceInfo;
100c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        XmlResourceParser parser = null;
101c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        try {
102c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            parser = si.loadXmlMetaData(pm, HostNfcFService.SERVICE_META_DATA);
103c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            if (parser == null) {
104c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                throw new XmlPullParserException("No " + HostNfcFService.SERVICE_META_DATA +
105c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                        " meta-data");
106c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            }
107c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
108c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            int eventType = parser.getEventType();
109c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            while (eventType != XmlPullParser.START_TAG &&
110c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    eventType != XmlPullParser.END_DOCUMENT) {
111c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                eventType = parser.next();
112c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            }
113c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
114c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String tagName = parser.getName();
115c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            if (!"host-nfcf-service".equals(tagName)) {
116c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                throw new XmlPullParserException(
117c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                        "Meta-data does not start with <host-nfcf-service> tag");
118c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            }
119c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
120c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            Resources res = pm.getResourcesForApplication(si.applicationInfo);
121c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            AttributeSet attrs = Xml.asAttributeSet(parser);
122c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            TypedArray sa = res.obtainAttributes(attrs,
123c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    com.android.internal.R.styleable.HostNfcFService);
124c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            mService = info;
125c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            mDescription = sa.getString(
126c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    com.android.internal.R.styleable.HostNfcFService_description);
127c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            mDynamicSystemCode = null;
128c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            mDynamicNfcid2 = null;
129c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            sa.recycle();
130c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
131c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String systemCode = null;
132c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String nfcid2 = null;
133c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            final int depth = parser.getDepth();
134c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
135c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            while (((eventType = parser.next()) != XmlPullParser.END_TAG ||
136c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    parser.getDepth() > depth) && eventType != XmlPullParser.END_DOCUMENT) {
137c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                tagName = parser.getName();
138c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                if (eventType == XmlPullParser.START_TAG &&
139c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                        "system-code-filter".equals(tagName) && systemCode == null) {
140c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    final TypedArray a = res.obtainAttributes(attrs,
141c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                            com.android.internal.R.styleable.SystemCodeFilter);
142c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    systemCode = a.getString(
143c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                            com.android.internal.R.styleable.SystemCodeFilter_name).toUpperCase();
144c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    if (!NfcFCardEmulation.isValidSystemCode(systemCode) &&
145c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                            !systemCode.equalsIgnoreCase("NULL")) {
146c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                        Log.e(TAG, "Invalid System Code: " + systemCode);
147c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                        systemCode = null;
148c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    }
149c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    a.recycle();
150c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                } else if (eventType == XmlPullParser.START_TAG &&
151c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                        "nfcid2-filter".equals(tagName) && nfcid2 == null) {
152c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    final TypedArray a = res.obtainAttributes(attrs,
153c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                            com.android.internal.R.styleable.Nfcid2Filter);
154c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    nfcid2 = a.getString(
155c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                            com.android.internal.R.styleable.Nfcid2Filter_name).toUpperCase();
156c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    if (!nfcid2.equalsIgnoreCase("RANDOM") &&
157c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                            !nfcid2.equalsIgnoreCase("NULL") &&
158c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                            !NfcFCardEmulation.isValidNfcid2(nfcid2)) {
159c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                        Log.e(TAG, "Invalid NFCID2: " + nfcid2);
160c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                        nfcid2 = null;
161c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    }
162c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    a.recycle();
163c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                }
164c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            }
165c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            mSystemCode = (systemCode == null ? "NULL" : systemCode);
166c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            mNfcid2 = (nfcid2 == null ? "NULL" : nfcid2);
167c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        } catch (NameNotFoundException e) {
168c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            throw new XmlPullParserException("Unable to create context for: " + si.packageName);
169c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        } finally {
170c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            if (parser != null) parser.close();
171c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        }
172c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        // Set uid
173c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        mUid = si.applicationInfo.uid;
174c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
175c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
176c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public ComponentName getComponent() {
177c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return new ComponentName(mService.serviceInfo.packageName,
178c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                mService.serviceInfo.name);
179c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
180c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
181c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public String getSystemCode() {
182c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return (mDynamicSystemCode == null ? mSystemCode : mDynamicSystemCode);
183c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
184c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
185c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public void setOrReplaceDynamicSystemCode(String systemCode) {
186c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        mDynamicSystemCode = systemCode;
187c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
188c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
189c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public String getNfcid2() {
190c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return (mDynamicNfcid2 == null ? mNfcid2 : mDynamicNfcid2);
191c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
192c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
193c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public void setOrReplaceDynamicNfcid2(String nfcid2) {
194c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        mDynamicNfcid2 = nfcid2;
195c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
196c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
197c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public String getDescription() {
198c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return mDescription;
199c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
200c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
201c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public int getUid() {
202c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return mUid;
203c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
204c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
205c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public CharSequence loadLabel(PackageManager pm) {
206c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return mService.loadLabel(pm);
207c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
208c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
209c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public Drawable loadIcon(PackageManager pm) {
210c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return mService.loadIcon(pm);
211c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
212c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
213c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    @Override
214c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public String toString() {
215c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        StringBuilder out = new StringBuilder("NfcFService: ");
216c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        out.append(getComponent());
217c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        out.append(", description: " + mDescription);
218c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        out.append(", System Code: " + mSystemCode);
219c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (mDynamicSystemCode != null) {
220c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            out.append(", dynamic System Code: " + mDynamicSystemCode);
221c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        }
222c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        out.append(", NFCID2: " + mNfcid2);
223c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (mDynamicNfcid2 != null) {
224c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            out.append(", dynamic NFCID2: " + mDynamicNfcid2);
225c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        }
226c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return out.toString();
227c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
228c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
229c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    @Override
230c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public boolean equals(Object o) {
231c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (this == o) return true;
232c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (!(o instanceof NfcFServiceInfo)) return false;
233c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        NfcFServiceInfo thatService = (NfcFServiceInfo) o;
234c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
235c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (!thatService.getComponent().equals(this.getComponent())) return false;
236c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (!thatService.mSystemCode.equalsIgnoreCase(this.mSystemCode)) return false;
237c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (!thatService.mNfcid2.equalsIgnoreCase(this.mNfcid2)) return false;
238c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
239c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return true;
240c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
241c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
242c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    @Override
243c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public int hashCode() {
244c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return getComponent().hashCode();
245c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
246c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
247c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    @Override
248c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public int describeContents() {
249c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        return 0;
250c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
251c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
252c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    @Override
253c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public void writeToParcel(Parcel dest, int flags) {
254c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        mService.writeToParcel(dest, flags);
255c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        dest.writeString(mDescription);
256c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        dest.writeString(mSystemCode);
257c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        dest.writeInt(mDynamicSystemCode != null ? 1 : 0);
258c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (mDynamicSystemCode != null) {
259c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            dest.writeString(mDynamicSystemCode);
260c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        }
261c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        dest.writeString(mNfcid2);
262c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        dest.writeInt(mDynamicNfcid2 != null ? 1 : 0);
263c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        if (mDynamicNfcid2 != null) {
264c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            dest.writeString(mDynamicNfcid2);
265c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        }
266c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        dest.writeInt(mUid);
267c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    };
268c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
269c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public static final Parcelable.Creator<NfcFServiceInfo> CREATOR =
270c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            new Parcelable.Creator<NfcFServiceInfo>() {
271c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        @Override
272c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        public NfcFServiceInfo createFromParcel(Parcel source) {
273c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
274c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String description = source.readString();
275c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String systemCode = source.readString();
276c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String dynamicSystemCode = null;
277c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            if (source.readInt() != 0) {
278c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                dynamicSystemCode = source.readString();
279c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            }
280c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String nfcid2 = source.readString();
281c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            String dynamicNfcid2 = null;
282c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            if (source.readInt() != 0) {
283c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                dynamicNfcid2 = source.readString();
284c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            }
285c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            int uid = source.readInt();
286c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            NfcFServiceInfo service = new NfcFServiceInfo(info, description,
287c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                    systemCode, dynamicSystemCode, nfcid2, dynamicNfcid2, uid);
288c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            return service;
289c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        }
290c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
291c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        @Override
292c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        public NfcFServiceInfo[] newArray(int size) {
293c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito            return new NfcFServiceInfo[size];
294c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        }
295c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    };
296c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
297c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
298c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        pw.println("    " + getComponent() +
299c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito                " (Description: " + getDescription() + ")");
300c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        pw.println("    System Code: " + getSystemCode());
301c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito        pw.println("    NFCID2: " + getNfcid2());
302c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito    }
303c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito}
304c52adfe12469a1d1bcd5b7119b83363e094a7b84Yoshinobu Ito
305