OSDN Git Service

am 60d04edf: am e7c9540b: Refresh date display at midnight.
[android-x86/packages-apps-DeskClock.git] / src / com / android / deskclock / DeskClock.java
index 625f03f..e45f38a 100644 (file)
@@ -29,6 +29,7 @@ import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.database.Cursor;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
@@ -94,13 +95,11 @@ public class DeskClock extends Activity {
     // Alarm action for midnight (so we can update the date display).
     private static final String ACTION_MIDNIGHT = "com.android.deskclock.MIDNIGHT";
 
-    // Interval between polls of the weather widget. Its refresh period is
-    // likely to be much longer (~3h), but we want to pick up any changes
-    // within 5 minutes.
-    private final long QUERY_WEATHER_DELAY = 5 * 60 * 1000; // 5 min
+    // Interval between forced polls of the weather widget.
+    private final long QUERY_WEATHER_DELAY = 60 * 60 * 1000; // 1 hr
 
     // Delay before engaging the burn-in protection mode (green-on-black).
-    private final long SCREEN_SAVER_TIMEOUT = 10 * 60 * 1000; // 10 min
+    private final long SCREEN_SAVER_TIMEOUT = 5 * 60 * 1000; // 5 min
 
     // Repositioning delay in screen saver.
     private final long SCREEN_SAVER_MOVE_DELAY = 60 * 1000; // 1 min
@@ -165,9 +164,7 @@ public class DeskClock extends Activity {
     private int mBatteryLevel = -1;
     private boolean mPluggedIn = false;
 
-    private boolean mInDock = false;
-
-    private int mIdleTimeoutEpoch = 0;
+    private boolean mLaunchedFromDock = false;
 
     private Random mRNG;
 
@@ -177,12 +174,23 @@ public class DeskClock extends Activity {
         @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
-            if (Intent.ACTION_DATE_CHANGED.equals(action)) {
+            if (DEBUG) Log.d(LOG_TAG, "mIntentReceiver.onReceive: action=" + action + ", intent=" + intent);
+            if (Intent.ACTION_DATE_CHANGED.equals(action) || ACTION_MIDNIGHT.equals(action)) {
                 refreshDate();
             } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
                 handleBatteryUpdate(
                     intent.getIntExtra("status", BATTERY_STATUS_UNKNOWN),
                     intent.getIntExtra("level", 0));
+            } else if (Intent.ACTION_DOCK_EVENT.equals(action)) {
+                int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, -1);
+                if (DEBUG) Log.d(LOG_TAG, "ACTION_DOCK_EVENT, state=" + state);
+                if (state == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                    if (mLaunchedFromDock) {
+                        // moveTaskToBack(false);
+                        finish();
+                    }
+                    mLaunchedFromDock = false;
+                }
             }
         }
     };
@@ -196,15 +204,21 @@ public class DeskClock extends Activity {
             } else if (m.what == UPDATE_WEATHER_DISPLAY_MSG) {
                 updateWeatherDisplay();
             } else if (m.what == SCREEN_SAVER_TIMEOUT_MSG) {
-                if (m.arg1 == mIdleTimeoutEpoch) {
-                    saveScreen();
-                }
+                saveScreen();
             } else if (m.what == SCREEN_SAVER_MOVE_MSG) {
                 moveScreenSaver();
             }
         }
     };
 
+    private final ContentObserver mContentObserver = new ContentObserver(mHandy) {
+        @Override
+        public void onChange(boolean selfChange) {
+            if (DEBUG) Log.d(LOG_TAG, "content observer notified that weather changed");
+            refreshWeather();
+        }
+    };
+
 
     private void moveScreenSaver() {
         moveScreenSaverTo(-1,-1);
@@ -253,6 +267,14 @@ public class DeskClock extends Activity {
         win.setAttributes(winParams);
     }
 
+    private void scheduleScreenSaver() {
+        // reschedule screen saver
+        mHandy.removeMessages(SCREEN_SAVER_TIMEOUT_MSG);
+        mHandy.sendMessageDelayed(
+            Message.obtain(mHandy, SCREEN_SAVER_TIMEOUT_MSG),
+            SCREEN_SAVER_TIMEOUT);
+    }
+
     private void restoreScreen() {
         if (!mScreenSaverMode) return;
         if (DEBUG) Log.d(LOG_TAG, "restoreScreen");
@@ -261,6 +283,9 @@ public class DeskClock extends Activity {
         doDim(false); // restores previous dim mode
         // policy: update weather info when returning from screen saver
         if (mPluggedIn) requestWeatherDataFetch();
+
+        scheduleScreenSaver();
+
         refreshAll();
     }
 
@@ -325,8 +350,7 @@ public class DeskClock extends Activity {
     private void requestWeatherDataFetch() {
         if (DEBUG) Log.d(LOG_TAG, "forcing the Genie widget to update weather now...");
         sendBroadcast(new Intent(ACTION_GENIE_REFRESH).putExtra("requestWeather", true));
-        // update the display with any new data
-        scheduleWeatherQueryDelayed(5000);
+        // we expect the result to show up in our content observer
     }
 
     private boolean supportsWeather() {
@@ -520,9 +544,19 @@ public class DeskClock extends Activity {
     }
 
     @Override
+    public void onNewIntent(Intent newIntent) {
+        super.onNewIntent(newIntent);
+        if (DEBUG) Log.d(LOG_TAG, "onNewIntent with intent: " + newIntent);
+
+        // update our intent so that we can consult it to determine whether or
+        // not the most recent launch was via a dock event 
+        setIntent(newIntent);
+    }
+
+    @Override
     public void onResume() {
         super.onResume();
-        if (DEBUG) Log.d(LOG_TAG, "onResume");
+        if (DEBUG) Log.d(LOG_TAG, "onResume with intent: " + getIntent());
 
         // reload the date format in case the user has changed settings
         // recently
@@ -531,47 +565,69 @@ public class DeskClock extends Activity {
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_DATE_CHANGED);
         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        filter.addAction(Intent.ACTION_DOCK_EVENT);
         filter.addAction(ACTION_MIDNIGHT);
+        registerReceiver(mIntentReceiver, filter);
 
+        // Listen for updates to weather data
+        Uri weatherNotificationUri = new Uri.Builder()
+            .scheme(android.content.ContentResolver.SCHEME_CONTENT)
+            .authority(WEATHER_CONTENT_AUTHORITY)
+            .path(WEATHER_CONTENT_PATH)
+            .build();
+        getContentResolver().registerContentObserver(
+            weatherNotificationUri, true, mContentObserver);
+
+        // Elaborate mechanism to find out when the day rolls over
         Calendar today = Calendar.getInstance();
+        today.set(Calendar.HOUR_OF_DAY, 0);
+        today.set(Calendar.MINUTE, 0);
+        today.set(Calendar.SECOND, 0);
         today.add(Calendar.DATE, 1);
+        long alarmTimeUTC = today.getTimeInMillis() + today.get(Calendar.ZONE_OFFSET);
         mMidnightIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_MIDNIGHT), 0);
         AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
-        am.setRepeating(AlarmManager.RTC, today.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mMidnightIntent);
-        registerReceiver(mIntentReceiver, filter);
+        am.setRepeating(AlarmManager.RTC, alarmTimeUTC, AlarmManager.INTERVAL_DAY, mMidnightIntent);
+        if (DEBUG) Log.d(LOG_TAG, "set repeating midnight event at "
+            + alarmTimeUTC + " repeating every "
+            + AlarmManager.INTERVAL_DAY + " with intent: " + mMidnightIntent);
+
+        // un-dim when resuming
+        mDimmed = false;
+        doDim(false);
 
-        doDim(false); // un-dim when resuming
         restoreScreen(); // disable screen saver
         refreshAll(); // will schedule periodic weather fetch
 
         setWakeLock(mPluggedIn);
 
-        mIdleTimeoutEpoch++;
-        mHandy.sendMessageDelayed(
-            Message.obtain(mHandy, SCREEN_SAVER_TIMEOUT_MSG, mIdleTimeoutEpoch, 0),
-            SCREEN_SAVER_TIMEOUT);
+        scheduleScreenSaver();
 
         final boolean launchedFromDock
             = getIntent().hasCategory(Intent.CATEGORY_DESK_DOCK);
 
-        if (supportsWeather() && launchedFromDock && !mInDock) {
+        if (supportsWeather() && launchedFromDock && !mLaunchedFromDock) {
             // policy: fetch weather if launched via dock connection
             if (DEBUG) Log.d(LOG_TAG, "Device now docked; forcing weather to refresh right now");
             requestWeatherDataFetch();
         }
 
-        mInDock = launchedFromDock;
+        mLaunchedFromDock = launchedFromDock;
     }
 
     @Override
     public void onPause() {
         if (DEBUG) Log.d(LOG_TAG, "onPause");
 
-        // Turn off the screen saver. (But don't un-dim.)
+        // Turn off the screen saver and cancel any pending timeouts.
+        // (But don't un-dim.)
+        mHandy.removeMessages(SCREEN_SAVER_TIMEOUT_MSG);
         restoreScreen();
 
         // Other things we don't want to be doing in the background.
         unregisterReceiver(mIntentReceiver);
+        getContentResolver().unregisterContentObserver(mContentObserver);
+
         AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
         am.cancel(mMidnightIntent);
         unscheduleWeatherQuery();