Merge "Import translations. DO NOT MERGE" into pi-dev
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 7644a45..84d343d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1437,7 +1437,7 @@
     <string name="forward_intent_to_work" msgid="621480743856004612">"أنت تستخدم هذا التطبيق في ملفك الشخصي للعمل"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"طريقة الإرسال"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"مزامنة"</string>
-    <string name="accessibility_binding_label" msgid="4148120742096474641">"إمكانية الدخول"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"إمكانية الوصول"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"الخلفية"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"تغيير الخلفية"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"برنامج تلقّي الإشعارات الصوتية"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 104bea3..db9a7b0 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -209,7 +209,7 @@
     <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Sat će se ugasiti."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon će se isključiti."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"Da li želite da isključite telefon?"</string>
-    <string name="reboot_safemode_title" msgid="7054509914500140361">"Ponovo pokreni sistem u bezbednom režimu"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Restartuj sistem u bezbednom režimu"</string>
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"Da li želite da ponovo pokrenete sistem u bezbednom režimu? Ovo će onemogućiti sve instalirane aplikacije nezavisnih proizvođača. One će biti vraćene kada ponovo pokrenete sistem."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Nedavno"</string>
     <string name="no_recent_tasks" msgid="8794906658732193473">"Nema nedavnih aplikacija."</string>
@@ -831,7 +831,7 @@
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabričko testiranje nije uspelo"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Radnja FACTORY_TEST je podržana samo za pakete instalirane u direktorijumu /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nije pronađen nijedan paket koji obezbeđuje radnju FACTORY_TEST."</string>
-    <string name="factorytest_reboot" msgid="6320168203050791643">"Ponovo pokreni"</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Restartuj"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"Na stranici na adresi „<xliff:g id="TITLE">%s</xliff:g>“ piše:"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Potvrda navigacije"</string>
@@ -1251,7 +1251,7 @@
     <string name="sim_done_button" msgid="827949989369963775">"Gotovo"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM kartica je dodata"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Restartujte uređaj da biste mogli da pristupite mobilnoj mreži."</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"Ponovo pokreni"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Restartuj"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Aktivirajte mobilnu uslugu"</string>
     <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Preuzmite aplikaciju mobilnog operatera da biste aktivirali novi SIM"</string>
     <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"Preuzmite aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> da biste aktivirali novu SIM karticu"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9358c4c..aa6b75c 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -735,7 +735,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Tryk på Menu for at låse op eller foretage et nødopkald."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Tryk på Menu for at låse op."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Tegn oplåsningsmønster"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødopkald"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødsituation"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Tilbage til opkald"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Rigtigt!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Prøv igen"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index e976707..dc4a913 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -573,8 +573,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"携帯通信会社のSMSサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"携帯通信会社のサービスへのバインド"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"携帯通信会社のサービスにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
-    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"マナーモードへのアクセス"</string>
-    <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"マナーモード設定の読み取りと書き込みをアプリに許可します。"</string>
+    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"サイレント モードへのアクセス"</string>
+    <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"サイレント モード設定の読み取りと書き込みをアプリに許可します。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"画面ロックのパスワードとPINの長さと使用できる文字を制御します。"</string>
     <string name="policylab_watchLogin" msgid="5091404125971980158">"画面ロック解除試行の監視"</string>
@@ -1736,10 +1736,10 @@
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>まで"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>(次のアラーム)まで"</string>
     <string name="zen_mode_forever" msgid="931849471004038757">"自分が OFF にするまで"</string>
-    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"マナーモードを OFF にするまで"</string>
+    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"サイレント モードを OFF にするまで"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"折りたたむ"</string>
-    <string name="zen_mode_feature_name" msgid="5254089399895895004">"マナーモード"</string>
+    <string name="zen_mode_feature_name" msgid="5254089399895895004">"サイレント モード"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ダウンタイム"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"平日の夜"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"週末"</string>
@@ -1875,10 +1875,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"着信や通知をバイブレーションで知らせます"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"着信音と通知音をミュートします"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"システムの変更"</string>
-    <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"マナーモード"</string>
-    <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"新機能: マナーモードでは通知が非表示になります"</string>
+    <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"サイレント モード"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"新機能: サイレント モードでは通知が非表示になります"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"タップすると、詳細を確認して設定を変更できます。"</string>
-    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"マナーモードが変わりました"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"サイレント モードが変わりました"</string>
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"タップしてブロック対象をご確認ください。"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"システム"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"設定"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 8bfaf01..d0ea4bc 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -209,7 +209,7 @@
     <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Сат ће се угасити."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефон ће се искључити."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"Да ли желите да искључите телефон?"</string>
-    <string name="reboot_safemode_title" msgid="7054509914500140361">"Поново покрени систем у безбедном режиму"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Рестартуј систем у безбедном режиму"</string>
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"Да ли желите да поново покренете систем у безбедном режиму? Ово ће онемогућити све инсталиране апликације независних произвођача. Оне ће бити враћене када поново покренете систем."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Недавно"</string>
     <string name="no_recent_tasks" msgid="8794906658732193473">"Нема недавних апликација."</string>
@@ -831,7 +831,7 @@
     <string name="factorytest_failed" msgid="5410270329114212041">"Фабричко тестирање није успело"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Радња FACTORY_TEST је подржана само за пакете инсталиране у директоријуму /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Није пронађен ниједан пакет који обезбеђује радњу FACTORY_TEST."</string>
-    <string name="factorytest_reboot" msgid="6320168203050791643">"Поново покрени"</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Рестартуј"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"На страници на адреси „<xliff:g id="TITLE">%s</xliff:g>“ пише:"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Потврда навигације"</string>
@@ -1251,7 +1251,7 @@
     <string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM картица је додата"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Рестартујте уређај да бисте могли да приступите мобилној мрежи."</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"Поново покрени"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Рестартуј"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Активирајте мобилну услугу"</string>
     <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Преузмите апликацију мобилног оператера да бисте активирали нови SIM"</string>
     <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"Преузмите апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> да бисте активирали нову SIM картицу"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 843bb3b..efca492 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1349,7 +1349,7 @@
     <string name="forward_intent_to_work" msgid="621480743856004612">"Ginagamit mo ang app na ito sa iyong profile sa trabaho"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Pamamaraan ng pag-input"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"I-sync"</string>
-    <string name="accessibility_binding_label" msgid="4148120742096474641">"Kakayahang Ma-access"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Pagiging Accessible"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Baguhin ang wallpaper"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index caf7faf..647c64b 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1127,7 +1127,7 @@
     <string name="dump_heap_title" msgid="5864292264307651673">"Yığın dökümü paylaşılsın mı?"</string>
     <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g>, <xliff:g id="SIZE">%2$s</xliff:g> olan işlem bellek sınırını aştı. İşlemin geliştiricisiyle paylaşabileceğiniz bir bellek yığını dökümü hazır. Dikkat: Bu bellek yığını dökümü, uygulamanın erişebildiği tüm kişisel bilgilerinizi içerebilir."</string>
     <string name="sendText" msgid="5209874571959469142">"Kısa mesaj için bir işlem seçin"</string>
-    <string name="volume_ringtone" msgid="6885421406845734650">"Zil sesi düzeyi"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Zil ses düzeyi"</string>
     <string name="volume_music" msgid="5421651157138628171">"Medya ses düzeyi"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth üzerinden çalıyor"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Sessiz zil sesi ayarlandı"</string>
@@ -1137,7 +1137,7 @@
     <string name="volume_notification" msgid="2422265656744276715">"Bildirim ses düzeyi"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"Ses"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth ses düzeyi"</string>
-    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Zil sesi düzeyi"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Zil ses düzeyi"</string>
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"Çağrı ses düzeyi"</string>
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Medya ses düzeyi"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildirim ses düzeyi"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 4570c41..135ae1c 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1273,7 +1273,7 @@
     <string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-карту додано"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Перезапустіть пристрій, щоб отримати доступ до мобільної мережі."</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"Перезапуск"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Перезапустити"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Активувати мобільну службу"</string>
     <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Завантажити додаток оператора, щоб активувати нову SIM-карту"</string>
     <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"Щоб активувати нову SIM-карту, завантажте додаток <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 3c16329..c44b385 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -17,10 +17,7 @@
 package com.android.systemui.statusbar.policy;
 
 import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
 import android.os.UserManager;
@@ -38,14 +35,13 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final ArrayList<Callback> mCallbacks = new ArrayList<>();
-    private final WifiStateReceiver mWifiStateReceiver = new WifiStateReceiver();
     private final ConnectivityManager mConnectivityManager;
     private final WifiManager mWifiManager;
     private final Context mContext;
 
     private int mHotspotState;
     private int mNumConnectedDevices;
-    private boolean mWaitingForCallback;
+    private boolean mWaitingForTerminalState;
 
     public HotspotControllerImpl(Context context) {
         mContext = context;
@@ -63,7 +59,9 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("HotspotController state:");
-        pw.print("  mHotspotEnabled="); pw.println(stateToString(mHotspotState));
+        pw.print("  mHotspotState="); pw.println(stateToString(mHotspotState));
+        pw.print("  mNumConnectedDevices="); pw.println(mNumConnectedDevices);
+        pw.print("  mWaitingForTerminalState="); pw.println(mWaitingForTerminalState);
     }
 
     private static String stateToString(int hotspotState) {
@@ -99,7 +97,6 @@
         if (DEBUG) Log.d(TAG, "removeCallback " + callback);
         synchronized (mCallbacks) {
             mCallbacks.remove(callback);
-
             updateWifiStateListeners(!mCallbacks.isEmpty());
         }
     }
@@ -112,7 +109,6 @@
      * @param shouldListen whether we should start listening to various wifi statuses
      */
     private void updateWifiStateListeners(boolean shouldListen) {
-        mWifiStateReceiver.setListening(shouldListen);
         if (shouldListen) {
             mWifiManager.registerSoftApCallback(
                     this,
@@ -129,21 +125,27 @@
 
     @Override
     public boolean isHotspotTransient() {
-        return mWaitingForCallback || (mHotspotState == WifiManager.WIFI_AP_STATE_ENABLING);
+        return mWaitingForTerminalState || (mHotspotState == WifiManager.WIFI_AP_STATE_ENABLING);
     }
 
     @Override
     public void setHotspotEnabled(boolean enabled) {
-        if (mWaitingForCallback) {
-            if (DEBUG) Log.d(TAG, "Ignoring setHotspotEnabled; waiting for callback.");
+        if (mWaitingForTerminalState) {
+            if (DEBUG) Log.d(TAG, "Ignoring setHotspotEnabled; waiting for terminal state.");
             return;
         }
         if (enabled) {
-            OnStartTetheringCallback callback = new OnStartTetheringCallback();
-            mWaitingForCallback = true;
+            mWaitingForTerminalState = true;
             if (DEBUG) Log.d(TAG, "Starting tethering");
-            mConnectivityManager.startTethering(
-                    ConnectivityManager.TETHERING_WIFI, false, callback);
+            mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, false,
+                    new ConnectivityManager.OnStartTetheringCallback() {
+                        @Override
+                        public void onTetheringFailed() {
+                            if (DEBUG) Log.d(TAG, "onTetheringFailed");
+                            maybeResetSoftApState();
+                            fireHotspotChangedCallback();
+                        }
+                    });
         } else {
             mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
         }
@@ -155,97 +157,57 @@
     }
 
     /**
-     * Sends a hotspot changed callback with the new enabled status. Wraps
-     * {@link #fireHotspotChangedCallback(boolean, int)} and assumes that the number of devices has
-     * not changed.
-     *
-     * @param enabled whether the hotspot is enabled
+     * Sends a hotspot changed callback.
+     * Be careful when calling over multiple threads, especially if one of them is the main thread
+     * (as it can be blocked).
      */
-    private void fireHotspotChangedCallback(boolean enabled) {
-        fireHotspotChangedCallback(enabled, mNumConnectedDevices);
-    }
-
-    /**
-     * Sends a hotspot changed callback with the new enabled status & the number of devices
-     * connected to the hotspot. Be careful when calling over multiple threads, especially if one of
-     * them is the main thread (as it can be blocked).
-     *
-     * @param enabled whether the hotspot is enabled
-     * @param numConnectedDevices number of devices connected to the hotspot
-     */
-    private void fireHotspotChangedCallback(boolean enabled, int numConnectedDevices) {
+    private void fireHotspotChangedCallback() {
         synchronized (mCallbacks) {
             for (Callback callback : mCallbacks) {
-                callback.onHotspotChanged(enabled, numConnectedDevices);
+                callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices);
             }
         }
     }
 
     @Override
     public void onStateChanged(int state, int failureReason) {
-        // Do nothing - we don't care about changing anything here.
+        // Update internal hotspot state for tracking before using any enabled/callback methods.
+        mHotspotState = state;
+
+        maybeResetSoftApState();
+        if (!isHotspotEnabled()) {
+            // Reset num devices if the hotspot is no longer enabled so we don't get ghost
+            // counters.
+            mNumConnectedDevices = 0;
+        }
+
+        fireHotspotChangedCallback();
+    }
+
+    private void maybeResetSoftApState() {
+        if (!mWaitingForTerminalState) {
+            return; // Only reset soft AP state if enabled from this controller.
+        }
+
+        switch (mHotspotState) {
+            case WifiManager.WIFI_AP_STATE_FAILED:
+                // TODO(b/110697252): must be called to reset soft ap state after failure
+                mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
+                // Fall through
+            case WifiManager.WIFI_AP_STATE_ENABLED:
+            case WifiManager.WIFI_AP_STATE_DISABLED:
+                mWaitingForTerminalState = false;
+                break;
+            case WifiManager.WIFI_AP_STATE_ENABLING:
+            case WifiManager.WIFI_AP_STATE_DISABLING:
+            default:
+                break;
+        }
     }
 
     @Override
     public void onNumClientsChanged(int numConnectedDevices) {
         mNumConnectedDevices = numConnectedDevices;
-        fireHotspotChangedCallback(isHotspotEnabled(), numConnectedDevices);
-    }
-
-    private final class OnStartTetheringCallback extends
-            ConnectivityManager.OnStartTetheringCallback {
-        @Override
-        public void onTetheringStarted() {
-            if (DEBUG) Log.d(TAG, "onTetheringStarted");
-            mWaitingForCallback = false;
-            // Don't fire a callback here, instead wait for the next update from wifi.
-        }
-
-        @Override
-        public void onTetheringFailed() {
-            if (DEBUG) Log.d(TAG, "onTetheringFailed");
-            mWaitingForCallback = false;
-            fireHotspotChangedCallback(isHotspotEnabled());
-          // TODO: Show error.
-        }
-    }
-
-    /**
-     * Class to listen in on wifi state and update the hotspot state
-     */
-    private final class WifiStateReceiver extends BroadcastReceiver {
-        private boolean mRegistered;
-
-        public void setListening(boolean listening) {
-            if (listening && !mRegistered) {
-                if (DEBUG) Log.d(TAG, "Registering receiver");
-                final IntentFilter filter = new IntentFilter();
-                filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
-                mContext.registerReceiver(this, filter);
-                mRegistered = true;
-            } else if (!listening && mRegistered) {
-                if (DEBUG) Log.d(TAG, "Unregistering receiver");
-                mContext.unregisterReceiver(this);
-                mRegistered = false;
-            }
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            int state = intent.getIntExtra(
-                    WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
-            if (DEBUG) Log.d(TAG, "onReceive " + state);
-
-            // Update internal hotspot state for tracking before using any enabled/callback methods.
-            mHotspotState = state;
-
-            if (!isHotspotEnabled()) {
-                // Reset num devices if the hotspot is no longer enabled so we don't get ghost
-                // counters.
-                mNumConnectedDevices = 0;
-            }
-
-            fireHotspotChangedCallback(isHotspotEnabled());
-        }
+        fireHotspotChangedCallback();
     }
 }