1 /*
2  * Copyright (C) 2011 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 com.android.server.pm;
18 
19 import android.content.ComponentName;
20 import android.content.IntentFilter;
21 import android.util.Log;
22 
23 import com.android.internal.util.XmlUtils;
24 import com.android.modules.utils.TypedXmlPullParser;
25 import com.android.modules.utils.TypedXmlSerializer;
26 import com.android.server.utils.SnapshotCache;
27 
28 import org.xmlpull.v1.XmlPullParserException;
29 
30 import java.io.IOException;
31 import java.io.PrintWriter;
32 
33 class PreferredActivity extends WatchedIntentFilter implements PreferredComponent.Callbacks {
34     private static final String TAG = "PreferredActivity";
35 
36     private static final boolean DEBUG_FILTERS = false;
37 
38     final PreferredComponent mPref;
39 
40     // The cache for snapshots, so they are not rebuilt if the base object has not
41     // changed.
42     final SnapshotCache<PreferredActivity> mSnapshot;
43 
makeCache()44     private SnapshotCache makeCache() {
45         return new SnapshotCache<PreferredActivity>(this, this) {
46             @Override
47             public PreferredActivity createSnapshot() {
48                 PreferredActivity s = new PreferredActivity(mSource);
49                 s.seal();
50                 return s;
51             }};
52     }
53 
54     PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity,
55             boolean always) {
56         super(filter);
57         mPref = new PreferredComponent(this, match, set, activity, always);
58         mSnapshot = makeCache();
59     }
60 
61     PreferredActivity(WatchedIntentFilter filter, int match, ComponentName[] set,
62             ComponentName activity, boolean always) {
63         this(filter.mFilter, match, set, activity, always);
64     }
65 
66     // Copy constructor used only to create a snapshot
67     private PreferredActivity(PreferredActivity f) {
68         super(f);
69         mPref = f.mPref;
70         mSnapshot = new SnapshotCache.Sealed();
71     }
72 
73     PreferredActivity(TypedXmlPullParser parser) throws XmlPullParserException, IOException {
74         mPref = new PreferredComponent(this, parser);
75         mSnapshot = makeCache();
76     }
77 
78     public void writeToXml(TypedXmlSerializer serializer, boolean full) throws IOException {
79         mPref.writeToXml(serializer, full);
80         serializer.startTag(null, "filter");
81         mFilter.writeToXml(serializer);
82         serializer.endTag(null, "filter");
83     }
84 
85     public boolean onReadTag(String tagName, TypedXmlPullParser parser)
86             throws XmlPullParserException, IOException {
87         if (tagName.equals("filter")) {
88             if (DEBUG_FILTERS) {
89                 Log.i(TAG, "Starting to parse filter...");
90             }
91             mFilter.readFromXml(parser);
92             if (DEBUG_FILTERS) {
93                 Log.i(TAG, "Finished filter: depth=" + parser.getDepth() + " tag="
94                         + parser.getName());
95             }
96         } else {
97             PackageManagerService.reportSettingsProblem(Log.WARN,
98                     "Unknown element under <preferred-activities>: " + parser.getName());
99             XmlUtils.skipCurrentTag(parser);
100         }
101         return true;
102     }
103 
104     public void dumpPref(PrintWriter out, String prefix, PreferredActivity filter) {
105         mPref.dump(out, prefix, filter);
106     }
107 
108     @Override
109     public String toString() {
110         return "PreferredActivity{0x" + Integer.toHexString(System.identityHashCode(this))
111                 + " " + mPref.mComponent.flattenToShortString() + "}";
112     }
113 
114     public PreferredActivity snapshot() {
115         return mSnapshot.snapshot();
116     }
117 }
118