Only show the keyboard when the user explicitly focuses an Input. (#6713)

Fixes https://github.com/flutter/flutter/issues/6603
diff --git a/packages/flutter/lib/src/widgets/editable.dart b/packages/flutter/lib/src/widgets/editable.dart
index e6938bc..d802345 100644
--- a/packages/flutter/lib/src/widgets/editable.dart
+++ b/packages/flutter/lib/src/widgets/editable.dart
@@ -273,8 +273,12 @@
     return newScrollOffset;
   }
 
+  // True if the focus was explicitly requested last frame. This ensures we
+  // don't show the keyboard when focus defaults back to the RawInput.
+  bool _requestingFocus = false;
+
   void _attachOrDetachKeyboard(bool focused) {
-    if (focused && !_isAttachedToKeyboard) {
+    if (focused && !_isAttachedToKeyboard && _requestingFocus) {
       _textInputConnection = TextInput.attach(
           this, new TextInputConfiguration(inputType: config.keyboardType))
         ..setEditingState(_getTextEditingStateFromInputValue(_currentValue))
@@ -286,6 +290,7 @@
       }
       _clearComposing();
     }
+    _requestingFocus = false;
   }
 
   void _clearComposing() {
@@ -306,6 +311,9 @@
       _textInputConnection.show();
     } else {
       Focus.moveTo(config.focusKey);
+      setState(() {
+        _requestingFocus = true;
+      });
     }
   }
 
diff --git a/packages/flutter/test/widgets/form_test.dart b/packages/flutter/test/widgets/form_test.dart
index 965fa9c..ca0ba77 100644
--- a/packages/flutter/test/widgets/form_test.dart
+++ b/packages/flutter/test/widgets/form_test.dart
@@ -14,6 +14,12 @@
     mockTextInput.enterText(text);
   }
 
+  Future<Null> showKeyboard(WidgetTester tester) async {
+    RawInputState editable = tester.state(find.byType(RawInput).first);
+    editable.requestKeyboard();
+    await tester.pump();
+  }
+
   testWidgets('onSaved callback is called', (WidgetTester tester) async {
     GlobalKey<FormState> formKey = new GlobalKey<FormState>();
     String fieldValue;
@@ -32,6 +38,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     expect(fieldValue, isNull);
 
@@ -65,6 +72,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     Future<Null> checkErrorText(String testValue) async {
       enterText(testValue);
@@ -81,7 +89,6 @@
   testWidgets('Multiple Inputs communicate', (WidgetTester tester) async {
     GlobalKey<FormState> formKey = new GlobalKey<FormState>();
     GlobalKey<FormFieldState<InputValue>> fieldKey = new GlobalKey<FormFieldState<InputValue>>();
-    GlobalKey inputFocusKey = new GlobalKey();
     GlobalKey focusKey = new GlobalKey();
     // Input 2's validator depends on a input 1's value.
     String errorText(InputValue input) => fieldKey.currentState.value?.text.toString() + '/error';
@@ -96,9 +103,7 @@
               child: new Block(
                 children: <Widget>[
                   new InputFormField(
-                    autofocus: true,
-                    key: fieldKey,
-                    focusKey: inputFocusKey,
+                    key: fieldKey
                   ),
                   new InputFormField(
                     validator: errorText,
@@ -112,8 +117,7 @@
     }
 
     await tester.pumpWidget(builder());
-    await tester.pump();
-    Focus.moveTo(inputFocusKey);
+    await showKeyboard(tester);
 
     Future<Null> checkErrorText(String testValue) async {
       enterText(testValue);
@@ -147,6 +151,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     // initial value should be loaded into keyboard editing state
     expect(mockTextInput.editingState, isNotNull);
@@ -187,7 +192,7 @@
     }
 
     await tester.pumpWidget(builder(false));
-    await tester.pump();
+    await showKeyboard(tester);
 
     expect(fieldValue, isNull);
     expect(formKey.currentState.hasErrors, isFalse);
diff --git a/packages/flutter/test/widgets/input_test.dart b/packages/flutter/test/widgets/input_test.dart
index a5f40f9..024f0ff 100644
--- a/packages/flutter/test/widgets/input_test.dart
+++ b/packages/flutter/test/widgets/input_test.dart
@@ -50,6 +50,12 @@
     mockTextInput.enterText(text);
   }
 
+  Future<Null> showKeyboard(WidgetTester tester) async {
+    RawInputState editable = tester.state(find.byType(RawInput).first);
+    editable.requestKeyboard();
+    await tester.pump();
+  }
+
   // Returns the first RenderEditable.
   RenderEditable findRenderEditable(WidgetTester tester) {
     RenderObject root = tester.renderObject(find.byType(RawInput));
@@ -94,6 +100,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     RenderBox findInputBox() => tester.renderObject(find.byKey(inputKey));
 
@@ -134,6 +141,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     RawInputState editableText = tester.state(find.byType(RawInput));
 
@@ -179,6 +187,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     const String testValue = 'ABC';
     updateEditingState(new TextEditingState(
@@ -215,6 +224,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     String testValue = 'abc def ghi';
     enterText(testValue);
@@ -262,6 +272,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     String testValue = 'abc def ghi';
     enterText(testValue);
@@ -337,6 +348,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     String testValue = 'abc def ghi';
     enterText(testValue);
@@ -402,6 +414,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     String testValue = 'abc def ghi';
     enterText(testValue);
@@ -452,6 +465,7 @@
     }
 
     await tester.pumpWidget(builder(3));
+    await showKeyboard(tester);
 
     RenderBox findInputBox() => tester.renderObject(find.byKey(inputKey));
 
@@ -514,6 +528,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     String testValue = kThreeLines;
     String cutValue = 'First line of stuff keeps going until abcdef ghijk. ';
@@ -605,6 +620,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     enterText(kFourLines);
     await tester.idle();
@@ -690,6 +706,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     Future<Null> checkText(String testValue) async {
       enterText(testValue);
@@ -722,6 +739,7 @@
     }
 
     await tester.pumpWidget(builder());
+    await showKeyboard(tester);
 
     Future<Null> checkText(String testValue) async {
       enterText(testValue);
diff --git a/packages/flutter_test/lib/src/widget_tester.dart b/packages/flutter_test/lib/src/widget_tester.dart
index 9849ac8..5d528b9 100644
--- a/packages/flutter_test/lib/src/widget_tester.dart
+++ b/packages/flutter_test/lib/src/widget_tester.dart
@@ -163,6 +163,10 @@
   /// microtasks, by calling [pump] with the same `duration` (if any). The
   /// supplied [EnginePhase] is the final phase reached during the pump pass; if
   /// not supplied, the whole pass is executed.
+  ///
+  /// Subsequent calls to this is different from [pump] in that it forces a full
+  /// rebuild of the tree, even if [widget] is the same as the previous call.
+  /// [pump] will only rebuild the widgets that have changed.
   Future<Null> pumpWidget(Widget widget, [
     Duration duration,
     EnginePhase phase = EnginePhase.sendSemanticsTree