Clamp app widget updates from updatePeriodMillis to a minimum of 30 minutes.
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 8530c35..a2e0ba0a 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -57,6 +57,9 @@
      *
      * <p>This field corresponds to the <code>android:updatePeriodMillis</code> attribute in
      * the AppWidget meta-data file.
+     *
+     * <p class="note"><b>Note:</b> Updates requested with <code>updatePeriodMillis</code>
+     * will not be delivered more than once every 30 minutes.</p>
      */
     public int updatePeriodMillis;
 
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 131e156..78db6f9 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -68,6 +68,7 @@
 
     private static final String SETTINGS_FILENAME = "appwidgets.xml";
     private static final String SETTINGS_TMP_FILENAME = SETTINGS_FILENAME + ".tmp";
+    private static final int MIN_UPDATE_PERIOD = 30 * 60 * 1000; // 30 minutes
 
     /*
      * When identifying a Host or Provider based on the calling process, use the uid field.
@@ -629,9 +630,12 @@
                 Binder.restoreCallingIdentity(token);
             }
             if (!alreadyRegistered) {
+                long period = p.info.updatePeriodMillis;
+                if (period < MIN_UPDATE_PERIOD) {
+                    period = MIN_UPDATE_PERIOD;
+                }
                 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                        SystemClock.elapsedRealtime() + p.info.updatePeriodMillis,
-                        p.info.updatePeriodMillis, p.broadcast);
+                        SystemClock.elapsedRealtime() + period, period, p.broadcast);
             }
         }
     }