Merge "Add missing bullet points in javadoc of InputMethodManager.java"
diff --git a/api/current.txt b/api/current.txt
index 6fdd161..f4bfced 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9065,6 +9065,7 @@
     method public int getMinimumWidth();
     method public abstract int getOpacity();
     method public boolean getPadding(android.graphics.Rect);
+    method public int getResolvedLayoutDirectionSelf();
     method public int[] getState();
     method public android.graphics.Region getTransparentRegion();
     method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
@@ -9099,6 +9100,10 @@
     method public abstract void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
 
+  public static abstract interface Drawable.Callback2 implements android.graphics.drawable.Drawable.Callback {
+    method public abstract int getResolvedLayoutDirection(android.graphics.drawable.Drawable);
+  }
+
   public static abstract class Drawable.ConstantState {
     ctor public Drawable.ConstantState();
     method public abstract int getChangingConfigurations();
@@ -23109,7 +23114,7 @@
     method public void recycle();
   }
 
-  public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
+  public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.graphics.drawable.Drawable.Callback2 android.view.KeyEvent.Callback {
     ctor public View(android.content.Context);
     ctor public View(android.content.Context, android.util.AttributeSet);
     ctor public View(android.content.Context, android.util.AttributeSet, int);
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index 04cf1a3..5b94784 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -36,6 +36,7 @@
 
     public final NetworkTemplate template;
     public int cycleDay;
+    public String cycleTimezone;
     public long warningBytes;
     public long limitBytes;
     public long lastWarningSnooze;
@@ -44,15 +45,18 @@
 
     private static final long DEFAULT_MTU = 1500;
 
-    public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes,
-            long limitBytes, boolean metered) {
-        this(template, cycleDay, warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, metered);
+    public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
+            long warningBytes, long limitBytes, boolean metered) {
+        this(template, cycleDay, cycleTimezone, warningBytes, limitBytes, SNOOZE_NEVER,
+                SNOOZE_NEVER, metered);
     }
 
-    public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes,
-            long limitBytes, long lastWarningSnooze, long lastLimitSnooze, boolean metered) {
+    public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
+            long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze,
+            boolean metered) {
         this.template = checkNotNull(template, "missing NetworkTemplate");
         this.cycleDay = cycleDay;
+        this.cycleTimezone = checkNotNull(cycleTimezone, "missing cycleTimezone");
         this.warningBytes = warningBytes;
         this.limitBytes = limitBytes;
         this.lastWarningSnooze = lastWarningSnooze;
@@ -63,6 +67,7 @@
     public NetworkPolicy(Parcel in) {
         template = in.readParcelable(null);
         cycleDay = in.readInt();
+        cycleTimezone = in.readString();
         warningBytes = in.readLong();
         limitBytes = in.readLong();
         lastWarningSnooze = in.readLong();
@@ -70,10 +75,11 @@
         metered = in.readInt() != 0;
     }
 
-    /** {@inheritDoc} */
+    @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeParcelable(template, flags);
         dest.writeInt(cycleDay);
+        dest.writeString(cycleTimezone);
         dest.writeLong(warningBytes);
         dest.writeLong(limitBytes);
         dest.writeLong(lastWarningSnooze);
@@ -81,7 +87,7 @@
         dest.writeInt(metered ? 1 : 0);
     }
 
-    /** {@inheritDoc} */
+    @Override
     public int describeContents() {
         return 0;
     }
@@ -112,7 +118,7 @@
         lastLimitSnooze = SNOOZE_NEVER;
     }
 
-    /** {@inheritDoc} */
+    @Override
     public int compareTo(NetworkPolicy another) {
         if (another == null || another.limitBytes == LIMIT_DISABLED) {
             // other value is missing or disabled; we win
@@ -127,8 +133,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(template, cycleDay, warningBytes, limitBytes, lastWarningSnooze,
-                lastLimitSnooze, metered);
+        return Objects.hashCode(template, cycleDay, cycleTimezone, warningBytes, limitBytes,
+                lastWarningSnooze, lastLimitSnooze, metered);
     }
 
     @Override
@@ -139,6 +145,7 @@
                     && limitBytes == other.limitBytes
                     && lastWarningSnooze == other.lastWarningSnooze
                     && lastLimitSnooze == other.lastLimitSnooze && metered == other.metered
+                    && Objects.equal(cycleTimezone, other.cycleTimezone)
                     && Objects.equal(template, other.template);
         }
         return false;
@@ -146,17 +153,19 @@
 
     @Override
     public String toString() {
-        return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", warningBytes="
-                + warningBytes + ", limitBytes=" + limitBytes + ", lastWarningSnooze="
-                + lastWarningSnooze + ", lastLimitSnooze=" + lastLimitSnooze + ", metered="
-                + metered;
+        return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", cycleTimezone="
+                + cycleTimezone + ", warningBytes=" + warningBytes + ", limitBytes=" + limitBytes
+                + ", lastWarningSnooze=" + lastWarningSnooze + ", lastLimitSnooze="
+                + lastLimitSnooze + ", metered=" + metered;
     }
 
     public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
+        @Override
         public NetworkPolicy createFromParcel(Parcel in) {
             return new NetworkPolicy(in);
         }
 
+        @Override
         public NetworkPolicy[] newArray(int size) {
             return new NetworkPolicy[size];
         }
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 9d253c7..7173751 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -131,7 +131,7 @@
      * @hide
      */
     public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
-        final Time now = new Time(Time.TIMEZONE_UTC);
+        final Time now = new Time(policy.cycleTimezone);
         now.set(currentTime);
 
         // first, find cycle boundary for current month
@@ -157,7 +157,7 @@
 
     /** {@hide} */
     public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
-        final Time now = new Time(Time.TIMEZONE_UTC);
+        final Time now = new Time(policy.cycleTimezone);
         now.set(currentTime);
 
         // first, find cycle boundary for current month
@@ -183,7 +183,7 @@
 
     /**
      * Snap to the cycle day for the current month given; when cycle day doesn't
-     * exist, it snaps to 1st of following month.
+     * exist, it snaps to last second of current month.
      *
      * @hide
      */
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 07ae93b..3001ea1 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -193,9 +193,6 @@
         }
     }
 
-    /**
-     * @hide
-     */
     @Override
     public int getResolvedLayoutDirection(Drawable dr) {
         return (dr == mDrawable) ?
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index e298acb..3bc4f7f 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -910,9 +910,6 @@
         }
     }
 
-    /**
-     * @hide
-     */
     @Override
     public int getResolvedLayoutDirection(Drawable who) {
         return (who == mProgressDrawable || who == mIndeterminateDrawable) ?
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 4c89218..b8db848 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1214,7 +1214,7 @@
             if (imm != null) imm.restartInput(this);
         }
 
-        if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+        if (mEditor != null) getEditor().invalidateTextDisplayList();
         prepareCursorControllers();
 
         // start or stop the cursor blinking as appropriate
@@ -2328,7 +2328,7 @@
     public void setHighlightColor(int color) {
         if (mHighlightColor != color) {
             mHighlightColor = color;
-            if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+            if (mEditor != null) getEditor().invalidateTextDisplayList();
             invalidate();
         }
     }
@@ -2349,7 +2349,7 @@
         mShadowDx = dx;
         mShadowDy = dy;
 
-        if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+        if (mEditor != null) getEditor().invalidateTextDisplayList();
         invalidate();
     }
 
@@ -2841,7 +2841,7 @@
             }
         }
         if (inval) {
-            if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+            if (mEditor != null) getEditor().invalidateTextDisplayList();
             invalidate();
         }
     }
@@ -3334,7 +3334,7 @@
 
         // Invalidate display list if hint will be used
         if (mEditor != null && mText.length() == 0 && mHint != null) {
-            getEditor().mTextDisplayListIsValid = false;
+            getEditor().invalidateTextDisplayList();
         }
     }
 
@@ -4396,9 +4396,6 @@
         }
     }
 
-    /**
-     * @hide
-     */
     @Override
     public int getResolvedLayoutDirection(Drawable who) {
         if (who == null) return View.LAYOUT_DIRECTION_LTR;
@@ -4429,13 +4426,13 @@
                     if (dr.mDrawableStart != null) dr.mDrawableStart.mutate().setAlpha(alpha);
                     if (dr.mDrawableEnd != null) dr.mDrawableEnd.mutate().setAlpha(alpha);
                 }
-                if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+                if (mEditor != null) getEditor().invalidateTextDisplayList();
             }
             return true;
         }
 
         if (mCurrentAlpha != 255) {
-            if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+            if (mEditor != null) getEditor().invalidateTextDisplayList();
         }
         mCurrentAlpha = 255;
         return false;
@@ -6292,7 +6289,7 @@
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
-        if (changed && mEditor != null) getEditor().mTextDisplayListIsValid = false;
+        if (changed && mEditor != null) getEditor().invalidateTextDisplayList();
     }
 
     private boolean isShowingHint() {
@@ -7130,7 +7127,7 @@
             } else {
                 ims.mContentChanged = true;
             }
-            if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+            if (mEditor != null) getEditor().invalidateTextDisplayList();
         }
 
         if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
@@ -8277,7 +8274,7 @@
             if (getEditor().mPositionListener != null) {
                 getEditor().mPositionListener.onScrollChanged();
             }
-            getEditor().mTextDisplayListIsValid = false;
+            getEditor().invalidateTextDisplayList();
         }
     }
 
@@ -11303,7 +11300,6 @@
         InputMethodState mInputMethodState;
 
         DisplayList mTextDisplayList;
-        boolean mTextDisplayListIsValid;
 
         boolean mFrozenWithFocus;
         boolean mSelectionMoved;
@@ -11392,9 +11388,7 @@
                 removeCallbacks(mShowSuggestionRunnable);
             }
 
-            if (mTextDisplayList != null) {
-                mTextDisplayList.invalidate();
-            }
+            invalidateTextDisplayList();
 
             if (mSpellChecker != null) {
                 mSpellChecker.closeSession();
@@ -11551,7 +11545,7 @@
 
         void sendOnTextChanged(int start, int after) {
             updateSpellCheckSpans(start, start + after, false);
-            mTextDisplayListIsValid = false;
+            invalidateTextDisplayList();
 
             // Hide the controllers as soon as text is modified (typing, procedural...)
             // We do not hide the span controllers, since they can be added when a new text is
@@ -11708,8 +11702,7 @@
             layout.drawBackground(canvas, highlight, mHighlightPaint, cursorOffsetVertical,
                     firstLine, lastLine);
 
-            if (mTextDisplayList == null || !mTextDisplayList.isValid() ||
-                    !mTextDisplayListIsValid) {
+            if (mTextDisplayList == null || !mTextDisplayList.isValid()) {
                 if (mTextDisplayList == null) {
                     mTextDisplayList = getHardwareRenderer().createDisplayList("Text");
                 }
@@ -11726,7 +11719,6 @@
                 } finally {
                     hardwareCanvas.onPostDraw();
                     mTextDisplayList.end();
-                    mTextDisplayListIsValid = true;
                 }
             }
             canvas.translate(mScrollX, mScrollY);
@@ -11744,6 +11736,10 @@
             if (translate) canvas.translate(0, -cursorOffsetVertical);
         }
 
+        private void invalidateTextDisplayList() {
+            if (mTextDisplayList != null) mTextDisplayList.invalidate();
+        }
+
         private void updateCursorsPositions() {
             if (mCursorDrawableRes == 0) {
                 mCursorCount = 0;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
index 7233e7f..3ec9031 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
@@ -42,17 +42,13 @@
     public int mSleepTime = 2 * 60 * 1000;
     public String mReconnectSsid = "securenetdhcp";
     public String mReconnectPassword = "androidwifi";
+    public boolean mWifiOnlyFlag = false;
 
     @Override
     public TestSuite getAllTests() {
         TestSuite suite = new InstrumentationTestSuite(this);
-        if (!UtilHelper.isWifiOnly(getContext())) {
-            suite.addTestSuite(WifiApStress.class);
-            suite.addTestSuite(WifiStressTest.class);
-        } else {
-            // only the wifi stress tests
-            suite.addTestSuite(WifiStressTest.class);
-        }
+        suite.addTestSuite(WifiApStress.class);
+        suite.addTestSuite(WifiStressTest.class);
         return suite;
     }
 
@@ -64,13 +60,11 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        if (!UtilHelper.isWifiOnly(getContext())) {
-            String valueStr = (String) icicle.get("softap_iterations");
-            if (valueStr != null) {
-                int iteration = Integer.parseInt(valueStr);
-                if (iteration > 0) {
-                    mSoftapIterations = iteration;
-                }
+        String valueStr = (String) icicle.get("softap_iterations");
+        if (valueStr != null) {
+            int iteration = Integer.parseInt(valueStr);
+            if (iteration > 0) {
+                mSoftapIterations = iteration;
             }
         }
 
@@ -107,5 +101,10 @@
                 mSleepTime = 1000 * sleepTime;
             }
         }
+
+        String wifiOnlyFlag = (String) icicle.get("wifi-only");
+        if (wifiOnlyFlag != null) {
+            mWifiOnlyFlag = true;
+        }
     }
 }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
index 9c1922f..b94306a 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
@@ -35,23 +35,13 @@
  */
 
 public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
-    public String TEST_SSID = null;
+    public boolean mWifiOnlyFlag = false;
+    public String mTestSsid = null;
 
     @Override
     public TestSuite getAllTests() {
         TestSuite suite = new InstrumentationTestSuite(this);
-        if (!UtilHelper.isWifiOnly(getContext())) {
-            suite.addTestSuite(ConnectivityManagerMobileTest.class);
-        } else {
-            // create a new test suite
-            suite.setName("ConnectivityManagerWifiOnlyFunctionalTests");
-            String[] methodNames = {"testConnectToWifi", "testConnectToWifWithKnownAP",
-                    "testDisconnectWifi", "testWifiStateChange"};
-            Class<ConnectivityManagerMobileTest> testClass = ConnectivityManagerMobileTest.class;
-            for (String method: methodNames) {
-                suite.addTest(TestSuite.createTest(testClass, method));
-            }
-        }
+        suite.addTestSuite(ConnectivityManagerMobileTest.class);
         suite.addTestSuite(WifiConnectionTest.class);
         return suite;
     }
@@ -66,7 +56,11 @@
         super.onCreate(icicle);
         String testSSID = (String) icicle.get("ssid");
         if (testSSID != null) {
-            TEST_SSID = testSSID;
+            mTestSsid = testSSID;
+        }
+        String wifiOnlyFlag = (String) icicle.get("wifi-only");
+        if (wifiOnlyFlag != null) {
+            mWifiOnlyFlag = true;
         }
     }
 }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
deleted file mode 100644
index b9fe6ed..0000000
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.connectivitymanagertest;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.util.Log;
-
-public class UtilHelper {
-
-    private static Boolean mIsWifiOnly = null;
-    private static final Object sLock = new Object();
-
-    /**
-     * Return true if device is a wifi only device.
-     */
-    public static boolean isWifiOnly(Context context) {
-        synchronized (sLock) {
-            // cache the result from pkgMgr statically. It will never change, since its a
-            // device configuration setting
-            if (mIsWifiOnly == null) {
-                PackageManager pkgMgr = context.getPackageManager();
-                mIsWifiOnly = Boolean.valueOf(!pkgMgr
-                        .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
-                        && pkgMgr.hasSystemFeature(PackageManager.FEATURE_WIFI));
-                String deviceType = mIsWifiOnly ? "wifi-only" : "telephony";
-                Log.d("ConnectivityManagerTest", String.format("detected a %s device", deviceType));
-            }
-        }
-        return mIsWifiOnly;
-    }
-}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index 52326d5..bf188d3 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -31,16 +31,15 @@
 import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
 import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
 import com.android.connectivitymanagertest.NetworkState;
-import com.android.connectivitymanagertest.UtilHelper;
 
 public class ConnectivityManagerMobileTest extends
         ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
     private static final String LOG_TAG = "ConnectivityManagerMobileTest";
 
-    private String TEST_ACCESS_POINT;
+    private String mTestAccessPoint;
     private ConnectivityManagerTestActivity cmActivity;
     private WakeLock wl;
-    private boolean mIsWifiOnlyDevice;
+    private boolean mWifiOnlyFlag;
 
     public ConnectivityManagerMobileTest() {
         super(ConnectivityManagerTestActivity.class);
@@ -52,7 +51,9 @@
         cmActivity = getActivity();
         ConnectivityManagerTestRunner mRunner =
                 (ConnectivityManagerTestRunner)getInstrumentation();
-        TEST_ACCESS_POINT = mRunner.TEST_SSID;
+        mTestAccessPoint = mRunner.mTestSsid;
+        mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
+
         PowerManager pm = (PowerManager)getInstrumentation().
                 getContext().getSystemService(Context.POWER_SERVICE);
         wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "CMWakeLock");
@@ -63,8 +64,8 @@
             log("airplane is not disabled, disable it.");
             cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
         }
-        mIsWifiOnlyDevice = UtilHelper.isWifiOnly(mRunner.getTargetContext());
-        if (!mIsWifiOnlyDevice) {
+
+        if (!mWifiOnlyFlag) {
             if (!cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
                     ConnectivityManagerTestActivity.LONG_TIMEOUT)) {
                 // Note: When the test fails in setUp(), tearDown is not called. In that case,
@@ -113,6 +114,10 @@
     //              event should be expected.
     @LargeTest
     public void test3GToWifiNotification() {
+        if (mWifiOnlyFlag) {
+            Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+            return;
+        }
         // Enable Wi-Fi to avoid initial UNKNOWN state
         cmActivity.enableWifi();
         sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
@@ -159,9 +164,9 @@
     // Test case 2: test connection to a given AP
     @LargeTest
     public void testConnectToWifi() {
-        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+        assertNotNull("SSID is null", mTestAccessPoint);
         NetworkInfo networkInfo;
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             //Prepare for connectivity verification
             networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
             cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
@@ -172,15 +177,15 @@
                 NetworkState.TO_CONNECTION, State.CONNECTED);
 
         // Enable Wifi and connect to a test access point
-        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
-                cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        assertTrue("failed to connect to " + mTestAccessPoint,
+                cmActivity.connectToWifi(mTestAccessPoint));
 
         assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         log("wifi state is enabled");
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
         }
@@ -192,7 +197,7 @@
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
                 log("Mobile state transition validation failed.");
                 log("reason: " +
@@ -205,10 +210,10 @@
     // Test case 3: connect to Wifi with known AP
     @LargeTest
     public void testConnectToWifWithKnownAP() {
-        assertNotNull("SSID is null", TEST_ACCESS_POINT);
-        // Connect to TEST_ACCESS_POINT
-        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
-                cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        assertNotNull("SSID is null", mTestAccessPoint);
+        // Connect to mTestAccessPoint
+        assertTrue("failed to connect to " + mTestAccessPoint,
+                cmActivity.connectToWifi(mTestAccessPoint));
         assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
@@ -227,13 +232,13 @@
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
                 State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
         }
 
         NetworkInfo networkInfo;
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             //Prepare for connectivity state verification
             networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
             cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
@@ -253,7 +258,7 @@
         // Wait for Wifi to be connected and mobile to be disconnected
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
         }
@@ -270,11 +275,11 @@
     // Test case 4:  test disconnect Wifi
     @LargeTest
     public void testDisconnectWifi() {
-        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+        assertNotNull("SSID is null", mTestAccessPoint);
 
         // connect to Wifi
-        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
-                   cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        assertTrue("failed to connect to " + mTestAccessPoint,
+                   cmActivity.connectToWifi(mTestAccessPoint));
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
             ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -283,7 +288,7 @@
         sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
 
         NetworkInfo networkInfo;
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
             cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
                                                   networkInfo.getState(),
@@ -299,7 +304,7 @@
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
         }
@@ -311,7 +316,7 @@
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
                 log("Mobile state transition validation failed.");
                 log("reason: " +
@@ -324,6 +329,10 @@
     // Test case 5: test connectivity from 3G to airplane mode, then to 3G again
     @LargeTest
     public void testDataConnectionWith3GToAmTo3G() {
+        if (mWifiOnlyFlag) {
+            Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+            return;
+        }
         //Prepare for state verification
         NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
         cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
@@ -340,7 +349,9 @@
 
         networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
         assertEquals(State.DISCONNECTED, networkInfo.getState());
-
+        // wait until mobile is turn off
+        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
             log("Mobile state transition validation failed.");
             log("reason: " +
@@ -382,13 +393,17 @@
     // Test case 6: test connectivity with airplane mode Wifi connected
     @LargeTest
     public void testDataConnectionOverAMWithWifi() {
-        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+        if (mWifiOnlyFlag) {
+            Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+            return;
+        }
+        assertNotNull("SSID is null", mTestAccessPoint);
         // Eanble airplane mode
         log("Enable airplane mode");
         cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
 
         NetworkInfo networkInfo;
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
             networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
@@ -402,8 +417,8 @@
                                               NetworkState.TO_CONNECTION, State.CONNECTED);
 
         // Connect to Wifi
-        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
-                   cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        assertTrue("failed to connect to " + mTestAccessPoint,
+                   cmActivity.connectToWifi(mTestAccessPoint));
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                             ConnectivityManagerTestActivity.LONG_TIMEOUT));
 
@@ -414,7 +429,7 @@
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue("State validation failed", false);
         }
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
                 log("state validation for Mobile failed");
                 log("reason: " +
@@ -428,11 +443,15 @@
     // Test case 7: test connectivity while transit from Wifi->AM->Wifi
     @LargeTest
     public void testDataConnectionWithWifiToAMToWifi () {
-        // Connect to TEST_ACCESS_POINT
-        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+        if (mWifiOnlyFlag) {
+            Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+            return;
+        }
+        // Connect to mTestAccessPoint
+        assertNotNull("SSID is null", mTestAccessPoint);
         // Connect to Wifi
-        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
-                cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        assertTrue("failed to connect to " + mTestAccessPoint,
+                cmActivity.connectToWifi(mTestAccessPoint));
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -466,7 +485,7 @@
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                             ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        if (!mIsWifiOnlyDevice) {
+        if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
         }
@@ -483,10 +502,10 @@
     // Test case 8: test wifi state change while connecting/disconnecting to/from an AP
     @LargeTest
     public void testWifiStateChange () {
-        assertNotNull("SSID is null", TEST_ACCESS_POINT);
-        //Connect to TEST_ACCESS_POINT
-        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
-                   cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        assertNotNull("SSID is null", mTestAccessPoint);
+        //Connect to mTestAccessPoint
+        assertTrue("failed to connect to " + mTestAccessPoint,
+                   cmActivity.connectToWifi(mTestAccessPoint));
         assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
@@ -503,7 +522,7 @@
         // Disconnect from the current AP
         log("disconnect from the AP");
         if (!cmActivity.disconnectAP()) {
-            log("failed to disconnect from " + TEST_ACCESS_POINT);
+            log("failed to disconnect from " + mTestAccessPoint);
         }
 
         // Verify the connectivity state for Wifi is DISCONNECTED
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 41104fe..7e136be 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -51,6 +51,7 @@
     private int iterations;
     private BufferedWriter mOutputWriter = null;
     private int mLastIteration = 0;
+    private boolean mWifiOnlyFlag;
 
     public WifiApStress() {
         super(ConnectivityManagerTestActivity.class);
@@ -63,6 +64,7 @@
         ConnectivityManagerStressTestRunner mRunner =
             (ConnectivityManagerStressTestRunner)getInstrumentation();
         iterations = mRunner.mSoftapIterations;
+        mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
         mAct.turnScreenOn();
     }
 
@@ -79,6 +81,10 @@
 
     @LargeTest
     public void testWifiHotSpot() {
+        if (mWifiOnlyFlag) {
+            Log.v(TAG, this.getName() + " is excluded for wi-fi only test");
+            return;
+        }
         WifiConfiguration config = new WifiConfiguration();
         config.SSID = NETWORK_ID;
         config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index feb63cd..f46546f 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -34,7 +34,6 @@
 
 import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
 import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
-import com.android.connectivitymanagertest.UtilHelper;
 
 import java.io.BufferedWriter;
 import java.io.File;
@@ -75,7 +74,7 @@
     private String mPassword;
     private ConnectivityManagerStressTestRunner mRunner;
     private BufferedWriter mOutputWriter = null;
-    private boolean mIsWifiOnlyDevice;
+    private boolean mWifiOnlyFlag;
 
     public WifiStressTest() {
         super(ConnectivityManagerTestActivity.class);
@@ -91,13 +90,13 @@
         mPassword = mRunner.mReconnectPassword;
         mScanIterations = mRunner.mScanIterations;
         mWifiSleepTime = mRunner.mSleepTime;
+        mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
         log(String.format("mReconnectIterations(%d), mSsid(%s), mPassword(%s),"
             + "mScanIterations(%d), mWifiSleepTime(%d)", mReconnectIterations, mSsid,
             mPassword, mScanIterations, mWifiSleepTime));
         mOutputWriter = new BufferedWriter(new FileWriter(new File(
                 Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
         mAct.turnScreenOn();
-        mIsWifiOnlyDevice = UtilHelper.isWifiOnly(mRunner.getTargetContext());
         if (!mAct.mWifiManager.isWifiEnabled()) {
             log("Enable wi-fi before stress tests.");
             if (!mAct.enableWifi()) {
@@ -269,7 +268,7 @@
             assertTrue("Wait for Wi-Fi to idle timeout",
                     mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
                     6 * ConnectivityManagerTestActivity.SHORT_TIMEOUT));
-            if (!mIsWifiOnlyDevice) {
+            if (!mWifiOnlyFlag) {
                 // use long timeout as the pppd startup may take several retries.
                 assertTrue("Wait for cellular connection timeout",
                         mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
@@ -280,7 +279,7 @@
             assertEquals("Wi-Fi is reconnected", State.DISCONNECTED,
                     mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
 
-            if (!mIsWifiOnlyDevice) {
+            if (!mWifiOnlyFlag) {
                 assertEquals("Cellular connection is down", State.CONNECTED,
                              mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
                 assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index 29edc04..c41dd07 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -24,7 +24,6 @@
 import android.graphics.*;
 import android.view.Gravity;
 import android.util.AttributeSet;
-import android.view.View;
 
 import java.io.IOException;
 
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 4b9c98f..043adae 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -296,8 +296,6 @@
 
     /**
      * Implement this interface if you want to create an drawable that is RTL aware
-     *
-     * @hide
      */
     public static interface Callback2 extends Callback {
         /**
@@ -387,8 +385,6 @@
     /**
      * Use the current {@link android.graphics.drawable.Drawable.Callback2} implementation to get
      * the resolved layout direction of this Drawable.
-     *
-     * @hide
      */
     public int getResolvedLayoutDirectionSelf() {
         final Callback callback = getCallback();
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 5fd5a16..ccad250 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -24,7 +24,6 @@
 import android.graphics.*;
 import android.view.Gravity;
 import android.util.AttributeSet;
-import android.view.View;
 
 import java.io.IOException;
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 339ae0a..b4310ea 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1189,7 +1189,7 @@
 }
 
 void OpenGLRenderer::setupDrawColorUniforms() {
-    if (mColorSet || (mShader && mSetShaderColor)) {
+    if ((mColorSet && !mShader) || (mShader && mSetShaderColor)) {
         mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA);
     }
 }
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index a890068..2ad24e2 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -156,6 +156,7 @@
     private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
     private static final int VERSION_ADDED_METERED = 4;
     private static final int VERSION_SPLIT_SNOOZE = 5;
+    private static final int VERSION_ADDED_TIMEZONE = 6;
 
     // @VisibleForTesting
     public static final int TYPE_WARNING = 0x1;
@@ -171,6 +172,7 @@
     private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
     private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
     private static final String ATTR_CYCLE_DAY = "cycleDay";
+    private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
     private static final String ATTR_WARNING_BYTES = "warningBytes";
     private static final String ATTR_LIMIT_BYTES = "limitBytes";
     private static final String ATTR_LAST_SNOOZE = "lastSnooze";
@@ -922,13 +924,15 @@
                     com.android.internal.R.integer.config_networkPolicyDefaultWarning)
                     * MB_IN_BYTES;
 
-            final Time time = new Time(Time.TIMEZONE_UTC);
+            final Time time = new Time();
             time.setToNow();
+
             final int cycleDay = time.monthDay;
+            final String cycleTimezone = time.timezone;
 
             final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
-            mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, warningBytes,
-                    LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true));
+            mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, cycleTimezone,
+                    warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true));
             writePolicyLocked();
         }
     }
@@ -964,6 +968,12 @@
                         final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
                         final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
                         final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
+                        final String cycleTimezone;
+                        if (version >= VERSION_ADDED_TIMEZONE) {
+                            cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
+                        } else {
+                            cycleTimezone = Time.TIMEZONE_UTC;
+                        }
                         final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
                         final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
                         final long lastLimitSnooze;
@@ -998,8 +1008,8 @@
                         final NetworkTemplate template = new NetworkTemplate(
                                 networkTemplate, subscriberId);
                         mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
-                                warningBytes, limitBytes, lastWarningSnooze, lastLimitSnooze,
-                                metered));
+                                cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
+                                lastLimitSnooze, metered));
 
                     } else if (TAG_UID_POLICY.equals(tag)) {
                         final int uid = readIntAttribute(in, ATTR_UID);
@@ -1054,7 +1064,7 @@
             out.startDocument(null, true);
 
             out.startTag(null, TAG_POLICY_LIST);
-            writeIntAttribute(out, ATTR_VERSION, VERSION_SPLIT_SNOOZE);
+            writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_TIMEZONE);
             writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
 
             // write all known network policies
@@ -1068,6 +1078,7 @@
                     out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
                 }
                 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
+                out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone);
                 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
                 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
                 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index e863f8b..b4fd55e 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -32,6 +32,7 @@
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static android.text.format.Time.TIMEZONE_UTC;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
@@ -439,7 +440,7 @@
         final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
 
         final NetworkPolicy policy = new NetworkPolicy(
-                sTemplateWifi, 5, 1024L, 1024L, false);
+                sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false);
         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
         assertTimeEquals(expectedCycle, actualCycle);
     }
@@ -450,7 +451,7 @@
         final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
 
         final NetworkPolicy policy = new NetworkPolicy(
-                sTemplateWifi, 20, 1024L, 1024L, false);
+                sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false);
         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
         assertTimeEquals(expectedCycle, actualCycle);
     }
@@ -461,7 +462,7 @@
         final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
 
         final NetworkPolicy policy = new NetworkPolicy(
-                sTemplateWifi, 30, 1024L, 1024L, false);
+                sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
         assertTimeEquals(expectedCycle, actualCycle);
     }
@@ -472,14 +473,53 @@
         final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z");
 
         final NetworkPolicy policy = new NetworkPolicy(
-                sTemplateWifi, 30, 1024L, 1024L, false);
+                sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
         assertTimeEquals(expectedCycle, actualCycle);
     }
 
+    public void testCycleBoundaryLeapYear() throws Exception {
+        final NetworkPolicy policy = new NetworkPolicy(
+                sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
+
+        assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"),
+                computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy));
+        assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
+                computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy));
+        assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
+                computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
+        assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"),
+                computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
+
+        assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"),
+                computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy));
+        assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"),
+                computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy));
+        assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"),
+                computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
+        assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"),
+                computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
+    }
+
+    public void testNextCycleTimezoneAfterUtc() throws Exception {
+        // US/Central is UTC-6
+        final NetworkPolicy policy = new NetworkPolicy(
+                sTemplateWifi, 10, "US/Central", 1024L, 1024L, false);
+        assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"),
+                computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
+    }
+
+    public void testNextCycleTimezoneBeforeUtc() throws Exception {
+        // Israel is UTC+2
+        final NetworkPolicy policy = new NetworkPolicy(
+                sTemplateWifi, 10, "Israel", 1024L, 1024L, false);
+        assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"),
+                computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
+    }
+
     public void testNextCycleSane() throws Exception {
         final NetworkPolicy policy = new NetworkPolicy(
-                sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, false);
+                sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
         final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
 
         // walk forwards, ensuring that cycle boundaries don't get stuck
@@ -494,7 +534,7 @@
 
     public void testLastCycleSane() throws Exception {
         final NetworkPolicy policy = new NetworkPolicy(
-                sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, false);
+                sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
         final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
 
         // walk backwards, ensuring that cycle boundaries look sane
@@ -552,7 +592,7 @@
 
         replay();
         setNetworkPolicies(new NetworkPolicy(
-                sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
+                sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
         future.get();
         verifyAndReset();
     }
@@ -609,8 +649,8 @@
             future = expectMeteredIfacesChanged();
 
             replay();
-            setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES,
-                    2 * MB_IN_BYTES, false));
+            setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1
+                    * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
             future.get();
             verifyAndReset();
         }
@@ -740,8 +780,9 @@
             future = expectMeteredIfacesChanged(TEST_IFACE);
 
             replay();
-            setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, WARNING_DISABLED,
-                    LIMIT_DISABLED, true));
+            setNetworkPolicies(new NetworkPolicy(
+                    sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
+                    true));
             future.get();
             verifyAndReset();
         }