[Thread] initial Thread network service

This commit sets up the initial Thread network service for the
Android Thread feature which allows an Android device to create
a Thread network and being a Border Router.

See https://www.threadgroup.org/What-is-Thread for background of
Thread.

See b/235016403 for the Android Thread feature request.

Test: lunch aosp_cf_x86_64_tv-userdebug
      m && launch_cvd
      atest CtsThreadNetworkTestCases
Bug: 262683651
Change-Id: Ie1bb23084531f67165ec068ea3ca39592dbc01d1
diff --git a/service-t/src/com/android/server/ConnectivityServiceInitializer.java b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
index 624c5df..003ec8c 100644
--- a/service-t/src/com/android/server/ConnectivityServiceInitializer.java
+++ b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
@@ -16,7 +16,10 @@
 
 package com.android.server;
 
+import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.thread.ThreadNetworkManager;
 import android.util.Log;
 
 import com.android.modules.utils.build.SdkLevel;
@@ -26,6 +29,7 @@
 import com.android.server.ethernet.EthernetServiceImpl;
 import com.android.server.nearby.NearbyService;
 import com.android.server.remoteauth.RemoteAuthService;
+import com.android.server.thread.ThreadNetworkService;
 
 /**
  * Connectivity service initializer for core networking. This is called by system server to create
@@ -40,6 +44,7 @@
     private final NearbyService mNearbyService;
     private final EthernetServiceImpl mEthernetServiceImpl;
     private final RemoteAuthService mRemoteAuthService;
+    private final ThreadNetworkService mThreadNetworkService;
 
     public ConnectivityServiceInitializer(Context context) {
         super(context);
@@ -52,6 +57,7 @@
         mNsdService = createNsdService(context);
         mNearbyService = createNearbyService(context);
         mRemoteAuthService = createRemoteAuthService(context);
+        mThreadNetworkService = createThreadNetworkService(context);
     }
 
     @Override
@@ -93,6 +99,12 @@
             publishBinderService(RemoteAuthService.SERVICE_NAME, mRemoteAuthService,
                     /* allowIsolated= */ false);
         }
+
+        if (mThreadNetworkService != null) {
+            Log.i(TAG, "Registering " + ThreadNetworkManager.SERVICE_NAME);
+            publishBinderService(ThreadNetworkManager.SERVICE_NAME, mThreadNetworkService,
+                    /* allowIsolated= */ false);
+        }
     }
 
     @Override
@@ -104,6 +116,10 @@
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && mEthernetServiceImpl != null) {
             mEthernetServiceImpl.start();
         }
+
+        if (mThreadNetworkService != null) {
+            mThreadNetworkService.onBootPhase(phase);
+        }
     }
 
     /**
@@ -171,4 +187,25 @@
         }
         return EthernetService.create(context);
     }
+
+    /**
+     * Returns Thread network service instance if supported.
+     * Thread is supported if all of below are satisfied:
+     * 1. the FEATURE_THREAD_NETWORK is available
+     * 2. the SDK level is V+, or SDK level is U and the device is a TV
+     */
+    @Nullable
+    private ThreadNetworkService createThreadNetworkService(final Context context) {
+        final PackageManager pm = context.getPackageManager();
+        if (!pm.hasSystemFeature(ThreadNetworkManager.FEATURE_NAME)) {
+            return null;
+        }
+        if (!SdkLevel.isAtLeastU()) {
+            return null;
+        }
+        if (!SdkLevel.isAtLeastV() && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            return null;
+        }
+        return new ThreadNetworkService(context);
+    }
 }