Merge "NetworkPolicyManagerService: Allow data saver to be on by default."
diff --git a/core/java/android/content/pm/PackageBackwardCompatibility.java b/core/java/android/content/pm/PackageBackwardCompatibility.java
new file mode 100644
index 0000000..4de160b
--- /dev/null
+++ b/core/java/android/content/pm/PackageBackwardCompatibility.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 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 android.content.pm;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageParser.Package;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+
+import java.util.ArrayList;
+
+/**
+ * Modifies {@link Package} in order to maintain backwards compatibility.
+ *
+ * @hide
+ */
+@VisibleForTesting
+public class PackageBackwardCompatibility {
+
+    private static final String ANDROID_TEST_MOCK = "android.test.mock";
+
+    private static final String ANDROID_TEST_RUNNER = "android.test.runner";
+
+    /**
+     * Modify the shared libraries in the supplied {@link Package} to maintain backwards
+     * compatibility.
+     *
+     * @param pkg the {@link Package} to modify.
+     */
+    @VisibleForTesting
+    public static void modifySharedLibraries(Package pkg) {
+        ArrayList<String> usesLibraries = pkg.usesLibraries;
+        ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
+
+        usesLibraries = orgApacheHttpLegacy(usesLibraries);
+        usesOptionalLibraries = orgApacheHttpLegacy(usesOptionalLibraries);
+
+        // android.test.runner has a dependency on android.test.mock so if android.test.runner
+        // is present but android.test.mock is not then add android.test.mock.
+        boolean androidTestMockPresent = ArrayUtils.contains(usesLibraries, ANDROID_TEST_MOCK)
+                || ArrayUtils.contains(usesOptionalLibraries, ANDROID_TEST_MOCK);
+        if (ArrayUtils.contains(usesLibraries, ANDROID_TEST_RUNNER) && !androidTestMockPresent) {
+            usesLibraries.add(ANDROID_TEST_MOCK);
+        }
+        if (ArrayUtils.contains(usesOptionalLibraries, ANDROID_TEST_RUNNER)
+                && !androidTestMockPresent) {
+            usesOptionalLibraries.add(ANDROID_TEST_MOCK);
+        }
+
+        pkg.usesLibraries = usesLibraries;
+        pkg.usesOptionalLibraries = usesOptionalLibraries;
+    }
+
+    private static ArrayList<String> orgApacheHttpLegacy(@Nullable ArrayList<String> libraries) {
+        // "org.apache.http.legacy" is now a part of the boot classpath so it doesn't need
+        // to be an explicit dependency.
+        //
+        // A future change will remove this library from the boot classpath, at which point
+        // all apps that target SDK 21 and earlier will have it automatically added to their
+        // dependency lists.
+        return ArrayUtils.remove(libraries, "org.apache.http.legacy");
+    }
+}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 426c4f2..a37e89e 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3846,7 +3846,7 @@
         // every activity info has had a chance to set it from its attributes.
         setMaxAspectRatio(owner);
 
-        modifySharedLibrariesForBackwardCompatibility(owner);
+        PackageBackwardCompatibility.modifySharedLibraries(owner);
 
         if (hasDomainURLs(owner)) {
             owner.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
@@ -3857,18 +3857,6 @@
         return true;
     }
 
-    private static void modifySharedLibrariesForBackwardCompatibility(Package owner) {
-        // "org.apache.http.legacy" is now a part of the boot classpath so it doesn't need
-        // to be an explicit dependency.
-        //
-        // A future change will remove this library from the boot classpath, at which point
-        // all apps that target SDK 21 and earlier will have it automatically added to their
-        // dependency lists.
-        owner.usesLibraries = ArrayUtils.remove(owner.usesLibraries, "org.apache.http.legacy");
-        owner.usesOptionalLibraries = ArrayUtils.remove(owner.usesOptionalLibraries,
-                "org.apache.http.legacy");
-    }
-
     /**
      * Check if one of the IntentFilter as both actions DEFAULT / VIEW and a HTTP/HTTPS data URI
      */
diff --git a/core/tests/coretests/README b/core/tests/coretests/README
index aced441..ea282a0 100644
--- a/core/tests/coretests/README
+++ b/core/tests/coretests/README
@@ -28,7 +28,7 @@
 
 Next, install the resulting APK and run tests as you would normal JUnit tests:
 
-  adb install out/target/product/.../data/app/FrameworksCoreTests/FrameworksCoreTests.apk
+  adb install -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
   adb shell am instrument -w \
     com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
 
diff --git a/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java b/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java
new file mode 100644
index 0000000..4d2a047
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 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 android.content.pm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.content.pm.PackageParser.Package;
+import android.os.Build;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+@SmallTest
+@RunWith(JUnit4.class)
+public class PackageBackwardCompatibilityTest {
+
+    private static final String ORG_APACHE_HTTP_LEGACY = "org.apache.http.legacy";
+
+    private static final String ANDROID_TEST_RUNNER = "android.test.runner";
+
+    private static final String ANDROID_TEST_MOCK = "android.test.mock";
+
+    private Package mPackage;
+
+    private static ArrayList<String> arrayList(String... strings) {
+        ArrayList<String> list = new ArrayList<>();
+        Collections.addAll(list, strings);
+        return list;
+    }
+
+    @Before
+    public void setUp() {
+        mPackage = new Package("org.package.name");
+        mPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+    }
+
+    @Test
+    public void null_usesLibraries() {
+        PackageBackwardCompatibility.modifySharedLibraries(mPackage);
+        assertNull("usesLibraries not updated correctly", mPackage.usesLibraries);
+    }
+
+    @Test
+    public void null_usesOptionalLibraries() {
+        PackageBackwardCompatibility.modifySharedLibraries(mPackage);
+        assertNull("usesOptionalLibraries not updated correctly", mPackage.usesOptionalLibraries);
+    }
+
+    @Test
+    public void remove_org_apache_http_legacy_from_usesLibraries() {
+        mPackage.usesLibraries = arrayList(ORG_APACHE_HTTP_LEGACY);
+        PackageBackwardCompatibility.modifySharedLibraries(mPackage);
+        assertNull("usesLibraries not updated correctly", mPackage.usesLibraries);
+    }
+
+    @Test
+    public void remove_org_apache_http_legacy_from_usesOptionalLibraries() {
+        mPackage.usesOptionalLibraries = arrayList(ORG_APACHE_HTTP_LEGACY);
+        PackageBackwardCompatibility.modifySharedLibraries(mPackage);
+        assertNull("usesOptionalLibraries not updated correctly", mPackage.usesOptionalLibraries);
+    }
+
+    @Test
+    public void android_test_runner_in_usesLibraries() {
+        mPackage.usesLibraries = arrayList(ANDROID_TEST_RUNNER);
+        PackageBackwardCompatibility.modifySharedLibraries(mPackage);
+        assertEquals("usesLibraries not updated correctly",
+                arrayList(ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK),
+                mPackage.usesLibraries);
+    }
+
+    @Test
+    public void android_test_runner_in_usesOptionalLibraries() {
+        mPackage.usesOptionalLibraries = arrayList(ANDROID_TEST_RUNNER);
+        PackageBackwardCompatibility.modifySharedLibraries(mPackage);
+        assertEquals("usesOptionalLibraries not updated correctly",
+                arrayList(ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK),
+                mPackage.usesOptionalLibraries);
+    }
+
+    @Test
+    public void android_test_runner_in_usesLibraries_android_test_mock_in_usesOptionalLibraries() {
+        mPackage.usesLibraries = arrayList(ANDROID_TEST_RUNNER);
+        mPackage.usesOptionalLibraries = arrayList(ANDROID_TEST_MOCK);
+        PackageBackwardCompatibility.modifySharedLibraries(mPackage);
+        assertEquals("usesLibraries not updated correctly",
+                arrayList(ANDROID_TEST_RUNNER),
+                mPackage.usesLibraries);
+        assertEquals("usesOptionalLibraries not updated correctly",
+                arrayList(ANDROID_TEST_MOCK),
+                mPackage.usesOptionalLibraries);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 5005f9d..820a773 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -24,6 +24,8 @@
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.PorterDuff;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.UserHandle;
 import android.support.v4.graphics.ColorUtils;
 import android.text.TextUtils;
@@ -48,6 +50,7 @@
 public class KeyguardStatusView extends GridLayout {
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     private static final String TAG = "KeyguardStatusView";
+    private static final int MARQUEE_DELAY_MS = 2000;
 
     private final LockPatternUtils mLockPatternUtils;
     private final AlarmManager mAlarmManager;
@@ -59,6 +62,8 @@
     private ViewGroup mClockContainer;
     private ChargingView mBatteryDoze;
     private View mKeyguardStatusArea;
+    private Runnable mPendingMarqueeStart;
+    private Handler mHandler;
 
     private View[] mVisibleInDoze;
     private boolean mPulsing;
@@ -112,9 +117,29 @@
         super(context, attrs, defStyle);
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mLockPatternUtils = new LockPatternUtils(getContext());
+        mHandler = new Handler(Looper.myLooper());
     }
 
     private void setEnableMarquee(boolean enabled) {
+        if (DEBUG) Log.v(TAG, "Schedule setEnableMarquee: " + (enabled ? "Enable" : "Disable"));
+        if (enabled) {
+            if (mPendingMarqueeStart == null) {
+                mPendingMarqueeStart = () -> {
+                    setEnableMarqueeImpl(true);
+                    mPendingMarqueeStart = null;
+                };
+                mHandler.postDelayed(mPendingMarqueeStart, MARQUEE_DELAY_MS);
+            }
+        } else {
+            if (mPendingMarqueeStart != null) {
+                mHandler.removeCallbacks(mPendingMarqueeStart);
+                mPendingMarqueeStart = null;
+            }
+            setEnableMarqueeImpl(false);
+        }
+    }
+
+    private void setEnableMarqueeImpl(boolean enabled) {
         if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
         if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled);
         if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled);
diff --git a/test-runner/Android.mk b/test-runner/Android.mk
index 9053b23..3c3718a 100644
--- a/test-runner/Android.mk
+++ b/test-runner/Android.mk
@@ -22,9 +22,15 @@
 # =====================================
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := \
+    $(filter-out $(android_test_mock_source_files), $(call all-java-files-under, src))
 
-LOCAL_JAVA_LIBRARIES := core-oj core-libart framework legacy-test
+LOCAL_JAVA_LIBRARIES := \
+    core-oj \
+    core-libart \
+    framework \
+    legacy-test \
+    android.test.mock \
 
 LOCAL_MODULE:= android.test.runner