2 * Copyright 2011 Google Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.google.ipc.invalidation.ticl.android2;
19 import com.google.ipc.invalidation.util.Preconditions;
21 import android.content.Context;
22 import android.content.pm.ApplicationInfo;
23 import android.content.pm.PackageManager;
24 import android.content.pm.PackageManager.NameNotFoundException;
26 import java.util.HashMap;
31 * Interface to the {@code AndroidManifest.xml} that provides access to the configuration data
32 * required by the Android Ticl.
35 public class AndroidTiclManifest {
38 * Cache of {@link ApplicationMetadata} to avoid repeatedly scanning manifest. The key is the
39 * package name for the context.
41 private static final Map<String, ApplicationMetadata> applicationMetadataCache =
42 new HashMap<String, ApplicationMetadata>();
44 /** Application metadata from the Android manifest. */
45 private final ApplicationMetadata metadata;
47 public AndroidTiclManifest(Context context) {
48 metadata = createApplicationMetadata(Preconditions.checkNotNull(context));
51 /** Returns the name of the class implementing the Ticl service. */
52 public String getTiclServiceClass() {
53 return metadata.ticlServiceClass;
56 /** Returns the name of the class on which listener events will be invoked. */
57 String getListenerClass() {
58 return metadata.listenerClass;
61 /** Returns the name of the class implementing the invalidation listener intent service. */
62 public String getListenerServiceClass() {
63 return metadata.listenerServiceClass;
67 * Returns the name of the class implementing the background invalidation listener intent service.
69 String getBackgroundInvalidationListenerServiceClass() {
70 return metadata.backgroundInvalidationListenerServiceClass;
74 * If it has not already been cached for the given {@code context}, creates and caches application
75 * metadata from the manifest.
77 private static ApplicationMetadata createApplicationMetadata(Context context) {
78 synchronized (applicationMetadataCache) {
79 String packageName = context.getPackageName();
80 ApplicationMetadata metadata = applicationMetadataCache.get(packageName);
81 if (metadata == null) {
82 metadata = new ApplicationMetadata(context);
83 applicationMetadataCache.put(packageName, metadata);
89 /** Application metadata for a specific context. */
90 private static final class ApplicationMetadata {
92 * Name of the {@code <application>} metadata element whose value gives the Java class that
93 * implements the application {@code InvalidationListener}. Must be set if
94 * {@link #LISTENER_SERVICE_NAME_KEY} is not set.
96 private static final String LISTENER_NAME_KEY = "ipc.invalidation.ticl.listener_class";
99 * Name of the {@code <application>} metadata element whose value gives the Java class that
100 * implements the Ticl service. Should only be set in tests.
102 private static final String TICL_SERVICE_NAME_KEY = "ipc.invalidation.ticl.service_class";
105 * Name of the {@code <application>} metadata element whose value gives the Java class that
106 * implements the application's invalidation listener intent service.
108 private static final String LISTENER_SERVICE_NAME_KEY =
109 "ipc.invalidation.ticl.listener_service_class";
112 * Name of the {@code <application>} metadata element whose value gives the Java class that
113 * implements the application's background invalidation listener intent service.
115 private static final String BACKGROUND_INVALIDATION_LISTENER_SERVICE_NAME_KEY =
116 "ipc.invalidation.ticl.background_invalidation_listener_service_class";
118 /** Default values returned if not overriden by the manifest file. */
119 private static final Map<String, String> DEFAULTS = new HashMap<String, String>();
121 DEFAULTS.put(TICL_SERVICE_NAME_KEY,
122 "com.google.ipc.invalidation.ticl.android2.TiclService");
123 DEFAULTS.put(LISTENER_NAME_KEY, "");
124 DEFAULTS.put(LISTENER_SERVICE_NAME_KEY,
125 "com.google.ipc.invalidation.ticl.android2.AndroidInvalidationListenerStub");
126 DEFAULTS.put(BACKGROUND_INVALIDATION_LISTENER_SERVICE_NAME_KEY, null);
129 private final String ticlServiceClass;
130 private final String listenerClass;
131 private final String listenerServiceClass;
132 private final String backgroundInvalidationListenerServiceClass;
134 ApplicationMetadata(Context context) {
135 ApplicationInfo appInfo;
137 // Read metadata from manifest.xml
138 appInfo = context.getPackageManager()
139 .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
140 } catch (NameNotFoundException exception) {
141 throw new RuntimeException("Cannot read own application info", exception);
143 ticlServiceClass = readApplicationMetadata(appInfo, TICL_SERVICE_NAME_KEY);
144 listenerClass = readApplicationMetadata(appInfo, LISTENER_NAME_KEY);
145 listenerServiceClass = readApplicationMetadata(appInfo, LISTENER_SERVICE_NAME_KEY);
146 backgroundInvalidationListenerServiceClass =
147 readApplicationMetadata(appInfo, BACKGROUND_INVALIDATION_LISTENER_SERVICE_NAME_KEY);
151 * Returns the metadata-provided value for {@code key} in {@code appInfo} if one
152 * exists, or the value from {@link #DEFAULTS} if one does not.
154 private static String readApplicationMetadata(ApplicationInfo appInfo, String key) {
156 if (appInfo.metaData != null) {
157 value = appInfo.metaData.getString(key);
159 // Return the manifest value if present or the default value if not.
160 return (value != null) ? value : DEFAULTS.get(key);