diff options
author | Ahmed ElArabawy <arabawy@google.com> | 2019-04-04 12:14:19 -0700 |
---|---|---|
committer | Ahmed ElArabawy <arabawy@google.com> | 2019-04-08 15:48:05 -0700 |
commit | d887ddebca94d27c94a1154a9cf6a528d465d79e (patch) | |
tree | 970e026c823cac2ec03cf5c775b2db0eb476f7b2 /service | |
parent | 6bd5f0a9b91a2042f0f818abb97832a2b2102947 (diff) |
Run WifiLock operations from on wifi thread
In current implementatoin the WifiLock operations run on the wifi service
thread pool. Since the application thread blocks on the return of the
that thread, apps go into ANR when the calls block.
This commit runs those operations on the wifi thread. This also removes
the need to use an AsyncChannel for requesting the supported features.
Bug: 129288264
Test: Manual
Test: atest com.android.server.wifi
Change-Id: I08f6e18d532ca14381d0cc1505cbf44c8f3d9608
Diffstat (limited to 'service')
3 files changed, 46 insertions, 62 deletions
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index fbcc45568..988bdf086 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -319,7 +319,8 @@ public class WifiInjector { mWifiConfigStore, mWifiNetworkSuggestionsManager, mWifiMetrics.getWakeupMetrics(), this, mFrameworkFacade, mClock); mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService(), - mClientModeImpl, mFrameworkFacade, clientModeImplLooper, mClock, mWifiMetrics); + mClientModeImpl, mFrameworkFacade, new Handler(clientModeImplLooper), mWifiNative, + mClock, mWifiMetrics); mWifiController = new WifiController(mContext, mClientModeImpl, clientModeImplLooper, mSettingsStore, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade, mActiveModeWarden); diff --git a/service/java/com/android/server/wifi/WifiLockManager.java b/service/java/com/android/server/wifi/WifiLockManager.java index 3d4ceb1e7..ab0871554 100644 --- a/service/java/com/android/server/wifi/WifiLockManager.java +++ b/service/java/com/android/server/wifi/WifiLockManager.java @@ -20,9 +20,8 @@ import android.app.ActivityManager; import android.content.Context; import android.net.wifi.WifiManager; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; -import android.os.Looper; -import android.os.Message; import android.os.RemoteException; import android.os.WorkSource; import android.os.WorkSource.WorkChain; @@ -31,9 +30,6 @@ import android.util.SparseArray; import android.util.StatsLog; import com.android.internal.app.IBatteryStats; -import com.android.internal.util.AsyncChannel; -import com.android.server.wifi.util.WifiAsyncChannel; -import com.android.server.wifi.util.WifiHandler; import java.io.PrintWriter; import java.util.ArrayList; @@ -62,9 +58,9 @@ public class WifiLockManager { private final FrameworkFacade mFrameworkFacade; private final ClientModeImpl mClientModeImpl; private final ActivityManager mActivityManager; - private final ClientModeImplInterfaceHandler mCmiIfaceHandler; + private final Handler mHandler; private final WifiMetrics mWifiMetrics; - private WifiAsyncChannel mClientModeImplChannel; + private final WifiNative mWifiNative; private final List<WifiLock> mWifiLocks = new ArrayList<>(); // map UIDs to their corresponding records (for low-latency locks) @@ -85,15 +81,16 @@ public class WifiLockManager { private long mCurrentSessionStartTimeMs; WifiLockManager(Context context, IBatteryStats batteryStats, - ClientModeImpl clientModeImpl, FrameworkFacade frameworkFacade, Looper looper, - Clock clock, WifiMetrics wifiMetrics) { + ClientModeImpl clientModeImpl, FrameworkFacade frameworkFacade, Handler handler, + WifiNative wifiNative, Clock clock, WifiMetrics wifiMetrics) { mContext = context; mBatteryStats = batteryStats; mClientModeImpl = clientModeImpl; mFrameworkFacade = frameworkFacade; mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); - mCmiIfaceHandler = new ClientModeImplInterfaceHandler(looper); mCurrentOpMode = WifiManager.WIFI_MODE_NO_LOCKS_HELD; + mWifiNative = wifiNative; + mHandler = handler; mClock = clock; mWifiMetrics = wifiMetrics; @@ -147,7 +144,7 @@ public class WifiLockManager { mActivityManager.addOnUidImportanceListener(new ActivityManager.OnUidImportanceListener() { @Override public void onUidImportance(final int uid, final int importance) { - mCmiIfaceHandler.post(() -> { + mHandler.post(() -> { UidRec uidRec = mLowLatencyUidWatchList.get(uid); if (uidRec == null) { // Not a uid in the watch list @@ -647,10 +644,13 @@ public class WifiLockManager { } private int getLowLatencyModeSupport() { - if (mLatencyModeSupport == LOW_LATENCY_SUPPORT_UNDEFINED - && mClientModeImplChannel != null) { - long supportedFeatures = - mClientModeImpl.syncGetSupportedFeatures(mClientModeImplChannel); + if (mLatencyModeSupport == LOW_LATENCY_SUPPORT_UNDEFINED) { + String ifaceName = mWifiNative.getClientInterfaceName(); + if (ifaceName == null) { + return LOW_LATENCY_SUPPORT_UNDEFINED; + } + + long supportedFeatures = mWifiNative.getSupportedFeatureSet(ifaceName); if (supportedFeatures != 0) { if ((supportedFeatures & WifiManager.WIFI_FEATURE_LOW_LATENCY) != 0) { mLatencyModeSupport = LOW_LATENCY_SUPPORTED; @@ -793,45 +793,6 @@ public class WifiLockManager { } } - /** - * Handles interaction with ClientModeImpl - */ - private class ClientModeImplInterfaceHandler extends WifiHandler { - private WifiAsyncChannel mCmiChannel; - - ClientModeImplInterfaceHandler(Looper looper) { - super(TAG, looper); - mCmiChannel = mFrameworkFacade.makeWifiAsyncChannel(TAG); - mCmiChannel.connect(mContext, this, mClientModeImpl.getHandler()); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { - if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { - mClientModeImplChannel = mCmiChannel; - } else { - Slog.e(TAG, "ClientModeImpl connection failure, error=" + msg.arg1); - mClientModeImplChannel = null; - } - break; - } - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { - Slog.e(TAG, "ClientModeImpl channel lost, msg.arg1 =" + msg.arg1); - mClientModeImplChannel = null; - //Re-establish connection - mCmiChannel.connect(mContext, this, mClientModeImpl.getHandler()); - break; - } - default: { - Slog.d(TAG, "ClientModeImplInterfaceHandler.handleMessage ignoring msg=" + msg); - break; - } - } - } - } - private class WifiLock implements IBinder.DeathRecipient { String mTag; int mUid; diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 5f0ac3b95..611474604 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -2808,25 +2808,47 @@ public class WifiServiceImpl extends BaseWifiService { mLog.info("acquireWifiLock uid=% lockMode=%") .c(Binder.getCallingUid()) .c(lockMode).flush(); - if (mWifiLockManager.acquireWifiLock(lockMode, tag, binder, ws)) { - return true; + + Mutable<Boolean> lockSuccess = new Mutable<>(); + boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler().runWithScissors( + () -> { + lockSuccess.value = mWifiLockManager.acquireWifiLock(lockMode, tag, binder, ws); + }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS); + if (!runWithScissorsSuccess) { + Log.e(TAG, "Failed to post runnable to acquireWifiLock"); + return false; } - return false; + + return lockSuccess.value; } @Override public void updateWifiLockWorkSource(IBinder binder, WorkSource ws) { mLog.info("updateWifiLockWorkSource uid=%").c(Binder.getCallingUid()).flush(); - mWifiLockManager.updateWifiLockWorkSource(binder, ws); + + boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler().runWithScissors( + () -> { + mWifiLockManager.updateWifiLockWorkSource(binder, ws); + }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS); + if (!runWithScissorsSuccess) { + Log.e(TAG, "Failed to post runnable to updateWifiLockWorkSource"); + } } @Override public boolean releaseWifiLock(IBinder binder) { mLog.info("releaseWifiLock uid=%").c(Binder.getCallingUid()).flush(); - if (mWifiLockManager.releaseWifiLock(binder)) { - return true; + + Mutable<Boolean> lockSuccess = new Mutable<>(); + boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler().runWithScissors( + () -> { + lockSuccess.value = mWifiLockManager.releaseWifiLock(binder); + }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS); + if (!runWithScissorsSuccess) { + Log.e(TAG, "Failed to post runnable to releaseWifiLock"); + return false; } - return false; + return lockSuccess.value; } @Override |