From 2b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 7 Nov 2014 13:42:13 -0800 Subject: [PATCH] Add NetworkConnectivityUtils class Change-Id: I7bd71f1d4ef0fc0fe21ddfd9f3e11463f53ac4e7 --- .../keyboard/KeyboardSwitcher.java | 6 +- .../android/inputmethod/latin/LatinIME.java | 30 +++--- .../latin/RichInputMethodManager.java | 21 +--- .../latin/utils/NetworkConnectivityUtils.java | 101 ++++++++++++++++++ 4 files changed, 123 insertions(+), 35 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/utils/NetworkConnectivityUtils.java diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 5e3a5f17c..800fd33b4 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -40,11 +40,13 @@ import com.android.inputmethod.latin.define.ProductionFlags; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.utils.CapsModeUtils; +import com.android.inputmethod.latin.utils.NetworkConnectivityUtils; import com.android.inputmethod.latin.utils.RecapitalizeStatus; import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.latin.utils.ScriptUtils; -public final class KeyboardSwitcher implements KeyboardState.SwitchActions { +public final class KeyboardSwitcher implements KeyboardState.SwitchActions, + NetworkConnectivityUtils.NetworkStateChangeListener { private static final String TAG = KeyboardSwitcher.class.getSimpleName(); private SubtypeSwitcher mSubtypeSwitcher; @@ -414,6 +416,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { return mCurrentInputView; } + // {@link NetworkConnectivityUtils.NetworkStateChangeListener#onNetworkStateChanged(boolean)}. + @Override public void onNetworkStateChanged() { if (mKeyboardView == null) { return; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 27115e266..d6ec57fe6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -32,7 +32,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.inputmethodservice.InputMethodService; import android.media.AudioManager; -import android.net.ConnectivityManager; import android.os.Build; import android.os.Debug; import android.os.IBinder; @@ -100,6 +99,7 @@ import com.android.inputmethod.latin.utils.ImportantNoticeUtils; import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.JniUtils; import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper; +import com.android.inputmethod.latin.utils.NetworkConnectivityUtils; import com.android.inputmethod.latin.utils.StatsUtils; import com.android.inputmethod.latin.utils.StatsUtilsManager; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; @@ -592,13 +592,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen loadSettings(); resetDictionaryFacilitatorIfNecessary(); - // Register to receive ringer mode change and network state change. - // Also receive installation and removal of a dictionary pack. - final IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); - registerReceiver(mConnectivityAndRingerModeChangeReceiver, filter); + NetworkConnectivityUtils.onCreate(this /* context */, mKeyboardSwitcher /* listener */); + // Register to receive ringer mode change. + final IntentFilter filter = new IntentFilter(); + filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); + registerReceiver(mRingerModeChangeReceiver, filter); + + // Register to receive installation and removal of a dictionary pack. final IntentFilter packageFilter = new IntentFilter(); packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); @@ -726,7 +727,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mPersonalizationDictionaryUpdater.onDestroy(); mContextualDictionaryUpdater.onDestroy(); mSettings.onDestroy(); - unregisterReceiver(mConnectivityAndRingerModeChangeReceiver); + NetworkConnectivityUtils.onDestroy(this /* context */); + unregisterReceiver(mRingerModeChangeReceiver); unregisterReceiver(mDictionaryPackInstallReceiver); unregisterReceiver(mDictionaryDumpBroadcastReceiver); mStatsUtilsManager.onDestroy(); @@ -738,7 +740,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void recycle() { unregisterReceiver(mDictionaryPackInstallReceiver); unregisterReceiver(mDictionaryDumpBroadcastReceiver); - unregisterReceiver(mConnectivityAndRingerModeChangeReceiver); + unregisterReceiver(mRingerModeChangeReceiver); + NetworkConnectivityUtils.onDestroy(this /* context */); mInputLogic.recycle(); } @@ -1828,15 +1831,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // boolean onKeyLongPress(final int keyCode, final KeyEvent event); // boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event); - // receive ringer mode change and network state change. - private final BroadcastReceiver mConnectivityAndRingerModeChangeReceiver = - new BroadcastReceiver() { + // receive ringer mode change. + private final BroadcastReceiver mRingerModeChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); - if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { - mRichImm.onNetworkStateChanged(intent); - } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { + if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { AudioAndHapticFeedbackManager.getInstance().onRingerModeChanged(); } } diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java index 462121789..bc700c0b7 100644 --- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java +++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java @@ -20,11 +20,8 @@ import static com.android.inputmethod.latin.common.Constants.Subtype.KEYBOARD_MO import static com.android.inputmethod.latin.common.Constants.Subtype.ExtraValue.REQ_NETWORK_CONNECTIVITY; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.inputmethodservice.InputMethodService; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.os.AsyncTask; import android.os.Build; import android.os.IBinder; @@ -36,10 +33,10 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.latin.settings.AdditionalFeaturesSettingUtils; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; +import com.android.inputmethod.latin.utils.NetworkConnectivityUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Collections; @@ -72,7 +69,6 @@ public class RichInputMethodManager { private RichInputMethodSubtype mCurrentRichInputMethodSubtype; private InputMethodInfo mShortcutInputMethodInfo; private InputMethodSubtype mShortcutSubtype; - private boolean mIsNetworkConnected; final HashMap> mSubtypeListCacheWithImplicitlySelectedSubtypes = new HashMap<>(); final HashMap> @@ -116,11 +112,6 @@ public class RichInputMethodManager { // Initialize the current input method subtype and the shortcut IME. refreshSubtypeCaches(); - - final ConnectivityManager connectivityManager = - (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - final NetworkInfo info = connectivityManager.getActiveNetworkInfo(); - mIsNetworkConnected = (info != null && info.isConnected()); } public InputMethodSubtype[] getAdditionalSubtypes() { @@ -591,16 +582,8 @@ public class RichInputMethodManager { return true; } if (mShortcutSubtype.containsExtraValueKey(REQ_NETWORK_CONNECTIVITY)) { - return mIsNetworkConnected; + return NetworkConnectivityUtils.isNetworkConnected(); } return true; } - - public void onNetworkStateChanged(final Intent intent) { - final boolean noConnection = intent.getBooleanExtra( - ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); - mIsNetworkConnected = !noConnection; - - KeyboardSwitcher.getInstance().onNetworkStateChanged(); - } } diff --git a/java/src/com/android/inputmethod/latin/utils/NetworkConnectivityUtils.java b/java/src/com/android/inputmethod/latin/utils/NetworkConnectivityUtils.java new file mode 100644 index 000000000..101c55067 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/NetworkConnectivityUtils.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.utils; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import javax.annotation.Nonnull; + +/** + * This class keeps track of the network connectivity state by receiving the system intent + * {@link ConnectivityManager#CONNECTIVITY_ACTION}, and invokes an registered call back to notify + * changes of the network connectivity state. + */ +public final class NetworkConnectivityUtils { + private static NetworkConnectivityReceiver sNetworkConnectivityReceiver; + + public interface NetworkStateChangeListener { + /** + * Called when the network connectivity state has changed. + */ + public void onNetworkStateChanged(); + } + + private static class NetworkConnectivityReceiver extends BroadcastReceiver { + @Nonnull + private final NetworkStateChangeListener mListener; + private boolean mIsNetworkConnected; + + public NetworkConnectivityReceiver(@Nonnull final NetworkStateChangeListener listener, + final boolean isNetworkConnected) { + mListener = listener; + mIsNetworkConnected = isNetworkConnected; + } + + public synchronized boolean isNetworkConnected() { + return mIsNetworkConnected; + } + + @Override + public void onReceive(final Context context, final Intent intent) { + final String action = intent.getAction(); + if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { + final boolean noConnection = intent.getBooleanExtra( + ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); + synchronized (this) { + mIsNetworkConnected = !noConnection; + } + mListener.onNetworkStateChanged(); + } + } + } + + private NetworkConnectivityUtils() { + // This utility class is not publicly instantiable. + } + + public static void onCreate(@Nonnull final Context context, + @Nonnull final NetworkStateChangeListener listener) { + final ConnectivityManager connectivityManager = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + final NetworkInfo info = connectivityManager.getActiveNetworkInfo(); + final boolean isNetworkConnected = (info != null && info.isConnected()); + + // Register {@link BroadcastReceiver} for the network connectivity state change. + final NetworkConnectivityReceiver receiver = new NetworkConnectivityReceiver( + listener, isNetworkConnected); + final IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + context.registerReceiver(receiver, filter); + + sNetworkConnectivityReceiver = receiver; + } + + public static void onDestroy(final Context context) { + context.unregisterReceiver(sNetworkConnectivityReceiver); + } + + public static boolean isNetworkConnected() { + final NetworkConnectivityReceiver receiver = sNetworkConnectivityReceiver; + return receiver != null && receiver.isNetworkConnected(); + } +}