Home | History | Annotate | Download | only in settings
      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.settings;
     18 
     19 import static android.provider.Settings.Secure.SCREENSAVER_COMPONENT;
     20 
     21 import android.app.AlertDialog;
     22 import android.content.Context;
     23 import android.content.ComponentName;
     24 import android.content.ContentResolver;
     25 import android.content.DialogInterface;
     26 import android.content.Intent;
     27 import android.content.pm.ActivityInfo;
     28 import android.content.pm.ApplicationInfo;
     29 import android.content.pm.ComponentInfo;
     30 import android.content.pm.PackageManager;
     31 import android.content.pm.ResolveInfo;
     32 import android.content.res.Resources;
     33 import android.os.Bundle;
     34 import android.os.RemoteException;
     35 import android.os.ServiceManager;
     36 import android.preference.Preference;
     37 import android.provider.Settings;
     38 import android.service.dreams.IDreamManager;
     39 import android.util.AttributeSet;
     40 import android.util.Log;
     41 import android.view.Gravity;
     42 import android.view.LayoutInflater;
     43 import android.view.View;
     44 import android.view.ViewGroup;
     45 import android.widget.ArrayAdapter;
     46 import android.widget.ListView;
     47 import android.widget.BaseAdapter;
     48 import android.widget.ImageView;
     49 import android.widget.ListAdapter;
     50 import android.widget.TextView;
     51 
     52 import java.text.Collator;
     53 import java.util.ArrayList;
     54 import java.util.Collections;
     55 import java.util.Comparator;
     56 import java.util.List;
     57 
     58 public class DreamComponentPreference extends Preference {
     59     private static final String TAG = "DreamComponentPreference";
     60 
     61     private static final boolean SHOW_DOCK_APPS = false;
     62     private static final boolean SHOW_DREAM_SERVICES = true;
     63     private static final boolean SHOW_DREAM_ACTIVITIES = false;
     64 
     65     private final PackageManager pm;
     66     private final ContentResolver resolver;
     67     private final Collator   sCollator = Collator.getInstance();
     68 
     69     public DreamComponentPreference(Context context, AttributeSet attrs) {
     70         super(context, attrs);
     71         pm = getContext().getPackageManager();
     72         resolver = getContext().getContentResolver();
     73 
     74         refreshFromSettings();
     75     }
     76 
     77     private void refreshFromSettings() {
     78         ComponentName cn = null;
     79         IDreamManager dm = IDreamManager.Stub.asInterface(
     80                 ServiceManager.getService("dreams"));
     81         try {
     82             cn = dm.getDreamComponent();
     83         } catch (RemoteException ex) {
     84             setSummary("(unknown)");
     85             return;
     86         }
     87 
     88         try {
     89             setSummary(pm.getActivityInfo(cn, 0).loadLabel(pm));
     90         } catch (PackageManager.NameNotFoundException ex) {
     91             try {
     92                 setSummary(pm.getServiceInfo(cn, 0).loadLabel(pm));
     93             } catch (PackageManager.NameNotFoundException ex2) {
     94                 setSummary("(unknown)");
     95             }
     96         }
     97     }
     98 
     99     // Group by package, then by name.
    100     Comparator<ResolveInfo> sResolveInfoComparator = new Comparator<ResolveInfo>() {
    101         @Override
    102         public int compare(ResolveInfo a, ResolveInfo b) {
    103             CharSequence sa, sb;
    104 
    105             ApplicationInfo aia = a.activityInfo != null ? a.activityInfo.applicationInfo : a.serviceInfo.applicationInfo;
    106             ApplicationInfo aib = b.activityInfo != null ? b.activityInfo.applicationInfo : b.serviceInfo.applicationInfo;
    107 
    108             if (!aia.equals(aib)) {
    109                 sa = pm.getApplicationLabel(aia);
    110                 sb = pm.getApplicationLabel(aib);
    111             } else {
    112                 sa = a.loadLabel(pm);
    113                 if (sa == null) {
    114                     sa = (a.activityInfo != null) ? a.activityInfo.name : a.serviceInfo.name;
    115                 }
    116                 sb = b.loadLabel(pm);
    117                 if (sb == null) {
    118                     sb = (b.activityInfo != null) ? b.activityInfo.name : b.serviceInfo.name;
    119                 }
    120             }
    121             return sCollator.compare(sa.toString(), sb.toString());
    122         }
    123     };
    124 
    125     public class DreamListAdapter extends BaseAdapter implements ListAdapter {
    126         private ArrayList<ResolveInfo> results;
    127         private final LayoutInflater inflater;
    128 
    129         public DreamListAdapter(Context context) {
    130             Intent choosy = new Intent(Intent.ACTION_MAIN)
    131                         .addCategory("android.intent.category.DREAM");
    132 
    133             inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    134 
    135             results = new ArrayList<ResolveInfo>();
    136 
    137             if (SHOW_DREAM_ACTIVITIES) {
    138                 results.addAll(pm.queryIntentActivities(choosy, PackageManager.GET_META_DATA));
    139             }
    140 
    141             if (SHOW_DREAM_SERVICES) {
    142                 results.addAll(pm.queryIntentServices(choosy, PackageManager.GET_META_DATA));
    143             }
    144 
    145             // Group by package
    146             Collections.sort(results, sResolveInfoComparator);
    147 
    148             if (SHOW_DOCK_APPS) {
    149                 choosy = new Intent(Intent.ACTION_MAIN)
    150                             .addCategory(Intent.CATEGORY_DESK_DOCK);
    151 
    152                 List<ResolveInfo> dockApps = pm.queryIntentActivities(choosy, 0);
    153                 for (ResolveInfo app : dockApps) {
    154                     // do not insert duplicate packages
    155                     int pos = Collections.binarySearch(results, app, sResolveInfoComparator);
    156                     if (pos < 0) {
    157                         results.add(-1-pos, app);
    158                     }
    159                 }
    160             }
    161         }
    162 
    163         @Override
    164         public int getCount() {
    165             return results.size();
    166         }
    167 
    168         @Override
    169         public Object getItem(int position) {
    170             return results.get(position);
    171         }
    172 
    173         @Override
    174         public long getItemId (int position) {
    175             return (long) position;
    176         }
    177 
    178         private CharSequence loadDescription(ResolveInfo ri) {
    179             CharSequence desc = null;
    180             if (ri != null) {
    181                 Bundle metaData = (ri.activityInfo != null) ? ri.activityInfo.metaData : ri.serviceInfo.metaData;
    182                 Log.d(TAG, "loadDescription: ri=" + ri + " metaData=" + metaData);
    183                 if (metaData != null) {
    184                     desc = metaData.getCharSequence("android.screensaver.description");
    185                     Log.d(TAG, "loadDescription: desc=" + desc);
    186                     if (desc != null) {
    187                         desc = desc.toString().trim();
    188                     }
    189                 }
    190             }
    191             return desc;
    192         }
    193 
    194         @Override
    195         public View getView(int position, View convertView, ViewGroup parent) {
    196             View row = (convertView != null)
    197                 ? convertView
    198                 : inflater.inflate(R.layout.dream_picker_row, parent, false);
    199             ResolveInfo ri = results.get(position);
    200             ((TextView)row.findViewById(R.id.title)).setText(ri.loadLabel(pm));
    201             ((ImageView)row.findViewById(R.id.icon)).setImageDrawable(ri.loadIcon(pm));
    202             return row;
    203         }
    204     }
    205 
    206     @Override
    207     protected void onClick() {
    208         final DreamListAdapter list = new DreamListAdapter(getContext());
    209         AlertDialog alert = new AlertDialog.Builder(getContext())
    210             .setAdapter(
    211                 list,
    212                 new DialogInterface.OnClickListener() {
    213                     @Override
    214                     public void onClick(DialogInterface dialog, int which) {
    215                         ResolveInfo ri = (ResolveInfo)list.getItem(which);
    216                         String pn = (ri.activityInfo != null) ? ri.activityInfo.applicationInfo.packageName
    217                                 : ri.serviceInfo.applicationInfo.packageName;
    218                         String n = (ri.activityInfo != null) ? ri.activityInfo.name : ri.serviceInfo.name;
    219                         ComponentName cn = new ComponentName(pn, n);
    220 
    221                         setSummary(ri.loadLabel(pm));
    222                         //getContext().startActivity(intent);
    223 
    224                         IDreamManager dm = IDreamManager.Stub.asInterface(
    225                                 ServiceManager.getService("dreams"));
    226                         try {
    227                             dm.setDreamComponent(cn);
    228                         } catch (RemoteException ex) {
    229                             // too bad, so sad, oh mom, oh dad
    230                         }
    231                     }
    232                 })
    233             .create();
    234         alert.show();
    235     }
    236 }
    237