CalendarUtils.java revision a7c0390d9c5dd4ff730de505682687fae5f5ced0
1636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden/*
2636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * Copyright (C) 2010 The Android Open Source Project
3636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden *
4636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
5636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * you may not use this file except in compliance with the License.
6636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * You may obtain a copy of the License at
7636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden *
8636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
9636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden *
10636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * Unless required by applicable law or agreed to in writing, software
11636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
12636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * See the License for the specific language governing permissions and
14636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * limitations under the License.
15636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden */
16636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
17636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenpackage com.android.calendar;
18636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
19636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.content.AsyncQueryHandler;
20636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.content.ContentResolver;
21636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.content.ContentValues;
22636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.content.Context;
23636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.content.SharedPreferences;
24636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.database.Cursor;
25a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.CalendarCache;
26636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.text.TextUtils;
27636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.text.format.DateUtils;
28636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.text.format.Time;
29636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport android.util.Log;
30636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
31636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport java.util.Formatter;
32636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport java.util.HashSet;
33636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenimport java.util.Locale;
34636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
35636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden/**
36636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * A class containing utility methods related to Calendar apps.
37636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden *
38636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden * This class is expected to move into the app framework eventually.
39636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden */
40636269c7220a2b12e090cab43a91eb34922eb61fAndy McFaddenpublic class CalendarUtils {
41636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden    private static final boolean DEBUG = false;
42636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden    private static final String TAG = "CalendarUtils";
43636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
44636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden    /**
45636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden     * This class contains methods specific to reading and writing time zone
46636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden     * values.
47636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden     */
48636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden    public static class TimeZoneUtils {
49636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private static final String[] TIMEZONE_TYPE_ARGS = { CalendarCache.TIMEZONE_KEY_TYPE };
50636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private static final String[] TIMEZONE_INSTANCES_ARGS =
51636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                { CalendarCache.TIMEZONE_KEY_INSTANCES };
52636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
53636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private static StringBuilder mSB = new StringBuilder(50);
54636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private static Formatter mF = new Formatter(mSB, Locale.getDefault());
55636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private volatile static boolean mFirstTZRequest = true;
56636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private volatile static boolean mTZQueryInProgress = false;
57636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
58636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private volatile static boolean mUseHomeTZ = false;
59636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private volatile static String mHomeTZ = Time.getCurrentTimezone();
60636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
61636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private static HashSet<Runnable> mTZCallbacks = new HashSet<Runnable>();
62636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private static int mToken = 1;
63636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private static AsyncTZHandler mHandler;
64636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
65636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        // The name of the shared preferences file. This name must be maintained for historical
66636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        // reasons, as it's what PreferenceManager assigned the first time the file was created.
67636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private final String mPrefsName;
68636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
69636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
70636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * This is the key used for writing whether or not a home time zone should
71636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * be used in the Calendar app to the Calendar Preferences.
72636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
73636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public static final String KEY_HOME_TZ_ENABLED = "preferences_home_tz_enabled";
74636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
75636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * This is the key used for writing the time zone that should be used if
76636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * home time zones are enabled for the Calendar app.
77636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
78636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public static final String KEY_HOME_TZ = "preferences_home_tz";
79636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
80636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
81636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * This is a helper class for handling the async queries and updates for the
82636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * time zone settings in Calendar.
83636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
84636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        private class AsyncTZHandler extends AsyncQueryHandler {
85636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            public AsyncTZHandler(ContentResolver cr) {
86636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                super(cr);
87636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
88636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
89636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            @Override
90636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
91636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                synchronized (mTZCallbacks) {
92636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    if (cursor == null) {
93636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        mTZQueryInProgress = false;
94636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        mFirstTZRequest = true;
95636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        return;
96636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    }
97636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
98636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    boolean writePrefs = false;
99636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    // Check the values in the db
100636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    int keyColumn = cursor.getColumnIndexOrThrow(CalendarCache.KEY);
101636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    int valueColumn = cursor.getColumnIndexOrThrow(CalendarCache.VALUE);
102636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    while(cursor.moveToNext()) {
103636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        String key = cursor.getString(keyColumn);
104636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        String value = cursor.getString(valueColumn);
105636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        if (TextUtils.equals(key, CalendarCache.TIMEZONE_KEY_TYPE)) {
106636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                            boolean useHomeTZ = !TextUtils.equals(
107636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                                    value, CalendarCache.TIMEZONE_TYPE_AUTO);
108636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                            if (useHomeTZ != mUseHomeTZ) {
109636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                                writePrefs = true;
110636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                                mUseHomeTZ = useHomeTZ;
111636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                            }
112636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        } else if (TextUtils.equals(
113636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                                key, CalendarCache.TIMEZONE_KEY_INSTANCES_PREVIOUS)) {
114636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                            if (!TextUtils.isEmpty(value) && !TextUtils.equals(mHomeTZ, value)) {
115636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                                writePrefs = true;
116636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                                mHomeTZ = value;
117636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                            }
118636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        }
119636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    }
120636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    cursor.close();
121636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    if (writePrefs) {
122636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        SharedPreferences prefs = getSharedPreferences((Context)cookie, mPrefsName);
123636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        // Write the prefs
124636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        setSharedPreference(prefs, KEY_HOME_TZ_ENABLED, mUseHomeTZ);
125636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        setSharedPreference(prefs, KEY_HOME_TZ, mHomeTZ);
126636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    }
127636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
128636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mTZQueryInProgress = false;
129636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    for (Runnable callback : mTZCallbacks) {
130636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        if (callback != null) {
131636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                            callback.run();
132636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        }
133636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    }
134636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mTZCallbacks.clear();
135636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
136636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
137636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
138636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
139636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
140636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * The name of the file where the shared prefs for Calendar are stored
141636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * must be provided. All activities within an app should provide the
142636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * same preferences name or behavior may become erratic.
143636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
144636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param prefsName
145636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
146636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public TimeZoneUtils(String prefsName) {
147636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            mPrefsName = prefsName;
148636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
149636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
150636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
151636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * Formats a date or a time range according to the local conventions.
152636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
153636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * This formats a date/time range using Calendar's time zone and the
154636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * local conventions for the region of the device.
155636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
156636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * If the {@link DateUtils#FORMAT_UTC} flag is used it will pass in
157636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * the UTC time zone instead.
158636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
159636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param context the context is required only if the time is shown
160636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param startMillis the start time in UTC milliseconds
161636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param endMillis the end time in UTC milliseconds
162636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param flags a bit mask of options See
163636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * {@link DateUtils#formatDateRange(Context, Formatter, long, long, int, String) formatDateRange}
164636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @return a string containing the formatted date/time range.
165636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
166636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public String formatDateRange(Context context, long startMillis,
167636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                long endMillis, int flags) {
168636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            String date;
169636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            String tz;
170636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            if ((flags & DateUtils.FORMAT_UTC) != 0) {
171636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                tz = Time.TIMEZONE_UTC;
172636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            } else {
173636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                tz = getTimeZone(context, null);
174636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
175636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            synchronized (mSB) {
176636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                mSB.setLength(0);
177636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                date = DateUtils.formatDateRange(context, mF, startMillis, endMillis, flags,
178636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        tz).toString();
179636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
180636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            return date;
181636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
182636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
183636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
184636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * Writes a new home time zone to the db.
185636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
186636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * Updates the home time zone in the db asynchronously and updates
187636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * the local cache. Sending a time zone of
188636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * {@link CalendarCache#TIMEZONE_TYPE_AUTO} will cause it to be set
189636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * to the device's time zone. null or empty tz will be ignored.
190636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
191636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param context The calling activity
192636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param timeZone The time zone to set Calendar to, or
193636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * {@link CalendarCache#TIMEZONE_TYPE_AUTO}
194636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
195636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public void setTimeZone(Context context, String timeZone) {
196636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            if (TextUtils.isEmpty(timeZone)) {
197636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                if (DEBUG) {
198636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    Log.d(TAG, "Empty time zone, nothing to be done.");
199636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
200636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                return;
201636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
202636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            boolean updatePrefs = false;
203636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            synchronized (mTZCallbacks) {
204636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                if (CalendarCache.TIMEZONE_TYPE_AUTO.equals(timeZone)) {
205636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    if (mUseHomeTZ) {
206636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        updatePrefs = true;
207636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    }
208636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mUseHomeTZ = false;
209636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                } else {
210636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    if (!mUseHomeTZ || !TextUtils.equals(mHomeTZ, timeZone)) {
211636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        updatePrefs = true;
212636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    }
213636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mUseHomeTZ = true;
214636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mHomeTZ = timeZone;
215636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
216636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
217636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            if (updatePrefs) {
218636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                // Write the prefs
219636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                SharedPreferences prefs = getSharedPreferences(context, mPrefsName);
220636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                setSharedPreference(prefs, KEY_HOME_TZ_ENABLED, mUseHomeTZ);
221636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                setSharedPreference(prefs, KEY_HOME_TZ, mHomeTZ);
222636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
223636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                // Update the db
224636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                ContentValues values = new ContentValues();
225636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                if (mHandler != null) {
226636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mHandler.cancelOperation(mToken);
227636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
228636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
229636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                mHandler = new AsyncTZHandler(context.getContentResolver());
230636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
231636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                // skip 0 so query can use it
232636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                if (++mToken == 0) {
233636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mToken = 1;
234636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
235636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
236636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                // Write the use home tz setting
237636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                values.put(CalendarCache.VALUE, mUseHomeTZ ? CalendarCache.TIMEZONE_TYPE_HOME
238636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        : CalendarCache.TIMEZONE_TYPE_AUTO);
239636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                mHandler.startUpdate(mToken, null, CalendarCache.URI, values, CalendarCache.WHERE,
240636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        TIMEZONE_TYPE_ARGS);
241636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
242636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                // If using a home tz write it to the db
243636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                if (mUseHomeTZ) {
244636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    ContentValues values2 = new ContentValues();
245636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    values2.put(CalendarCache.VALUE, mHomeTZ);
246636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mHandler.startUpdate(mToken, null, CalendarCache.URI, values2,
247636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                            CalendarCache.WHERE, TIMEZONE_INSTANCES_ARGS);
248636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
249636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
250636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
251636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
252636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
253636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * Gets the time zone that Calendar should be displayed in
254636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
255636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * This is a helper method to get the appropriate time zone for Calendar. If this
256636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * is the first time this method has been called it will initiate an asynchronous
257636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * query to verify that the data in preferences is correct. The callback supplied
258636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * will only be called if this query returns a value other than what is stored in
259636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * preferences and should cause the calling activity to refresh anything that
260636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * depends on calling this method.
261636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
262636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param context The calling activity
263636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param callback The runnable that should execute if a query returns new values
264636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @return The string value representing the time zone Calendar should display
265636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
266636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public String getTimeZone(Context context, Runnable callback) {
267636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            synchronized (mTZCallbacks){
268636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                if (mFirstTZRequest) {
269636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mTZQueryInProgress = true;
270636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mFirstTZRequest = false;
271636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
272636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    SharedPreferences prefs = getSharedPreferences(context, mPrefsName);
273636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mUseHomeTZ = prefs.getBoolean(KEY_HOME_TZ_ENABLED, false);
274636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mHomeTZ = prefs.getString(KEY_HOME_TZ, Time.getCurrentTimezone());
275636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
276636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    // When the async query returns it should synchronize on
277636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    // mTZCallbacks, update mUseHomeTZ, mHomeTZ, and the
278636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    // preferences, set mTZQueryInProgress to false, and call all
279636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    // the runnables in mTZCallbacks.
280636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    if (mHandler == null) {
281636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                        mHandler = new AsyncTZHandler(context.getContentResolver());
282636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    }
283636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mHandler.startQuery(0, context, CalendarCache.URI, CalendarCache.POJECTION,
284636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                            null, null, null);
285636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
286636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                if (mTZQueryInProgress) {
287636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mTZCallbacks.add(callback);
288636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
289636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
290636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            return mUseHomeTZ ? mHomeTZ : Time.getCurrentTimezone();
291636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
292636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
293636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
294636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * Forces a query of the database to check for changes to the time zone.
295636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * This should be called if another app may have modified the db. If a
296636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * query is already in progress the callback will be added to the list
297636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * of callbacks to be called when it returns.
298636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
299636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param context The calling activity
300636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param callback The runnable that should execute if a query returns
301636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *            new values
302636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
303636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public void forceDBRequery(Context context, Runnable callback) {
304636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            synchronized (mTZCallbacks){
305636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                if (mTZQueryInProgress) {
306636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    mTZCallbacks.add(callback);
307636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                    return;
308636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                }
309636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                mFirstTZRequest = true;
310636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden                getTimeZone(context, callback);
311636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            }
312636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
313636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden    }
314636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
315636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
316636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * A helper method for writing a String value to the preferences
317636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * asynchronously.
318636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
319636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param context A context with access to the correct preferences
320636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param key The preference to write to
321636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param value The value to write
322636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
323636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public static void setSharedPreference(SharedPreferences prefs, String key, String value) {
324636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden//            SharedPreferences prefs = getSharedPreferences(context);
325636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            SharedPreferences.Editor editor = prefs.edit();
326636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            editor.putString(key, value);
327636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            editor.apply();
328636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
329636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
330636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /**
331636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * A helper method for writing a boolean value to the preferences
332636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * asynchronously.
333636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         *
334636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param context A context with access to the correct preferences
335636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param key The preference to write to
336636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         * @param value The value to write
337636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden         */
338636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public static void setSharedPreference(SharedPreferences prefs, String key, boolean value) {
339636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden//            SharedPreferences prefs = getSharedPreferences(context, prefsName);
340636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            SharedPreferences.Editor editor = prefs.edit();
341636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            editor.putBoolean(key, value);
342636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            editor.apply();
343636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
344636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden
345636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        /** Return a properly configured SharedPreferences instance */
346636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        public static SharedPreferences getSharedPreferences(Context context, String prefsName) {
347636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden            return context.getSharedPreferences(prefsName, Context.MODE_PRIVATE);
348636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden        }
349636269c7220a2b12e090cab43a91eb34922eb61fAndy McFadden}
350