From 3b7510ed9bfef56393116bf94ada7b66ae5b2d37 Mon Sep 17 00:00:00 2001 From: rubienr Date: Sun, 12 Oct 2014 20:49:52 +0200 Subject: [PATCH] begun fixing memleaks --- source/WebSMSTool/AndroidManifest.xml | 6 +- .../IncomingServiceMessageHandler.java | 6 + .../ist/akm/activities/MainActivity.java | 21 +- .../akm/activities/StartServiceFragment.java | 115 +++-- .../activities/preferences/PrefsFragment.java | 2 + .../activities/trace/AndroidUILogSink.java | 7 + .../src/at/tugraz/ist/akm/io/FileReader.java | 56 ++- .../ist/akm/keystore/ApplicationKeyStore.java | 1 + .../ist/akm/monitoring/BatteryStatus.java | 193 ++++---- .../ist/akm/monitoring/SystemMonitor.java | 11 +- .../monitoring/TelephonySignalStrength.java | 6 +- .../akm/networkInterface/WifiIpAddress.java | 9 + .../akm/phonebook/CacheModifiedHandler.java | 1 + .../ist/akm/phonebook/PhonebookBridge.java | 21 + ...nSharedPreferenceEventListenValidator.java | 11 +- .../RenewCertificateDialogPreference.java | 16 +- .../SharedPreferencesProvider.java | 2 + .../ist/akm/preferences/StringFormatter.java | 8 +- .../src/at/tugraz/ist/akm/sms/SmsBridge.java | 9 + .../ist/akm/statusbar/FireNotification.java | 5 + .../ist/akm/texting/TextingAdapter.java | 418 ++++++++++-------- .../ist/akm/texting/TextingInterface.java | 59 +-- .../tugraz/ist/akm/trace/AndroidLogSink.java | 5 + .../src/at/tugraz/ist/akm/trace/ILogSink.java | 4 + .../at/tugraz/ist/akm/trace/TraceService.java | 6 + .../AbstractHttpRequestProcessor.java | 51 ++- .../EchoJsonRequestProcessor.java | 12 +- .../FaviconLoadRequestProcessor.java | 9 +- .../FileRequestProcessor.java | 15 +- .../JsonAPIRequestProcessor.java | 20 +- .../AbstractRequestInterceptor.java | 19 +- .../interceptor/AuthorizationInterceptor.java | 2 + .../webservice/server/SimpleWebServer.java | 50 ++- .../webservice/service/WebSMSToolService.java | 30 +- .../test/base/WebSMSToolActivityTestcase.java | 9 +- .../WebSMSToolInstrumentationTestcase.java | 7 +- .../test/monitoring/SystemMonitorTest.java | 2 + .../test/phonebook/PhonebookBridgeTest.java | 1 + .../ist/akm/test/sms/SmsBridgeTest.java | 3 + .../akm/test/texting/TextingAdapterTest.java | 8 +- .../handler/FileRequestHandlerTest.java | 5 +- .../server/MockSimpleWebServer.java | 2 +- .../server/SimpleWebServerTest.java | 21 +- 43 files changed, 852 insertions(+), 412 deletions(-) diff --git a/source/WebSMSTool/AndroidManifest.xml b/source/WebSMSTool/AndroidManifest.xml index b1d3dd7..28b256f 100644 --- a/source/WebSMSTool/AndroidManifest.xml +++ b/source/WebSMSTool/AndroidManifest.xml @@ -45,8 +45,7 @@ + android:label="@string/app_name" > + android:exported="false" + android:process=":process" > mServiceClass = WebSMSToolService.class; - private final String mServiceComponentNameSuffix = mServiceClass - .getSimpleName(); - private WifiIpAddress mWifiState = null; private ProgressBar mProgressBar = null; @@ -59,9 +55,14 @@ public class StartServiceFragment extends Fragment implements TextView mAccessRestrictionPassword = null; LinearLayout mAccessRestrictionLayout = null; + private Boolean mIsBoundToService = false; + private Messenger mServiceMessenger = null; + + private IncomingServiceMessageHandler mIncomingServiceMessageHandler = new IncomingServiceMessageHandler( + this); final Messenger mClientMessenger = new Messenger( - new IncomingServiceMessageHandler(this)); + mIncomingServiceMessageHandler); private ServiceRunningStates mServiceRunningState = ServiceRunningStates.BEFORE_SINGULARITY; @@ -83,23 +84,44 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, } + @Override + public void onDestroyView() + { + invalidateMainFragmentUI(); + super.onDestroyView(); + } + + @Override public void onDestroy() { + stopService(); mLog.debug("on destroy"); - mStartSmsServiceIntent = null; mLog = null; mButton = null; mInfoFieldView = null; + unbindFromService(); + mIncomingServiceMessageHandler.onClose(); + mIncomingServiceMessageHandler = null; + mLog = null; super.onDestroy(); } + private void unbindFromService() + { + if (mIsBoundToService) + { + getActivity().getApplicationContext().unbindService(this); + mIsBoundToService = false; + } + } + + @Override public void onStart() { super.onStart(); - setUpMainFragmentUI(getView()); mLog.debug("on start"); } @@ -118,8 +140,19 @@ public void onResume() super.onResume(); mLog.debug("on resume"); setServiceDisabledUI(); - getActivity().getApplicationContext().bindService( - mStartSmsServiceIntent, this, Context.BIND_AUTO_CREATE); + bindToService(); + } + + + private void bindToService() + { + if (mIsBoundToService == false) + { + getActivity().getApplicationContext().bindService( + new Intent(getActivity(), WebSMSToolService.class), this, + Context.BIND_AUTO_CREATE); + mIsBoundToService = true; + } } @@ -134,7 +167,6 @@ public void onPause() private void setUpMainFragmentUI(View view) { - mStartSmsServiceIntent = new Intent(getActivity(), mServiceClass); mButton = (ToggleButton) view.findViewById(R.id.start_stop_server); mInfoFieldView = (TextView) view.findViewById(R.id.adress_data_field); mButton.setOnClickListener(this); @@ -162,6 +194,24 @@ private void setUpMainFragmentUI(View view) } + private void invalidateMainFragmentUI() + { + mButton.setOnClickListener(null); + mButton = null; + mInfoFieldView = null; + mWifiState.onClose(); + mWifiState = null; + mProgressBar = null; + mSmsRecievedView = null; + mSmsSentView = null; + mNetworkRxBytes = null; + mNetworkTxBytes = null; + mAccessRestrictionUsername = null; + mAccessRestrictionPassword = null; + mAccessRestrictionLayout = null; + } + + private void tearDownMainFragmentUI() { mButton.setOnClickListener(null); @@ -180,14 +230,11 @@ public void onClick(View view) mLog.info("starting web service"); displayStartingService(); - // TODO: we are bound here, send server config again before asking for start + // TODO: we are bound here, send server config again before + // asking for start mProgressBar.setIndeterminate(true); - getActivity().getApplicationContext().startService( - mStartSmsServiceIntent); - -// getActivity().getApplicationContext().bindService( -// mStartSmsServiceIntent, StartServiceFragment.this, -// Context.BIND_AUTO_CREATE); + startService(); + } else { displayNoWifiConnected(); @@ -201,7 +248,7 @@ public void onClick(View view) askWebServiceForServiceStopAsync(); try { - getActivity().getApplicationContext().unbindService(this); + unbindFromService(); } catch (IllegalArgumentException iae) { @@ -212,6 +259,20 @@ public void onClick(View view) } + private void startService() + { + getActivity().getApplicationContext().startService( + new Intent(getActivity(), WebSMSToolService.class)); + } + + + private void stopService() + { + getActivity().getApplicationContext().stopService( + new Intent(getActivity(), WebSMSToolService.class)); + } + + private boolean isServiceRunning() { mLog.debug("service is in runningstate [" @@ -326,16 +387,18 @@ protected void onWebServiceClientRegistered() @Override public void onServiceConnected(ComponentName name, IBinder service) { + String serviceComponentNameSuffix = WebSMSToolService.class + .getSimpleName(); String inServiceName = name.flattenToShortString(); - if (inServiceName.endsWith(mServiceComponentNameSuffix)) + if (inServiceName.endsWith(serviceComponentNameSuffix)) { - mLog.debug("bound to service [" + mServiceComponentNameSuffix + "]"); + mLog.debug("bound to service [" + serviceComponentNameSuffix + "]"); mServiceMessenger = new Messenger(service); askWebServiceForClientRegistrationAsync(); } else { mLog.error("failed binding fragment to service[" + inServiceName - + "] expected [*" + mServiceComponentNameSuffix + "]"); + + "] expected [*" + serviceComponentNameSuffix + "]"); } } @@ -344,15 +407,17 @@ public void onServiceConnected(ComponentName name, IBinder service) public void onServiceDisconnected(ComponentName name) { String inServiceName = name.flattenToShortString(); - if (inServiceName.endsWith(mServiceComponentNameSuffix)) + String serviceComponentNameSuffix = WebSMSToolService.class + .getSimpleName(); + if (inServiceName.endsWith(serviceComponentNameSuffix)) { - mLog.debug("unbound from service [" + mServiceComponentNameSuffix + mLog.debug("unbound from service [" + serviceComponentNameSuffix + "]"); mServiceMessenger = null; } else { mLog.error("failed unbinding fragment to service[" + inServiceName - + "] expected [*" + mServiceComponentNameSuffix + "]"); + + "] expected [*" + serviceComponentNameSuffix + "]"); } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/activities/preferences/PrefsFragment.java b/source/WebSMSTool/src/at/tugraz/ist/akm/activities/preferences/PrefsFragment.java index ca97081..2403b80 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/activities/preferences/PrefsFragment.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/activities/preferences/PrefsFragment.java @@ -102,6 +102,8 @@ public void onPause() public void onStop() { mLog.debug("fragment onStop()"); + mPreferenceChangedListener.onClose(); + mPreferenceChangedListener = null; super.onStop(); } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/activities/trace/AndroidUILogSink.java b/source/WebSMSTool/src/at/tugraz/ist/akm/activities/trace/AndroidUILogSink.java index 78c26ea..d442685 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/activities/trace/AndroidUILogSink.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/activities/trace/AndroidUILogSink.java @@ -70,4 +70,11 @@ public void verbose(final String tag, final String message) } android.util.Log.v(tag, message); } + + @Override + public void onClose() + { + mActivity = null; + mLogView = null; + } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/io/FileReader.java b/source/WebSMSTool/src/at/tugraz/ist/akm/io/FileReader.java index 6fb454c..9715548 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/io/FileReader.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/io/FileReader.java @@ -23,48 +23,72 @@ import android.content.Context; -public class FileReader { - private final Context mContext; - private final String mFilePath; +public class FileReader +{ + private Context mContext; + private String mFilePath; private final static String mDefaultCharset = "UTF8"; - public FileReader(final Context context, final String filePath) { + + public FileReader(final Context context, final String filePath) + { this.mContext = context; - this.mFilePath = filePath; + this.mFilePath = new String(filePath); } - public String read() { + + public String read() + { InputStream is = null; InputStreamReader isr = null; BufferedReader reader = null; StringBuilder builder = new StringBuilder(); - try { + try + { is = mContext.getAssets().open(mFilePath); isr = new InputStreamReader(is, mDefaultCharset); reader = new BufferedReader(isr); String line; - while ((line = reader.readLine()) != null) { + while ((line = reader.readLine()) != null) + { builder.append(line).append("\n"); } - } catch (IOException ioException) { + } + catch (IOException ioException) + { ioException.printStackTrace(); - } finally { - try { - if (is != null) { + } + finally + { + try + { + if (is != null) + { is.close(); } - if (isr != null) { + if (isr != null) + { isr.close(); } - if (reader != null) { + if (reader != null) + { reader.close(); } - } catch (IOException ioException) { + } + catch (IOException ioException) + { ioException.printStackTrace(); } } return builder.toString(); } -} \ No newline at end of file + + + public void onClose() + { + mContext = null; + mFilePath = null; + } +} diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/keystore/ApplicationKeyStore.java b/source/WebSMSTool/src/at/tugraz/ist/akm/keystore/ApplicationKeyStore.java index 87021fc..a89bd90 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/keystore/ApplicationKeyStore.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/keystore/ApplicationKeyStore.java @@ -217,6 +217,7 @@ public void close() mKeyPair = null; mKeyFactory = null; mInKeyStore = null; + mLog = null; } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/BatteryStatus.java b/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/BatteryStatus.java index 058c43b..f77a806 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/BatteryStatus.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/BatteryStatus.java @@ -27,85 +27,116 @@ import android.util.Base64; import at.tugraz.ist.akm.R; -public class BatteryStatus { - - private int mBatteryLevel = 0; - private int mBatteryIconId = 0; - private boolean mIsCharging = false; - private boolean mIsFull = false; - private int mChargePlug = 0; - private boolean mISUsbCharge = false; - private boolean mIsAcCharge = false; - private Context mContext = null; - - public BatteryStatus(Context context, Intent batteryStatus) { - mContext = context; - int extraStatus = batteryStatus.getIntExtra( - BatteryManager.EXTRA_STATUS, -1); - mIsCharging = (extraStatus == BatteryManager.BATTERY_STATUS_CHARGING || extraStatus == BatteryManager.BATTERY_STATUS_FULL); - - mIsFull = (extraStatus == BatteryManager.BATTERY_STATUS_FULL); - - mChargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, - -1); - mISUsbCharge = (mChargePlug == BatteryManager.BATTERY_PLUGGED_USB); - - mIsAcCharge = (mChargePlug == BatteryManager.BATTERY_PLUGGED_AC); - - mBatteryIconId = batteryStatus.getIntExtra( - BatteryManager.EXTRA_ICON_SMALL, -1); - - mBatteryLevel = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, - -1); - } - - public int getBatteryLevel() { - return mBatteryLevel; - } - - public int getBatteryIconId() { - return mBatteryIconId; - } - - public byte[] getBatteryIconBytes() { - - int batteryIconId = R.raw.battery_level0; - if (mBatteryLevel >= 80) { - batteryIconId = R.raw.battery_level4; - } else if (mBatteryLevel >= 60) { - batteryIconId = R.raw.battery_level3; - } else if (mBatteryLevel >= 40) { - batteryIconId = R.raw.battery_level2; - } else if (mBatteryLevel >= 20) { - batteryIconId = R.raw.battery_level1; - } - - Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), batteryIconId); - ByteArrayOutputStream os=new ByteArrayOutputStream(); - bmp.compress(android.graphics.Bitmap.CompressFormat.PNG, 100,(OutputStream) os); - bmp = null; - byte[] byteArray = os.toByteArray(); - - return Base64.encode(byteArray, Base64.DEFAULT); - } - - public boolean getIsCharging() { - return mIsCharging; - } - - public boolean getIsFull() { - return mIsFull; - } - - public int getChargePlug() { - return mChargePlug; - } - - public boolean getIsUsbCharge() { - return mISUsbCharge; - } - - public boolean getIsAcCharge() { - return mIsAcCharge; - } +public class BatteryStatus +{ + + private int mBatteryLevel = 0; + private int mBatteryIconId = 0; + private boolean mIsCharging = false; + private boolean mIsFull = false; + private int mChargePlug = 0; + private boolean mISUsbCharge = false; + private boolean mIsAcCharge = false; + private Context mContext = null; + + + public BatteryStatus(Context context, Intent batteryStatus) + { + mContext = context; + int extraStatus = batteryStatus.getIntExtra( + BatteryManager.EXTRA_STATUS, -1); + mIsCharging = (extraStatus == BatteryManager.BATTERY_STATUS_CHARGING || extraStatus == BatteryManager.BATTERY_STATUS_FULL); + + mIsFull = (extraStatus == BatteryManager.BATTERY_STATUS_FULL); + + mChargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, + -1); + mISUsbCharge = (mChargePlug == BatteryManager.BATTERY_PLUGGED_USB); + + mIsAcCharge = (mChargePlug == BatteryManager.BATTERY_PLUGGED_AC); + + mBatteryIconId = batteryStatus.getIntExtra( + BatteryManager.EXTRA_ICON_SMALL, -1); + + mBatteryLevel = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, + -1); + } + + + public int getBatteryLevel() + { + return mBatteryLevel; + } + + + public int getBatteryIconId() + { + return mBatteryIconId; + } + + + public byte[] getBatteryIconBytes() + { + + int batteryIconId = R.raw.battery_level0; + if (mBatteryLevel >= 80) + { + batteryIconId = R.raw.battery_level4; + } else if (mBatteryLevel >= 60) + { + batteryIconId = R.raw.battery_level3; + } else if (mBatteryLevel >= 40) + { + batteryIconId = R.raw.battery_level2; + } else if (mBatteryLevel >= 20) + { + batteryIconId = R.raw.battery_level1; + } + + Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), + batteryIconId); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + bmp.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, + (OutputStream) os); + bmp = null; + byte[] byteArray = os.toByteArray(); + + return Base64.encode(byteArray, Base64.DEFAULT); + } + + + public boolean getIsCharging() + { + return mIsCharging; + } + + + public boolean getIsFull() + { + return mIsFull; + } + + + public int getChargePlug() + { + return mChargePlug; + } + + + public boolean getIsUsbCharge() + { + return mISUsbCharge; + } + + + public boolean getIsAcCharge() + { + return mIsAcCharge; + } + + + public void onClose() + { + mContext = null; + } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/SystemMonitor.java b/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/SystemMonitor.java index b060de3..fcbcff9 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/SystemMonitor.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/SystemMonitor.java @@ -56,6 +56,15 @@ public void stop() } + public void onClose() + { + mContext = null; + mTel = null; + mSingalStrength = null; + mLog = null; + } + + public BatteryStatus getBatteryStatus() { IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); @@ -83,7 +92,7 @@ public synchronized TelephonySignalStrength getTelephonySignalStrength() { return null; } - + TelephonySignalStrength telSignalStrength = new TelephonySignalStrength( mContext); telSignalStrength.takeNewSignalStrength(mSingalStrength); diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/TelephonySignalStrength.java b/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/TelephonySignalStrength.java index c6918b7..9ff0589 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/TelephonySignalStrength.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/monitoring/TelephonySignalStrength.java @@ -40,12 +40,16 @@ public class TelephonySignalStrength private int mSignalIconId = 0; private Context mContext = null; - public TelephonySignalStrength(Context context) { mContext = context; } + public void onClose() + { + mContext = null; + } + public void takeNewSignalStrength(SignalStrength signalStrength) { diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/networkInterface/WifiIpAddress.java b/source/WebSMSTool/src/at/tugraz/ist/akm/networkInterface/WifiIpAddress.java index 075210f..caea5f1 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/networkInterface/WifiIpAddress.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/networkInterface/WifiIpAddress.java @@ -40,6 +40,7 @@ public WifiIpAddress(Context appContext) public String readLocalIpAddress() { + NetworkInfo mobileNetInfo = mConnectivityManager .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); @@ -196,4 +197,12 @@ public boolean isWifiAPEnabled() return false; } + + public void onClose() + { + mWifiManager = null; + mLog = null; + mConnectivityManager = null; + } + } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/phonebook/CacheModifiedHandler.java b/source/WebSMSTool/src/at/tugraz/ist/akm/phonebook/CacheModifiedHandler.java index 7767a7b..93d1185 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/phonebook/CacheModifiedHandler.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/phonebook/CacheModifiedHandler.java @@ -32,6 +32,7 @@ public CacheModifiedHandler(PhonebookBridge phonebook) public void onClose() { mPhonebook = null; + mLog = null; } public Message newCacheModifiedMessage() diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/phonebook/PhonebookBridge.java b/source/WebSMSTool/src/at/tugraz/ist/akm/phonebook/PhonebookBridge.java index a36ae0e..d6dc33f 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/phonebook/PhonebookBridge.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/phonebook/PhonebookBridge.java @@ -78,6 +78,12 @@ public void onChange(boolean selfChange) mCallback.contactModifiedCallback(); } } + + + public void onClose() + { + mCallback = null; + } } @@ -120,6 +126,20 @@ public void stop() } + public void onClose() + { + mContext = null; + mContentResolver = null; + mLog = null; + mContactReader = null; + mCachedContactReader = null; + mContactContentCursor = null; + mContactContentObserver = null; + mExternalContactModifiedCallback = null; + mCacheModifiedHandler = null; + } + + public List fetchContacts(ContactFilter filter) { return mCachedContactReader.fetchContacts(); @@ -174,6 +194,7 @@ private void unregisterContactChangedObserver() { mContactContentCursor .unregisterContentObserver(mContactContentObserver); + mContactContentObserver.onClose(); mContactContentObserver = null; mContactContentCursor.close(); } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/OnSharedPreferenceEventListenValidator.java b/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/OnSharedPreferenceEventListenValidator.java index 3ed1beb..602e852 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/OnSharedPreferenceEventListenValidator.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/OnSharedPreferenceEventListenValidator.java @@ -18,7 +18,8 @@ public class OnSharedPreferenceEventListenValidator implements private int mMinPortNumber = 1024; private int mMaxPortNumber = 65535; - private LogClient mLog = new LogClient(this); + private LogClient mLog = new LogClient( + OnSharedPreferenceEventListenValidator.class.getCanonicalName()); private PreferenceFragment mFragment = null; private Context mContext = null; @@ -220,4 +221,12 @@ private boolean handlePreference(Preference preference) return false; } + + public void onClose() + { + mFragment = null; + mContext = null; + mLog = null; + } + } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/RenewCertificateDialogPreference.java b/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/RenewCertificateDialogPreference.java index b16f1ca..b817247 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/RenewCertificateDialogPreference.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/RenewCertificateDialogPreference.java @@ -14,7 +14,7 @@ public class RenewCertificateDialogPreference extends DialogPreference RenewCertificateDialogPreference.class.getCanonicalName()); Context mContext = null; - StringFormatter mStrings = null; + StringFormatter mStrings = null; public RenewCertificateDialogPreference(Context context, AttributeSet attrs) @@ -45,6 +45,7 @@ public void onClick(DialogInterface dialog, int which) { } setSummary(mStrings.certificateDialogSummary()); + onClose(); } @@ -63,6 +64,15 @@ private void renewCertificate() } - - + private void onClose() + { + mContext = null; + if (mStrings != null) + { + mStrings.onClose(); + mStrings = null; + } + mLog = null; + } + } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/SharedPreferencesProvider.java b/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/SharedPreferencesProvider.java index 0602184..16b4ef5 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/SharedPreferencesProvider.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/SharedPreferencesProvider.java @@ -49,6 +49,8 @@ public void close() if (mSettings != null) mSettings.closeDatabase(); mSettings = null; + mApplicationContext = null; + mSharedPreferences = null; } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/StringFormatter.java b/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/StringFormatter.java index 30b7f03..34a4293 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/StringFormatter.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/preferences/StringFormatter.java @@ -12,7 +12,8 @@ public class StringFormatter Context mContext = null; - protected StringFormatter() + @SuppressWarnings("unused") + private StringFormatter() { } @@ -59,6 +60,9 @@ public String certificateDialogSummary() R.string.preferences_security_renew_certificate_dialog_preference_no_certificate); } return summary; - + } + + public void onClose() { + mContext = null; } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/sms/SmsBridge.java b/source/WebSMSTool/src/at/tugraz/ist/akm/sms/SmsBridge.java index 91604dd..6a45f0f 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/sms/SmsBridge.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/sms/SmsBridge.java @@ -84,6 +84,15 @@ public void stop() { mContext.unregisterReceiver(mSmsSentNotifier); mSmsSentNotifier = null; } + + public void onClose() { + mContext = null; + mContentResolver = null; + mSmsSink = null; + mSmsBoxReader = null; + mSmsBoxWriter = null; + mExternalSmsSentCallback = null; + } /** * 1st: try to parse the TextMessage and store to content://sms/sent 2nd: diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/statusbar/FireNotification.java b/source/WebSMSTool/src/at/tugraz/ist/akm/statusbar/FireNotification.java index 5502614..811a2a9 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/statusbar/FireNotification.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/statusbar/FireNotification.java @@ -70,4 +70,9 @@ public void cancelAll() { mNotificationManager.cancelAll(); } + + public void onClose() { + mContext = null; + mNotificationManager = null; + } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/texting/TextingAdapter.java b/source/WebSMSTool/src/at/tugraz/ist/akm/texting/TextingAdapter.java index 61585ef..68f27c1 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/texting/TextingAdapter.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/texting/TextingAdapter.java @@ -33,183 +33,245 @@ import at.tugraz.ist.akm.trace.LogClient; public class TextingAdapter extends LogClient implements TextingInterface, - SmsIOCallback, IContactModifiedCallback { - - private Context mContext = null; - private SmsBridge mSmsBridge = null; - private PhonebookBridge mPhoneBook = null; - - private SmsIOCallback mExternalTextMessageCallback = null; - private IContactModifiedCallback mExternalPhonebookModifiedCallback = null; - - private VolatileOutgoingReport mOutgoingStatistics = new VolatileOutgoingReport(); - private VolatileIncomingReport mIncomingStatistics = new VolatileIncomingReport(); - private VolatilePhonebookReport mPhonebookStatistics = new VolatilePhonebookReport(); - - public TextingAdapter(Context context, SmsIOCallback smsIOCallback, - IContactModifiedCallback contactModifiedCallback) { - super(TextingAdapter.class.getName()); - mContext = context; - - mExternalTextMessageCallback = smsIOCallback; - mExternalPhonebookModifiedCallback = contactModifiedCallback; - - mSmsBridge = new SmsBridge(mContext); - mPhoneBook = new PhonebookBridge(mContext); - } - - public void start() { - info("starting " + getClass().getSimpleName()); - registerSmsCallbacks(); - registerPhonebookCallbacks(); - mSmsBridge.start(); - mPhoneBook.start(); - } - - public void stop() { - info("stopping " + getClass().getSimpleName()); - mPhoneBook.stop(); - mSmsBridge.stop(); - } - - /* - * (non-Javadoc) - * - * @see - * at.tugraz.ist.akm.texting.TextingInterface#sendTextMessage(at.tugraz. - * ist.akm.sms.TextMessage) - */ - @Override - synchronized public int sendTextMessage(TextMessage message) { - mOutgoingStatistics - .setNumPending(mOutgoingStatistics.getNumPending() + 1); - return mSmsBridge.sendTextMessage(message); - } - - /* - * (non-Javadoc) - * - * @see - * at.tugraz.ist.akm.texting.TextingInterface#fetchTextMessages(at.tugraz - * .ist.akm.content.query.TextMessageFilter) - */ - @Override - public List fetchTextMessages(TextMessageFilter filter) { - return mSmsBridge.fetchTextMessages(filter); - } - - @Override - public List fetchContacts(ContactFilter filter) { - return mPhoneBook.fetchContacts(filter); - } - - @Override - public void smsSentCallback(Context context, List message) { - info("sms sent successfully"); - mOutgoingStatistics - .setNumPending(mOutgoingStatistics.getNumPending() - 1); - if (mExternalTextMessageCallback != null) { - mExternalTextMessageCallback.smsSentCallback(context, message); - } - } - - @Override - public void smsSentErrorCallback(Context context, List message) { - info("failed to send sms"); - mOutgoingStatistics.setNumErroneous(mOutgoingStatistics - .getNumErroneous() + 1); - if (mExternalTextMessageCallback != null) { - mExternalTextMessageCallback.smsSentErrorCallback(context, message); - } - } - - @Override - public void smsDeliveredCallback(Context context, List messages) { - TextMessage message = messages.get(0); - info("sms was delivered (to address ["+message.getAddress() +"] on ["+message.getDate()+"] text ["+message.getBody()+"])"); - - if (mExternalTextMessageCallback != null) { - mExternalTextMessageCallback.smsDeliveredCallback(context, messages); - } - - } - - @Override - public void smsReceivedCallback(Context context, List message) { - info("sms received"); - mIncomingStatistics - .setNumReceived(mIncomingStatistics.getNumReceived() + 1); - if (mExternalTextMessageCallback != null) { - mExternalTextMessageCallback.smsReceivedCallback(context, message); - } - } - - @Override - public void contactModifiedCallback() { - info("contact modified"); - mPhonebookStatistics - .setNumChanges(mPhonebookStatistics.getNumChanges() + 1); - if (mExternalPhonebookModifiedCallback != null) { - mExternalPhonebookModifiedCallback.contactModifiedCallback(); - } - } - - @Override - public int updateTextMessage(TextMessage message) { - return mSmsBridge.updateTextMessage(message); - } - - /** - * return all tread IDs for the specified address - * - * @param phoneNumber - * the phone number - */ - @Override - public List fetchThreadIds(final String phoneNumber) { - return mSmsBridge.fetchThreadIds(phoneNumber); - } - - /** - * This method don't touches anything internally but gives you a new - * instance you can do anything you want with. - * - * @return A brief information about the outgoing state. - */ - @Override - public VolatileOutgoingReport getOutgoingReport() { - return new VolatileOutgoingReport(mOutgoingStatistics); - } - - /** - * This method don't touches anything internally but gives you a new - * instance you can do anything you want with. - * - * @return A brief information about the incoming state. - */ - @Override - public VolatileIncomingReport getIncomingReport() { - return new VolatileIncomingReport(mIncomingStatistics); - } - - /** - * This method don't touches anything internally but gives you a new - * instance you can do anything you want with. - * - * @return A brief information about the contact (changes, updated) state. - */ - @Override - public VolatilePhonebookReport getPhonebookReport() { - return new VolatilePhonebookReport(mPhonebookStatistics); - } - - private void registerSmsCallbacks() { - mSmsBridge.setSmsSentCallback(this); - } - - private void registerPhonebookCallbacks() { - mPhoneBook - .setContactModifiedCallback(this); - } + SmsIOCallback, IContactModifiedCallback +{ + private Context mContext = null; + private SmsBridge mSmsBridge = null; + private PhonebookBridge mPhoneBook = null; + + private SmsIOCallback mExternalTextMessageCallback = null; + private IContactModifiedCallback mExternalPhonebookModifiedCallback = null; + + private VolatileOutgoingReport mOutgoingStatistics = new VolatileOutgoingReport(); + private VolatileIncomingReport mIncomingStatistics = new VolatileIncomingReport(); + private VolatilePhonebookReport mPhonebookStatistics = new VolatilePhonebookReport(); + + + public TextingAdapter(Context context, SmsIOCallback smsIOCallback, + IContactModifiedCallback contactModifiedCallback) + { + super(TextingAdapter.class.getName()); + mContext = context; + + mExternalTextMessageCallback = smsIOCallback; + mExternalPhonebookModifiedCallback = contactModifiedCallback; + + mSmsBridge = new SmsBridge(mContext); + mPhoneBook = new PhonebookBridge(mContext); + } + + + public void start() + { + info("starting " + getClass().getSimpleName()); + registerSmsCallbacks(); + registerPhonebookCallbacks(); + mSmsBridge.start(); + mPhoneBook.start(); + } + + + public void stop() + { + info("stopping " + getClass().getSimpleName()); + mPhoneBook.stop(); + mSmsBridge.stop(); + } + + + @Override + public void close() + { + mPhoneBook.onClose(); + mPhoneBook = null; + mSmsBridge.onClose(); + mSmsBridge = null; + + mContext = null; + + mExternalTextMessageCallback = null; + mExternalPhonebookModifiedCallback = null; + + mOutgoingStatistics = null; + mIncomingStatistics = null; + mPhonebookStatistics = null; + } + + + /* + * (non-Javadoc) + * + * @see + * at.tugraz.ist.akm.texting.TextingInterface#sendTextMessage(at.tugraz. + * ist.akm.sms.TextMessage) + */ + @Override + synchronized public int sendTextMessage(TextMessage message) + { + mOutgoingStatistics + .setNumPending(mOutgoingStatistics.getNumPending() + 1); + return mSmsBridge.sendTextMessage(message); + } + + + /* + * (non-Javadoc) + * + * @see + * at.tugraz.ist.akm.texting.TextingInterface#fetchTextMessages(at.tugraz + * .ist.akm.content.query.TextMessageFilter) + */ + @Override + public List fetchTextMessages(TextMessageFilter filter) + { + return mSmsBridge.fetchTextMessages(filter); + } + + + @Override + public List fetchContacts(ContactFilter filter) + { + return mPhoneBook.fetchContacts(filter); + } + + + @Override + public void smsSentCallback(Context context, List message) + { + info("sms sent successfully"); + mOutgoingStatistics + .setNumPending(mOutgoingStatistics.getNumPending() - 1); + if (mExternalTextMessageCallback != null) + { + mExternalTextMessageCallback.smsSentCallback(context, message); + } + } + + + @Override + public void smsSentErrorCallback(Context context, List message) + { + info("failed to send sms"); + mOutgoingStatistics.setNumErroneous(mOutgoingStatistics + .getNumErroneous() + 1); + if (mExternalTextMessageCallback != null) + { + mExternalTextMessageCallback.smsSentErrorCallback(context, message); + } + } + + + @Override + public void smsDeliveredCallback(Context context, List messages) + { + TextMessage message = messages.get(0); + info("sms was delivered (to address [" + message.getAddress() + + "] on [" + message.getDate() + "] text [" + message.getBody() + + "])"); + + if (mExternalTextMessageCallback != null) + { + mExternalTextMessageCallback + .smsDeliveredCallback(context, messages); + } + + } + + + @Override + public void smsReceivedCallback(Context context, List message) + { + info("sms received"); + mIncomingStatistics + .setNumReceived(mIncomingStatistics.getNumReceived() + 1); + if (mExternalTextMessageCallback != null) + { + mExternalTextMessageCallback.smsReceivedCallback(context, message); + } + } + + + @Override + public void contactModifiedCallback() + { + info("contact modified"); + mPhonebookStatistics + .setNumChanges(mPhonebookStatistics.getNumChanges() + 1); + if (mExternalPhonebookModifiedCallback != null) + { + mExternalPhonebookModifiedCallback.contactModifiedCallback(); + } + } + + + @Override + public int updateTextMessage(TextMessage message) + { + return mSmsBridge.updateTextMessage(message); + } + + + /** + * return all tread IDs for the specified address + * + * @param phoneNumber + * the phone number + */ + @Override + public List fetchThreadIds(final String phoneNumber) + { + return mSmsBridge.fetchThreadIds(phoneNumber); + } + + + /** + * This method don't touches anything internally but gives you a new + * instance you can do anything you want with. + * + * @return A brief information about the outgoing state. + */ + @Override + public VolatileOutgoingReport getOutgoingReport() + { + return new VolatileOutgoingReport(mOutgoingStatistics); + } + + + /** + * This method don't touches anything internally but gives you a new + * instance you can do anything you want with. + * + * @return A brief information about the incoming state. + */ + @Override + public VolatileIncomingReport getIncomingReport() + { + return new VolatileIncomingReport(mIncomingStatistics); + } + + + /** + * This method don't touches anything internally but gives you a new + * instance you can do anything you want with. + * + * @return A brief information about the contact (changes, updated) state. + */ + @Override + public VolatilePhonebookReport getPhonebookReport() + { + return new VolatilePhonebookReport(mPhonebookStatistics); + } + + + private void registerSmsCallbacks() + { + mSmsBridge.setSmsSentCallback(this); + } + + + private void registerPhonebookCallbacks() + { + mPhoneBook.setContactModifiedCallback(this); + } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/texting/TextingInterface.java b/source/WebSMSTool/src/at/tugraz/ist/akm/texting/TextingInterface.java index f49e5c8..c6390b8 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/texting/TextingInterface.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/texting/TextingInterface.java @@ -16,6 +16,7 @@ package at.tugraz.ist.akm.texting; +import java.io.Closeable; import java.util.List; import at.tugraz.ist.akm.content.query.ContactFilter; @@ -26,28 +27,36 @@ import at.tugraz.ist.akm.texting.reports.VolatileOutgoingReport; import at.tugraz.ist.akm.texting.reports.VolatilePhonebookReport; -public interface TextingInterface { - - public void start(); - - public void stop(); - - - public int sendTextMessage(TextMessage message); - - public List fetchTextMessages(TextMessageFilter filter); - - public int updateTextMessage(TextMessage message); - - public List fetchContacts(ContactFilter filter); - - public List fetchThreadIds(final String address); - - public VolatileIncomingReport getIncomingReport(); - - public VolatileOutgoingReport getOutgoingReport(); - - public VolatilePhonebookReport getPhonebookReport(); - - -} \ No newline at end of file +public interface TextingInterface extends Closeable +{ + + public void start(); + + + public void stop(); + + + public int sendTextMessage(TextMessage message); + + + public List fetchTextMessages(TextMessageFilter filter); + + + public int updateTextMessage(TextMessage message); + + + public List fetchContacts(ContactFilter filter); + + + public List fetchThreadIds(final String address); + + + public VolatileIncomingReport getIncomingReport(); + + + public VolatileOutgoingReport getOutgoingReport(); + + + public VolatilePhonebookReport getPhonebookReport(); + +} diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/trace/AndroidLogSink.java b/source/WebSMSTool/src/at/tugraz/ist/akm/trace/AndroidLogSink.java index 09306fc..6eb8381 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/trace/AndroidLogSink.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/trace/AndroidLogSink.java @@ -52,4 +52,9 @@ public void verbose(final String tag, final String message) { android.util.Log.v(tag, message); } + + @Override + public void onClose() + { + } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/trace/ILogSink.java b/source/WebSMSTool/src/at/tugraz/ist/akm/trace/ILogSink.java index f85781c..12ee016 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/trace/ILogSink.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/trace/ILogSink.java @@ -30,6 +30,10 @@ public interface ILogSink public void error(final String tag, final String message); + public void verbose(final String tag, final String message); + + + public void onClose(); } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/trace/TraceService.java b/source/WebSMSTool/src/at/tugraz/ist/akm/trace/TraceService.java index 33ea67e..4e70f4a 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/trace/TraceService.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/trace/TraceService.java @@ -51,6 +51,12 @@ private static TraceService getInstance() { return mLogger; } + public void onClose() { + mSink.onClose(); + mSink = null; + mLogger = null; + } + private void distributeLog(final LogLevel level, final String tag, final String message, final Throwable t) { if (mEnabled) { diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/AbstractHttpRequestProcessor.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/AbstractHttpRequestProcessor.java index 0b87c27..1c4645c 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/AbstractHttpRequestProcessor.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/AbstractHttpRequestProcessor.java @@ -16,6 +16,7 @@ package at.tugraz.ist.akm.webservice.requestprocessor; +import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -37,26 +38,24 @@ import at.tugraz.ist.akm.webservice.WebServerConstants; import at.tugraz.ist.akm.webservice.requestprocessor.interceptor.IRequestInterceptor; -public abstract class AbstractHttpRequestProcessor implements HttpRequestHandler { - private final LogClient mLog = new LogClient(AbstractHttpRequestProcessor.class.getCanonicalName()); - protected final Context mContext; - protected final XmlNode mConfig; - protected final HttpRequestHandlerRegistry mRegistry; - private final List mRequestInterceptorList = new ArrayList(); - +public abstract class AbstractHttpRequestProcessor implements HttpRequestHandler, Closeable +{ + private LogClient mLog = new LogClient(AbstractHttpRequestProcessor.class.getCanonicalName()); + protected Context mContext; + protected XmlNode mConfig; + protected HttpRequestHandlerRegistry mRegistry; + private List mRequestInterceptorList = new ArrayList(); protected HttpResponseDataAppender mResponseDataAppender = new HttpResponseDataAppender(); - protected HashMap mUri2FileInfo = new HashMap(); - private String mUriPattern = null; public static class FileInfo { - final String mContentType; - final String mFile; + String mContentType; + String mFile; - public FileInfo(final String file, final String contentType) { - this.mFile = file; - this.mContentType = contentType; + public FileInfo(String file,String contentType) { + mFile = file; + mContentType = contentType; } @Override @@ -68,9 +67,9 @@ public String toString() { public AbstractHttpRequestProcessor(final Context context, final XmlNode config, final HttpRequestHandlerRegistry registry) { - this.mContext = context; - this.mConfig = config; - this.mRegistry = registry; + mContext = context; + mConfig = config; + mRegistry = registry; assignUriMappingToRegistry(); } @@ -142,17 +141,27 @@ public void handle(HttpRequest httpRequest, HttpResponse httpResponse, HttpConte public abstract void handleRequest(RequestLine requestLine, String requestData, HttpResponse httpResponse) throws HttpException, IOException; - /** - * adapter: call it to ensure proper cleanup - */ - public void onClose() { + @Override + public void close() { if (mRegistry != null) { mLog.debug("close request handler for URI [" + mUriPattern + "]"); mRegistry.unregister(mUriPattern); + mRegistry = null; } for ( IRequestInterceptor interceptor : mRequestInterceptorList ) { interceptor.onClose(); } mRequestInterceptorList.clear(); + mRequestInterceptorList = null; + + mContext = null; + mConfig = null; + + mResponseDataAppender = null; + mUri2FileInfo.clear(); + mUri2FileInfo = null; + + mUriPattern = null; + mLog = null; } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/EchoJsonRequestProcessor.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/EchoJsonRequestProcessor.java index 893d809..f88544f 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/EchoJsonRequestProcessor.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/EchoJsonRequestProcessor.java @@ -16,6 +16,7 @@ package at.tugraz.ist.akm.webservice.requestprocessor; +import java.io.Closeable; import java.io.IOException; import my.org.apache.http.HttpException; @@ -32,9 +33,9 @@ import at.tugraz.ist.akm.trace.LogClient; import at.tugraz.ist.akm.webservice.WebServerConstants; -public class EchoJsonRequestProcessor extends AbstractHttpRequestProcessor +public class EchoJsonRequestProcessor extends AbstractHttpRequestProcessor { - private final LogClient mLog = new LogClient(this); + private LogClient mLog = new LogClient(this); public EchoJsonRequestProcessor(final Context context, final XmlNode config, final HttpRequestHandlerRegistry registry) @@ -70,4 +71,11 @@ public void handleRequest(RequestLine requestLine, String requestData, mLog.debug("ignoring request type: " + requestLine.getMethod()); } } + + @Override + public void close() + { + mLog = null; + super.close(); + } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/FaviconLoadRequestProcessor.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/FaviconLoadRequestProcessor.java index fdc0d76..d5329fc 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/FaviconLoadRequestProcessor.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/FaviconLoadRequestProcessor.java @@ -17,7 +17,7 @@ public class FaviconLoadRequestProcessor extends AbstractHttpRequestProcessor { - private final LogClient mLog = new LogClient(this); + private LogClient mLog = new LogClient(this); public FaviconLoadRequestProcessor(Context context, XmlNode config, HttpRequestHandlerRegistry registry) { @@ -41,4 +41,11 @@ public void handleRequest(RequestLine requestLine, String requestData, mLog.error("what a terrible failure", ex); } } + + @Override + public void close() + { + super.close(); + mLog = null; + } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/FileRequestProcessor.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/FileRequestProcessor.java index ea996b6..6447c13 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/FileRequestProcessor.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/FileRequestProcessor.java @@ -29,7 +29,7 @@ public class FileRequestProcessor extends AbstractHttpRequestProcessor { - private final LogClient mLog = new LogClient(this); + private LogClient mLog = new LogClient(this); public FileRequestProcessor(final Context context, final XmlNode config, final HttpRequestHandlerRegistry registry) { @@ -49,7 +49,18 @@ public void handleRequest(RequestLine requestLine, String requestData, HttpRespo return; } - final String data = new FileReader(mContext, fileInfo.mFile).read(); + FileReader reader = new FileReader(mContext, fileInfo.mFile); + final String data = reader.read(); + reader.onClose(); + reader = null; + mResponseDataAppender.appendHttpResponseData(httpResponse, fileInfo.mContentType, data); } + + @Override + public void close() + { + super.close(); + mLog = null; + } } diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/JsonAPIRequestProcessor.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/JsonAPIRequestProcessor.java index 6c51a97..9270aa3 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/JsonAPIRequestProcessor.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/JsonAPIRequestProcessor.java @@ -164,10 +164,19 @@ public synchronized void handleRequest(RequestLine requestLine, @Override - public synchronized void onClose() + public synchronized void close() { mTextingAdapter.stop(); + try + { + mTextingAdapter.close(); + } + catch (IOException e) + { + mLog.debug("failed closing texting adapter", e); + } mSystemMonitor.stop(); + mSystemMonitor.onClose(); mJsonFactory = null; mTextingAdapter = null; @@ -177,7 +186,12 @@ public synchronized void onClose() mSMSReceivedList = null; mSMSSentErrorList = null; - super.onClose(); + mJsonContactList = null; + mJsonContactListLock = null; + + mExternalSMSIoCallback = null; + + super.close(); } @@ -691,11 +705,13 @@ private synchronized JSONObject createPollingInfo() { result.put("battery", mJsonFactory.createJsonObject(batteryStatus)); + batteryStatus.onClose(); } if (telSignalStrength != null) { result.put("signal", mJsonFactory.createJsonObject(telSignalStrength)); + telSignalStrength.onClose(); } this.setSuccessState(result); diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/interceptor/AbstractRequestInterceptor.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/interceptor/AbstractRequestInterceptor.java index 154a455..2f77516 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/interceptor/AbstractRequestInterceptor.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/interceptor/AbstractRequestInterceptor.java @@ -16,17 +16,19 @@ package at.tugraz.ist.akm.webservice.requestprocessor.interceptor; +import java.io.Closeable; + import my.org.apache.http.HttpRequest; import my.org.apache.http.HttpResponse; import android.content.Context; import at.tugraz.ist.akm.webservice.requestprocessor.HttpResponseDataAppender; import at.tugraz.ist.akm.webservice.server.WebserverProtocolConfig; -public abstract class AbstractRequestInterceptor implements IRequestInterceptor { - protected final HttpResponseDataAppender responseDataAppender = new HttpResponseDataAppender(); - - protected final WebserverProtocolConfig mServerConfig; - protected final Context mContext; +public abstract class AbstractRequestInterceptor implements IRequestInterceptor, Closeable +{ + protected HttpResponseDataAppender responseDataAppender = new HttpResponseDataAppender(); + protected WebserverProtocolConfig mServerConfig; + protected Context mContext; public AbstractRequestInterceptor(WebserverProtocolConfig config, Context context) @@ -38,5 +40,10 @@ public AbstractRequestInterceptor(WebserverProtocolConfig config, @Override public abstract boolean process(HttpRequest httpRequest, String requestData, HttpResponse httpResponse); - public abstract void onClose(); + @Override + public void close() { + mServerConfig = null; + mContext = null; + responseDataAppender = null; + } } \ No newline at end of file diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/interceptor/AuthorizationInterceptor.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/interceptor/AuthorizationInterceptor.java index ccca968..0326669 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/interceptor/AuthorizationInterceptor.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/requestprocessor/interceptor/AuthorizationInterceptor.java @@ -96,6 +96,8 @@ public boolean process(HttpRequest httpRequest, String requestData, responseDataAppender.appendHttpResponseData(httpResponse, WebServerConstants.HTTP.CONTENTY_TYPE_TEXT_HTML, filereader.read()); + filereader.onClose(); + filereader = null; } return authSuccess; diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/server/SimpleWebServer.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/server/SimpleWebServer.java index 93efe3d..4c93ebf 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/server/SimpleWebServer.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/server/SimpleWebServer.java @@ -50,31 +50,22 @@ public class SimpleWebServer implements SmsIOCallback { - private final static LogClient mLog = new LogClient( + private LogClient mLog = new LogClient( SimpleWebServer.class.getName()); - - HttpRequestHandlerRegistry mRegistry = new HttpRequestHandlerRegistry(); + private HttpRequestHandlerRegistry mRegistry = new HttpRequestHandlerRegistry(); private BasicHttpContext mHttpContext = new BasicHttpContext(); - - private final Context mContext; + private Context mContext = null; private ServerThread mServerThread = null; private Vector mHandlerReferenceListing = new Vector(); - private InetAddress mSocketAddress = null; private ServerSocket mServerSocket = null; - - private String mKeyStorePass; + private String mKeyStorePass = null; private WebserverProtocolConfig mServerConfig = null; - - private SSLContext mSSLContext; - + private SSLContext mSSLContext = null; private boolean mIsServerRunning = false; - private WakeLock mWakeLock = null; - private SmsIOCallback mExternalSmsIoCallback = null; - public synchronized void registerSmsIoCallback(SmsIOCallback callback) { mExternalSmsIoCallback = callback; @@ -90,7 +81,7 @@ public synchronized void unregisterSMSIoCallback() public SimpleWebServer(Context context, WebserverProtocolConfig serverConfig) throws Exception { - this.mContext = context; + mContext = context; PowerManager pm = (PowerManager) mContext .getSystemService(Context.POWER_SERVICE); @@ -98,8 +89,10 @@ public SimpleWebServer(Context context, WebserverProtocolConfig serverConfig) .getClass().getName()); WifiIpAddress wifiAddressReader = new WifiIpAddress(context); - this.mSocketAddress = InetAddress.getByName(wifiAddressReader + mSocketAddress = InetAddress.getByName(wifiAddressReader .readLocalIpAddress()); + wifiAddressReader.onClose(); + wifiAddressReader = null; setNewServerConfiguration(serverConfig); @@ -267,9 +260,9 @@ public synchronized boolean startServer() } catch (IOException ioException) { - mLog.error("cannot bind [" + mServerConfig.protocolName + "] socket to [" - + mSocketAddress + ":" + mServerConfig.port + "]", - ioException); + mLog.error("cannot bind [" + mServerConfig.protocolName + + "] socket to [" + mSocketAddress + ":" + + mServerConfig.port + "]", ioException); return false; } @@ -328,11 +321,28 @@ private void closeRegistry() { for (AbstractHttpRequestProcessor toBeCleanedUp : mHandlerReferenceListing) { - toBeCleanedUp.onClose(); + toBeCleanedUp.close(); } } + public void onClose() + { + mRegistry = null; + mHttpContext = null; + mContext = null; + mHandlerReferenceListing = null; + mSocketAddress = null; + mServerSocket = null; + mKeyStorePass = null; + mServerConfig = null; + mSSLContext = null; + mWakeLock = null; + mExternalSmsIoCallback = null; + mLog = null; + } + + private void initSSLContext() { ApplicationKeyStore appKeystore = new ApplicationKeyStore(); diff --git a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/service/WebSMSToolService.java b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/service/WebSMSToolService.java index 6ed75bd..ef82e78 100644 --- a/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/service/WebSMSToolService.java +++ b/source/WebSMSTool/src/at/tugraz/ist/akm/webservice/service/WebSMSToolService.java @@ -45,12 +45,12 @@ public class WebSMSToolService extends Service implements SmsIOCallback public static final String SERVICE_STARTED = "at.tugraz.ist.akm.sms.SERVICE_STARTED"; private Intent mServiceStartedStickyIntend = null; - private final LogClient mLog = new LogClient(this); + private LogClient mLog = new LogClient(this); private SimpleWebServer mServer = null; private WebserverProtocolConfig mServerConfig = null; private static BroadcastReceiver mIntentReceiver = null; private Messenger mClientMessenger = null; - private final Messenger mServiceMessenger = new Messenger( + private Messenger mServiceMessenger = new Messenger( new IncomingClientMessageHandler(this)); private ServiceRunningStates mServiceRunningState = ServiceRunningStates.BEFORE_SINGULARITY; @@ -268,15 +268,16 @@ public int onStartCommand(Intent intent, int flags, int startId) @Override public boolean stopService(Intent name) { - boolean stopped = stopWebSMSToolService(); + stopWebSMSToolService(); super.stopService(name); - return stopped; + return true; } @Override public void onDestroy() { + onClose(); super.onDestroy(); } @@ -329,6 +330,8 @@ private boolean stopWebSMSToolService() throw new Exception("server failed to stop"); } setRunningState(ServiceRunningStates.STOPPED); + mServer.unregisterSMSIoCallback(); + mServer.onClose(); } catch (Exception ex) { @@ -341,6 +344,20 @@ private boolean stopWebSMSToolService() } + private void onClose() + { + mNetworkStatsPropagationTimer.cancel(); + mNetworkStatsPropagationTimer = null; + mServiceStartedStickyIntend = null; + mLog = null; + mServer = null; + mServerConfig = null; + mIntentReceiver = null; + mClientMessenger = null; + mServiceMessenger = null; + } + + public void onWifiStateChanged(Context context, Intent intent) { String extraKey = WifiManager.EXTRA_WIFI_STATE; @@ -363,8 +380,7 @@ public void onWifiStateChanged(Context context, Intent intent) { return; } - // TODO stopwerbsmstoolservice() before stopself(); - // check on enabled only? + mLog.debug("wifi state changed, turning off service"); stopSelf(); } @@ -404,6 +420,7 @@ private void unregisterIntentReceiver() { mLog.debug("unregister wifi change intent receiver"); unregisterReceiver(mIntentReceiver); + mIntentReceiver = null; } @@ -512,7 +529,6 @@ protected void onClientRequstStopService() if (getRunningState() == ServiceRunningStates.RUNNING) { stopWebSMSToolService(); - stopSelf(); } else { mLog.debug("failed client request for stopping service in state [" diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/base/WebSMSToolActivityTestcase.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/base/WebSMSToolActivityTestcase.java index 9d87951..631f2b3 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/base/WebSMSToolActivityTestcase.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/base/WebSMSToolActivityTestcase.java @@ -27,16 +27,18 @@ public class WebSMSToolActivityTestcase extends ActivityTestCase { protected Context mContext = null; protected ContentResolver mContentResolver = null; - protected LogClient mLog = null; + private LogClient mLog = null; + private String mLogTag = null; public WebSMSToolActivityTestcase(String logTag) { TraceService.setSink(new ExceptionThrowingLogSink()); - mLog = new LogClient(logTag); + mLogTag = new String(logTag); } @Override protected void setUp() throws Exception { super.setUp(); + mLog = new LogClient(mLogTag); logVerbose(getName() + ".setUp()"); mContext = getInstrumentation().getTargetContext(); assertTrue(mContext != null); @@ -47,6 +49,9 @@ protected void setUp() throws Exception { @Override protected void tearDown() throws Exception { logVerbose(getName() + ".tearDown()"); + mContext = null; + mContentResolver = null; + mLog = null; super.tearDown(); } diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/base/WebSMSToolInstrumentationTestcase.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/base/WebSMSToolInstrumentationTestcase.java index 9af98f9..b38c472 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/base/WebSMSToolInstrumentationTestcase.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/base/WebSMSToolInstrumentationTestcase.java @@ -28,15 +28,17 @@ public class WebSMSToolInstrumentationTestcase extends InstrumentationTestCase { protected Context mContext = null; protected ContentResolver mContentResolver = null; private LogClient mLog = null; + private String mLogTag = null; public WebSMSToolInstrumentationTestcase(String logTag) { TraceService.setSink(new ExceptionThrowingLogSink()); - mLog = new LogClient(logTag); + mLogTag = new String(logTag); } @Override protected void setUp() throws Exception { super.setUp(); + mLog = new LogClient(mLogTag); logVerbose(getName() + ".setUp()"); mContext = getInstrumentation().getTargetContext(); @@ -47,6 +49,9 @@ protected void setUp() throws Exception { @Override protected void tearDown() throws Exception { logVerbose(getName() + ".tearDown()"); + mContext = null; + mContentResolver = null; + mLog = null; super.tearDown(); } diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/monitoring/SystemMonitorTest.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/monitoring/SystemMonitorTest.java index b1a9931..bc05379 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/monitoring/SystemMonitorTest.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/monitoring/SystemMonitorTest.java @@ -44,6 +44,7 @@ protected void setUp() throws Exception public void tearDown() { mSystemMonitor.stop(); + mSystemMonitor.onClose(); } @@ -55,6 +56,7 @@ public void testSystemMonitor_batteryState() logBStats(bStats); assertTrue(bStats.getBatteryIconId() > 0); byte[] bytes = bStats.getBatteryIconBytes(); + bStats.onClose(); assertTrue(bytes.length > 0); } catch (Exception ex) diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/phonebook/PhonebookBridgeTest.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/phonebook/PhonebookBridgeTest.java index 8fa4ffb..755dedc 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/phonebook/PhonebookBridgeTest.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/phonebook/PhonebookBridgeTest.java @@ -37,6 +37,7 @@ public void testPhonebookBridgeContactChangedCallback() throws Throwable { PhonebookTestsHelper.deleteContact(mrFoo[2], mrFoo[0] + " " + mrFoo[1], mContentResolver); Thread.sleep(1000); phonebook.stop(); + phonebook.onClose(); } catch (Exception ex) { ex.printStackTrace(); assertTrue(false); diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/sms/SmsBridgeTest.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/sms/SmsBridgeTest.java index 3ddc2cf..88ae399 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/sms/SmsBridgeTest.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/sms/SmsBridgeTest.java @@ -48,6 +48,7 @@ public void testSmsBridgeSendSms() smsBridge.sendTextMessage(SmsHelper.getDummyTextMessage()); Thread.sleep(1000); smsBridge.stop(); + smsBridge.onClose(); } catch (Exception ex) { ex.printStackTrace(); @@ -69,6 +70,7 @@ public void testSmsBridgeFetchInbox() { SmsHelper.logTextMessage(message); } smsBridge.stop(); + smsBridge.onClose(); } catch (Exception ex) { ex.printStackTrace(); assertTrue(false); @@ -86,6 +88,7 @@ public void testSmsBridgeFetchOutbox() { SmsHelper.logTextMessage(message); } smsBridge.stop(); + smsBridge.onClose(); } catch (Exception ex) { ex.printStackTrace(); assertTrue(false); diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/texting/TextingAdapterTest.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/texting/TextingAdapterTest.java index e70de14..d230e60 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/texting/TextingAdapterTest.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/texting/TextingAdapterTest.java @@ -63,6 +63,7 @@ public void testSendLongText() throws Exception } assertTrue(mCountSent >= awaitedCallbacks); texting.stop(); + texting.close(); } @@ -78,10 +79,11 @@ public void testSendNoException() throws Exception Thread.sleep(1000); assertTrue(mCountSent > 0); texting.stop(); + texting.close(); } - public void testFetchContactsNoException() + public void testFetchContactsNoException() throws Exception { TextingInterface texting = new TextingAdapter(mContext, this, this); texting.start(); @@ -92,10 +94,11 @@ public void testFetchContactsNoException() assertTrue(contacts.size() == 1 | contacts.size() == 0); texting.stop(); + texting.close(); } - public void testFetchMessagesNoException() + public void testFetchMessagesNoException() throws Exception { TextingInterface texting = new TextingAdapter(mContext, this, this); texting.start(); @@ -104,6 +107,7 @@ public void testFetchMessagesNoException() filter.setAddress("01906666"); texting.fetchTextMessages(filter); texting.stop(); + texting.close(); } diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/handler/FileRequestHandlerTest.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/handler/FileRequestHandlerTest.java index 099fa6c..b4539cb 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/handler/FileRequestHandlerTest.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/handler/FileRequestHandlerTest.java @@ -89,9 +89,12 @@ public void testHandle() { httpResponse.getEntity().writeTo(baos); + FileReader reader = new FileReader(getInstrumentation().getContext(), DATA_FILE); Assert.assertEquals( - new FileReader(getInstrumentation().getContext(), DATA_FILE).read(), + reader.read(), new String(baos.toByteArray(), DEFAULT_ENCODING)); + reader.onClose(); + reader = null; } catch (HttpException httpException) { Assert.fail("Exception => " + httpException.getMessage()); diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/server/MockSimpleWebServer.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/server/MockSimpleWebServer.java index 8129fdf..8a6bf33 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/server/MockSimpleWebServer.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/server/MockSimpleWebServer.java @@ -32,7 +32,7 @@ public MockSimpleWebServer(Context context, WebserverProtocolConfig config) private MockSimpleWebServer(Context context) throws Exception { - super(context, new WebserverProtocolConfig()); + super(null, null); } diff --git a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/server/SimpleWebServerTest.java b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/server/SimpleWebServerTest.java index ef970a2..a0d61be 100644 --- a/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/server/SimpleWebServerTest.java +++ b/source/WebSMSToolTest/src/at/tugraz/ist/akm/test/webservice/server/SimpleWebServerTest.java @@ -62,8 +62,8 @@ private void startServer(final boolean useMockServer) throws Exception mWebserver = null; } - mWebserver = useMockServer ? new MockSimpleWebServer(mContext, mServerConfig) - : new SimpleWebServer(mContext, mServerConfig); + mWebserver = useMockServer ? new MockSimpleWebServer(mContext, + mServerConfig) : new SimpleWebServer(mContext, mServerConfig); mHttpClient = new DefaultHttpClient(); @@ -96,12 +96,14 @@ protected void setUp() throws Exception mServerConfig.username = "huaba"; } + @Override protected void tearDown() throws Exception { super.tearDown(); } + public void testStartStopServer() { @@ -124,6 +126,7 @@ public void testStartStopServer() mWebserver.stopServer(); waitForServiceBeingStopped(20, 200); assertFalse(mWebserver.isRunning()); + mWebserver.onClose(); } catch (Exception ex) { @@ -187,6 +190,7 @@ public void testSimpleJsonRequest() HttpResponse httpresponse = mHttpClient.execute(httppost); stopServer(); + mWebserver.onClose(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); httpresponse.getEntity().writeTo(baos); @@ -263,13 +267,15 @@ public void testSimpleFileRequest() HttpResponse response = mHttpClient.execute(httppost); stopServer(); + mWebserver.onClose(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); response.getEntity().writeTo(baos); - Assert.assertEquals( - new FileReader(mContext, "web/index.html").read(), - new String(baos.toByteArray(), DEFAULT_ENCODING)); - + FileReader reader = new FileReader(mContext, "web/index.html"); + Assert.assertEquals(reader.read(), new String(baos.toByteArray(), + DEFAULT_ENCODING)); + reader.onClose(); + reader = null; } catch (Exception ex) { @@ -289,7 +295,7 @@ public void testStartSecureServer() mServerConfig.port = 8888; mServerConfig.protocolName = "https"; mServerConfig.username = "huaba"; - + SharedPreferencesProvider serverConfig = new SharedPreferencesProvider( mContext); String keystorePassword = "foobar64"; @@ -316,5 +322,6 @@ public void testStartSecureServer() stopServer(); Assert.assertFalse(mWebserver.isRunning()); + mWebserver.onClose(); } }