anchor.diff:      if (!_checkForSupportedAdbVersion() || !_checkForSupportedAndroidVersion())
         return new LaunchResult.failed();
   
  -    String localBundlePath;
  -
  -    if (!prebuiltApplication) {
  -      localBundlePath = await flx.buildFlx(
  -        mainPath: mainPath,
  -        precompiledSnapshot: isAotBuildMode(debuggingOptions.buildMode),
  -        includeRobotoFonts: false
  -      );
  -      if (localBundlePath == null)
  +    final bool traceStartup = platformArgs['trace-startup'] ?? false;
  +    final AndroidApk apk = package;
  +    printTrace('$this startApp');
  +
  +    ProtocolDiscovery observatoryDiscovery;
  +    ProtocolDiscovery diagnosticDiscovery;
  +
  +    DeviceLogReader logReader = getLogReader();
  +    if (debuggingOptions.debuggingEnabled) {
  +      observatoryDiscovery = new ProtocolDiscovery(logReader, ProtocolDiscovery.kObservatoryService);
  +      diagnosticDiscovery = new ProtocolDiscovery(logReader, ProtocolDiscovery.kDiagnosticService);
  +    }
  +
  +    List<String> cmd;
  +
  +    cmd = adbCommandForDevice(<String>[
  +      'shell', 'am', 'start',
  +      '-a', 'android.intent.action.RUN',
  +      '-f', '0x20000000',  // FLAG_ACTIVITY_SINGLE_TOP
  +      '--ez', 'enable-background-compilation', 'true',
  +    ]);
  +
  +    if (traceStartup)
  +      cmd.addAll(<String>['--ez', 'trace-startup', 'true']);
  +    if (route != null)
  +      cmd.addAll(<String>['--es', 'route', route]);
  +    if (debuggingOptions.debuggingEnabled) {
  +      if (debuggingOptions.buildMode == BuildMode.debug)
  +        cmd.addAll(<String>['--ez', 'enable-checked-mode', 'true']);
  +      if (debuggingOptions.startPaused)
  +        cmd.addAll(<String>['--ez', 'start-paused', 'true']);
  +    }
  +    cmd.add(apk.launchActivity);
  +    String result = runCheckedSync(cmd);
  +    // This invocation returns 0 even when it fails.
  +    if (result.contains('Error: ')) {
  +      printError(result.trim());
  +      return new LaunchResult.failed();
  +    }
  +
  +    if (!debuggingOptions.debuggingEnabled) {
  +      return new LaunchResult.succeeded();
  +    } else {
  +      // Wait for the service protocol port here. This will complete once the
  +      // device has printed "Observatory is listening on...".
  +      printTrace('Waiting for observatory port to be available...');
  +
  +      try {
  +        int observatoryDevicePort, diagnosticDevicePort;
  +
  +        if (debuggingOptions.buildMode == BuildMode.debug) {
  +          Future<List<int>> scrapeServicePorts = Future.wait(
  +              <Future<int>>[observatoryDiscovery.nextPort(), diagnosticDiscovery.nextPort()]
  +          );
  +          List<int> devicePorts = await scrapeServicePorts.timeout(new Duration(seconds: 20));
  +          observatoryDevicePort = devicePorts[0];
  +          diagnosticDevicePort = devicePorts[1];
  +        } else {
  +          observatoryDevicePort = await observatoryDiscovery.nextPort().timeout(new Duration(seconds: 20));
  +        }
  +
  +        printTrace('observatory port on device: $observatoryDevicePort');
  +        int observatoryLocalPort = await debuggingOptions.findBestObservatoryPort();
  +        // TODO(devoncarew): Remember the forwarding information (so we can later remove the
  +        // port forwarding).
  +        observatoryLocalPort = await _forwardPort(ProtocolDiscovery.kObservatoryService, observatoryDevicePort, observatoryLocalPort);
  +
  +        int diagnosticLocalPort;
  +        if (diagnosticDevicePort != null) {
  +          printTrace('diagnostic port on device: $diagnosticDevicePort');
  +          diagnosticLocalPort = await debuggingOptions.findBestDiagnosticPort();
  +          diagnosticLocalPort = await _forwardPort(ProtocolDiscovery.kDiagnosticService, diagnosticDevicePort, diagnosticLocalPort);
  +        }
  +
  +        return new LaunchResult.succeeded(
  +            observatoryPort: observatoryLocalPort,
  +            diagnosticPort: diagnosticLocalPort
  +        );
  +      } catch (error) {
  +        if (error is TimeoutException)
  +          printError('Timed out while waiting for a debug connection.');
  +        else
  +          printError('Error waiting for a debug connection: $error');
           return new LaunchResult.failed();
  -    }
  -
  -    printTrace('Starting bundle for $this.');
  -
  -    return startBundle(
  -      package,
  -      localBundlePath,
  -      traceStartup: platformArgs['trace-startup'] ?? false,
  -      route: route,
  -      options: debuggingOptions
  -    );
  +      } finally {
  +        observatoryDiscovery.cancel();
  +        diagnosticDiscovery.cancel();
  +      }
  +    }
     }
   
     @override
  
positive.code: import '../base/process.dart';
  import '../build_info.dart';
  import '../device.dart';
  import '../flx.dart' as flx;
  import '../globals.dart';
  import '../protocol_discovery.dart';
  import 'adb.dart';
  
negative.code: import 'android_sdk.dart';
  
  const String _defaultAdbPath = 'adb';
  
  class AndroidDevices extends PollingDeviceDiscovery {
    AndroidDevices() : super('AndroidDevices');
  