146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff/* 246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Copyright (C) 2009 The Android Open Source Project 346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * 446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Licensed under the Apache License, Version 2.0 (the "License"); 546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * you may not use this file except in compliance with the License. 646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * You may obtain a copy of the License at 746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * 846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * http://www.apache.org/licenses/LICENSE-2.0 946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * 1046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Unless required by applicable law or agreed to in writing, software 1146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * distributed under the License is distributed on an "AS IS" BASIS, 1246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * See the License for the specific language governing permissions and 1446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * limitations under the License. 1546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff */ 1646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 1746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffpackage com.android.providers.calendar; 1846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 1946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.app.ListActivity; 2046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.content.ContentResolver; 2146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.database.Cursor; 2246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.os.AsyncTask; 2346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.os.Bundle; 2446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.os.Handler; 25b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErikimport android.provider.CalendarContract; 2646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.widget.ListAdapter; 2746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.widget.SimpleAdapter; 2846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport android.view.Window; 2946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 3046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport java.util.ArrayList; 3146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport java.util.HashMap; 3246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport java.util.List; 3346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffimport java.util.Map; 3446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 3546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff/** 3646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Displays info about all the user's calendars, for debugging. 3746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * 3846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * The info is displayed as a ListActivity, where each entry has the calendar name 3946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * followed by information about the calendar. 4046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff */ 4146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriffpublic class CalendarDebug extends ListActivity { 4246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private static final String[] CALENDARS_PROJECTION = new String[]{ 43b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars._ID, 44b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, 4546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff }; 4646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private static final int INDEX_ID = 0; 4746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private static final int INDEX_DISPLAY_NAME = 1; 4846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 4946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private static final String[] EVENTS_PROJECTION = new String[]{ 50b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events._ID, 5146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff }; 5246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private static final String KEY_TITLE = "title"; 5346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private static final String KEY_TEXT = "text"; 5446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 5546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private ContentResolver mContentResolver; 5646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private ListActivity mActivity; 5746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 5846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff /** 5946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Task to fetch info from the database and display as a ListActivity. 6046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff */ 6146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff private class FetchInfoTask extends AsyncTask<Void, Void, List<Map<String, String>>> { 6246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff /** 6346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Starts spinner while task is running. 6446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * 6546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @see #onPostExecute 6646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @see #doInBackground 6746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff */ 6846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff @Override 6946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff protected void onPreExecute() { 7046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff setProgressBarIndeterminateVisibility(true); 7146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 7246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 7346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff /** 7446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Fetches debugging info from the database 7546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @param params Void 7646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @return a Map for each calendar 7746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff */ 78744fa975b40b24ea7377c0e273f60a7a4d47e2e0RoboErik @Override 7946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff protected List<Map<String, String>> doInBackground(Void... params) { 8046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff Cursor cursor = null; 8146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff // items is the list of items to display in the list. 8246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff List<Map<String, String>> items = new ArrayList<Map<String, String>>(); 8346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff try { 84b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik cursor = mContentResolver.query(CalendarContract.Calendars.CONTENT_URI, 8546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff CALENDARS_PROJECTION, 8646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff null, null /* selectionArgs */, 87b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.DEFAULT_SORT_ORDER); 8846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff if (cursor == null) { 8946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff addItem(items, mActivity.getString(R.string.calendar_info_error), ""); 9046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } else { 9146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff while (cursor.moveToNext()) { 9246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff // Process each calendar 9346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff int id = cursor.getInt(INDEX_ID); 9446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff int eventCount = -1; 9546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff int dirtyCount = -1; 9646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff String displayName = cursor.getString(INDEX_DISPLAY_NAME); 9746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 9846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff // Compute number of events in the calendar 99b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik String where = CalendarContract.Events.CALENDAR_ID + "=" + id; 100744fa975b40b24ea7377c0e273f60a7a4d47e2e0RoboErik Cursor eventCursor = mContentResolver.query( 101744fa975b40b24ea7377c0e273f60a7a4d47e2e0RoboErik CalendarContract.Events.CONTENT_URI, EVENTS_PROJECTION, where, 102744fa975b40b24ea7377c0e273f60a7a4d47e2e0RoboErik null, null); 10346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff try { 10446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff eventCount = eventCursor.getCount(); 10546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } finally { 10646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff eventCursor.close(); 10746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 10846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 10946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff // Compute number of dirty events in the calendar 110b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik String dirtyWhere = CalendarContract.Events.CALENDAR_ID + "=" + id 111b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " AND " + CalendarContract.Events.DIRTY + "=1"; 112744fa975b40b24ea7377c0e273f60a7a4d47e2e0RoboErik Cursor dirtyCursor = mContentResolver.query( 113744fa975b40b24ea7377c0e273f60a7a4d47e2e0RoboErik CalendarContract.Events.CONTENT_URI, EVENTS_PROJECTION, dirtyWhere, 114744fa975b40b24ea7377c0e273f60a7a4d47e2e0RoboErik null, null); 11546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff try { 11646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff dirtyCount = dirtyCursor.getCount(); 11746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } finally { 11846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff dirtyCursor.close(); 11946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 12046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 12146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff // Format the output 12246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff String text; 12346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff if (dirtyCount == 0) { 12446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff text = mActivity.getString(R.string.calendar_info_events, 12546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff eventCount); 12646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } else { 12746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff text = mActivity.getString(R.string.calendar_info_events_dirty, 12846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff eventCount, dirtyCount); 12946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 13046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 13146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff addItem(items, displayName, text); 13246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 13346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 13446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } catch (Exception e) { 13546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff // Want to catch all exceptions. The point of this code is to debug 13646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff // when something bad is happening. 13746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff addItem(items, mActivity.getString(R.string.calendar_info_error), e.toString()); 13846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } finally { 13946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff if (cursor != null) { 14046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff cursor.close(); 14146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 14246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 14346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 14446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff if (items.size() == 0) { 14546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff addItem(items, mActivity.getString(R.string.calendar_info_no_calendars), ""); 14646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 14746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff return items; 14846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 14946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 15046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff /** 15146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Runs on the UI thread to display the debugging info. 15246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * 15346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @param items The info items to display. 15446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @see #onPreExecute 15546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @see #doInBackground 15646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff */ 15746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff @Override 15846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff protected void onPostExecute(List<Map<String, String>> items) { 15946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff setProgressBarIndeterminateVisibility(false); 16046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff ListAdapter adapter = new SimpleAdapter(mActivity, items, 16146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff android.R.layout.simple_list_item_2, new String[]{KEY_TITLE, KEY_TEXT}, 16246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff new int[]{android.R.id.text1, android.R.id.text2}); 16346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 16446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff // Bind to our new adapter. 16546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff setListAdapter(adapter); 16646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 16746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 16846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 169744fa975b40b24ea7377c0e273f60a7a4d47e2e0RoboErik @Override 17046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff protected void onCreate(Bundle savedInstanceState) { 17146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff super.onCreate(savedInstanceState); 17246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 17346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff mActivity = this; 17446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff mContentResolver = getContentResolver(); 17546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff getListView(); // Instantiate, for spinner 17646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff new FetchInfoTask().execute(); 17746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 17846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 17946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff 18046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff /** 18146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * Adds an item to the item map 18246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @param items The item map to update 18346cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @param title Title of the item 18446cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff * @param text Text of the item 18546cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff */ 18646cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff protected void addItem(List<Map<String, String>> items, String title, String text) { 18746cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff Map<String, String> itemMap = new HashMap<String, String>(); 18846cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff itemMap.put(KEY_TITLE, title); 18946cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff itemMap.put(KEY_TEXT, text); 19046cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff items.add(itemMap); 19146cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff } 19246cb0859f11a244e7136f1b92554148cf74fc732Ken Shirriff} 193