1e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler/*
2e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * Copyright (C) 2015 The Android Open Source Project
3e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler *
4e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
5e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * you may not use this file except in compliance with the License.
6e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * You may obtain a copy of the License at
7e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler *
8e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
9e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler *
10e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * Unless required by applicable law or agreed to in writing, software
11e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
12e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * See the License for the specific language governing permissions and
14e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler * limitations under the License
15e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler */
16e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
17e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerpackage com.android.settingslib.dream;
18e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
19e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.ComponentName;
20e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.Context;
21e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.Intent;
22e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.pm.PackageManager;
23e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.pm.ResolveInfo;
24e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.pm.ServiceInfo;
25e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.res.Resources;
26e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.res.TypedArray;
27e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.content.res.XmlResourceParser;
28e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.graphics.drawable.Drawable;
29e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.os.RemoteException;
30e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.os.ServiceManager;
31e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.provider.Settings;
32e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.service.dreams.DreamService;
33e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.service.dreams.IDreamManager;
34e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.util.AttributeSet;
35e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.util.Log;
36e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport android.util.Xml;
37e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
38e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport org.xmlpull.v1.XmlPullParser;
39e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport org.xmlpull.v1.XmlPullParserException;
40e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
41e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport java.io.IOException;
42e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport java.util.ArrayList;
43e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport java.util.Collections;
44e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport java.util.Comparator;
45e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerimport java.util.List;
46e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
47e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantlerpublic class DreamBackend {
48e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private static final String TAG = "DreamBackend";
49e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private static final boolean DEBUG = false;
50e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
51e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public static class DreamInfo {
52e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        public CharSequence caption;
53e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        public Drawable icon;
54e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        public boolean isActive;
55e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        public ComponentName componentName;
56e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        public ComponentName settingsComponentName;
57e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
58e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        @Override
59e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        public String toString() {
60e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            StringBuilder sb = new StringBuilder(DreamInfo.class.getSimpleName());
61e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            sb.append('[').append(caption);
62e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            if (isActive)
63e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                sb.append(",active");
64e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            sb.append(',').append(componentName);
65e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            if (settingsComponentName != null)
66e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                sb.append("settings=").append(settingsComponentName);
67e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return sb.append(']').toString();
68e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
69e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
70e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
71e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private final Context mContext;
72e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private final IDreamManager mDreamManager;
73e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private final DreamInfoComparator mComparator;
74e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private final boolean mDreamsEnabledByDefault;
75e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private final boolean mDreamsActivatedOnSleepByDefault;
76e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private final boolean mDreamsActivatedOnDockByDefault;
77e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
78e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public DreamBackend(Context context) {
79e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        mContext = context;
80e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        mDreamManager = IDreamManager.Stub.asInterface(
81e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                ServiceManager.getService(DreamService.DREAM_SERVICE));
82e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        mComparator = new DreamInfoComparator(getDefaultDream());
83e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        mDreamsEnabledByDefault = context.getResources()
84e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                .getBoolean(com.android.internal.R.bool.config_dreamsEnabledByDefault);
85e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        mDreamsActivatedOnSleepByDefault = context.getResources()
86e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                .getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
87e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        mDreamsActivatedOnDockByDefault = context.getResources()
88e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                .getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
89e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
90e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
91e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public List<DreamInfo> getDreamInfos() {
92e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        logd("getDreamInfos()");
93e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        ComponentName activeDream = getActiveDream();
94e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        PackageManager pm = mContext.getPackageManager();
95e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        Intent dreamIntent = new Intent(DreamService.SERVICE_INTERFACE);
96e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        List<ResolveInfo> resolveInfos = pm.queryIntentServices(dreamIntent,
97e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                PackageManager.GET_META_DATA);
98e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        List<DreamInfo> dreamInfos = new ArrayList<>(resolveInfos.size());
99e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        for (ResolveInfo resolveInfo : resolveInfos) {
100e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            if (resolveInfo.serviceInfo == null)
101e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                continue;
102e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            DreamInfo dreamInfo = new DreamInfo();
103e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            dreamInfo.caption = resolveInfo.loadLabel(pm);
104e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            dreamInfo.icon = resolveInfo.loadIcon(pm);
105e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            dreamInfo.componentName = getDreamComponentName(resolveInfo);
106e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            dreamInfo.isActive = dreamInfo.componentName.equals(activeDream);
107e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            dreamInfo.settingsComponentName = getSettingsComponentName(pm, resolveInfo);
108e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            dreamInfos.add(dreamInfo);
109e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
110e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        Collections.sort(dreamInfos, mComparator);
111e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        return dreamInfos;
112e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
113e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
114e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public ComponentName getDefaultDream() {
115e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (mDreamManager == null)
116e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return null;
117e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        try {
118e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return mDreamManager.getDefaultDreamComponent();
119e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        } catch (RemoteException e) {
120e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            Log.w(TAG, "Failed to get default dream", e);
121e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return null;
122e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
123e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
124e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
125e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public CharSequence getActiveDreamName() {
126e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        ComponentName cn = getActiveDream();
127e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (cn != null) {
128e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            PackageManager pm = mContext.getPackageManager();
129e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            try {
130e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                ServiceInfo ri = pm.getServiceInfo(cn, 0);
131e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                if (ri != null) {
132e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                    return ri.loadLabel(pm);
133e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                }
134e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            } catch (PackageManager.NameNotFoundException exc) {
135e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                return null; // uninstalled?
136e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            }
137e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
138e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        return null;
139e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
140e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
141e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public boolean isEnabled() {
142e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        return getBoolean(Settings.Secure.SCREENSAVER_ENABLED, mDreamsEnabledByDefault);
143e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
144e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
145e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public void setEnabled(boolean value) {
146e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        logd("setEnabled(%s)", value);
147e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        setBoolean(Settings.Secure.SCREENSAVER_ENABLED, value);
148e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
149e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
150e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public boolean isActivatedOnDock() {
151e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        return getBoolean(Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
152e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                mDreamsActivatedOnDockByDefault);
153e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
154e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
155e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public void setActivatedOnDock(boolean value) {
156e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        logd("setActivatedOnDock(%s)", value);
157e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        setBoolean(Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, value);
158e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
159e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
160e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public boolean isActivatedOnSleep() {
161e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        return getBoolean(Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
162e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                mDreamsActivatedOnSleepByDefault);
163e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
164e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
165e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public void setActivatedOnSleep(boolean value) {
166e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        logd("setActivatedOnSleep(%s)", value);
167e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        setBoolean(Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, value);
168e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
169e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
170e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private boolean getBoolean(String key, boolean def) {
171e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        return Settings.Secure.getInt(mContext.getContentResolver(), key, def ? 1 : 0) == 1;
172e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
173e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
174e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private void setBoolean(String key, boolean value) {
175e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        Settings.Secure.putInt(mContext.getContentResolver(), key, value ? 1 : 0);
176e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
177e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
178e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public void setActiveDream(ComponentName dream) {
179e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        logd("setActiveDream(%s)", dream);
180e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (mDreamManager == null)
181e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return;
182e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        try {
183e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            ComponentName[] dreams = { dream };
184e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            mDreamManager.setDreamComponents(dream == null ? null : dreams);
185e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        } catch (RemoteException e) {
186e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            Log.w(TAG, "Failed to set active dream to " + dream, e);
187e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
188e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
189e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
190e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public ComponentName getActiveDream() {
191e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (mDreamManager == null)
192e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return null;
193e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        try {
194e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            ComponentName[] dreams = mDreamManager.getDreamComponents();
195e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return dreams != null && dreams.length > 0 ? dreams[0] : null;
196e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        } catch (RemoteException e) {
197e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            Log.w(TAG, "Failed to get active dream", e);
198e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return null;
199e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
200e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
201e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
202e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public void launchSettings(DreamInfo dreamInfo) {
203e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        logd("launchSettings(%s)", dreamInfo);
204e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (dreamInfo == null || dreamInfo.settingsComponentName == null)
205e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return;
206e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        mContext.startActivity(new Intent().setComponent(dreamInfo.settingsComponentName));
207e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
208e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
209e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public void preview(DreamInfo dreamInfo) {
210e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        logd("preview(%s)", dreamInfo);
211e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (mDreamManager == null || dreamInfo == null || dreamInfo.componentName == null)
212e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return;
213e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        try {
214e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            mDreamManager.testDream(dreamInfo.componentName);
215e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        } catch (RemoteException e) {
216e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            Log.w(TAG, "Failed to preview " + dreamInfo, e);
217e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
218e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
219e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
220e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    public void startDreaming() {
221e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        logd("startDreaming()");
222e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (mDreamManager == null)
223e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return;
224e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        try {
225e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            mDreamManager.dream();
226e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        } catch (RemoteException e) {
227e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            Log.w(TAG, "Failed to dream", e);
228e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
229e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
230e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
231e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private static ComponentName getDreamComponentName(ResolveInfo resolveInfo) {
232e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (resolveInfo == null || resolveInfo.serviceInfo == null)
233e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return null;
234e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
235e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
236e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
237e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private static ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
238e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (resolveInfo == null
239e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                || resolveInfo.serviceInfo == null
240e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                || resolveInfo.serviceInfo.metaData == null)
241e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return null;
242e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        String cn = null;
243e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        XmlResourceParser parser = null;
244e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        Exception caughtException = null;
245e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        try {
246e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            parser = resolveInfo.serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA);
247e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            if (parser == null) {
248e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " meta-data");
249e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                return null;
250e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            }
251e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
252e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            AttributeSet attrs = Xml.asAttributeSet(parser);
253e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            int type;
254e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
255e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                    && type != XmlPullParser.START_TAG) {
256e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            }
257e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            String nodeName = parser.getName();
258e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            if (!"dream".equals(nodeName)) {
259e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                Log.w(TAG, "Meta-data does not start with dream tag");
260e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler                return null;
261e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            }
262e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.Dream);
263e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            cn = sa.getString(com.android.internal.R.styleable.Dream_settingsActivity);
264e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            sa.recycle();
265e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        } catch (PackageManager.NameNotFoundException|IOException|XmlPullParserException e) {
266e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            caughtException = e;
267e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        } finally {
268e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            if (parser != null) parser.close();
269e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
270e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (caughtException != null) {
271e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            Log.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
272e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return null;
273e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
274e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (cn != null && cn.indexOf('/') < 0) {
275e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            cn = resolveInfo.serviceInfo.packageName + "/" + cn;
276e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
277e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        return cn == null ? null : ComponentName.unflattenFromString(cn);
278e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
279e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
280e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private static void logd(String msg, Object... args) {
281e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        if (DEBUG)
282e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args));
283e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
284e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
285e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    private static class DreamInfoComparator implements Comparator<DreamInfo> {
286e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        private final ComponentName mDefaultDream;
287e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
288e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        public DreamInfoComparator(ComponentName defaultDream) {
289e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            mDefaultDream = defaultDream;
290e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
291e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
292e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        @Override
293e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        public int compare(DreamInfo lhs, DreamInfo rhs) {
294e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return sortKey(lhs).compareTo(sortKey(rhs));
295e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
296e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler
297e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        private String sortKey(DreamInfo di) {
298e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            StringBuilder sb = new StringBuilder();
299e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            sb.append(di.componentName.equals(mDefaultDream) ? '0' : '1');
300e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            sb.append(di.caption);
301e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler            return sb.toString();
302e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler        }
303e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler    }
304e43853ce2fe9a7b90abdc1c51361b70a8393b777Tony Mantler}
305