diff options
21 files changed, 776 insertions, 403 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index c58972e5310e..970739cc92eb 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -112,7 +112,6 @@ import android.net.lowpan.ILowpanManager; import android.net.lowpan.LowpanManager; import android.net.nsd.INsdManager; import android.net.nsd.NsdManager; -import android.net.wifi.IWifiManager; import android.net.wifi.IWifiScanner; import android.net.wifi.RttManager; import android.net.wifi.WifiManager; @@ -730,10 +729,8 @@ public final class SystemServiceRegistry { registerService(Context.WIFI_SERVICE, WifiManager.class, new CachedServiceFetcher<WifiManager>() { @Override - public WifiManager createService(ContextImpl ctx) throws ServiceNotFoundException { - IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_SERVICE); - IWifiManager service = IWifiManager.Stub.asInterface(b); - return new WifiManager(ctx.getOuterContext(), service, + public WifiManager createService(ContextImpl ctx) { + return new WifiManager(ctx.getOuterContext(), ConnectivityThread.getInstanceLooper()); }}); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 73bc908632b2..3adef3fb09d0 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3735,6 +3735,14 @@ public abstract class Context { public static final String NETWORK_STACK_SERVICE = "network_stack"; /** + * Use with {@link android.os.ServiceManager.getService()} to retrieve a + * {@link android.net.WifiStackClient} IBinder for communicating with the network stack + * @hide + * @see android.net.WifiStackClient + */ + public static final String WIFI_STACK_SERVICE = "wifi_stack"; + + /** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.net.IpSecManager} for encrypting Sockets or Networks with * IPSec. diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 4025a08e1b89..226c26900d17 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -350,4 +350,19 @@ applications that come with the platform <permission name="android.permission.MANAGE_DYNAMIC_SYSTEM"/> </privapp-permissions> + <privapp-permissions package="com.android.server.wifistack"> + <permission name="android.permission.CHANGE_CONFIGURATION"/> + <permission name="android.permission.CONNECTIVITY_INTERNAL"/> + <permission name="android.permission.DUMP"/> + <permission name="android.permission.INTERACT_ACROSS_USERS"/> + <permission name="android.permission.LOCAL_MAC_ADDRESS"/> + <permission name="android.permission.MANAGE_USERS"/> + <permission name="android.permission.PACKAGE_USAGE_STATS"/> + <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> + <permission name="android.permission.REQUEST_NETWORK_SCORES"/> + <permission name="android.permission.WRITE_SECURE_SETTINGS"/> + <permission name="android.permission.UPDATE_DEVICE_STATS"/> + <permission name="android.permission.UPDATE_APP_OPS_STATS"/> + <permission name="android.permission.LOCATION_HARDWARE"/> + </privapp-permissions> </permissions> diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 3e359d216234..d3bab5f41f39 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -224,7 +224,9 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro mConnectivityManager = connectivityManager; // check if verbose logging developer option has been turned on or off - sVerboseLogging = mWifiManager != null && (mWifiManager.getVerboseLoggingLevel() > 0); + sVerboseLogging = Settings.Global.getInt( + mContext.getContentResolver(), + Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0) > 0; mFilter = filter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 001e09406e3a..16a39750a9bd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -73,6 +73,7 @@ public class HotspotTile extends QSTileImpl<BooleanState> { if (listening) { refreshState(); } + mHotspotController.handleSetListening(listening); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java index 830b50e35490..8b06a9fa05a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java @@ -20,6 +20,8 @@ import com.android.systemui.Dumpable; import com.android.systemui.statusbar.policy.HotspotController.Callback; public interface HotspotController extends CallbackController<Callback>, Dumpable { + void handleSetListening(boolean listening); + boolean isHotspotEnabled(); boolean isHotspotTransient(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java index db2be0e78e9a..1c6d12f15e4c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -51,6 +51,7 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof private int mHotspotState; private int mNumConnectedDevices; private boolean mWaitingForTerminalState; + private boolean mListening; /** */ @@ -105,14 +106,18 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof if (DEBUG) Log.d(TAG, "addCallback " + callback); mCallbacks.add(callback); if (mWifiManager != null) { - if (mCallbacks.size() == 1) { - mWifiManager.registerSoftApCallback(this, mMainHandler); - } else { - // mWifiManager#registerSoftApCallback triggers a call to onNumClientsChanged - // on the Main Handler. In order to always update the callback on added, we - // make this call when adding callbacks after the first. - mMainHandler.post(() -> - callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices)); + if (mListening) { + if (mCallbacks.size() == 1) { + mWifiManager.registerSoftApCallback(this, mMainHandler); + } else { + // mWifiManager#registerSoftApCallback triggers a call to + // onNumClientsChanged on the Main Handler. In order to always update the + // callback on added, we make this call when adding callbacks after the + // first. + mMainHandler.post(() -> + callback.onHotspotChanged(isHotspotEnabled(), + mNumConnectedDevices)); + } } } } @@ -124,13 +129,24 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof if (DEBUG) Log.d(TAG, "removeCallback " + callback); synchronized (mCallbacks) { mCallbacks.remove(callback); - if (mCallbacks.isEmpty() && mWifiManager != null) { + if (mCallbacks.isEmpty() && mWifiManager != null && mListening) { mWifiManager.unregisterSoftApCallback(this); } } } @Override + public void handleSetListening(boolean listening) { + // Wait for the first |handleSetListening(true))| to register softap callbacks (for lazy + // registration of the softap callbacks). + if (mListening || !listening) return; + mListening = true; + if (mCallbacks.size() >= 1) { + mWifiManager.registerSoftApCallback(this, mMainHandler); + } + } + + @Override public boolean isHotspotEnabled() { return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 1c24bb9e88d1..04f96a46bbf7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -312,6 +312,7 @@ public class NetworkControllerImpl extends BroadcastReceiver filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(ConnectivityManager.INET_CONDITION_ACTION); filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); + filter.addAction(Intent.ACTION_BOOT_COMPLETED); filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); mContext.registerReceiver(this, filter, null, mReceiverHandler); mListening = true; @@ -513,6 +514,9 @@ public class NetworkControllerImpl extends BroadcastReceiver recalculateEmergency(); } break; + case Intent.ACTION_BOOT_COMPLETED: + mWifiSignalController.handleBootCompleted(); + break; case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: mConfig = Config.readConfig(mContext); mReceiverHandler.post(this::handleConfigurationChanged); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java index 6f63544d3cfa..a441f660ecb7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java @@ -38,6 +38,7 @@ import java.util.Objects; public class WifiSignalController extends SignalController<WifiSignalController.WifiState, SignalController.IconGroup> { private final boolean mHasMobileData; + private final WifiManager mWifiManager; private final WifiStatusTracker mWifiTracker; public WifiSignalController(Context context, boolean hasMobileData, @@ -49,13 +50,11 @@ public class WifiSignalController extends context.getSystemService(NetworkScoreManager.class); ConnectivityManager connectivityManager = context.getSystemService(ConnectivityManager.class); + mWifiManager = wifiManager; mWifiTracker = new WifiStatusTracker(mContext, wifiManager, networkScoreManager, connectivityManager, this::handleStatusUpdated); mWifiTracker.setListening(true); mHasMobileData = hasMobileData; - if (wifiManager != null) { - wifiManager.registerTrafficStateCallback(new WifiTrafficStateCallback(), null); - } // WiFi only has one state. mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup( "Wi-Fi Icons", @@ -128,6 +127,10 @@ public class WifiSignalController extends notifyListenersIfNecessary(); } + public void handleBootCompleted() { + mWifiManager.registerTrafficStateCallback(new WifiTrafficStateCallback(), null); + } + /** * Handler to receive the data activity on wifi. */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java index 3e4c4d6a7a8a..556ed5c30496 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java @@ -73,6 +73,7 @@ public class HotspotControllerImplTest extends SysuiTestCase { any(Handler.class)); mController = new HotspotControllerImpl(mContext, new Handler(mLooper.getLooper())); + mController.handleSetListening(true); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeHotspotController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeHotspotController.java index 016160aea433..c9681ac558f9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeHotspotController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeHotspotController.java @@ -26,6 +26,10 @@ public class FakeHotspotController extends BaseLeakChecker<Callback> implements } @Override + public void handleSetListening(boolean listening) { + } + + @Override public boolean isHotspotEnabled() { return false; } diff --git a/services/Android.bp b/services/Android.bp index b08d1a8095db..54157d0b7eb1 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -35,6 +35,7 @@ java_library { "services.usage", "services.usb", "services.voiceinteraction", + "services.wifi", "android.hidl.base-V1.0-java", ], diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index dee89e5d5c4d..ea3dd3d4ba8d 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -25,7 +25,7 @@ import android.annotation.Nullable; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; -import android.net.NetworkStackClient; +import android.net.ConnectivityModuleConnector; import android.os.Environment; import android.os.Handler; import android.os.Looper; @@ -116,7 +116,7 @@ public class PackageWatchdog { // File containing the XML data of monitored packages /data/system/package-watchdog.xml private final AtomicFile mPolicyFile; private final ExplicitHealthCheckController mHealthCheckController; - private final NetworkStackClient mNetworkStackClient; + private final ConnectivityModuleConnector mConnectivityModuleConnector; @GuardedBy("mLock") private boolean mIsPackagesReady; // Flag to control whether explicit health checks are supported or not @@ -138,7 +138,7 @@ public class PackageWatchdog { "package-watchdog.xml")), new Handler(Looper.myLooper()), BackgroundThread.getHandler(), new ExplicitHealthCheckController(context), - NetworkStackClient.getInstance()); + ConnectivityModuleConnector.getInstance()); } /** @@ -147,13 +147,13 @@ public class PackageWatchdog { @VisibleForTesting PackageWatchdog(Context context, AtomicFile policyFile, Handler shortTaskHandler, Handler longTaskHandler, ExplicitHealthCheckController controller, - NetworkStackClient networkStackClient) { + ConnectivityModuleConnector connectivityModuleConnector) { mContext = context; mPolicyFile = policyFile; mShortTaskHandler = shortTaskHandler; mLongTaskHandler = longTaskHandler; mHealthCheckController = controller; - mNetworkStackClient = networkStackClient; + mConnectivityModuleConnector = connectivityModuleConnector; loadFromFile(); } @@ -179,7 +179,7 @@ public class PackageWatchdog { () -> syncRequestsAsync()); setPropertyChangedListenerLocked(); updateConfigs(); - registerNetworkStackHealthListener(); + registerConnectivityModuleHealthListener(); } } @@ -743,11 +743,11 @@ public class PackageWatchdog { } } - private void registerNetworkStackHealthListener() { + private void registerConnectivityModuleHealthListener() { // TODO: have an internal method to trigger a rollback by reporting high severity errors, // and rely on ActivityManager to inform the watchdog of severe network stack crashes // instead of having this listener in parallel. - mNetworkStackClient.registerHealthListener( + mConnectivityModuleConnector.registerHealthListener( packageName -> { final VersionedPackage pkg = getVersionedPackage(packageName); if (pkg == null) { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 83b3194815e4..4ba75a60e4ab 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -39,7 +39,9 @@ import android.content.res.Resources.Theme; import android.database.sqlite.SQLiteCompatibilityWalFlags; import android.database.sqlite.SQLiteGlobal; import android.hardware.display.DisplayManagerInternal; +import android.net.ConnectivityModuleConnector; import android.net.NetworkStackClient; +import android.net.wifi.WifiStackClient; import android.os.BaseBundle; import android.os.Binder; import android.os.Build; @@ -1274,6 +1276,14 @@ public final class SystemServer { mSystemServiceManager.startService(CONTENT_SUGGESTIONS_SERVICE_CLASS); t.traceEnd(); + t.traceBegin("InitConnectivityModuleConnector"); + try { + ConnectivityModuleConnector.getInstance().init(context); + } catch (Throwable e) { + reportWtf("initializing ConnectivityModuleConnector", e); + } + t.traceEnd(); + t.traceBegin("InitNetworkStackClient"); try { NetworkStackClient.getInstance().init(); @@ -1336,40 +1346,6 @@ public final class SystemServer { t.traceEnd(); if (context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WIFI)) { - // Wifi Service must be started first for wifi-related services. - t.traceBegin("StartWifi"); - mSystemServiceManager.startService(WIFI_SERVICE_CLASS); - t.traceEnd(); - t.traceBegin("StartWifiScanning"); - mSystemServiceManager.startService( - "com.android.server.wifi.scanner.WifiScanningService"); - t.traceEnd(); - } - - if (context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WIFI_RTT)) { - t.traceBegin("StartRttService"); - mSystemServiceManager.startService( - "com.android.server.wifi.rtt.RttService"); - t.traceEnd(); - } - - if (context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WIFI_AWARE)) { - t.traceBegin("StartWifiAware"); - mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS); - t.traceEnd(); - } - - if (context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WIFI_DIRECT)) { - t.traceBegin("StartWifiP2P"); - mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS); - t.traceEnd(); - } - - if (context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_LOWPAN)) { t.traceBegin("StartLowpan"); mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS); @@ -2168,12 +2144,21 @@ public final class SystemServer { // ActivityManagerService.mSystemReady and ActivityManagerService.mProcessesReady // are set to true. Be careful if moving this to a different place in the // startup sequence. - NetworkStackClient.getInstance().start(context); + NetworkStackClient.getInstance().start(); } catch (Throwable e) { reportWtf("starting Network Stack", e); } t.traceEnd(); + t.traceBegin("StartWifiStack"); + try { + WifiStackClient.getInstance().start(); + } catch (Throwable e) { + reportWtf("starting Wifi Stack", e); + } + t.traceEnd(); + + t.traceBegin("MakeLocationServiceReady"); try { if (locationF != null) { diff --git a/services/net/java/android/net/ConnectivityModuleConnector.java b/services/net/java/android/net/ConnectivityModuleConnector.java new file mode 100644 index 000000000000..7333f583e8e8 --- /dev/null +++ b/services/net/java/android/net/ConnectivityModuleConnector.java @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.net; + +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.net.util.SharedLog; +import android.os.Build; +import android.os.Environment; +import android.os.IBinder; +import android.os.Process; +import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.DeviceConfig; +import android.text.format.DateUtils; +import android.util.ArraySet; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; + +import java.io.File; +import java.io.PrintWriter; + +/** + * Class used to communicate to the various networking mainline modules running in the network stack + * process from {@link com.android.server.SystemServer}. + * @hide + */ +public class ConnectivityModuleConnector { + private static final String TAG = ConnectivityModuleConnector.class.getSimpleName(); + private static final String IN_PROCESS_SUFFIX = ".InProcess"; + + private static final String PREFS_FILE = "ConnectivityModuleConnector.xml"; + private static final String PREF_KEY_LAST_CRASH_TIME = "lastcrash_time"; + private static final String CONFIG_MIN_CRASH_INTERVAL_MS = "min_crash_interval"; + private static final String CONFIG_MIN_UPTIME_BEFORE_CRASH_MS = "min_uptime_before_crash"; + private static final String CONFIG_ALWAYS_RATELIMIT_NETWORKSTACK_CRASH = + "always_ratelimit_networkstack_crash"; + + // Even if the network stack is lost, do not crash the system more often than this. + // Connectivity would be broken, but if the user needs the device for something urgent + // (like calling emergency services) we should not bootloop the device. + // This is the default value: the actual value can be adjusted via device config. + private static final long DEFAULT_MIN_CRASH_INTERVAL_MS = 6 * DateUtils.HOUR_IN_MILLIS; + + // Even if the network stack is lost, do not crash the system server if it was less than + // this much after boot. This avoids bootlooping the device, and crashes should address very + // infrequent failures, not failures on boot. + private static final long DEFAULT_MIN_UPTIME_BEFORE_CRASH_MS = 30 * DateUtils.MINUTE_IN_MILLIS; + + private static ConnectivityModuleConnector sInstance; + + private Context mContext; + @GuardedBy("mLog") + private final SharedLog mLog = new SharedLog(TAG); + @GuardedBy("mHealthListeners") + private final ArraySet<ConnectivityModuleHealthListener> mHealthListeners = new ArraySet<>(); + + private ConnectivityModuleConnector() { } + + /** + * Get the {@link ConnectivityModuleConnector} singleton instance. + */ + public static synchronized ConnectivityModuleConnector getInstance() { + if (sInstance == null) { + sInstance = new ConnectivityModuleConnector(); + } + return sInstance; + } + + /** + * Initialize the network stack connector. Should be called only once on device startup, before + * any client attempts to use the network stack. + */ + public void init(Context context) { + log("Network stack init"); + mContext = context; + } + + /** + * Callback interface for severe failures of the NetworkStack. + * + * <p>Useful for health monitors such as PackageWatchdog. + */ + public interface ConnectivityModuleHealthListener { + /** + * Called when there is a severe failure of the network stack. + * @param packageName Package name of the network stack. + */ + void onNetworkStackFailure(@NonNull String packageName); + } + + /** + * Callback invoked by the connector once the connection to the corresponding module is + * established. + */ + public interface ModuleServiceCallback { + /** + * Invoked when the corresponding service has connected. + * + * @param iBinder Binder object for the service. + */ + void onModuleServiceConnected(@NonNull IBinder iBinder); + } + + + /** + * Add a {@link ConnectivityModuleHealthListener} to listen to network stack health events. + */ + public void registerHealthListener(@NonNull ConnectivityModuleHealthListener listener) { + synchronized (mHealthListeners) { + mHealthListeners.add(listener); + } + } + + /** + * Start a module running in the network stack or system_server process. Should be called only + * once for each module per device startup. + * + * <p>This method will start a networking module either in the network stack + * process, or inside the system server on devices that do not support the corresponding + * mainline network . The corresponding networking module service's binder + * object will then be delivered asynchronously via the provided {@link ModuleServiceCallback}. + * + * @param serviceIntentBaseAction Base action to use for constructing the intent needed to + * bind to the corresponding module. + * @param servicePermissionName Permission to be held by the corresponding module. + */ + public void startModuleService( + @NonNull String serviceIntentBaseAction, + @NonNull String servicePermissionName, + @NonNull ModuleServiceCallback callback) { + log("Starting networking module " + serviceIntentBaseAction); + + final PackageManager pm = mContext.getPackageManager(); + + // Try to bind in-process if the device was shipped with an in-process version + Intent intent = getModuleServiceIntent(pm, serviceIntentBaseAction, servicePermissionName, + true /* inSystemProcess */); + + // Otherwise use the updatable module version + if (intent == null) { + intent = getModuleServiceIntent(pm, serviceIntentBaseAction, servicePermissionName, + false /* inSystemProcess */); + log("Starting networking module in network_stack process"); + } else { + log("Starting networking module in system_server process"); + } + + if (intent == null) { + maybeCrashWithTerribleFailure("Could not resolve the networking module", null); + return; + } + + final String packageName = intent.getComponent().getPackageName(); + + // Start the network stack. The service will be added to the service manager by the + // corresponding client in ModuleServiceCallback.onModuleServiceConnected(). + if (!mContext.bindServiceAsUser( + intent, new ModuleServiceConnection(packageName, callback), + Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { + maybeCrashWithTerribleFailure( + "Could not bind to networking module in-process, or in app with " + + intent, packageName); + return; + } + + log("Networking module service start requested"); + } + + private class ModuleServiceConnection implements ServiceConnection { + @NonNull + private final String mPackageName; + @NonNull + private final ModuleServiceCallback mModuleServiceCallback; + + private ModuleServiceConnection( + @NonNull String packageName, + @NonNull ModuleServiceCallback moduleCallback) { + mPackageName = packageName; + mModuleServiceCallback = moduleCallback; + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + logi("Networking module service connected"); + mModuleServiceCallback.onModuleServiceConnected(service); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + // onServiceDisconnected is not being called on device shutdown, so this method being + // called always indicates a bad state for the system server. + // This code path is only run by the system server: only the system server binds + // to the NetworkStack as a service. Other processes get the NetworkStack from + // the ServiceManager. + maybeCrashWithTerribleFailure("Lost network stack", mPackageName); + } + } + + @Nullable + private Intent getModuleServiceIntent( + @NonNull PackageManager pm, @NonNull String serviceIntentBaseAction, + @NonNull String servicePermissionName, boolean inSystemProcess) { + final Intent intent = + new Intent(inSystemProcess + ? serviceIntentBaseAction + IN_PROCESS_SUFFIX + : serviceIntentBaseAction); + final ComponentName comp = intent.resolveSystemService(pm, 0); + if (comp == null) { + return null; + } + intent.setComponent(comp); + + int uid = -1; + try { + uid = pm.getPackageUidAsUser(comp.getPackageName(), UserHandle.USER_SYSTEM); + } catch (PackageManager.NameNotFoundException e) { + logWtf("Networking module package not found", e); + // Fall through + } + + final int expectedUid = inSystemProcess ? Process.SYSTEM_UID : Process.NETWORK_STACK_UID; + if (uid != expectedUid) { + throw new SecurityException("Invalid network stack UID: " + uid); + } + + if (!inSystemProcess) { + checkModuleServicePermission(pm, comp, servicePermissionName); + } + + return intent; + } + + private void checkModuleServicePermission( + @NonNull PackageManager pm, @NonNull ComponentName comp, + @NonNull String servicePermissionName) { + final int hasPermission = + pm.checkPermission(servicePermissionName, comp.getPackageName()); + if (hasPermission != PERMISSION_GRANTED) { + throw new SecurityException( + "Networking module does not have permission " + servicePermissionName); + } + } + + private synchronized void maybeCrashWithTerribleFailure(@NonNull String message, + @Nullable String packageName) { + logWtf(message, null); + // uptime is monotonic even after a framework restart + final long uptime = SystemClock.elapsedRealtime(); + final long now = System.currentTimeMillis(); + final long minCrashIntervalMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_CONNECTIVITY, + CONFIG_MIN_CRASH_INTERVAL_MS, DEFAULT_MIN_CRASH_INTERVAL_MS); + final long minUptimeBeforeCrash = DeviceConfig.getLong(DeviceConfig.NAMESPACE_CONNECTIVITY, + CONFIG_MIN_UPTIME_BEFORE_CRASH_MS, DEFAULT_MIN_UPTIME_BEFORE_CRASH_MS); + final boolean alwaysRatelimit = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CONNECTIVITY, + CONFIG_ALWAYS_RATELIMIT_NETWORKSTACK_CRASH, false); + + final SharedPreferences prefs = getSharedPreferences(); + final long lastCrashTime = tryGetLastCrashTime(prefs); + + // Only crash if there was enough time since boot, and (if known) enough time passed since + // the last crash. + // time and lastCrashTime may be unreliable if devices have incorrect clock time, but they + // are only used to limit the number of crashes compared to only using the time since boot, + // which would also be OK behavior by itself. + // - If lastCrashTime is incorrectly more than the current time, only look at uptime + // - If it is much less than current time, only look at uptime + // - If current time is during the next few hours after last crash time, don't crash. + // Considering that this only matters if last boot was some time ago, it's likely that + // time will be set correctly. Otherwise, not crashing is not a big problem anyway. Being + // in this last state would also not last for long since the window is only a few hours. + final boolean alwaysCrash = Build.IS_DEBUGGABLE && !alwaysRatelimit; + final boolean justBooted = uptime < minUptimeBeforeCrash; + final boolean haveLastCrashTime = (lastCrashTime != 0) && (lastCrashTime < now); + final boolean haveKnownRecentCrash = + haveLastCrashTime && (now < lastCrashTime + minCrashIntervalMs); + if (alwaysCrash || (!justBooted && !haveKnownRecentCrash)) { + // The system is not bound to its network stack (for example due to a crash in the + // network stack process): better crash rather than stay in a bad state where all + // networking is broken. + // Using device-encrypted SharedPreferences as DeviceConfig does not have a synchronous + // API to persist settings before a crash. + tryWriteLastCrashTime(prefs, now); + throw new IllegalStateException(message); + } + + // Here the system crashed recently already. Inform listeners that something is + // definitely wrong. + if (packageName != null) { + final ArraySet<ConnectivityModuleHealthListener> listeners; + synchronized (mHealthListeners) { + listeners = new ArraySet<>(mHealthListeners); + } + for (ConnectivityModuleHealthListener listener : listeners) { + listener.onNetworkStackFailure(packageName); + } + } + } + + @Nullable + private SharedPreferences getSharedPreferences() { + try { + final File prefsFile = new File( + Environment.getDataSystemDeDirectory(UserHandle.USER_SYSTEM), PREFS_FILE); + return mContext.createDeviceProtectedStorageContext() + .getSharedPreferences(prefsFile, Context.MODE_PRIVATE); + } catch (Throwable e) { + logWtf("Error loading shared preferences", e); + return null; + } + } + + private long tryGetLastCrashTime(@Nullable SharedPreferences prefs) { + if (prefs == null) return 0L; + try { + return prefs.getLong(PREF_KEY_LAST_CRASH_TIME, 0L); + } catch (Throwable e) { + logWtf("Error getting last crash time", e); + return 0L; + } + } + + private void tryWriteLastCrashTime(@Nullable SharedPreferences prefs, long value) { + if (prefs == null) return; + try { + prefs.edit().putLong(PREF_KEY_LAST_CRASH_TIME, value).commit(); + } catch (Throwable e) { + logWtf("Error writing last crash time", e); + } + } + + private void log(@NonNull String message) { + Slog.d(TAG, message); + synchronized (mLog) { + mLog.log(message); + } + } + + private void logWtf(@NonNull String message, @Nullable Throwable e) { + Slog.wtf(TAG, message, e); + synchronized (mLog) { + mLog.e(message); + } + } + + private void loge(@NonNull String message, @Nullable Throwable e) { + Slog.e(TAG, message, e); + synchronized (mLog) { + mLog.e(message); + } + } + + private void logi(@NonNull String message) { + Slog.i(TAG, message); + synchronized (mLog) { + mLog.i(message); + } + } + + /** + * Dump ConnectivityModuleConnector logs to the specified {@link PrintWriter}. + */ + public void dump(PrintWriter pw) { + // dump is thread-safe on SharedLog + mLog.dump(null, pw, null); + } +} diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java index 56b728c87180..abb46664e40d 100644 --- a/services/net/java/android/net/NetworkStackClient.java +++ b/services/net/java/android/net/NetworkStackClient.java @@ -15,40 +15,27 @@ */ package android.net; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.net.dhcp.DhcpServingParamsParcel; import android.net.dhcp.IDhcpServerCallbacks; import android.net.ip.IIpClientCallbacks; import android.net.util.SharedLog; import android.os.Binder; -import android.os.Build; -import android.os.Environment; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.SystemClock; import android.os.UserHandle; -import android.provider.DeviceConfig; -import android.text.format.DateUtils; -import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; -import java.io.File; import java.io.PrintWriter; import java.util.ArrayList; @@ -60,24 +47,6 @@ public class NetworkStackClient { private static final String TAG = NetworkStackClient.class.getSimpleName(); private static final int NETWORKSTACK_TIMEOUT_MS = 10_000; - private static final String IN_PROCESS_SUFFIX = ".InProcess"; - private static final String PREFS_FILE = "NetworkStackClientPrefs.xml"; - private static final String PREF_KEY_LAST_CRASH_TIME = "lastcrash_time"; - private static final String CONFIG_MIN_CRASH_INTERVAL_MS = "min_crash_interval"; - private static final String CONFIG_MIN_UPTIME_BEFORE_CRASH_MS = "min_uptime_before_crash"; - private static final String CONFIG_ALWAYS_RATELIMIT_NETWORKSTACK_CRASH = - "always_ratelimit_networkstack_crash"; - - // Even if the network stack is lost, do not crash the system more often than this. - // Connectivity would be broken, but if the user needs the device for something urgent - // (like calling emergency services) we should not bootloop the device. - // This is the default value: the actual value can be adjusted via device config. - private static final long DEFAULT_MIN_CRASH_INTERVAL_MS = 6 * DateUtils.HOUR_IN_MILLIS; - - // Even if the network stack is lost, do not crash the system server if it was less than - // this much after boot. This avoids bootlooping the device, and crashes should address very - // infrequent failures, not failures on boot. - private static final long DEFAULT_MIN_UPTIME_BEFORE_CRASH_MS = 30 * DateUtils.MINUTE_IN_MILLIS; private static NetworkStackClient sInstance; @@ -93,26 +62,10 @@ public class NetworkStackClient { private volatile boolean mWasSystemServerInitialized = false; - @GuardedBy("mHealthListeners") - private final ArraySet<NetworkStackHealthListener> mHealthListeners = new ArraySet<>(); - private interface NetworkStackCallback { void onNetworkStackConnected(INetworkStackConnector connector); } - /** - * Callback interface for severe failures of the NetworkStack. - * - * <p>Useful for health monitors such as PackageWatchdog. - */ - public interface NetworkStackHealthListener { - /** - * Called when there is a severe failure of the network stack. - * @param packageName Package name of the network stack. - */ - void onNetworkStackFailure(@NonNull String packageName); - } - private NetworkStackClient() { } /** @@ -126,15 +79,6 @@ public class NetworkStackClient { } /** - * Add a {@link NetworkStackHealthListener} to listen to network stack health events. - */ - public void registerHealthListener(@NonNull NetworkStackHealthListener listener) { - synchronized (mHealthListeners) { - mHealthListeners.add(listener); - } - } - - /** * Create a DHCP server according to the specified parameters. * * <p>The server will be returned asynchronously through the provided callbacks. @@ -195,32 +139,13 @@ public class NetworkStackClient { }); } - private class NetworkStackConnection implements ServiceConnection { - @NonNull - private final Context mContext; - @NonNull - private final String mPackageName; - - private NetworkStackConnection(@NonNull Context context, @NonNull String packageName) { - mContext = context; - mPackageName = packageName; - } - + private class NetworkStackConnection implements + ConnectivityModuleConnector.ModuleServiceCallback { @Override - public void onServiceConnected(ComponentName name, IBinder service) { + public void onModuleServiceConnected(IBinder service) { logi("Network stack service connected"); registerNetworkStackService(service); } - - @Override - public void onServiceDisconnected(ComponentName name) { - // onServiceDisconnected is not being called on device shutdown, so this method being - // called always indicates a bad state for the system server. - // This code path is only run by the system server: only the system server binds - // to the NetworkStack as a service. Other processes get the NetworkStack from - // the ServiceManager. - maybeCrashWithTerribleFailure("Lost network stack", mContext, mPackageName); - } } private void registerNetworkStackService(@NonNull IBinder service) { @@ -259,171 +184,13 @@ public class NetworkStackClient { * connector will then be delivered asynchronously to clients that requested it before it was * started. */ - public void start(Context context) { - log("Starting network stack"); - - final PackageManager pm = context.getPackageManager(); - - // Try to bind in-process if the device was shipped with an in-process version - Intent intent = getNetworkStackIntent(pm, true /* inSystemProcess */); - - // Otherwise use the updatable module version - if (intent == null) { - intent = getNetworkStackIntent(pm, false /* inSystemProcess */); - log("Starting network stack process"); - } else { - log("Starting network stack in-process"); - } - - if (intent == null) { - maybeCrashWithTerribleFailure("Could not resolve the network stack", context, null); - return; - } - - final String packageName = intent.getComponent().getPackageName(); - - // Start the network stack. The service will be added to the service manager in - // NetworkStackConnection.onServiceConnected(). - if (!context.bindServiceAsUser(intent, new NetworkStackConnection(context, packageName), - Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { - maybeCrashWithTerribleFailure( - "Could not bind to network stack in-process, or in app with " + intent, - context, packageName); - return; - } - + public void start() { + ConnectivityModuleConnector.getInstance().startModuleService( + INetworkStackConnector.class.getName(), PERMISSION_MAINLINE_NETWORK_STACK, + new NetworkStackConnection()); log("Network stack service start requested"); } - @Nullable - private Intent getNetworkStackIntent(@NonNull PackageManager pm, boolean inSystemProcess) { - final String baseAction = INetworkStackConnector.class.getName(); - final Intent intent = - new Intent(inSystemProcess ? baseAction + IN_PROCESS_SUFFIX : baseAction); - final ComponentName comp = intent.resolveSystemService(pm, 0); - - if (comp == null) { - return null; - } - intent.setComponent(comp); - - int uid = -1; - try { - uid = pm.getPackageUidAsUser(comp.getPackageName(), UserHandle.USER_SYSTEM); - } catch (PackageManager.NameNotFoundException e) { - logWtf("Network stack package not found", e); - // Fall through - } - - final int expectedUid = inSystemProcess ? Process.SYSTEM_UID : Process.NETWORK_STACK_UID; - if (uid != expectedUid) { - throw new SecurityException("Invalid network stack UID: " + uid); - } - - if (!inSystemProcess) { - checkNetworkStackPermission(pm, comp); - } - - return intent; - } - - private void checkNetworkStackPermission( - @NonNull PackageManager pm, @NonNull ComponentName comp) { - final int hasPermission = - pm.checkPermission(PERMISSION_MAINLINE_NETWORK_STACK, comp.getPackageName()); - if (hasPermission != PERMISSION_GRANTED) { - throw new SecurityException( - "Network stack does not have permission " + PERMISSION_MAINLINE_NETWORK_STACK); - } - } - - private void maybeCrashWithTerribleFailure(@NonNull String message, - @NonNull Context context, @Nullable String packageName) { - logWtf(message, null); - // uptime is monotonic even after a framework restart - final long uptime = SystemClock.elapsedRealtime(); - final long now = System.currentTimeMillis(); - final long minCrashIntervalMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_CONNECTIVITY, - CONFIG_MIN_CRASH_INTERVAL_MS, DEFAULT_MIN_CRASH_INTERVAL_MS); - final long minUptimeBeforeCrash = DeviceConfig.getLong(DeviceConfig.NAMESPACE_CONNECTIVITY, - CONFIG_MIN_UPTIME_BEFORE_CRASH_MS, DEFAULT_MIN_UPTIME_BEFORE_CRASH_MS); - final boolean alwaysRatelimit = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CONNECTIVITY, - CONFIG_ALWAYS_RATELIMIT_NETWORKSTACK_CRASH, false); - - final SharedPreferences prefs = getSharedPreferences(context); - final long lastCrashTime = tryGetLastCrashTime(prefs); - - // Only crash if there was enough time since boot, and (if known) enough time passed since - // the last crash. - // time and lastCrashTime may be unreliable if devices have incorrect clock time, but they - // are only used to limit the number of crashes compared to only using the time since boot, - // which would also be OK behavior by itself. - // - If lastCrashTime is incorrectly more than the current time, only look at uptime - // - If it is much less than current time, only look at uptime - // - If current time is during the next few hours after last crash time, don't crash. - // Considering that this only matters if last boot was some time ago, it's likely that - // time will be set correctly. Otherwise, not crashing is not a big problem anyway. Being - // in this last state would also not last for long since the window is only a few hours. - final boolean alwaysCrash = Build.IS_DEBUGGABLE && !alwaysRatelimit; - final boolean justBooted = uptime < minUptimeBeforeCrash; - final boolean haveLastCrashTime = (lastCrashTime != 0) && (lastCrashTime < now); - final boolean haveKnownRecentCrash = - haveLastCrashTime && (now < lastCrashTime + minCrashIntervalMs); - if (alwaysCrash || (!justBooted && !haveKnownRecentCrash)) { - // The system is not bound to its network stack (for example due to a crash in the - // network stack process): better crash rather than stay in a bad state where all - // networking is broken. - // Using device-encrypted SharedPreferences as DeviceConfig does not have a synchronous - // API to persist settings before a crash. - tryWriteLastCrashTime(prefs, now); - throw new IllegalStateException(message); - } - - // Here the system crashed recently already. Inform listeners that something is - // definitely wrong. - if (packageName != null) { - final ArraySet<NetworkStackHealthListener> listeners; - synchronized (mHealthListeners) { - listeners = new ArraySet<>(mHealthListeners); - } - for (NetworkStackHealthListener listener : listeners) { - listener.onNetworkStackFailure(packageName); - } - } - } - - @Nullable - private SharedPreferences getSharedPreferences(@NonNull Context context) { - try { - final File prefsFile = new File( - Environment.getDataSystemDeDirectory(UserHandle.USER_SYSTEM), PREFS_FILE); - return context.createDeviceProtectedStorageContext() - .getSharedPreferences(prefsFile, Context.MODE_PRIVATE); - } catch (Throwable e) { - logWtf("Error loading shared preferences", e); - return null; - } - } - - private long tryGetLastCrashTime(@Nullable SharedPreferences prefs) { - if (prefs == null) return 0L; - try { - return prefs.getLong(PREF_KEY_LAST_CRASH_TIME, 0L); - } catch (Throwable e) { - logWtf("Error getting last crash time", e); - return 0L; - } - } - - private void tryWriteLastCrashTime(@Nullable SharedPreferences prefs, long value) { - if (prefs == null) return; - try { - prefs.edit().putLong(PREF_KEY_LAST_CRASH_TIME, value).commit(); - } catch (Throwable e) { - logWtf("Error writing last crash time", e); - } - } - /** * Log a message in the local log. */ @@ -524,6 +291,8 @@ public class NetworkStackClient { public void dump(PrintWriter pw) { // dump is thread-safe on SharedLog mLog.dump(null, pw, null); + // dump connectivity module connector logs. + ConnectivityModuleConnector.getInstance().dump(pw); final int requestsQueueLength; synchronized (mPendingNetStackRequests) { diff --git a/services/wifi/Android.bp b/services/wifi/Android.bp new file mode 100644 index 000000000000..3c916a6d00cd --- /dev/null +++ b/services/wifi/Android.bp @@ -0,0 +1,11 @@ +// Interfaces between the core system and the wifi mainline module. +java_library_static { + name: "services.wifi", + srcs: [ + "java/**/*.java", + "java/**/*.aidl", + ], + libs: [ + "services.net", + ], +} diff --git a/services/wifi/java/android/net/wifi/IWifiStackConnector.aidl b/services/wifi/java/android/net/wifi/IWifiStackConnector.aidl new file mode 100644 index 000000000000..eadc7260e81b --- /dev/null +++ b/services/wifi/java/android/net/wifi/IWifiStackConnector.aidl @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing perNmissions and + * limitations under the License. + */ +package android.net.wifi; + +/** @hide */ +interface IWifiStackConnector { + IBinder retrieveApiServiceImpl(String serviceName); + boolean startApiService(String serviceName); +} diff --git a/services/wifi/java/android/net/wifi/WifiStackClient.java b/services/wifi/java/android/net/wifi/WifiStackClient.java new file mode 100644 index 000000000000..fa66e4c5eeea --- /dev/null +++ b/services/wifi/java/android/net/wifi/WifiStackClient.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.net.wifi; + +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; + +import android.annotation.NonNull; +import android.content.Context; +import android.net.ConnectivityModuleConnector; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; + +/** + * Service used to communicate with the wifi stack, which could be running in a separate + * module. + * @hide + */ +public class WifiStackClient { + public static final String PERMISSION_MAINLINE_WIFI_STACK = + "android.permission.MAINLINE_WIFI_STACK"; + + private static final String TAG = WifiStackClient.class.getSimpleName(); + private static WifiStackClient sInstance; + + private WifiStackClient() { } + + /** + * Get the WifiStackClient singleton instance. + */ + public static synchronized WifiStackClient getInstance() { + if (sInstance == null) { + sInstance = new WifiStackClient(); + } + return sInstance; + } + + private class WifiStackConnection implements + ConnectivityModuleConnector.ModuleServiceCallback { + @Override + public void onModuleServiceConnected(IBinder service) { + Log.i(TAG, "Wifi stack connected"); + + registerWifiStackService(service); + IWifiStackConnector connector = IWifiStackConnector.Stub.asInterface(service); + registerApiServiceAndStart(connector, Context.WIFI_SERVICE); + registerApiServiceAndStart(connector, Context.WIFI_SCANNING_SERVICE); + registerApiServiceAndStart(connector, Context.WIFI_P2P_SERVICE); + registerApiServiceAndStart(connector, Context.WIFI_AWARE_SERVICE); + registerApiServiceAndStart(connector, Context.WIFI_RTT_RANGING_SERVICE); + } + } + + private void registerWifiStackService(@NonNull IBinder service) { + ServiceManager.addService(Context.WIFI_STACK_SERVICE, service, + false /* allowIsolated */, + DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); + Log.i(TAG, "Wifi stack service registered"); + } + + private void registerApiServiceAndStart( + IWifiStackConnector stackConnector, String serviceName) { + IBinder service = null; + try { + service = stackConnector.retrieveApiServiceImpl(serviceName); + } catch (RemoteException e) { + throw new RuntimeException("Failed to retrieve service impl " + serviceName, e); + } + if (service == null) { + Log.i(TAG, "Service " + serviceName + " not available"); + return; + } + Log.i(TAG, "Registering " + serviceName); + ServiceManager.addService(serviceName, service); + + boolean success = false; + try { + success = stackConnector.startApiService(serviceName); + } catch (RemoteException e) { + throw new RuntimeException("Failed to start service " + serviceName, e); + } + if (!success) { + throw new RuntimeException("Service " + serviceName + " start failed"); + } + } + + /** + * Start the wifi stack. Should be called only once on device startup. + * + * <p>This method will start the wifi stack either in the wifi stack + * process, or inside the system server on devices that do not support the wifi stack + * module. + */ + public void start() { + Log.i(TAG, "Starting wifi stack"); + ConnectivityModuleConnector.getInstance().startModuleService( + IWifiStackConnector.class.getName(), PERMISSION_MAINLINE_WIFI_STACK, + new WifiStackConnection()); + } +} diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index 232b5cb17023..c42201fa0d3e 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -35,8 +35,8 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; -import android.net.NetworkStackClient; -import android.net.NetworkStackClient.NetworkStackHealthListener; +import android.net.ConnectivityModuleConnector; +import android.net.ConnectivityModuleConnector.ConnectivityModuleHealthListener; import android.os.Handler; import android.os.test.TestLooper; import android.provider.DeviceConfig; @@ -86,11 +86,11 @@ public class PackageWatchdogTest { private TestLooper mTestLooper; private Context mSpyContext; @Mock - private NetworkStackClient mMockNetworkStackClient; + private ConnectivityModuleConnector mConnectivityModuleConnector; @Mock private PackageManager mMockPackageManager; @Captor - private ArgumentCaptor<NetworkStackHealthListener> mNetworkStackCallbackCaptor; + private ArgumentCaptor<ConnectivityModuleHealthListener> mConnectivityModuleCallbackCaptor; @Before public void setUp() throws Exception { @@ -736,7 +736,7 @@ public class PackageWatchdogTest { wd.startObservingHealth(observer, Collections.singletonList(APP_A), SHORT_DURATION); // Notify of NetworkStack failure - mNetworkStackCallbackCaptor.getValue().onNetworkStackFailure(APP_A); + mConnectivityModuleCallbackCaptor.getValue().onNetworkStackFailure(APP_A); // Run handler so package failures are dispatched to observers mTestLooper.dispatchAll(); @@ -782,18 +782,18 @@ public class PackageWatchdogTest { Handler handler = new Handler(mTestLooper.getLooper()); PackageWatchdog watchdog = new PackageWatchdog(mSpyContext, policyFile, handler, handler, controller, - mMockNetworkStackClient); + mConnectivityModuleConnector); // Verify controller is not automatically started assertFalse(controller.mIsEnabled); if (withPackagesReady) { // Only capture the NetworkStack callback for the latest registered watchdog - reset(mMockNetworkStackClient); + reset(mConnectivityModuleConnector); watchdog.onPackagesReady(); // Verify controller by default is started when packages are ready assertTrue(controller.mIsEnabled); - verify(mMockNetworkStackClient).registerHealthListener( - mNetworkStackCallbackCaptor.capture()); + verify(mConnectivityModuleConnector).registerHealthListener( + mConnectivityModuleCallbackCaptor.capture()); } return watchdog; } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 20d772c8fb11..ca65736d8ec2 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -50,6 +50,7 @@ import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; +import android.os.ServiceManager; import android.os.WorkSource; import android.util.Log; import android.util.Pair; @@ -1149,18 +1150,40 @@ public class WifiManager { * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. * @param context the application context - * @param service the Binder interface * @hide - hide this because it takes in a parameter of type IWifiManager, which * is a system private class. */ - public WifiManager(Context context, IWifiManager service, Looper looper) { + public WifiManager(Context context, Looper looper) { mContext = context; - mService = service; mLooper = looper; mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; + } + + /** + * This is used only for unit testing. + * @hide + */ + @VisibleForTesting + public WifiManager(Context context, IWifiManager service, Looper looper) { + this(context, looper); + mService = service; updateVerboseLoggingEnabledFromService(); } + private IWifiManager getIWifiManager() throws RemoteException { + if (mService == null) { + synchronized (this) { + mService = IWifiManager.Stub.asInterface( + ServiceManager.getService(Context.WIFI_SERVICE)); + if (mService == null) { + throw new RemoteException("Wifi Service not running"); + } + updateVerboseLoggingEnabledFromService(); + } + } + return mService; + } + /** * Return a list of all the networks configured for the current foreground * user. @@ -1201,7 +1224,7 @@ public class WifiManager { public List<WifiConfiguration> getConfiguredNetworks() { try { ParceledListSlice<WifiConfiguration> parceledList = - mService.getConfiguredNetworks(mContext.getOpPackageName()); + getIWifiManager().getConfiguredNetworks(mContext.getOpPackageName()); if (parceledList == null) { return Collections.emptyList(); } @@ -1217,7 +1240,7 @@ public class WifiManager { public List<WifiConfiguration> getPrivilegedConfiguredNetworks() { try { ParceledListSlice<WifiConfiguration> parceledList = - mService.getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); + getIWifiManager().getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); if (parceledList == null) { return Collections.emptyList(); } @@ -1249,13 +1272,13 @@ public class WifiManager { List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> configs = new ArrayList<>(); try { Map<String, Map<Integer, List<ScanResult>>> results = - mService.getAllMatchingFqdnsForScanResults( + getIWifiManager().getAllMatchingFqdnsForScanResults( scanResults); if (results.isEmpty()) { return configs; } List<WifiConfiguration> wifiConfigurations = - mService.getWifiConfigsForPasspointProfiles( + getIWifiManager().getWifiConfigsForPasspointProfiles( new ArrayList<>(results.keySet())); for (WifiConfiguration configuration : wifiConfigurations) { Map<Integer, List<ScanResult>> scanResultsPerNetworkType = results.get( @@ -1293,7 +1316,7 @@ public class WifiManager { return new HashMap<>(); } try { - return mService.getMatchingOsuProviders(scanResults); + return getIWifiManager().getMatchingOsuProviders(scanResults); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1320,7 +1343,7 @@ public class WifiManager { public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders( @NonNull Set<OsuProvider> osuProviders) { try { - return mService.getMatchingPasspointConfigsForOsuProviders( + return getIWifiManager().getMatchingPasspointConfigsForOsuProviders( new ArrayList<>(osuProviders)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1405,7 +1428,7 @@ public class WifiManager { */ private int addOrUpdateNetwork(WifiConfiguration config) { try { - return mService.addOrUpdateNetwork(config, mContext.getOpPackageName()); + return getIWifiManager().addOrUpdateNetwork(config, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1631,7 +1654,7 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - mService.registerNetworkRequestMatchCallback( + getIWifiManager().registerNetworkRequestMatchCallback( binder, new NetworkRequestMatchCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { @@ -1657,7 +1680,7 @@ public class WifiManager { Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback); try { - mService.unregisterNetworkRequestMatchCallback(callback.hashCode()); + getIWifiManager().unregisterNetworkRequestMatchCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1691,7 +1714,8 @@ public class WifiManager { public @NetworkSuggestionsStatusCode int addNetworkSuggestions( @NonNull List<WifiNetworkSuggestion> networkSuggestions) { try { - return mService.addNetworkSuggestions(networkSuggestions, mContext.getOpPackageName()); + return getIWifiManager().addNetworkSuggestions( + networkSuggestions, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1714,7 +1738,7 @@ public class WifiManager { public @NetworkSuggestionsStatusCode int removeNetworkSuggestions( @NonNull List<WifiNetworkSuggestion> networkSuggestions) { try { - return mService.removeNetworkSuggestions( + return getIWifiManager().removeNetworkSuggestions( networkSuggestions, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1760,7 +1784,8 @@ public class WifiManager { */ public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { try { - if (!mService.addOrUpdatePasspointConfiguration(config, mContext.getOpPackageName())) { + if (!getIWifiManager().addOrUpdatePasspointConfiguration( + config, mContext.getOpPackageName())) { throw new IllegalArgumentException(); } } catch (RemoteException e) { @@ -1783,7 +1808,8 @@ public class WifiManager { }) public void removePasspointConfiguration(String fqdn) { try { - if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) { + if (!getIWifiManager().removePasspointConfiguration( + fqdn, mContext.getOpPackageName())) { throw new IllegalArgumentException(); } } catch (RemoteException e) { @@ -1806,7 +1832,7 @@ public class WifiManager { }) public List<PasspointConfiguration> getPasspointConfigurations() { try { - return mService.getPasspointConfigurations(mContext.getOpPackageName()); + return getIWifiManager().getPasspointConfigurations(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1826,7 +1852,7 @@ public class WifiManager { */ public void queryPasspointIcon(long bssid, String fileName) { try { - mService.queryPasspointIcon(bssid, fileName); + getIWifiManager().queryPasspointIcon(bssid, fileName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1840,7 +1866,7 @@ public class WifiManager { */ public int matchProviderWithCurrentNetwork(String fqdn) { try { - return mService.matchProviderWithCurrentNetwork(fqdn); + return getIWifiManager().matchProviderWithCurrentNetwork(fqdn); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1854,7 +1880,7 @@ public class WifiManager { */ public void deauthenticateNetwork(long holdoff, boolean ess) { try { - mService.deauthenticateNetwork(holdoff, ess); + getIWifiManager().deauthenticateNetwork(holdoff, ess); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1884,7 +1910,7 @@ public class WifiManager { @Deprecated public boolean removeNetwork(int netId) { try { - return mService.removeNetwork(netId, mContext.getOpPackageName()); + return getIWifiManager().removeNetwork(netId, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1939,7 +1965,8 @@ public class WifiManager { boolean success; try { - success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName()); + success = getIWifiManager().enableNetwork( + netId, attemptConnect, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1975,7 +2002,7 @@ public class WifiManager { @Deprecated public boolean disableNetwork(int netId) { try { - return mService.disableNetwork(netId, mContext.getOpPackageName()); + return getIWifiManager().disableNetwork(netId, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1998,7 +2025,7 @@ public class WifiManager { @Deprecated public boolean disconnect() { try { - return mService.disconnect(mContext.getOpPackageName()); + return getIWifiManager().disconnect(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2022,7 +2049,7 @@ public class WifiManager { @Deprecated public boolean reconnect() { try { - return mService.reconnect(mContext.getOpPackageName()); + return getIWifiManager().reconnect(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2046,7 +2073,7 @@ public class WifiManager { @Deprecated public boolean reassociate() { try { - return mService.reassociate(mContext.getOpPackageName()); + return getIWifiManager().reassociate(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2132,7 +2159,7 @@ public class WifiManager { private long getSupportedFeatures() { try { - return mService.getSupportedFeatures(); + return getIWifiManager().getSupportedFeatures(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2261,10 +2288,9 @@ public class WifiManager { * @hide */ public WifiActivityEnergyInfo getControllerActivityEnergyInfo() { - if (mService == null) return null; try { synchronized(this) { - return mService.reportActivityInfo(); + return getIWifiManager().reportActivityInfo(); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2304,7 +2330,7 @@ public class WifiManager { public boolean startScan(WorkSource workSource) { try { String packageName = mContext.getOpPackageName(); - return mService.startScan(packageName); + return getIWifiManager().startScan(packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2333,7 +2359,7 @@ public class WifiManager { */ public WifiInfo getConnectionInfo() { try { - return mService.getConnectionInfo(mContext.getOpPackageName()); + return getIWifiManager().getConnectionInfo(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2347,7 +2373,7 @@ public class WifiManager { */ public List<ScanResult> getScanResults() { try { - return mService.getScanResults(mContext.getOpPackageName()); + return getIWifiManager().getScanResults(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2366,7 +2392,7 @@ public class WifiManager { @Deprecated public boolean isScanAlwaysAvailable() { try { - return mService.isScanAlwaysAvailable(); + return getIWifiManager().isScanAlwaysAvailable(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2397,7 +2423,7 @@ public class WifiManager { */ public void setCountryCode(@NonNull String country) { try { - mService.setCountryCode(country); + getIWifiManager().setCountryCode(country); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2411,12 +2437,12 @@ public class WifiManager { */ @UnsupportedAppUsage public String getCountryCode() { - try { - String country = mService.getCountryCode(); - return country; - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + try { + String country = getIWifiManager().getCountryCode(); + return country; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @@ -2427,7 +2453,7 @@ public class WifiManager { @UnsupportedAppUsage public boolean isDualBandSupported() { try { - return mService.isDualBandSupported(); + return getIWifiManager().isDualBandSupported(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2440,7 +2466,7 @@ public class WifiManager { */ public boolean isDualModeSupported() { try { - return mService.needs5GHzToAnyApBandConversion(); + return getIWifiManager().needs5GHzToAnyApBandConversion(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2453,7 +2479,7 @@ public class WifiManager { */ public DhcpInfo getDhcpInfo() { try { - return mService.getDhcpInfo(); + return getIWifiManager().getDhcpInfo(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2480,7 +2506,7 @@ public class WifiManager { @Deprecated public boolean setWifiEnabled(boolean enabled) { try { - return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); + return getIWifiManager().setWifiEnabled(mContext.getOpPackageName(), enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2495,7 +2521,7 @@ public class WifiManager { */ public int getWifiState() { try { - return mService.getWifiEnabledState(); + return getIWifiManager().getWifiEnabledState(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2569,7 +2595,7 @@ public class WifiManager { */ public void updateInterfaceIpState(String ifaceName, int mode) { try { - mService.updateInterfaceIpState(ifaceName, mode); + getIWifiManager().updateInterfaceIpState(ifaceName, mode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2587,7 +2613,7 @@ public class WifiManager { */ public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) { try { - return mService.startSoftAp(wifiConfig); + return getIWifiManager().startSoftAp(wifiConfig); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2602,7 +2628,7 @@ public class WifiManager { */ public boolean stopSoftAp() { try { - return mService.stopSoftAp(); + return getIWifiManager().stopSoftAp(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2671,7 +2697,7 @@ public class WifiManager { new LocalOnlyHotspotCallbackProxy(this, looper, callback); try { String packageName = mContext.getOpPackageName(); - int returnCode = mService.startLocalOnlyHotspot( + int returnCode = getIWifiManager().startLocalOnlyHotspot( proxy.getMessenger(), new Binder(), packageName); if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { // Send message to the proxy to make sure we call back on the correct thread @@ -2723,7 +2749,7 @@ public class WifiManager { } mLOHSCallbackProxy = null; try { - mService.stopLocalOnlyHotspot(); + getIWifiManager().stopLocalOnlyHotspot(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2753,7 +2779,7 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer); try { - mService.startWatchLocalOnlyHotspot( + getIWifiManager().startWatchLocalOnlyHotspot( mLOHSObserverProxy.getMessenger(), new Binder()); mLOHSObserverProxy.registered(); } catch (RemoteException e) { @@ -2777,7 +2803,7 @@ public class WifiManager { } mLOHSObserverProxy = null; try { - mService.stopWatchLocalOnlyHotspot(); + getIWifiManager().stopWatchLocalOnlyHotspot(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2797,7 +2823,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState() { try { - return mService.getWifiApEnabledState(); + return getIWifiManager().getWifiApEnabledState(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2826,7 +2852,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public WifiConfiguration getWifiApConfiguration() { try { - return mService.getWifiApConfiguration(); + return getIWifiManager().getWifiApConfiguration(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2843,7 +2869,8 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { try { - return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName()); + return getIWifiManager().setWifiApConfiguration( + wifiConfig, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2858,7 +2885,7 @@ public class WifiManager { public void notifyUserOfApBandConversion() { Log.d(TAG, "apBand was converted, notify the user"); try { - mService.notifyUserOfApBandConversion(mContext.getOpPackageName()); + getIWifiManager().notifyUserOfApBandConversion(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2886,7 +2913,7 @@ public class WifiManager { */ public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) { try { - mService.enableTdls(remoteIPAddress.getHostAddress(), enable); + getIWifiManager().enableTdls(remoteIPAddress.getHostAddress(), enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2900,7 +2927,7 @@ public class WifiManager { */ public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) { try { - mService.enableTdlsWithMacAddress(remoteMacAddress, enable); + getIWifiManager().enableTdlsWithMacAddress(remoteMacAddress, enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3189,8 +3216,8 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - mService.registerSoftApCallback(binder, new SoftApCallbackProxy(looper, callback), - callback.hashCode()); + getIWifiManager().registerSoftApCallback( + binder, new SoftApCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3210,7 +3237,7 @@ public class WifiManager { Log.v(TAG, "unregisterSoftApCallback: callback=" + callback); try { - mService.unregisterSoftApCallback(callback.hashCode()); + getIWifiManager().unregisterSoftApCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3780,7 +3807,7 @@ public class WifiManager { public void disableEphemeralNetwork(String SSID) { if (SSID == null) throw new IllegalArgumentException("SSID cannot be null"); try { - mService.disableEphemeralNetwork(SSID, mContext.getOpPackageName()); + getIWifiManager().disableEphemeralNetwork(SSID, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3824,7 +3851,7 @@ public class WifiManager { @UnsupportedAppUsage private Messenger getWifiServiceMessenger() { try { - return mService.getWifiServiceMessenger(mContext.getOpPackageName()); + return getIWifiManager().getWifiServiceMessenger(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3884,10 +3911,10 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { try { - mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); + getIWifiManager().acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); synchronized (WifiManager.this) { if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { - mService.releaseWifiLock(mBinder); + getIWifiManager().releaseWifiLock(mBinder); throw new UnsupportedOperationException( "Exceeded maximum number of wifi locks"); } @@ -3917,7 +3944,7 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { - mService.releaseWifiLock(mBinder); + getIWifiManager().releaseWifiLock(mBinder); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -3980,7 +4007,7 @@ public class WifiManager { } if (changed && mHeld) { try { - mService.updateWifiLockWorkSource(mBinder, mWorkSource); + getIWifiManager().updateWifiLockWorkSource(mBinder, mWorkSource); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4008,7 +4035,7 @@ public class WifiManager { synchronized (mBinder) { if (mHeld) { try { - mService.releaseWifiLock(mBinder); + getIWifiManager().releaseWifiLock(mBinder); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4121,10 +4148,10 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { try { - mService.acquireMulticastLock(mBinder, mTag); + getIWifiManager().acquireMulticastLock(mBinder, mTag); synchronized (WifiManager.this) { if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { - mService.releaseMulticastLock(mTag); + getIWifiManager().releaseMulticastLock(mTag); throw new UnsupportedOperationException( "Exceeded maximum number of wifi locks"); } @@ -4166,7 +4193,7 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { - mService.releaseMulticastLock(mTag); + getIWifiManager().releaseMulticastLock(mTag); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4243,7 +4270,7 @@ public class WifiManager { */ public boolean isMulticastEnabled() { try { - return mService.isMulticastEnabled(); + return getIWifiManager().isMulticastEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4256,7 +4283,7 @@ public class WifiManager { @UnsupportedAppUsage public boolean initializeMulticastFiltering() { try { - mService.initializeMulticastFiltering(); + getIWifiManager().initializeMulticastFiltering(); return true; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4281,7 +4308,7 @@ public class WifiManager { @UnsupportedAppUsage public void enableVerboseLogging (int verbose) { try { - mService.enableVerboseLogging(verbose); + getIWifiManager().enableVerboseLogging(verbose); } catch (Exception e) { //ignore any failure here Log.e(TAG, "enableVerboseLogging " + e.toString()); @@ -4296,7 +4323,7 @@ public class WifiManager { @UnsupportedAppUsage public int getVerboseLoggingLevel() { try { - return mService.getVerboseLoggingLevel(); + return getIWifiManager().getVerboseLoggingLevel(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4309,7 +4336,7 @@ public class WifiManager { */ public void factoryReset() { try { - mService.factoryReset(mContext.getOpPackageName()); + getIWifiManager().factoryReset(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4323,7 +4350,7 @@ public class WifiManager { @UnsupportedAppUsage public Network getCurrentNetwork() { try { - return mService.getCurrentNetwork(); + return getIWifiManager().getCurrentNetwork(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4355,7 +4382,7 @@ public class WifiManager { */ public void enableWifiConnectivityManager(boolean enabled) { try { - mService.enableWifiConnectivityManager(enabled); + getIWifiManager().enableWifiConnectivityManager(enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4367,7 +4394,7 @@ public class WifiManager { */ public byte[] retrieveBackupData() { try { - return mService.retrieveBackupData(); + return getIWifiManager().retrieveBackupData(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4379,7 +4406,7 @@ public class WifiManager { */ public void restoreBackupData(byte[] data) { try { - mService.restoreBackupData(data); + getIWifiManager().restoreBackupData(data); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4395,7 +4422,7 @@ public class WifiManager { @Deprecated public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) { try { - mService.restoreSupplicantBackupData(supplicantData, ipConfigData); + getIWifiManager().restoreSupplicantBackupData(supplicantData, ipConfigData); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4424,7 +4451,7 @@ public class WifiManager { throw new IllegalArgumentException("callback must not be null"); } try { - mService.startSubscriptionProvisioning(provider, + getIWifiManager().startSubscriptionProvisioning(provider, new ProvisioningCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4538,7 +4565,7 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - mService.registerTrafficStateCallback( + getIWifiManager().registerTrafficStateCallback( binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4558,7 +4585,7 @@ public class WifiManager { Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback); try { - mService.unregisterTrafficStateCallback(callback.hashCode()); + getIWifiManager().unregisterTrafficStateCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4614,7 +4641,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses() { try { - return mService.getFactoryMacAddresses(); + return getIWifiManager().getFactoryMacAddresses(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4683,7 +4710,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(@DeviceMobilityState int state) { try { - mService.setDeviceMobilityState(state); + getIWifiManager().setDeviceMobilityState(state); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4738,8 +4765,9 @@ public class WifiManager { @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { - mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId, - enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback)); + getIWifiManager().startDppAsConfiguratorInitiator( + binder, enrolleeUri, selectedNetworkId, enrolleeNetworkRole, + new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4764,7 +4792,7 @@ public class WifiManager { @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { - mService.startDppAsEnrolleeInitiator(binder, configuratorUri, + getIWifiManager().startDppAsEnrolleeInitiator(binder, configuratorUri, new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4786,7 +4814,7 @@ public class WifiManager { public void stopEasyConnectSession() { try { /* Request lower layers to stop/abort and clear resources */ - mService.stopDppSession(); + getIWifiManager().stopDppSession(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4885,7 +4913,7 @@ public class WifiManager { Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener); } try { - mService.addOnWifiUsabilityStatsListener(new Binder(), + getIWifiManager().addOnWifiUsabilityStatsListener(new Binder(), new IOnWifiUsabilityStatsListener.Stub() { @Override public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, @@ -4922,7 +4950,7 @@ public class WifiManager { Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener); } try { - mService.removeOnWifiUsabilityStatsListener(listener.hashCode()); + getIWifiManager().removeOnWifiUsabilityStatsListener(listener.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4945,7 +4973,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { try { - mService.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); + getIWifiManager().updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } |