Refactor ios bundleid/android application process logic. (#27471)

When creating a flutter project,
Make sure: applicationid for android conforms to: https://developer.android.com/studio/build/application-id

Make sure: bundleid for ios conforms to:
https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html
(Not only the name,but also the organization, as it's a check for whole bundleid.)
diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart
index ec6f616..2a13c4c 100644
--- a/packages/flutter_tools/lib/src/commands/create.dart
+++ b/packages/flutter_tools/lib/src/commands/create.dart
@@ -559,7 +559,32 @@
 }
 
 String _createAndroidIdentifier(String organization, String name) {
-  return '$organization.$name'.replaceAll('_', '');
+  // Android application ID is specified in: https://developer.android.com/studio/build/application-id
+  // All characters must be alphanumeric or an underscore [a-zA-Z0-9_].
+  String tmpIdentifier = '$organization.$name';
+  final RegExp disallowed = RegExp(r'[^\w\.]');
+  tmpIdentifier = tmpIdentifier.replaceAll(disallowed, '');
+
+  // It must have at least two segments (one or more dots).
+  final List<String> segments = tmpIdentifier
+      .split('.')
+      .where((String segment) => segment.isNotEmpty)
+      .toList();
+  while (segments.length < 2) {
+    segments.add('untitled');
+  }
+
+  // Each segment must start with a letter.
+  final RegExp segmentPatternRegex = RegExp(r'^[a-zA-Z][\w]*$');
+  final List<String> prefixedSegments = segments
+      .map((String segment) {
+        if (!segmentPatternRegex.hasMatch(segment)) {
+          return 'u'+segment;
+        }
+        return segment;
+      })
+      .toList();
+  return prefixedSegments.join('.');
 }
 
 String _createPluginClassName(String name) {
@@ -569,10 +594,21 @@
 
 String _createUTIIdentifier(String organization, String name) {
   // Create a UTI (https://en.wikipedia.org/wiki/Uniform_Type_Identifier) from a base name
+  name = camelCase(name);
+  String tmpIdentifier = '$organization.$name';
   final RegExp disallowed = RegExp(r'[^a-zA-Z0-9\-\.\u0080-\uffff]+');
-  name = camelCase(name).replaceAll(disallowed, '');
-  name = name.isEmpty ? 'untitled' : name;
-  return '$organization.$name';
+  tmpIdentifier = tmpIdentifier.replaceAll(disallowed, '');
+
+  // It must have at least two segments (one or more dots).
+  final List<String> segments = tmpIdentifier
+      .split('.')
+      .where((String segment) => segment.isNotEmpty)
+      .toList();
+  while (segments.length < 2) {
+    segments.add('untitled');
+  }
+
+  return segments.join('.');
 }
 
 final Set<String> _packageDependencies = Set<String>.from(<String>[