diff options
Diffstat (limited to 'packages/SettingsLib')
4 files changed, 169 insertions, 62 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java index 60b5ba5..2606af2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java @@ -82,6 +82,7 @@ public class PermissionsInfo { // TODO: Add default permission icon. group.icon = info.icon != 0 ? info.loadIcon(mPm) : new ShapeDrawable(); group.name = info.name; + group.packageName = info.packageName; group.label = info.loadLabel(mPm).toString(); mGroups.add(group); mGroupLookup.put(permission, group); @@ -105,6 +106,7 @@ public class PermissionsInfo { // TODO: Add default permission icon. group.icon = groupInfo.icon != 0 ? groupInfo.loadIcon(mPm) : new ShapeDrawable(); group.name = groupInfo.name; + group.packageName = groupInfo.packageName; group.label = groupInfo.loadLabel(mPm).toString(); synchronized (mGroups) { mGroups.add(group); @@ -172,6 +174,7 @@ public class PermissionsInfo { public final List<String> possibleApps = new ArrayList<>(); public final List<String> grantedApps = new ArrayList<>(); public String name; + public String packageName; public String label; public Drawable icon; diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index 7eaa728..1ad7a51 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -826,6 +826,9 @@ public class AccessPoint implements Comparable<AccessPoint> { } static String removeDoubleQuotes(String string) { + if (TextUtils.isEmpty(string)) { + return ""; + } int length = string.length(); if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) { diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 09e6912..7060c64 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -26,6 +26,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Handler; +import android.os.Looper; import android.os.Message; import android.widget.Toast; @@ -63,10 +64,12 @@ public class WifiTracker { private final boolean mIncludeScans; private final boolean mIncludePasspoints; + private final MainHandler mMainHandler; + private final WorkHandler mWorkHandler; + private boolean mSavedNetworksExist; private boolean mRegistered; private ArrayList<AccessPoint> mAccessPoints = new ArrayList<>(); - private ArrayList<AccessPoint> mCachedAccessPoints = new ArrayList<>(); private NetworkInfo mLastNetworkInfo; private WifiInfo mLastInfo; @@ -74,23 +77,38 @@ public class WifiTracker { @VisibleForTesting Scanner mScanner; - public WifiTracker(Context context, WifiListener wifiListener, boolean includeSaved, - boolean includeScans) { - this(context, wifiListener, includeSaved, includeScans, false); + public WifiTracker(Context context, WifiListener wifiListener, + boolean includeSaved, boolean includeScans) { + this(context, wifiListener, null, includeSaved, includeScans); } - public WifiTracker(Context context, WifiListener wifiListener, boolean includeSaved, - boolean includeScans, boolean includePasspoints) { - this(context, wifiListener, includeSaved, includeScans, includePasspoints, - (WifiManager) context.getSystemService(Context.WIFI_SERVICE)); + + public WifiTracker(Context context, WifiListener wifiListener, Looper workerLooper, + boolean includeSaved, boolean includeScans) { + this(context, wifiListener, workerLooper, includeSaved, includeScans, false); + } + + public WifiTracker(Context context, WifiListener wifiListener, + boolean includeSaved, boolean includeScans, boolean includePasspoints) { + this(context, wifiListener, null, includeSaved, includeScans, includePasspoints); + } + + public WifiTracker(Context context, WifiListener wifiListener, Looper workerLooper, + boolean includeSaved, boolean includeScans, boolean includePasspoints) { + this(context, wifiListener, workerLooper, includeSaved, includeScans, includePasspoints, + (WifiManager) context.getSystemService(Context.WIFI_SERVICE), Looper.myLooper()); } @VisibleForTesting - WifiTracker(Context context, WifiListener wifiListener, boolean includeSaved, - boolean includeScans, boolean includePasspoints, WifiManager wifiManager) { + WifiTracker(Context context, WifiListener wifiListener, Looper workerLooper, + boolean includeSaved, boolean includeScans, boolean includePasspoints, + WifiManager wifiManager, Looper currentLooper) { if (!includeSaved && !includeScans) { throw new IllegalArgumentException("Must include either saved or scans"); } mContext = context; + mMainHandler = new MainHandler(currentLooper); + mWorkHandler = new WorkHandler( + workerLooper != null ? workerLooper : currentLooper); mWifiManager = wifiManager; mIncludeSaved = includeSaved; mIncludeScans = includeScans; @@ -147,7 +165,7 @@ public class WifiTracker { if (mWifiManager.isWifiEnabled()) { mScanner.resume(); } - updateAccessPoints(); + mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS); } /** @@ -171,6 +189,8 @@ public class WifiTracker { */ public void stopTracking() { if (mRegistered) { + mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS); + mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_NETWORK_INFO); mContext.unregisterReceiver(mReceiver); mRegistered = false; } @@ -213,16 +233,14 @@ public class WifiTracker { private void updateAccessPoints() { // Swap the current access points into a cached list. - ArrayList<AccessPoint> tmpSwp = mAccessPoints; - mAccessPoints = mCachedAccessPoints; - mCachedAccessPoints = tmpSwp; + ArrayList<AccessPoint> cachedAccessPoints = new ArrayList<>(mAccessPoints); + ArrayList<AccessPoint> accessPoints = new ArrayList<>(); + // Clear out the configs so we don't think something is saved when it isn't. - for (AccessPoint accessPoint : mCachedAccessPoints) { + for (AccessPoint accessPoint : cachedAccessPoints) { accessPoint.clearConfig(); } - mAccessPoints.clear(); - /** Lookup table to more quickly update AccessPoints by only considering objects with the * correct SSID. Maps SSID -> List of AccessPoints with the given SSID. */ Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>(); @@ -238,7 +256,7 @@ public class WifiTracker { if (config.selfAdded && config.numAssociation == 0) { continue; } - AccessPoint accessPoint = getCachedOrCreate(config); + AccessPoint accessPoint = getCachedOrCreate(config, cachedAccessPoints); if (mLastInfo != null && mLastNetworkInfo != null) { if (config.isPasspoint() == false) { accessPoint.update(mLastInfo, mLastNetworkInfo); @@ -246,7 +264,7 @@ public class WifiTracker { } if (mIncludeSaved) { if (!config.isPasspoint() || mIncludePasspoints) - mAccessPoints.add(accessPoint); + accessPoints.add(accessPoint); if (config.isPasspoint() == false) { apMap.put(accessPoint.getSsid(), accessPoint); @@ -254,7 +272,7 @@ public class WifiTracker { } else { // If we aren't using saved networks, drop them into the cache so that // we have access to their saved info. - mCachedAccessPoints.add(accessPoint); + cachedAccessPoints.add(accessPoint); } } } @@ -276,7 +294,7 @@ public class WifiTracker { } } if (!found && mIncludeScans) { - AccessPoint accessPoint = getCachedOrCreate(result); + AccessPoint accessPoint = getCachedOrCreate(result, cachedAccessPoints); if (mLastInfo != null && mLastNetworkInfo != null) { accessPoint.update(mLastInfo, mLastNetworkInfo); } @@ -296,24 +314,23 @@ public class WifiTracker { accessPoint.update(connectionConfig); } - mAccessPoints.add(accessPoint); + accessPoints.add(accessPoint); apMap.put(accessPoint.getSsid(), accessPoint); } } } // Pre-sort accessPoints to speed preference insertion - Collections.sort(mAccessPoints); - if (mListener != null) { - mListener.onAccessPointsChanged(); - } + Collections.sort(accessPoints); + mAccessPoints = accessPoints; + mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED); } - private AccessPoint getCachedOrCreate(ScanResult result) { - final int N = mCachedAccessPoints.size(); + private AccessPoint getCachedOrCreate(ScanResult result, ArrayList<AccessPoint> cache) { + final int N = cache.size(); for (int i = 0; i < N; i++) { - if (mCachedAccessPoints.get(i).matches(result)) { - AccessPoint ret = mCachedAccessPoints.remove(i); + if (cache.get(i).matches(result)) { + AccessPoint ret = cache.remove(i); ret.update(result); return ret; } @@ -321,11 +338,11 @@ public class WifiTracker { return new AccessPoint(mContext, result); } - private AccessPoint getCachedOrCreate(WifiConfiguration config) { - final int N = mCachedAccessPoints.size(); + private AccessPoint getCachedOrCreate(WifiConfiguration config, ArrayList<AccessPoint> cache) { + final int N = cache.size(); for (int i = 0; i < N; i++) { - if (mCachedAccessPoints.get(i).matches(config)) { - AccessPoint ret = mCachedAccessPoints.remove(i); + if (cache.get(i).matches(config)) { + AccessPoint ret = cache.remove(i); ret.loadConfig(config); return ret; } @@ -360,9 +377,7 @@ public class WifiTracker { } if (reorder) { Collections.sort(mAccessPoints); - if (mListener != null) { - mListener.onAccessPointsChanged(); - } + mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED); } } @@ -380,15 +395,13 @@ public class WifiTracker { mScanner.pause(); } } - if (mListener != null) { - mListener.onWifiStateChanged(state); - } + mMainHandler.obtainMessage(MainHandler.MSG_WIFI_STATE_CHANGED, state, 0).sendToTarget(); } public static List<AccessPoint> getCurrentAccessPoints(Context context, boolean includeSaved, boolean includeScans, boolean includePasspoints) { WifiTracker tracker = new WifiTracker(context, - null, includeSaved, includeScans, includePasspoints); + null, null, includeSaved, includeScans, includePasspoints); tracker.forceUpdate(); return tracker.getAccessPoints(); } @@ -404,25 +417,75 @@ public class WifiTracker { } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) || WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) || WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) { - updateAccessPoints(); + mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS); } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { NetworkInfo info = (NetworkInfo) intent.getParcelableExtra( WifiManager.EXTRA_NETWORK_INFO); mConnected.set(info.isConnected()); - if (mListener != null) { - mListener.onConnectedChanged(); - } - updateAccessPoints(); - updateNetworkInfo(info); + + mMainHandler.sendEmptyMessage(MainHandler.MSG_CONNECTED_CHANGED); + + mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS); + mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info) + .sendToTarget(); } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) { - updateNetworkInfo(null); + mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO); } } }; + private final class MainHandler extends Handler { + private static final int MSG_CONNECTED_CHANGED = 0; + private static final int MSG_WIFI_STATE_CHANGED = 1; + private static final int MSG_ACCESS_POINT_CHANGED = 2; + + public MainHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + if (mListener == null) { + return; + } + switch (msg.what) { + case MSG_CONNECTED_CHANGED: + mListener.onConnectedChanged(); + break; + case MSG_WIFI_STATE_CHANGED: + mListener.onWifiStateChanged(msg.arg1); + break; + case MSG_ACCESS_POINT_CHANGED: + mListener.onAccessPointsChanged(); + break; + } + } + } + + private final class WorkHandler extends Handler { + private static final int MSG_UPDATE_ACCESS_POINTS = 0; + private static final int MSG_UPDATE_NETWORK_INFO = 1; + + public WorkHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE_ACCESS_POINTS: + updateAccessPoints(); + break; + case MSG_UPDATE_NETWORK_INFO: + updateNetworkInfo((NetworkInfo) msg.obj); + break; + } + } + } + @VisibleForTesting class Scanner extends Handler { - private static final int MSG_SCAN = 0; + static final int MSG_SCAN = 0; private int mRetry = 0; diff --git a/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java index 8eb1ca4..103cd3a 100644 --- a/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java +++ b/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java @@ -23,9 +23,12 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiSsid; +import android.os.HandlerThread; +import android.os.Looper; import android.util.Log; import com.android.settingslib.BaseTest; +import com.android.settingslib.wifi.WifiTracker.Scanner; import com.android.settingslib.wifi.WifiTracker.WifiListener; import org.mockito.ArgumentCaptor; @@ -54,13 +57,25 @@ public class WifiTrackerTest extends BaseTest { private WifiTracker mWifiTracker; + private HandlerThread mWorkerThread; + private Looper mLooper; + private HandlerThread mMainThread; + private Looper mMainLooper; + @Override protected void setUp() throws Exception { super.setUp(); mWifiManager = Mockito.mock(WifiManager.class); mWifiListener = Mockito.mock(WifiListener.class); - mWifiTracker = new WifiTracker(mContext, mWifiListener, true, true, mWifiManager); + mWorkerThread = new HandlerThread("TestHandlerThread"); + mWorkerThread.start(); + mLooper = mWorkerThread.getLooper(); + mMainThread = new HandlerThread("TestHandlerThread"); + mMainThread.start(); + mMainLooper = mMainThread.getLooper(); + mWifiTracker = new WifiTracker(mContext, mWifiListener, mLooper, true, true, true, + mWifiManager, mMainLooper); mWifiTracker.mScanner = mWifiTracker.new Scanner(); Mockito.when(mWifiManager.isWifiEnabled()).thenReturn(true); } @@ -76,13 +91,14 @@ public class WifiTrackerTest extends BaseTest { } public void testAccessPointsCallback() { - sendScanResultsAvailable(); + sendScanResultsAndProcess(false); Mockito.verify(mWifiListener, Mockito.atLeastOnce()).onAccessPointsChanged(); } public void testConnectedCallback() { sendConnected(); + waitForThreads(); Mockito.verify(mWifiListener, Mockito.atLeastOnce()).onConnectedChanged(); assertEquals(true, mWifiTracker.isConnected()); @@ -94,6 +110,7 @@ public class WifiTrackerTest extends BaseTest { Intent i = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION); i.putExtra(WifiManager.EXTRA_WIFI_STATE, TEST_WIFI_STATE); mWifiTracker.mReceiver.onReceive(mContext, i); + waitForThreads(); ArgumentCaptor<Integer> wifiState = ArgumentCaptor.forClass(Integer.class); Mockito.verify(mWifiListener, Mockito.atLeastOnce()) @@ -106,7 +123,7 @@ public class WifiTrackerTest extends BaseTest { // Make scans be successful. Mockito.when(mWifiManager.startScan()).thenReturn(true); - mWifiTracker.mScanner.handleMessage(null); + mWifiTracker.mScanner.handleMessage(mWifiTracker.mScanner.obtainMessage(Scanner.MSG_SCAN)); Mockito.verify(mWifiManager, Mockito.atLeastOnce()).startScan(); } @@ -121,7 +138,7 @@ public class WifiTrackerTest extends BaseTest { // Send all of the configs and scan results to the tracker. Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs); Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults); - sendScanResultsAvailable(); + sendScanResultsAndProcess(false); List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints(); assertEquals("Expected number of results", NUM_NETWORKS, accessPoints.size()); @@ -131,7 +148,8 @@ public class WifiTrackerTest extends BaseTest { } public void testSavedOnly() { - mWifiTracker = new WifiTracker(mContext, mWifiListener, true, false, mWifiManager); + mWifiTracker = new WifiTracker(mContext, mWifiListener, mLooper, true, false, true, + mWifiManager, mMainLooper); mWifiTracker.mScanner = mWifiTracker.new Scanner(); List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>(); @@ -144,7 +162,7 @@ public class WifiTrackerTest extends BaseTest { // Send all of the configs and scan results to the tracker. Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs); Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults); - sendScanResultsAvailable(); + sendScanResultsAndProcess(false); List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints(); // Only expect the first two to come back in the results. @@ -154,7 +172,8 @@ public class WifiTrackerTest extends BaseTest { } public void testAvailableOnly() { - mWifiTracker = new WifiTracker(mContext, mWifiListener, false, true, mWifiManager); + mWifiTracker = new WifiTracker(mContext, mWifiListener, mLooper, false, true, true, + mWifiManager, mMainLooper); mWifiTracker.mScanner = mWifiTracker.new Scanner(); List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>(); @@ -167,7 +186,7 @@ public class WifiTrackerTest extends BaseTest { // Send all of the configs and scan results to the tracker. Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs); Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults); - sendScanResultsAvailable(); + sendScanResultsAndProcess(false); // Expect the last one (sorted order) to be left off since its only saved. List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints(); @@ -178,12 +197,13 @@ public class WifiTrackerTest extends BaseTest { } public void testNonEphemeralConnected() { - mWifiTracker = new WifiTracker(mContext, mWifiListener, false, true, mWifiManager); + mWifiTracker = new WifiTracker(mContext, mWifiListener, mLooper, false, true, true, + mWifiManager, mMainLooper); mWifiTracker.mScanner = mWifiTracker.new Scanner(); List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>(); List<ScanResult> scanResults = new ArrayList<ScanResult>(); - String[] expectedSsids = generateTestNetworks(wifiConfigs, scanResults, false); + generateTestNetworks(wifiConfigs, scanResults, false); // Tell WifiTracker we are connected now. sendConnected(); @@ -191,9 +211,8 @@ public class WifiTrackerTest extends BaseTest { // Send all of the configs and scan results to the tracker. Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs); Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults); - sendScanResultsAvailable(); // Do this twice to catch a bug that was happening in the caching, making things ephemeral. - sendScanResultsAvailable(); + sendScanResultsAndProcess(true); List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints(); assertEquals("Expected number of results", NUM_NETWORKS - 1, accessPoints.size()); @@ -299,9 +318,28 @@ public class WifiTrackerTest extends BaseTest { mWifiTracker.mReceiver.onReceive(mContext, intent); } - private void sendScanResultsAvailable() { + private void sendScanResultsAndProcess(boolean sendTwice) { Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); mWifiTracker.mReceiver.onReceive(mContext, i); + if (sendTwice) { + mWifiTracker.mReceiver.onReceive(mContext, i); + } + waitForThreads(); + } + + private void waitForThreads() { + // Run all processing. + mWorkerThread.quitSafely(); + try { + mWorkerThread.join(); + } catch (InterruptedException e) { + } + // Send all callbacks. + mMainThread.quitSafely(); + try { + mMainThread.join(); + } catch (InterruptedException e) { + } } } |