shill: cellular: Add Cellular.SIMPresent property.

This CL adds Cellular.SIMPresent property to indicate whether a SIM card
is present on a GSM or LTE modem.

BUG=chromium-os:34002
TEST=Tested the following:
1. Build and run unit tests.
2. Verify that the value of Cellular.SIMPresent property correctly
   indicates the presence of a SIM card on Novatel E396 and E362 modems.
CQ-DEPEND=I01a2c1dcf00fee78ce1f9f6c51a1df76327ee044

Change-Id: Id94f8f48f66458c20a519aaefcdfe7d6a59d2e8b
Reviewed-on: https://gerrit.chromium.org/gerrit/35810
Reviewed-by: Darin Petkov <petkov@chromium.org>
Commit-Ready: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
diff --git a/cellular_capability_gsm.cc b/cellular_capability_gsm.cc
index e7b887b..49f56d2 100644
--- a/cellular_capability_gsm.cc
+++ b/cellular_capability_gsm.cc
@@ -61,7 +61,8 @@
       get_imsi_retries_(0),
       get_imsi_retry_delay_milliseconds_(kGetIMSIRetryDelayMilliseconds),
       scanning_(false),
-      scan_interval_(0) {
+      scan_interval_(0),
+      sim_present_(false) {
   SLOG(Cellular, 2) << "Cellular capability constructed: GSM";
   PropertyStore *store = cellular->mutable_store();
   store->RegisterConstString(flimflam::kSelectedNetworkProperty,
@@ -72,6 +73,7 @@
                            &provider_requires_roaming_);
   store->RegisterConstBool(flimflam::kScanningProperty, &scanning_);
   store->RegisterUint16(flimflam::kScanIntervalProperty, &scan_interval_);
+  store->RegisterConstBool(shill::kSIMPresentProperty, &sim_present_);
   HelpRegisterDerivedKeyValueStore(
       flimflam::kSIMLockStatusProperty,
       &CellularCapabilityGSM::SimLockStatusToProperty,
@@ -146,9 +148,9 @@
   ResultCallback cb_ignore_error =
       Bind(&CellularCapabilityGSM::StepCompletedCallback,
            weak_ptr_factory_.GetWeakPtr(), ResultCallback(), true, tasks);
-  // Chrome uses IMSI to determine if a SIM is present before allowing the
-  // modem to be enabled, so shill needs to obtain IMSI even before the device
-  // is enabled.
+  // Chrome checks if a SIM is present before allowing the modem to be enabled,
+  // so shill needs to obtain IMSI, as an indicator of SIM presence, even
+  // before the device is enabled.
   tasks->push_back(Bind(&CellularCapabilityGSM::GetIMSI,
                         weak_ptr_factory_.GetWeakPtr(), cb_ignore_error));
   RunNextStep(tasks);
@@ -923,9 +925,11 @@
   if (error.IsSuccess()) {
     SLOG(Cellular, 2) << "IMSI: " << imsi;
     imsi_ = imsi;
+    sim_present_ = true;
     SetHomeProvider();
     callback.Run(error);
   } else {
+    sim_present_ = false;
     if (get_imsi_retries_++ < kGetIMSIRetryLimit) {
       SLOG(Cellular, 2) << "GetIMSI failed - " << error << ". Retrying";
       base::Callback<void(void)> retry_get_imsi_cb =