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