2 * Copyright (C) 2012 The Android Open Source Project
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.android.settings;
19 import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK;
20 import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP;
21 import static android.provider.Settings.Secure.SCREENSAVER_ENABLED;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.pm.PackageManager;
27 import android.content.pm.ResolveInfo;
28 import android.content.pm.PackageManager.NameNotFoundException;
29 import android.content.res.Resources;
30 import android.content.res.TypedArray;
31 import android.content.res.XmlResourceParser;
32 import android.graphics.drawable.Drawable;
33 import android.os.RemoteException;
34 import android.os.ServiceManager;
35 import android.provider.Settings;
36 import android.service.dreams.DreamService;
37 import android.service.dreams.IDreamManager;
38 import android.util.AttributeSet;
39 import android.util.Log;
40 import android.util.Xml;
42 import org.xmlpull.v1.XmlPullParser;
43 import org.xmlpull.v1.XmlPullParserException;
45 import java.io.IOException;
46 import java.util.ArrayList;
47 import java.util.Collections;
48 import java.util.Comparator;
49 import java.util.List;
51 public class DreamBackend {
52 private static final String TAG = DreamSettings.class.getSimpleName() + ".Backend";
54 public static class DreamInfo {
58 public ComponentName componentName;
59 public ComponentName settingsComponentName;
62 public String toString() {
63 StringBuilder sb = new StringBuilder(DreamInfo.class.getSimpleName());
64 sb.append('[').append(caption);
67 sb.append(',').append(componentName);
68 if (settingsComponentName != null)
69 sb.append("settings=").append(settingsComponentName);
70 return sb.append(']').toString();
74 private final Context mContext;
75 private final IDreamManager mDreamManager;
76 private final DreamInfoComparator mComparator;
78 public DreamBackend(Context context) {
80 mDreamManager = IDreamManager.Stub.asInterface(
81 ServiceManager.getService(DreamService.DREAM_SERVICE));
82 mComparator = new DreamInfoComparator(getDefaultDream());
85 public List<DreamInfo> getDreamInfos() {
86 logd("getDreamInfos()");
87 ComponentName activeDream = getActiveDream();
88 PackageManager pm = mContext.getPackageManager();
89 Intent dreamIntent = new Intent(DreamService.SERVICE_INTERFACE);
90 List<ResolveInfo> resolveInfos = pm.queryIntentServices(dreamIntent,
91 PackageManager.GET_META_DATA);
92 List<DreamInfo> dreamInfos = new ArrayList<DreamInfo>(resolveInfos.size());
93 for (ResolveInfo resolveInfo : resolveInfos) {
94 if (resolveInfo.serviceInfo == null)
96 DreamInfo dreamInfo = new DreamInfo();
97 dreamInfo.caption = resolveInfo.loadLabel(pm);
98 dreamInfo.icon = resolveInfo.loadIcon(pm);
99 dreamInfo.componentName = getDreamComponentName(resolveInfo);
100 dreamInfo.isActive = dreamInfo.componentName.equals(activeDream);
101 dreamInfo.settingsComponentName = getSettingsComponentName(pm, resolveInfo);
102 dreamInfos.add(dreamInfo);
104 Collections.sort(dreamInfos, mComparator);
108 public ComponentName getDefaultDream() {
109 if (mDreamManager == null)
112 return mDreamManager.getDefaultDreamComponent();
113 } catch (RemoteException e) {
114 Log.w(TAG, "Failed to get default dream", e);
119 public boolean isEnabled() {
120 return getBoolean(SCREENSAVER_ENABLED);
123 public void setEnabled(boolean value) {
124 logd("setEnabled(%s)", value);
125 setBoolean(SCREENSAVER_ENABLED, value);
128 public boolean isActivatedOnDock() {
129 return getBoolean(SCREENSAVER_ACTIVATE_ON_DOCK);
132 public void setActivatedOnDock(boolean value) {
133 logd("setActivatedOnDock(%s)", value);
134 setBoolean(SCREENSAVER_ACTIVATE_ON_DOCK, value);
137 public boolean isActivatedOnSleep() {
138 return getBoolean(SCREENSAVER_ACTIVATE_ON_SLEEP);
141 public void setActivatedOnSleep(boolean value) {
142 logd("setActivatedOnSleep(%s)", value);
143 setBoolean(SCREENSAVER_ACTIVATE_ON_SLEEP, value);
146 private boolean getBoolean(String key) {
147 return Settings.Secure.getInt(mContext.getContentResolver(), key, 1) == 1;
150 private void setBoolean(String key, boolean value) {
151 Settings.Secure.putInt(mContext.getContentResolver(), key, value ? 1 : 0);
154 public void setActiveDream(ComponentName dream) {
155 logd("setActiveDream(%s)", dream);
156 if (mDreamManager == null)
159 ComponentName[] dreams = { dream };
160 mDreamManager.setDreamComponents(dream == null ? null : dreams);
161 } catch (RemoteException e) {
162 Log.w(TAG, "Failed to set active dream to " + dream, e);
166 public ComponentName getActiveDream() {
167 if (mDreamManager == null)
170 ComponentName[] dreams = mDreamManager.getDreamComponents();
171 return dreams != null && dreams.length > 0 ? dreams[0] : null;
172 } catch (RemoteException e) {
173 Log.w(TAG, "Failed to get active dream", e);
178 public void launchSettings(DreamInfo dreamInfo) {
179 logd("launchSettings(%s)", dreamInfo);
180 if (dreamInfo == null || dreamInfo.settingsComponentName == null)
182 mContext.startActivity(new Intent().setComponent(dreamInfo.settingsComponentName));
185 public void preview(DreamInfo dreamInfo) {
186 logd("preview(%s)", dreamInfo);
187 if (mDreamManager == null || dreamInfo == null || dreamInfo.componentName == null)
190 mDreamManager.testDream(dreamInfo.componentName);
191 } catch (RemoteException e) {
192 Log.w(TAG, "Failed to preview " + dreamInfo, e);
196 public void startDreaming() {
197 logd("startDreaming()");
198 if (mDreamManager == null)
201 mDreamManager.dream();
202 } catch (RemoteException e) {
203 Log.w(TAG, "Failed to dream", e);
207 private static ComponentName getDreamComponentName(ResolveInfo resolveInfo) {
208 if (resolveInfo == null || resolveInfo.serviceInfo == null)
210 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
213 private static ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
214 if (resolveInfo == null
215 || resolveInfo.serviceInfo == null
216 || resolveInfo.serviceInfo.metaData == null)
219 XmlResourceParser parser = null;
220 Exception caughtException = null;
222 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA);
223 if (parser == null) {
224 Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " meta-data");
227 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
228 AttributeSet attrs = Xml.asAttributeSet(parser);
230 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
231 && type != XmlPullParser.START_TAG) {
233 String nodeName = parser.getName();
234 if (!"dream".equals(nodeName)) {
235 Log.w(TAG, "Meta-data does not start with dream tag");
238 TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.Dream);
239 cn = sa.getString(com.android.internal.R.styleable.Dream_settingsActivity);
241 } catch (NameNotFoundException e) {
243 } catch (IOException e) {
245 } catch (XmlPullParserException e) {
248 if (parser != null) parser.close();
250 if (caughtException != null) {
251 Log.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
254 return cn == null ? null : ComponentName.unflattenFromString(cn);
257 private static void logd(String msg, Object... args) {
258 if (DreamSettings.DEBUG)
259 Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args));
262 private static class DreamInfoComparator implements Comparator<DreamInfo> {
263 private final ComponentName mDefaultDream;
265 public DreamInfoComparator(ComponentName defaultDream) {
266 mDefaultDream = defaultDream;
270 public int compare(DreamInfo lhs, DreamInfo rhs) {
271 return sortKey(lhs).compareTo(sortKey(rhs));
274 private String sortKey(DreamInfo di) {
275 StringBuilder sb = new StringBuilder();
276 sb.append(di.componentName.equals(mDefaultDream) ? '0' : '1');
277 sb.append(di.caption);
278 return sb.toString();