diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java index e48d745c7e5..691cbd6f77a 100644 --- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java +++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java @@ -51,6 +51,8 @@ import com.android.settingslib.widget.LayoutPreference; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; @SearchIndexable public class MyDeviceInfoFragment extends DashboardFragment @@ -105,14 +107,9 @@ public class MyDeviceInfoFragment extends DashboardFragment Context context, MyDeviceInfoFragment fragment, Lifecycle lifecycle) { final List controllers = new ArrayList<>(); - final SlotSimStatus slotSimStatus = new SlotSimStatus(context); - for (int slotIndex = 0; slotIndex < slotSimStatus.size(); slotIndex ++) { - SimStatusPreferenceController slotRecord = - new SimStatusPreferenceController(context, - slotSimStatus.getPreferenceKey(slotIndex)); - slotRecord.init(fragment, slotSimStatus); - controllers.add(slotRecord); - } + final ExecutorService executor = (fragment == null) ? null : + Executors.newSingleThreadExecutor(); + final SlotSimStatus slotSimStatus = new SlotSimStatus(context, executor); controllers.add(new IpAddressPreferenceController(context, lifecycle)); controllers.add(new WifiMacAddressPreferenceController(context, lifecycle)); @@ -123,6 +120,17 @@ public class MyDeviceInfoFragment extends DashboardFragment controllers.add(new FeedbackPreferenceController(fragment, context)); controllers.add(new FccEquipmentIdPreferenceController(context)); controllers.add(new UptimePreferenceController(context, lifecycle)); + + for (int slotIndex = 0; slotIndex < slotSimStatus.size(); slotIndex ++) { + SimStatusPreferenceController slotRecord = + new SimStatusPreferenceController(context, + slotSimStatus.getPreferenceKey(slotIndex)); + slotRecord.init(fragment, slotSimStatus); + controllers.add(slotRecord); + } + if (executor != null) { + executor.shutdown(); + } return controllers; } diff --git a/src/com/android/settings/deviceinfo/simstatus/SlotSimStatus.java b/src/com/android/settings/deviceinfo/simstatus/SlotSimStatus.java index 70561815705..033222a4cbd 100644 --- a/src/com/android/settings/deviceinfo/simstatus/SlotSimStatus.java +++ b/src/com/android/settings/deviceinfo/simstatus/SlotSimStatus.java @@ -21,6 +21,10 @@ import android.telephony.TelephonyManager; import android.telephony.SubscriptionManager; import android.util.Log; +import java.util.concurrent.Executor; +import java.util.concurrent.Phaser; +import java.util.concurrent.atomic.AtomicInteger; + /** * A class for showing a summary of status of sim slots. */ @@ -28,7 +32,8 @@ public class SlotSimStatus { private static final String TAG = "SlotSimStatus"; - private int mNumberOfSlots; + private final AtomicInteger mNumberOfSlots = new AtomicInteger(0); + private final Phaser mBlocker = new Phaser(1); private int mBasePreferenceOrdering; private static final String KEY_SIM_STATUS = "sim_status"; @@ -38,11 +43,32 @@ public class SlotSimStatus { * @param context Context */ public SlotSimStatus(Context context) { - TelephonyManager telMgr = context.getSystemService(TelephonyManager.class); - if (telMgr == null) { - return; + this(context, null); + } + + /** + * Construct of class. + * @param context Context + * @param executor executor for offload to thread + */ + public SlotSimStatus(Context context, Executor executor) { + if (executor == null) { + queryRecords(context); + } else { + executor.execute(() -> queryRecords(context)); } - mNumberOfSlots = telMgr.getPhoneCount(); + } + + protected void queryRecords(Context context) { + TelephonyManager telMgr = context.getSystemService(TelephonyManager.class); + if (telMgr != null) { + mNumberOfSlots.set(telMgr.getPhoneCount()); + } + mBlocker.arrive(); + } + + protected void waitForResult() { + mBlocker.awaitAdvance(0); } /** @@ -58,7 +84,8 @@ public class SlotSimStatus { * @return number of slots */ public int size() { - return mNumberOfSlots; + waitForResult(); + return mNumberOfSlots.get(); } /** diff --git a/tests/unit/src/com/android/settings/deviceinfo/simstatus/SlotSimStatusTest.java b/tests/unit/src/com/android/settings/deviceinfo/simstatus/SlotSimStatusTest.java index 1a4e740ccf2..71f0faf5989 100644 --- a/tests/unit/src/com/android/settings/deviceinfo/simstatus/SlotSimStatusTest.java +++ b/tests/unit/src/com/android/settings/deviceinfo/simstatus/SlotSimStatusTest.java @@ -33,6 +33,9 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + @RunWith(AndroidJUnit4.class) public class SlotSimStatusTest { @@ -58,6 +61,16 @@ public class SlotSimStatusTest { assertEquals(new Integer(target.size()), new Integer(2)); } + @Test + public void size_returnNumberOfPhone_whenQueryInBackgroundThread() { + doReturn(2).when(mTelephonyManager).getPhoneCount(); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + SlotSimStatus target = new SlotSimStatus(mContext, executor); + + assertEquals(new Integer(target.size()), new Integer(2)); + } + @Test public void getPreferenceOrdering_returnOrdering_whenQuery() { doReturn(2).when(mTelephonyManager).getPhoneCount();