Android R0 Tethering source code

 

/frameworks/base/core/java/android/net/ConnectivityManager.java

2481      public void startTethering(int type, boolean showProvisioningUi,
2482              final OnStartTetheringCallback callback) {
2483          startTethering(type, showProvisioningUi, callback, null);
2484      }

2486      /**
2487       * Runs tether provisioning for the given type if needed and then starts tethering if
2488       * the check succeeds. If no carrier provisioning is required for tethering, tethering is
2489       * enabled immediately. If provisioning fails, tethering will not be enabled. It also
2490       * schedules tether provisioning re-checks if appropriate.
2491       *
2492       * @param type The type of tethering to start. Must be one of
2493       *         {@link ConnectivityManager.TETHERING_WIFI},
2494       *         {@link ConnectivityManager.TETHERING_USB}, or
2495       *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
2496       * @param showProvisioningUi a boolean indicating to show the provisioning app UI if there
2497       *         is one. This should be true the first time this function is called and also any time
2498       *         the user can see this UI. It gives users information from their carrier about the
2499       *         check failing and how they can sign up for tethering if possible.
2500       * @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
2501       *         of the result of trying to tether.
2502       * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
2503       *
2504       * @deprecated Use {@link TetheringManager#startTethering} instead.
2505       * @hide
2506       */
2507      @SystemApi
2508      @Deprecated
2509      @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
2510      public void startTethering(int type, boolean showProvisioningUi,
2511              final OnStartTetheringCallback callback, Handler handler) {
2512          Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null.");
2513  
2514          final Executor executor = new Executor() {
2515              @Override
2516              public void execute(Runnable command) {
2517                  if (handler == null) {
2518                      command.run();
2519                  } else {
2520                      handler.post(command);
2521                  }
2522              }
2523          };
2524  
2525          final StartTetheringCallback tetheringCallback = new StartTetheringCallback() {
2526              @Override
2527              public void onTetheringStarted() {
2528                  callback.onTetheringStarted();
2529              }
2530  
2531              @Override
2532              public void onTetheringFailed(final int error) {
2533                  callback.onTetheringFailed();
2534              }
2535          };
2536  
2537          final TetheringRequest request = new TetheringRequest.Builder(type)
2538                  .setShouldShowEntitlementUi(showProvisioningUi).build();
2539  
2540          mTetheringManager.startTethering(request, executor, tetheringCallback);
2541      }
/frameworks/base/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java

712      /**
713       * Starts tethering and runs tether provisioning for the given type if needed. If provisioning
714       * fails, stopTethering will be called automatically.
715       *
716       * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will
717       * fail if a tethering entitlement check is required.
718       *
719       * @param request a {@link TetheringRequest} which can specify the preferred configuration.
720       * @param executor {@link Executor} to specify the thread upon which the callback of
721       *         TetheringRequest will be invoked.
722       * @param callback A callback that will be called to indicate the success status of the
723       *                 tethering start request.
724       */
725      @RequiresPermission(anyOf = {
726              android.Manifest.permission.TETHER_PRIVILEGED,
727              android.Manifest.permission.WRITE_SETTINGS
728      })
729      public void startTethering(@NonNull final TetheringRequest request,
730              @NonNull final Executor executor, @NonNull final StartTetheringCallback callback) {
731          final String callerPkg = mContext.getOpPackageName();
732          Log.i(TAG, "startTethering caller:" + callerPkg);
733  
734          final IIntResultListener listener = new IIntResultListener.Stub() {
735              @Override
736              public void onResult(final int resultCode) {
737                  executor.execute(() -> {
738                      if (resultCode == TETHER_ERROR_NO_ERROR) {
739                          callback.onTetheringStarted();
740                      } else {
741                          callback.onTetheringFailed(resultCode);
742                      }
743                  });
744              }
745          };
746          getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener));
747      }

    /**
     * Attempt to both alter the mode of USB and Tethering of USB.
     *
     * @deprecated New client should not use this API anymore. All clients should use
     * #startTethering or #stopTethering which encapsulate proper entitlement logic. If the API is
     * used and an entitlement check is needed, downstream USB tethering will be enabled but will
     * not have any upstream.
     *
     * {@hide}
     */
    @Deprecated
    @SystemApi(client = MODULE_LIBRARIES)
    public int setUsbTethering(final boolean enable) {
        final String callerPkg = mContext.getOpPackageName();
        Log.i(TAG, "setUsbTethering caller:" + callerPkg);

        final RequestDispatcher dispatcher = new RequestDispatcher();

        return dispatcher.waitForResult((connector, listener) -> {
            try {
                connector.setUsbTethering(enable, callerPkg, listener);
            } catch (RemoteException e) {
                throw new IllegalStateException(e);
            }
        });
    }
/frameworks/base/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java

      private static class TetheringConnector extends ITetheringConnector.Stub {

        @Override
        public void setUsbTethering(boolean enable, String callerPkg, IIntResultListener listener) {
            if (checkAndNotifyCommonError(callerPkg, listener)) return;

            try {
                listener.onResult(mTethering.setUsbTethering(enable));
            } catch (RemoteException e) { }
        }
/frameworks/base/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java

1288      int setUsbTethering(boolean enable) {
1289          if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
1290          UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
1291          if (usbManager == null) {
1292              mLog.e("setUsbTethering: failed to get UsbManager!");
1293              return TETHER_ERROR_SERVICE_UNAVAIL;
1294          }
1295  
1296          synchronized (mPublicSync) {
1297              usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_RNDIS
1298                      : UsbManager.FUNCTION_NONE);
1299          }
1300          return TETHER_ERROR_NO_ERROR;
1301      }
 /frameworks/base/services/core/java/com/android/server/NetworkManagementService.java

992      @Override
993      public void startTethering(String[] dhcpRange) {
994          startTetheringWithConfiguration(true, dhcpRange);
995      }
996  
997      @Override
998      public void startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange) {
999          NetworkStack.checkNetworkStackPermission(mContext);
1000          try {
1001              NetdUtils.tetherStart(mNetdService, usingLegacyDnsProxy, dhcpRange);
1002          } catch (RemoteException | ServiceSpecificException e) {
1003              throw new IllegalStateException(e);
1004          }
1005      }
/packages/modules/NetworkStack/common/moduleutils/src/android/net/shared/NetdUtils.java

41      /** Start tethering. */
42      public static void tetherStart(final INetd netd, final boolean usingLegacyDnsProxy,
43              final String[] dhcpRange) throws RemoteException, ServiceSpecificException {
44          final TetherConfigParcel config = new TetherConfigParcel();
45          config.usingLegacyDnsProxy = usingLegacyDnsProxy;
46          config.dhcpRanges = dhcpRange;
47          netd.tetherStartWithConfiguration(config);
48      }
/system/netd/server/NetdNativeService.cpp

931  binder::Status NetdNativeService::tetherStartWithConfiguration(const TetherConfigParcel& config) {
932      NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
933      if (config.dhcpRanges.size() % 2 == 1) {
934          return statusFromErrcode(-EINVAL);
935      }
936      // TODO: Pass TetherConfigParcel directly.
937      int res = gCtls->tetherCtrl.startTethering(config.usingLegacyDnsProxy, config.dhcpRanges);
938      return statusFromErrcode(res);
939  }
/system/netd/server/TetherController.cpp

int TetherController::startTethering(bool usingLegacyDnsProxy,
                                     const std::vector<std::string>& dhcpRanges) {
    struct in_addr v4_addr;
    for (const auto& dhcpRange : dhcpRanges) {
        if (!inet_aton(dhcpRange.c_str(), &v4_addr)) {
            return -EINVAL;
        }
    }
    auto dhcp_ranges = toCstrVec(dhcpRanges);
    return startTethering(usingLegacyDnsProxy, dhcp_ranges.size(), dhcp_ranges.data());
}

int TetherController::startTethering(bool usingLegacyDnsProxy, int num_addrs, char** dhcp_ranges) {
    if (!usingLegacyDnsProxy && num_addrs == 0) {
        // Both DHCP and DnsProxy are disabled, we don't need to start dnsmasq
        configureForTethering(true);
        mIsTetheringStarted = true;
        return 0;
    }

    if (mIsTetheringStarted) {
        ALOGE("Tethering already started");
        errno = EBUSY;
        return -errno;
    }

    ALOGD("Starting tethering services");

    unique_fd pipeRead, pipeWrite;
    if (!Pipe(&pipeRead, &pipeWrite, O_CLOEXEC)) {
        int res = errno;
        ALOGE("pipe2() failed (%s)", strerror(errno));
        return -res;
    }

    // Set parameters
    Fwmark fwmark;
    fwmark.netId = NetworkController::LOCAL_NET_ID;
    fwmark.explicitlySelected = true;
    fwmark.protectedFromVpn = true;
    fwmark.permission = PERMISSION_SYSTEM;
    char markStr[UINT32_HEX_STRLEN];
    snprintf(markStr, sizeof(markStr), "0x%x", fwmark.intValue);

    std::vector<const std::string> argVector = {
            "/system/bin/dnsmasq",
            "--keep-in-foreground",
            "--no-resolv",
            "--no-poll",
            "--dhcp-authoritative",
            // TODO: pipe through metered status from ConnService
            "--dhcp-option-force=43,ANDROID_METERED",
            "--pid-file",
            "--listen-mark",
            markStr,
            "--user",
            kDnsmasqUsername,
    };

    if (!usingLegacyDnsProxy) {
        argVector.push_back("--port=0");
    }

    // DHCP server will be disabled if num_addrs == 0 and no --dhcp-range is passed.
    for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
        argVector.push_back(StringPrintf("--dhcp-range=%s,%s,1h", dhcp_ranges[addrIndex],
                                         dhcp_ranges[addrIndex + 1]));
    }

    std::vector<char*> args(argVector.size() + 1);
    for (unsigned i = 0; i < argVector.size(); i++) {
        args[i] = (char*)argVector[i].c_str();
    }

    /*
     * TODO: Create a monitoring thread to handle and restart
     * the daemon if it exits prematurely
     */

    // Note that don't modify any memory between vfork and execv.
    // Changing state of file descriptors would be fine. See posix_spawn_file_actions_add*
    // dup2 creates fd without CLOEXEC, dnsmasq will receive commands through the
    // duplicated fd.
    posix_spawn_file_actions_t fa;
    int res = posix_spawn_file_actions_init(&fa);
    if (res) {
        ALOGE("posix_spawn_file_actions_init failed (%s)", strerror(res));
        return -res;
    }
    const android::base::ScopeGuard faGuard = [&] { posix_spawn_file_actions_destroy(&fa); };
    res = posix_spawn_file_actions_adddup2(&fa, pipeRead.get(), STDIN_FILENO);
    if (res) {
        ALOGE("posix_spawn_file_actions_adddup2 failed (%s)", strerror(res));
        return -res;
    }

    posix_spawnattr_t attr;
    res = posix_spawnattr_init(&attr);
    if (res) {
        ALOGE("posix_spawnattr_init failed (%s)", strerror(res));
        return -res;
    }
    const android::base::ScopeGuard attrGuard = [&] { posix_spawnattr_destroy(&attr); };
    res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_USEVFORK);
    if (res) {
        ALOGE("posix_spawnattr_setflags failed (%s)", strerror(res));
        return -res;
    }

    pid_t pid;
    res = posix_spawn(&pid, args[0], &fa, &attr, &args[0], nullptr);
    if (res) {
        ALOGE("posix_spawn failed (%s)", strerror(res));
        return -res;
    }
    mDaemonPid = pid;
    mDaemonFd = pipeWrite.release();
    configureForTethering(true);
    mIsTetheringStarted = true;
    applyDnsInterfaces();
    ALOGD("Tethering services running");

    return 0;
}

int TetherController::stopTethering() {
    configureForTethering(false);

    if (!mIsTetheringStarted) {
        ALOGE("Tethering already stopped");
        return 0;
    }

    mIsTetheringStarted = false;
    // dnsmasq is not started
    if (mDaemonPid == 0) {
        return 0;
    }

    ALOGD("Stopping tethering services");

    kill(mDaemonPid, SIGTERM);
    waitpid(mDaemonPid, nullptr, 0);
    mDaemonPid = 0;
    close(mDaemonFd);
    mDaemonFd = -1;
    mDnsmasqState.clear();
    ALOGD("Tethering services stopped");
    return 0;
}

bool TetherController::isTetheringStarted() {
    return mIsTetheringStarted;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值