Loading src/com/android/settings/SecuritySettings.java +16 −5 Original line number Diff line number Diff line Loading @@ -76,6 +76,8 @@ import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.TileUtils; import java.util.ArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.List; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; Loading Loading @@ -937,8 +939,8 @@ public class SecuritySettings extends SettingsPreferenceFragment MY_USER_ID)); } if (mPowerButtonInstantlyLocks != null) { mPowerButtonInstantlyLocks.setChecked(mLockPatternUtils.getPowerButtonInstantlyLocks( MY_USER_ID)); mPowerButtonInstantlyLocks.setChecked( mLockPatternUtils.getPowerButtonInstantlyLocks(MY_USER_ID)); } updateOwnerInfo(); Loading Loading @@ -1202,9 +1204,18 @@ public class SecuritySettings extends SettingsPreferenceFragment FeatureFactory.getFactory(mContext).getDashboardFeatureProvider(mContext); if (dashboardFeatureProvider.isEnabled() && (packageVerifierState == PACKAGE_VERIFIER_STATE_ENABLED)) { // Calling the feature provider could potentially be slow, so do this on a separate // thread so as to not block the loading of Settings. Executors.newSingleThreadExecutor().execute(new Runnable() { @Override public void run() { DashboardCategory dashboardCategory = dashboardFeatureProvider.getTilesForCategory(CategoryKey.CATEGORY_SECURITY); mSummaryLoader.setSummary(this, getPackageVerifierSummary(dashboardCategory)); dashboardFeatureProvider.getTilesForCategory( CategoryKey.CATEGORY_SECURITY); mSummaryLoader.setSummary(SummaryProvider.this, getPackageVerifierSummary(dashboardCategory)); } }); } else { final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(mContext); if (fpm != null && fpm.isHardwareDetected()) { Loading src/com/android/settings/security/SecurityFeatureProviderImpl.java +48 −15 Original line number Diff line number Diff line Loading @@ -22,9 +22,12 @@ import android.content.IContentProvider; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import com.android.settings.trustagent.TrustAgentManager; import com.android.settings.trustagent.TrustAgentManagerImpl; import com.android.settingslib.drawer.DashboardCategory; import android.support.annotation.VisibleForTesting; import android.support.v4.content.ContextCompat; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; Loading @@ -35,6 +38,7 @@ import android.util.Pair; import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.TileUtils; import java.util.concurrent.Executors; import java.util.Map; /** Implementation for {@code SecurityFeatureProvider}. */ Loading @@ -43,8 +47,22 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider { private TrustAgentManager mTrustAgentManager; /** Update preferences with data from associated tiles. */ public void updatePreferences(Context context, PreferenceScreen preferenceScreen, public void updatePreferences(final Context context, final PreferenceScreen preferenceScreen, final DashboardCategory dashboardCategory) { // Fetching the summary and icon from the provider introduces latency, so do this on a // separate thread. Executors.newSingleThreadExecutor().execute(new Runnable() { @Override public void run() { updatePreferencesToRunOnWorkerThread(context, preferenceScreen, dashboardCategory); } }); } @VisibleForTesting void updatePreferencesToRunOnWorkerThread(Context context, PreferenceScreen preferenceScreen, DashboardCategory dashboardCategory) { if (preferenceScreen == null) { return; } Loading Loading @@ -82,18 +100,31 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider { TileUtils.getIconFromUri(context, packageName, iconUri, providerMap); if (icon != null) { // Icon is only returned if the icon belongs to Settings or the target app. // setIcon must be called on the UI thread. new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { try { matchingPref.setIcon(context.getPackageManager() .getResourcesForApplication(icon.first /* package name */) .getDrawable(icon.second /* res id */, context.getTheme())); } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { // Intentionally ignored. If icon resources cannot be found, do not update. .getDrawable(icon.second /* res id */, context.getTheme())); } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { // Intentionally ignored. If icon resources cannot be found, do not // update. } } }); } } if (!TextUtils.isEmpty(summaryUri)) { String summary = TileUtils.getTextFromUri(context, summaryUri, providerMap, TileUtils.META_DATA_PREFERENCE_SUMMARY); // setSummary must be called on UI thread. new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { // Only update the summary if it has actually changed. if (summary == null) { if (matchingPref.getSummary() != null) { Loading @@ -103,6 +134,8 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider { matchingPref.setSummary(summary); } } }); } } } Loading tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java +16 −6 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowLooper; import java.util.Map; Loading Loading @@ -102,8 +103,11 @@ public class SecurityFeatureProviderImplTest { @Test public void updateTilesData_shouldNotProcessEmptyScreenOrTiles() { mImpl.updatePreferences(mContext, null, null); mImpl.updatePreferences(mContext, new PreferenceScreen(mContext, null), null); mImpl.updatePreferencesToRunOnWorkerThread(mContext, null, null); ShadowLooper.runUiThreadTasks(); mImpl.updatePreferencesToRunOnWorkerThread( mContext, new PreferenceScreen(mContext, null), null); ShadowLooper.runUiThreadTasks(); verifyNoMoreInteractions(mPackageManager); } Loading @@ -111,13 +115,17 @@ public class SecurityFeatureProviderImplTest { public void updateTilesData_shouldNotProcessNonMatchingPreference() { DashboardCategory dashboardCategory = new DashboardCategory(); dashboardCategory.addTile(new Tile()); mImpl.updatePreferences(mContext, getPreferenceScreen(), dashboardCategory); mImpl.updatePreferencesToRunOnWorkerThread( mContext, getPreferenceScreen(), dashboardCategory); ShadowLooper.runUiThreadTasks(); verifyNoMoreInteractions(mPackageManager); } @Test public void updateTilesData_shouldNotProcessMatchingPreferenceWithNoData() { mImpl.updatePreferences(mContext, getPreferenceScreen(), getDashboardCategory()); mImpl.updatePreferencesToRunOnWorkerThread( mContext, getPreferenceScreen(), getDashboardCategory()); ShadowLooper.runUiThreadTasks(); verifyNoMoreInteractions(mPackageManager); } Loading @@ -135,7 +143,8 @@ public class SecurityFeatureProviderImplTest { dashboardCategory.getTile(0).intent = new Intent().setPackage("package"); dashboardCategory.getTile(0).metaData = bundle; mImpl.updatePreferences(mContext, screen, dashboardCategory); mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory); ShadowLooper.runUiThreadTasks(); verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable); verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY); } Loading @@ -157,7 +166,8 @@ public class SecurityFeatureProviderImplTest { dashboardCategory.getTile(0).intent = new Intent().setPackage("package"); dashboardCategory.getTile(0).metaData = bundle; mImpl.updatePreferences(mContext, screen, dashboardCategory); mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory); ShadowLooper.runUiThreadTasks(); verify(screen.findPreference(MOCK_KEY), never()).setSummary(anyString()); } Loading Loading
src/com/android/settings/SecuritySettings.java +16 −5 Original line number Diff line number Diff line Loading @@ -76,6 +76,8 @@ import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.TileUtils; import java.util.ArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.List; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; Loading Loading @@ -937,8 +939,8 @@ public class SecuritySettings extends SettingsPreferenceFragment MY_USER_ID)); } if (mPowerButtonInstantlyLocks != null) { mPowerButtonInstantlyLocks.setChecked(mLockPatternUtils.getPowerButtonInstantlyLocks( MY_USER_ID)); mPowerButtonInstantlyLocks.setChecked( mLockPatternUtils.getPowerButtonInstantlyLocks(MY_USER_ID)); } updateOwnerInfo(); Loading Loading @@ -1202,9 +1204,18 @@ public class SecuritySettings extends SettingsPreferenceFragment FeatureFactory.getFactory(mContext).getDashboardFeatureProvider(mContext); if (dashboardFeatureProvider.isEnabled() && (packageVerifierState == PACKAGE_VERIFIER_STATE_ENABLED)) { // Calling the feature provider could potentially be slow, so do this on a separate // thread so as to not block the loading of Settings. Executors.newSingleThreadExecutor().execute(new Runnable() { @Override public void run() { DashboardCategory dashboardCategory = dashboardFeatureProvider.getTilesForCategory(CategoryKey.CATEGORY_SECURITY); mSummaryLoader.setSummary(this, getPackageVerifierSummary(dashboardCategory)); dashboardFeatureProvider.getTilesForCategory( CategoryKey.CATEGORY_SECURITY); mSummaryLoader.setSummary(SummaryProvider.this, getPackageVerifierSummary(dashboardCategory)); } }); } else { final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(mContext); if (fpm != null && fpm.isHardwareDetected()) { Loading
src/com/android/settings/security/SecurityFeatureProviderImpl.java +48 −15 Original line number Diff line number Diff line Loading @@ -22,9 +22,12 @@ import android.content.IContentProvider; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import com.android.settings.trustagent.TrustAgentManager; import com.android.settings.trustagent.TrustAgentManagerImpl; import com.android.settingslib.drawer.DashboardCategory; import android.support.annotation.VisibleForTesting; import android.support.v4.content.ContextCompat; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; Loading @@ -35,6 +38,7 @@ import android.util.Pair; import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.TileUtils; import java.util.concurrent.Executors; import java.util.Map; /** Implementation for {@code SecurityFeatureProvider}. */ Loading @@ -43,8 +47,22 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider { private TrustAgentManager mTrustAgentManager; /** Update preferences with data from associated tiles. */ public void updatePreferences(Context context, PreferenceScreen preferenceScreen, public void updatePreferences(final Context context, final PreferenceScreen preferenceScreen, final DashboardCategory dashboardCategory) { // Fetching the summary and icon from the provider introduces latency, so do this on a // separate thread. Executors.newSingleThreadExecutor().execute(new Runnable() { @Override public void run() { updatePreferencesToRunOnWorkerThread(context, preferenceScreen, dashboardCategory); } }); } @VisibleForTesting void updatePreferencesToRunOnWorkerThread(Context context, PreferenceScreen preferenceScreen, DashboardCategory dashboardCategory) { if (preferenceScreen == null) { return; } Loading Loading @@ -82,18 +100,31 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider { TileUtils.getIconFromUri(context, packageName, iconUri, providerMap); if (icon != null) { // Icon is only returned if the icon belongs to Settings or the target app. // setIcon must be called on the UI thread. new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { try { matchingPref.setIcon(context.getPackageManager() .getResourcesForApplication(icon.first /* package name */) .getDrawable(icon.second /* res id */, context.getTheme())); } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { // Intentionally ignored. If icon resources cannot be found, do not update. .getDrawable(icon.second /* res id */, context.getTheme())); } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { // Intentionally ignored. If icon resources cannot be found, do not // update. } } }); } } if (!TextUtils.isEmpty(summaryUri)) { String summary = TileUtils.getTextFromUri(context, summaryUri, providerMap, TileUtils.META_DATA_PREFERENCE_SUMMARY); // setSummary must be called on UI thread. new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { // Only update the summary if it has actually changed. if (summary == null) { if (matchingPref.getSummary() != null) { Loading @@ -103,6 +134,8 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider { matchingPref.setSummary(summary); } } }); } } } Loading
tests/robotests/src/com/android/settings/security/SecurityFeatureProviderImplTest.java +16 −6 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowLooper; import java.util.Map; Loading Loading @@ -102,8 +103,11 @@ public class SecurityFeatureProviderImplTest { @Test public void updateTilesData_shouldNotProcessEmptyScreenOrTiles() { mImpl.updatePreferences(mContext, null, null); mImpl.updatePreferences(mContext, new PreferenceScreen(mContext, null), null); mImpl.updatePreferencesToRunOnWorkerThread(mContext, null, null); ShadowLooper.runUiThreadTasks(); mImpl.updatePreferencesToRunOnWorkerThread( mContext, new PreferenceScreen(mContext, null), null); ShadowLooper.runUiThreadTasks(); verifyNoMoreInteractions(mPackageManager); } Loading @@ -111,13 +115,17 @@ public class SecurityFeatureProviderImplTest { public void updateTilesData_shouldNotProcessNonMatchingPreference() { DashboardCategory dashboardCategory = new DashboardCategory(); dashboardCategory.addTile(new Tile()); mImpl.updatePreferences(mContext, getPreferenceScreen(), dashboardCategory); mImpl.updatePreferencesToRunOnWorkerThread( mContext, getPreferenceScreen(), dashboardCategory); ShadowLooper.runUiThreadTasks(); verifyNoMoreInteractions(mPackageManager); } @Test public void updateTilesData_shouldNotProcessMatchingPreferenceWithNoData() { mImpl.updatePreferences(mContext, getPreferenceScreen(), getDashboardCategory()); mImpl.updatePreferencesToRunOnWorkerThread( mContext, getPreferenceScreen(), getDashboardCategory()); ShadowLooper.runUiThreadTasks(); verifyNoMoreInteractions(mPackageManager); } Loading @@ -135,7 +143,8 @@ public class SecurityFeatureProviderImplTest { dashboardCategory.getTile(0).intent = new Intent().setPackage("package"); dashboardCategory.getTile(0).metaData = bundle; mImpl.updatePreferences(mContext, screen, dashboardCategory); mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory); ShadowLooper.runUiThreadTasks(); verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable); verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY); } Loading @@ -157,7 +166,8 @@ public class SecurityFeatureProviderImplTest { dashboardCategory.getTile(0).intent = new Intent().setPackage("package"); dashboardCategory.getTile(0).metaData = bundle; mImpl.updatePreferences(mContext, screen, dashboardCategory); mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory); ShadowLooper.runUiThreadTasks(); verify(screen.findPreference(MOCK_KEY), never()).setSummary(anyString()); } Loading