Merge "Fix ephemeral intent caching in notification" into oc-dev
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
index 040b330..8014eca 100644
--- a/core/java/android/app/VrManager.java
+++ b/core/java/android/app/VrManager.java
@@ -6,8 +6,6 @@
 import android.os.RemoteException;
 import android.service.vr.IVrManager;
 
-import java.io.FileDescriptor;
-
 /**
  * Used to control aspects of a devices Virtual Reality (VR) capabilities.
  * <p>
@@ -63,32 +61,4 @@
             e.rethrowFromSystemServer();
         }
     }
-
-    /**
-     * Initiate connection for system controller data.
-     *
-     * @param fd Controller data file descriptor.
-     *
-     * {@hide}
-     */
-    public void connectController(FileDescriptor fd) {
-        try {
-            mService.connectController(fd);
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Sever connection for system controller data.
-     *
-     * {@hide}
-     */
-    public void disconnectController() {
-        try {
-            mService.disconnectController();
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
-    }
 }
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index eceaa31..6aa601a 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -189,10 +189,11 @@
             if (mAmplitude < -1 || mAmplitude == 0 || mAmplitude > 255) {
                 throw new IllegalArgumentException(
                         "amplitude must either be DEFAULT_AMPLITUDE, " +
-                        "or between 1 and 255 inclusive");
+                        "or between 1 and 255 inclusive (amplitude=" + mAmplitude + ")");
             }
             if (mTiming <= 0) {
-                throw new IllegalArgumentException("timing must be positive");
+                throw new IllegalArgumentException(
+                        "timing must be positive (timing=" + mTiming + ")");
             }
         }
 
@@ -274,24 +275,31 @@
         public void validate() {
             if (mTimings.length != mAmplitudes.length) {
                 throw new IllegalArgumentException(
-                        "timing and amplitude arrays must be of equal length");
+                        "timing and amplitude arrays must be of equal length" +
+                        " (timings.length=" + mTimings.length +
+                        ", amplitudes.length=" + mAmplitudes.length + ")");
             }
             if (!hasNonZeroEntry(mTimings)) {
-                throw new IllegalArgumentException("at least one timing must be non-zero");
+                throw new IllegalArgumentException("at least one timing must be non-zero" +
+                        " (timings=" + Arrays.toString(mTimings) + ")");
             }
             for (long timing : mTimings) {
                 if (timing < 0) {
-                    throw new IllegalArgumentException("timings must all be >= 0");
+                    throw new IllegalArgumentException("timings must all be >= 0" +
+                            " (timings=" + Arrays.toString(mTimings) + ")");
                 }
             }
             for (int amplitude : mAmplitudes) {
                 if (amplitude < -1 || amplitude > 255) {
                     throw new IllegalArgumentException(
-                            "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255");
+                            "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255" +
+                            " (amplitudes=" + Arrays.toString(mAmplitudes) + ")");
                 }
             }
             if (mRepeat < -1 || mRepeat >= mTimings.length) {
-                throw new IllegalArgumentException("repeat index must be >= -1");
+                throw new IllegalArgumentException(
+                        "repeat index must be within the bounds of the timings array" +
+                        " (timings.length=" + mTimings.length + ", index=" + mRepeat +")");
             }
         }
 
@@ -375,7 +383,8 @@
         @Override
         public void validate() {
             if (mEffectId != EFFECT_CLICK) {
-                throw new IllegalArgumentException("Unknown prebaked effect type");
+                throw new IllegalArgumentException(
+                        "Unknown prebaked effect type (value=" + mEffectId + ")");
             }
         }
 
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 1e55c78..2f0eeca 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -157,6 +157,8 @@
         // This call needs to continue throwing ArrayIndexOutOfBoundsException but ignore all other
         // exceptions for compatibility purposes
         if (repeat < -1 || repeat >= pattern.length) {
+            Log.e(TAG, "vibrate called with repeat index out of bounds" +
+                    " (pattern.length=" + pattern.length + ", index=" + repeat + ")");
             throw new ArrayIndexOutOfBoundsException();
         }
 
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index fc8afe9..9b37a65 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -86,17 +86,5 @@
      * currently, else return the display id of the virtual display
      */
     int getVr2dDisplayId();
-
-    /**
-     * Initiate connection for system controller data.
-     *
-     * @param fd Controller data file descriptor.
-     */
-    void connectController(in FileDescriptor fd);
-
-    /**
-     * Sever connection for system controller data.
-     */
-    void disconnectController();
 }
 
diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
index 6e41831..8b5cc60 100644
--- a/core/tests/coretests/src/android/text/method/BackspaceTest.java
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -16,10 +16,13 @@
 
 package android.text.method;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.text.InputType;
+import android.util.KeyUtils;
 import android.view.KeyEvent;
+import android.widget.EditText;
 import android.widget.TextView.BufferType;
 import org.junit.Before;
 import org.junit.Test;
@@ -33,13 +36,21 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class BackspaceTest extends KeyListenerTestCase {
+public class BackspaceTest {
+    private EditText mTextView;
+
     private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
         public int getInputType() {
             return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
         }
     };
 
+    @Before
+    public void setup() {
+        mTextView = new EditText(InstrumentationRegistry.getInstrumentation().getContext());
+    }
+
+
     // Sync the state to the TextView and call onKeyDown with KEYCODE_DEL key event.
     // Then update the state to the result of TextView.
     private void backspace(final EditorState state, int modifiers) {
@@ -47,7 +58,8 @@
         mTextView.setKeyListener(mKeyListener);
         mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
 
-        final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_DEL, modifiers);
+        final KeyEvent keyEvent = KeyUtils.generateKeyEvent(
+            KeyEvent.KEYCODE_DEL, KeyEvent.ACTION_DOWN, modifiers);
         mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
 
         state.mText = mTextView.getText();
diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
index 6914e21..c3a5f80 100644
--- a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
+++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
@@ -16,10 +16,13 @@
 
 package android.text.method;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.text.InputType;
+import android.util.KeyUtils;
 import android.view.KeyEvent;
+import android.widget.EditText;
 import android.widget.TextView.BufferType;
 
 import org.junit.Before;
@@ -34,13 +37,20 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class ForwardDeleteTest extends KeyListenerTestCase {
+public class ForwardDeleteTest {
+    private EditText mTextView;
+
     private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
         public int getInputType() {
             return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
         }
     };
 
+    @Before
+    public void setup() {
+        mTextView = new EditText(InstrumentationRegistry.getInstrumentation().getContext());
+    }
+
     // Sync the state to the TextView and call onKeyDown with KEYCODE_FORWARD_DEL key event.
     // Then update the state to the result of TextView.
     private void forwardDelete(final EditorState state, int modifiers) {
@@ -48,7 +58,8 @@
         mTextView.setKeyListener(mKeyListener);
         mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
 
-        final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_FORWARD_DEL, modifiers);
+        final KeyEvent keyEvent = KeyUtils.generateKeyEvent(
+            KeyEvent.KEYCODE_FORWARD_DEL, KeyEvent.ACTION_DOWN, modifiers);
         mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
 
         state.mText = mTextView.getText();
diff --git a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java b/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
deleted file mode 100644
index 99a0091..0000000
--- a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2016 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.text.method;
-
-import android.app.Instrumentation;
-import android.support.test.InstrumentationRegistry;
-import android.view.KeyEvent;
-import android.widget.EditText;
-
-public abstract class KeyListenerTestCase {
-    protected Instrumentation mInstrumentation;
-    protected EditText mTextView;
-
-    public KeyListenerTestCase() {
-    }
-
-    protected void setup() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mTextView = new EditText(mInstrumentation.getContext());
-    }
-
-    protected static KeyEvent getKey(int keycode, int metaState) {
-        long currentTime = System.currentTimeMillis();
-        return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode,
-                0 /* repeat */, metaState);
-    }
-}
diff --git a/core/tests/coretests/src/android/util/KeyUtils.java b/core/tests/coretests/src/android/util/KeyUtils.java
index b58fda3..593f727 100644
--- a/core/tests/coretests/src/android/util/KeyUtils.java
+++ b/core/tests/coretests/src/android/util/KeyUtils.java
@@ -85,4 +85,19 @@
         }
         inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
     }
+
+    /**
+     * Generates a {@link KeyEvent}.
+     *
+     * @param keycode The integer keycode for the event to be generated.
+     * @param keyEventAction The integer {@link KeyEvent} action code.
+     * @param metaState Flags indicating which meta keys are currently pressed.
+     *
+     * @return a new {@link KeyEvent} for current time.
+     */
+    public static KeyEvent generateKeyEvent(int keycode, int keyEventAction, int metaState) {
+        long currentTime = System.currentTimeMillis();
+        return new KeyEvent(currentTime, currentTime, keyEventAction, keycode,
+            0 /* repeat */, metaState);
+    }
 }
diff --git a/services/core/Android.mk b/services/core/Android.mk
index f896478..15493467 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -13,7 +13,6 @@
     ../../../../system/netd/server/binder/android/net/INetd.aidl \
     ../../../../system/netd/server/binder/android/net/metrics/INetdEventListener.aidl \
     ../../../native/cmds/installd/binder/android/os/IInstalld.aidl \
-    ../../../native/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl \
 
 LOCAL_AIDL_INCLUDES += \
     system/netd/server/binder
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 0e183f0..9ef7410 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -39,7 +39,6 @@
 import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
@@ -47,7 +46,6 @@
 import android.service.vr.IVrListener;
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
-import android.service.vr.IVrWindowManager;
 import android.service.vr.VrListenerService;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -440,18 +438,6 @@
         }
 
         @Override
-        public void connectController(FileDescriptor fd) throws android.os.RemoteException {
-            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
-            VrManagerService.this.connectController(fd);
-        }
-
-        @Override
-        public void disconnectController() throws android.os.RemoteException {
-            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
-            VrManagerService.this.disconnectController();
-        }
-
-        @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
@@ -1184,20 +1170,4 @@
             return mVrModeEnabled;
         }
     }
-
-    private void connectController(FileDescriptor fd) throws android.os.RemoteException {
-        // TODO(b/36506799): move vr_wm code to VrCore and remove this.
-        IVrWindowManager remote =
-                IVrWindowManager.Stub.asInterface(
-                        ServiceManager.getService(IVrWindowManager.SERVICE_NAME));
-        remote.connectController(fd);
-    }
-
-    private void disconnectController() throws android.os.RemoteException {
-        // TODO(b/36506799): move vr_wm code to VrCore and remove this.
-        IVrWindowManager remote =
-                IVrWindowManager.Stub.asInterface(
-                        ServiceManager.getService(IVrWindowManager.SERVICE_NAME));
-        remote.disconnectController();
-    }
 }