From b9a16687f5ae7214f0d320328544081e7edc950c Mon Sep 17 00:00:00 2001 From: maxwen Date: Sun, 3 Aug 2025 17:29:57 +0000 Subject: [PATCH] Fixup: core: Add OmniJawsClient Cleaned up version from https://github.com/omnirom/android_packages_apps_OmniLib Keeping it accessible for weather client packages as well as SystemUI package. Change-Id: Ifadfaa7f4438e3bde52f116f002a7a5273790184 Squashed: From: Pranav Vashi Date: Sat, 7 Sep 2024 21:02:59 +0530 Subject: [PATCH] OmnijawsClient: Close cursor to avoid memory leak From: minaripenguin Date: Thu, 12 Sep 2024 21:36:35 +0800 Subject: [PATCH] OmnijawsClient: Fix memory leak rmp - do not hold long live context references especially from views, revise memory leak prone practices neobuddy89 - retain required helper functions Change-Id: Ie4cccb0eb37197be06595e75729883d078d06541 Co-authored-by: Pranav Vashi Co-authored-by: minaripenguin Co-authored-by: rmp22 <195054967+rmp22@users.noreply.github.com> Signed-off-by: Pranav Vashi Signed-off-by: Dmitrii Signed-off-by: MOVZX --- .../util/evolution/OmniJawsClient.java | 722 +++++++++--------- 1 file changed, 342 insertions(+), 380 deletions(-) diff --git a/core/java/com/android/internal/util/evolution/OmniJawsClient.java b/core/java/com/android/internal/util/evolution/OmniJawsClient.java index 06d520ea9b72b..b7b1afbd38612 100644 --- a/core/java/com/android/internal/util/evolution/OmniJawsClient.java +++ b/core/java/com/android/internal/util/evolution/OmniJawsClient.java @@ -1,27 +1,21 @@ /* -* Copyright (C) 2021 The OmniROM Project -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -*/ -package com.android.internal.util.crdroid; + * Copyright (C) 2021 The OmniROM project + * Copyright (C) 2022-2025 crDroid Android 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. + */ -import java.text.DecimalFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +package com.android.internal.util.crdroid; import android.content.BroadcastReceiver; import android.content.Context; @@ -30,28 +24,33 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; -import android.database.ContentObserver; import android.database.Cursor; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.Handler; -import android.os.UserHandle; -import android.provider.Settings; import android.text.TextUtils; import android.util.Log; +import java.lang.ref.WeakReference; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + public class OmniJawsClient { + private static final String TAG = "OmniJawsClient"; private static final boolean DEBUG = false; + public static final String SERVICE_PACKAGE = "org.omnirom.omnijaws"; - public static final Uri WEATHER_URI - = Uri.parse("content://org.omnirom.omnijaws.provider/weather"); - public static final Uri SETTINGS_URI - = Uri.parse("content://org.omnirom.omnijaws.provider/settings"); - public static final Uri CONTROL_URI - = Uri.parse("content://org.omnirom.omnijaws.provider/control"); + public static final Uri WEATHER_URI = Uri.parse("content://org.omnirom.omnijaws.provider/weather"); + public static final Uri SETTINGS_URI = Uri.parse("content://org.omnirom.omnijaws.provider/settings"); + public static final String WEATHER_UPDATE = SERVICE_PACKAGE + ".WEATHER_UPDATE"; + public static final String WEATHER_ERROR = SERVICE_PACKAGE + ".WEATHER_ERROR"; private static final String ICON_PACKAGE_DEFAULT = "org.omnirom.omnijaws"; private static final String ICON_PREFIX_DEFAULT = "google_new_light"; @@ -59,39 +58,317 @@ public class OmniJawsClient { public static final int EXTRA_ERROR_NETWORK = 0; public static final int EXTRA_ERROR_LOCATION = 1; public static final int EXTRA_ERROR_DISABLED = 2; - - private boolean mWeatherReceiverRegistered; - public static final String[] WEATHER_PROJECTION = new String[]{ - "city", - "wind_speed", - "wind_direction", - "condition_code", - "temperature", - "humidity", - "condition", - "forecast_low", - "forecast_high", - "forecast_condition", - "forecast_condition_code", - "time_stamp", - "forecast_date", - "pin_wheel" + public static final String[] WEATHER_PROJECTION = { + "city", "wind_speed", "wind_direction", "condition_code", "temperature", + "humidity", "condition", "forecast_low", "forecast_high", "forecast_condition", + "forecast_condition_code", "time_stamp", "forecast_date", "pin_wheel" }; - public static final String[] SETTINGS_PROJECTION = new String[] { - "enabled", - "units", - "provider", - "setup", - "icon_pack" + public static final String[] SETTINGS_PROJECTION = { + "enabled", "units", "provider", "setup", "icon_pack" }; - private static final String WEATHER_UPDATE = SERVICE_PACKAGE + ".WEATHER_UPDATE"; - private static final String WEATHER_ERROR = SERVICE_PACKAGE + ".WEATHER_ERROR"; - private static final DecimalFormat sNoDigitsFormat = new DecimalFormat("0"); + private static OmniJawsClient sInstance; + + private WeatherInfo mCachedInfo; + private Resources mRes; + private String mPackageName; + private String mIconPrefix; + private String mSettingIconPackage; + private boolean mMetric; + + private final List> mObservers = new ArrayList<>(); + private WeatherUpdateReceiver mReceiver; + private boolean mWeatherReceiverRegistered = false; + + public static OmniJawsClient get() { + if (sInstance == null) { + synchronized (OmniJawsClient.class) { + if (sInstance == null) { + sInstance = new OmniJawsClient(); + } + } + } + return sInstance; + } + + public interface OmniJawsObserver { + void weatherUpdated(); + void weatherError(int errorReason); + default void updateSettings() {} + } + + private class WeatherUpdateReceiver extends BroadcastReceiver { + @Override public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + pruneDeadObservers(); + for (WeakReference ref : mObservers) { + OmniJawsObserver obs = ref.get(); + if (obs == null) continue; + if (WEATHER_UPDATE.equals(action)) { + obs.weatherUpdated(); + } else if (WEATHER_ERROR.equals(action)) { + obs.weatherError(intent.getIntExtra(EXTRA_ERROR, 0)); + } + } + } + } + + public Intent getSettingsIntent(Context context) { + if (isOmniJawsEnabled(context)) { + return new Intent(Intent.ACTION_MAIN) + .setClassName(SERVICE_PACKAGE, SERVICE_PACKAGE + ".SettingsActivity"); + } + return null; + } + + public Intent getWeatherActivityIntent(Context context) { + if (isOmniJawsEnabled(context)) { + return new Intent(Intent.ACTION_MAIN) + .setClassName(SERVICE_PACKAGE, SERVICE_PACKAGE + ".WeatherActivity"); + } + return null; + } + + public WeatherInfo getWeatherInfo() { + return mCachedInfo; + } + + public void queryWeather(Context context) { + if (!isOmniJawsEnabled(context)) { + Log.w(TAG, "queryWeather while disabled"); + mCachedInfo = null; + return; + } + + try (Cursor weatherCursor = context.getContentResolver().query( + WEATHER_URI, WEATHER_PROJECTION, null, null, null)) { + + if (weatherCursor != null && weatherCursor.getCount() > 0) { + mCachedInfo = new WeatherInfo(); + List forecasts = new ArrayList<>(); + + for (int i = 0; i < weatherCursor.getCount(); i++) { + weatherCursor.moveToPosition(i); + if (i == 0) { + mCachedInfo.city = weatherCursor.getString(0); + mCachedInfo.windSpeed = getFormattedValue(weatherCursor.getFloat(1)); + mCachedInfo.windDirection = weatherCursor.getInt(2) + "\u00b0"; + mCachedInfo.conditionCode = weatherCursor.getInt(3); + mCachedInfo.temp = getFormattedValue(weatherCursor.getFloat(4)); + mCachedInfo.humidity = weatherCursor.getString(5); + mCachedInfo.condition = weatherCursor.getString(6); + mCachedInfo.timeStamp = Long.parseLong(weatherCursor.getString(11)); + mCachedInfo.pinWheel = weatherCursor.getString(13); + } else { + DayForecast day = new DayForecast(); + day.low = getFormattedValue(weatherCursor.getFloat(7)); + day.high = getFormattedValue(weatherCursor.getFloat(8)); + day.condition = weatherCursor.getString(9); + day.conditionCode = weatherCursor.getInt(10); + day.date = weatherCursor.getString(12); + forecasts.add(day); + } + } + mCachedInfo.forecasts = forecasts; + } + } catch (Exception e) { + Log.e(TAG, "queryWeather: weather", e); + } + + try (Cursor settingsCursor = context.getContentResolver().query( + SETTINGS_URI, SETTINGS_PROJECTION, null, null, null)) { + + if (settingsCursor != null && settingsCursor.moveToFirst()) { + mMetric = settingsCursor.getInt(1) == 0; + if (mCachedInfo != null) { + mCachedInfo.tempUnits = getTemperatureUnit(); + mCachedInfo.windUnits = getWindUnit(); + mCachedInfo.provider = settingsCursor.getString(2); + mCachedInfo.iconPack = settingsCursor.getString(4); + } + } + } catch (Exception e) { + Log.e(TAG, "queryWeather: settings", e); + } + + updateSettings(context); + } + + private void updateSettings(Context context) { + String iconPack = (mCachedInfo != null) ? mCachedInfo.iconPack : null; + if (iconPack == null || TextUtils.isEmpty(iconPack)) { + loadDefaultIconsPackage(context); + } else if (!iconPack.equals(mSettingIconPackage)) { + mSettingIconPackage = iconPack; + loadCustomIconPackage(context); + } + } + + private void loadDefaultIconsPackage(Context context) { + mPackageName = ICON_PACKAGE_DEFAULT; + mIconPrefix = ICON_PREFIX_DEFAULT; + mSettingIconPackage = mPackageName + "." + mIconPrefix; + try { + mRes = context.getPackageManager().getResourcesForApplication(mPackageName); + } catch (Exception e) { + Log.w(TAG, "No default icon package found"); + mRes = null; + } + } + + private void loadCustomIconPackage(Context context) { + int idx = mSettingIconPackage.lastIndexOf("."); + if (idx == -1) { + loadDefaultIconsPackage(context); + return; + } + mPackageName = mSettingIconPackage.substring(0, idx); + mIconPrefix = mSettingIconPackage.substring(idx + 1); + try { + mRes = context.getPackageManager().getResourcesForApplication(mPackageName); + } catch (Exception e) { + Log.w(TAG, "Icon pack loading failed, fallback to default"); + loadDefaultIconsPackage(context); + } + } + + private static String getFormattedValue(float value) { + if (Float.isNaN(value)) return "-"; + String result = sNoDigitsFormat.format(value); + return result.equals("-0") ? "0" : result; + } + + public boolean isOmniJawsServiceInstalled(Context context) { + return isAvailableApp(context, SERVICE_PACKAGE); + } + + public boolean isOmniJawsEnabled(Context context) { + if (!isOmniJawsServiceInstalled(context)) return false; + + try (Cursor c = context.getContentResolver().query( + SETTINGS_URI, SETTINGS_PROJECTION, null, null, null)) { + return c != null && c.moveToFirst() && c.getInt(0) == 1; + } catch (Exception e) { + Log.e(TAG, "isOmniJawsEnabled", e); + return false; + } + } + + private boolean isAvailableApp(Context context, String pkg) { + try { + PackageManager pm = context.getPackageManager(); + pm.getPackageInfo(pkg, PackageManager.GET_ACTIVITIES); + int state = pm.getApplicationEnabledSetting(pkg); + return state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED + && state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; + } catch (NameNotFoundException | IllegalArgumentException e) { + return false; + } + } + + public void addObserver(Context context, OmniJawsObserver observer) { + if (observer == null) return; + removeObserver(context, observer); + mObservers.add(new WeakReference<>(observer)); + registerReceiverIfNeeded(context); + } + + public void removeObserver(Context context, OmniJawsObserver observer) { + if (observer == null) return; + Iterator> it = mObservers.iterator(); + while (it.hasNext()) { + OmniJawsObserver o = it.next().get(); + if (o == null || o == observer) { + it.remove(); + } + } + if (mObservers.isEmpty()) { + unregisterReceiver(context); + } + } + + private void pruneDeadObservers() { + try { + mObservers.removeIf(ref -> ref.get() == null); + } catch (Exception e) { + Log.w(TAG, "Exception occured while pruning, ignoring"); + } + } + + private void registerReceiverIfNeeded(Context context) { + if (!mWeatherReceiverRegistered && !mObservers.isEmpty()) { + if (mReceiver != null) { + try { + context.unregisterReceiver(mReceiver); + } catch (Exception ignored) {} + } + mReceiver = new WeatherUpdateReceiver(); + IntentFilter filter = new IntentFilter(); + filter.addAction(WEATHER_UPDATE); + filter.addAction(WEATHER_ERROR); + context.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED); + mWeatherReceiverRegistered = true; + } + } + + private void unregisterReceiver(Context context) { + if (mWeatherReceiverRegistered && mReceiver != null) { + try { + context.unregisterReceiver(mReceiver); + } catch (Exception ignored) {} + mWeatherReceiverRegistered = false; + } + } + + private String getTemperatureUnit() { + return mMetric ? "\u00b0C" : "\u00b0F"; + } + + private String getWindUnit() { + return mMetric ? "km/h" : "mph"; + } + + public Drawable getWeatherConditionImage(Context context, int conditionCode) { + if (mRes == null) { + loadDefaultIconsPackage(context); + } + try { + int resId = mRes.getIdentifier(mIconPrefix + "_" + conditionCode, "drawable", mPackageName); + Drawable d = mRes.getDrawable(resId, null); + return d != null ? d : getDefaultConditionImage(context); + } catch (Exception e) { + Log.e(TAG, "getWeatherConditionImage", e); + return getDefaultConditionImage(context); + } + } + + private Drawable getDefaultConditionImage(Context context) { + try { + Resources res = context.getPackageManager().getResourcesForApplication(ICON_PACKAGE_DEFAULT); + int resId = res.getIdentifier(ICON_PREFIX_DEFAULT + "_na", "drawable", ICON_PACKAGE_DEFAULT); + Drawable d = res.getDrawable(resId, null); + return d != null ? d : new ColorDrawable(Color.RED); + } catch (Exception e) { + return new ColorDrawable(Color.RED); + } + } + + public Drawable getResOmni(Context context, String iconOmni) { + if (mRes == null) loadDefaultIconsPackage(context); + try { + int resId = mRes.getIdentifier(iconOmni, "drawable", mPackageName); + Drawable d = mRes.getDrawable(resId, null); + return d != null ? d : new ColorDrawable(Color.RED); + } catch (Exception e) { + Log.e(TAG, "getResOmni", e); + return new ColorDrawable(Color.RED); + } + } + public static class WeatherInfo { public String city; public String windSpeed; @@ -108,13 +385,13 @@ public class OmniJawsClient { public String pinWheel; public String iconPack; - public String toString() { - return city + ":" + new Date(timeStamp) + ": " + windSpeed + ":" + windDirection + ":" +conditionCode + ":" + temp + ":" + humidity + ":" + condition + ":" + tempUnits + ":" + windUnits + ": " + forecasts + ": " + iconPack; + public String getLastUpdateTime() { + return new SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(new Date(timeStamp)); } - public String getLastUpdateTime() { - SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); - return sdf.format(new Date(timeStamp)); + @Override + public String toString() { + return city + " @ " + new Date(timeStamp) + " | " + condition + " | " + temp; } } @@ -125,324 +402,9 @@ public class OmniJawsClient { public String condition; public String date; - public String toString() { - return "[" + low + ":" + high + ":" +conditionCode + ":" + condition + ":" + date + "]"; - } - } - - public static interface OmniJawsObserver { - public void weatherUpdated(); - public void weatherError(int errorReason); - default public void updateSettings() {}; - } - - private class WeatherUpdateReceiver extends BroadcastReceiver { @Override - public void onReceive(final Context context, Intent intent) { - String action = intent.getAction(); - for (OmniJawsObserver observer : mObserver) { - if (action.equals(WEATHER_UPDATE)) { - observer.weatherUpdated(); - } else if (action.equals(WEATHER_ERROR)) { - int errorReason = intent.getIntExtra(EXTRA_ERROR, 0); - observer.weatherError(errorReason); - } - } + public String toString() { + return "[" + date + " - " + low + "/" + high + " - " + condition + "]"; } } - - private Context mContext; - private WeatherInfo mCachedInfo; - private Resources mRes; - private String mPackageName; - private String mIconPrefix; - private String mSettingIconPackage; - private boolean mMetric; - private List mObserver; - private WeatherUpdateReceiver mReceiver; - - public OmniJawsClient(Context context) { - mContext = context; - mObserver = new ArrayList(); - } - - public Intent getSettingsIntent() { - if (isOmniJawsServiceInstalled()) { - Intent settings = new Intent(Intent.ACTION_MAIN) - .setClassName(SERVICE_PACKAGE, SERVICE_PACKAGE + ".SettingsActivity"); - return settings; - } - return null; - } - - public Intent getWeatherActivityIntent() { - if (isOmniJawsServiceInstalled()) { - Intent settings = new Intent(Intent.ACTION_MAIN) - .setClassName(SERVICE_PACKAGE, SERVICE_PACKAGE + ".WeatherActivity"); - return settings; - } - return null; - } - - public WeatherInfo getWeatherInfo() { - return mCachedInfo; - } - - private static String getFormattedValue(float value) { - if (Float.isNaN(value)) { - return "-"; - } - String formatted = sNoDigitsFormat.format(value); - if (formatted.equals("-0")) { - formatted = "0"; - } - return formatted; - } - - public void queryWeather() { - if (!isOmniJawsEnabled()) { - Log.w(TAG, "queryWeather while disabled"); - mCachedInfo = null; - return; - } - try { - mCachedInfo = null; - Cursor c = mContext.getContentResolver().query(WEATHER_URI, WEATHER_PROJECTION, - null, null, null); - if (c != null) { - try { - int count = c.getCount(); - if (count > 0) { - mCachedInfo = new WeatherInfo(); - List forecastList = new ArrayList(); - int i = 0; - for (i = 0; i < count; i++) { - c.moveToPosition(i); - if (i == 0) { - mCachedInfo.city = c.getString(0); - mCachedInfo.windSpeed = getFormattedValue(c.getFloat(1)); - mCachedInfo.windDirection = String.valueOf(c.getInt(2)) + "\u00b0"; - mCachedInfo.conditionCode = c.getInt(3); - mCachedInfo.temp = getFormattedValue(c.getFloat(4)); - mCachedInfo.humidity = c.getString(5); - mCachedInfo.condition = c.getString(6); - mCachedInfo.timeStamp = Long.valueOf(c.getString(11)); - mCachedInfo.pinWheel = c.getString(13); - } else { - DayForecast day = new DayForecast(); - day.low = getFormattedValue(c.getFloat(7)); - day.high = getFormattedValue(c.getFloat(8)); - day.condition = c.getString(9); - day.conditionCode = c.getInt(10); - day.date = c.getString(12); - forecastList.add(day); - } - } - mCachedInfo.forecasts = forecastList; - } - } finally { - c.close(); - } - } - c = mContext.getContentResolver().query(SETTINGS_URI, SETTINGS_PROJECTION, - null, null, null); - if (c != null) { - try { - int count = c.getCount(); - if (count == 1) { - c.moveToPosition(0); - mMetric = c.getInt(1) == 0; - if (mCachedInfo != null) { - mCachedInfo.tempUnits = getTemperatureUnit(); - mCachedInfo.windUnits = getWindUnit(); - mCachedInfo.provider = c.getString(2); - mCachedInfo.iconPack = c.getString(4); - } - } - } finally { - c.close(); - } - } - - if (DEBUG) Log.d(TAG, "queryWeather " + mCachedInfo); - updateSettings(); - } catch (Exception e) { - Log.e(TAG, "queryWeather", e); - } - } - - private void loadDefaultIconsPackage() { - mPackageName = ICON_PACKAGE_DEFAULT; - mIconPrefix = ICON_PREFIX_DEFAULT; - mSettingIconPackage = mPackageName + "." + mIconPrefix; - if (DEBUG) Log.d(TAG, "Load default icon pack " + mSettingIconPackage + " " + mPackageName + " " + mIconPrefix); - try { - PackageManager packageManager = mContext.getPackageManager(); - mRes = packageManager.getResourcesForApplication(mPackageName); - } catch (Exception e) { - mRes = null; - } - if (mRes == null) { - Log.w(TAG, "No default package found"); - } - } - - private Drawable getDefaultConditionImage() { - String packageName = ICON_PACKAGE_DEFAULT; - String iconPrefix = ICON_PREFIX_DEFAULT; - - try { - PackageManager packageManager = mContext.getPackageManager(); - Resources res = packageManager.getResourcesForApplication(packageName); - if (res != null) { - int resId = res.getIdentifier(iconPrefix + "_na", "drawable", packageName); - Drawable d = res.getDrawable(resId); - if (d != null) { - return d; - } - } - } catch (Exception e) { - } - // absolute absolute fallback - Log.w(TAG, "No default package found"); - return new ColorDrawable(Color.RED); - } - - private void loadCustomIconPackage() { - if (DEBUG) Log.d(TAG, "Load custom icon pack " + mSettingIconPackage); - int idx = mSettingIconPackage.lastIndexOf("."); - mPackageName = mSettingIconPackage.substring(0, idx); - mIconPrefix = mSettingIconPackage.substring(idx + 1); - if (DEBUG) Log.d(TAG, "Load custom icon pack " + mPackageName + " " + mIconPrefix); - try { - PackageManager packageManager = mContext.getPackageManager(); - mRes = packageManager.getResourcesForApplication(mPackageName); - } catch (Exception e) { - mRes = null; - } - if (mRes == null) { - Log.w(TAG, "Icon pack loading failed - loading default"); - loadDefaultIconsPackage(); - } - } - - public Drawable getWeatherConditionImage(int conditionCode) { - try { - int resId = mRes.getIdentifier(mIconPrefix + "_" + conditionCode, "drawable", mPackageName); - Drawable d = mRes.getDrawable(resId); - if (d != null) { - return d; - } - Log.w(TAG, "Failed to get condition image for " + conditionCode + " use default"); - resId = mRes.getIdentifier(mIconPrefix + "_na", "drawable", mPackageName); - d = mRes.getDrawable(resId); - if (d != null) { - return d; - } - } catch(Exception e) { - Log.e(TAG, "getWeatherConditionImage", e); - } - Log.w(TAG, "Failed to get condition image for " + conditionCode); - return getDefaultConditionImage(); - } - - public boolean isOmniJawsServiceInstalled() { - return isAvailableApp(SERVICE_PACKAGE); - } - - public boolean isOmniJawsEnabled() { - if (!isOmniJawsServiceInstalled()) { - return false; - } - boolean enabled = false; - try { - final Cursor c = mContext.getContentResolver().query(SETTINGS_URI, SETTINGS_PROJECTION, - null, null, null); - if (c != null) { - try { - int count = c.getCount(); - if (count == 1) { - c.moveToPosition(0); - enabled = c.getInt(0) == 1; - } - } finally { - c.close(); - } - } - } catch (Exception e) { - Log.e(TAG, "isOmniJawsEnabled", e); - } - return enabled; - } - - private String getTemperatureUnit() { - return "\u00b0" + (mMetric ? "C" : "F"); - } - - private String getWindUnit() { - return mMetric ? "km/h":"mph"; - } - - private void updateSettings() { - final String iconPack = mCachedInfo != null ? mCachedInfo.iconPack : null; - if (iconPack == null || TextUtils.isEmpty(iconPack)) { - loadDefaultIconsPackage(); - } else if (mSettingIconPackage == null || !iconPack.equals(mSettingIconPackage)) { - mSettingIconPackage = iconPack; - loadCustomIconPackage(); - } - } - - private boolean isAvailableApp(String packageName) { - final PackageManager pm = mContext.getPackageManager(); - try { - pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES); - int enabled = pm.getApplicationEnabledSetting(packageName); - return enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED && - enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; - } catch (NameNotFoundException e) { - return false; - } - } - - public void addObserver(OmniJawsObserver observer) { - if (mObserver.contains(observer)) { - removeObserver(observer); - } - mObserver.add(observer); - registerReceiverIfNeeded(); - } - - public void removeObserver(OmniJawsObserver observer) { - if (mObserver.contains(observer)) { - mObserver.remove(observer); - if (mObserver.isEmpty()) { - unregisterReceiver(); - } - } - } - - private void registerReceiverIfNeeded() { - if (mObserver.size() == 1 && !mWeatherReceiverRegistered) { - if (mReceiver != null) { - try { - mContext.unregisterReceiver(mReceiver); - } catch (Exception e) { - } - } - mReceiver = new WeatherUpdateReceiver(); - IntentFilter filter = new IntentFilter(); - filter.addAction(WEATHER_UPDATE); - filter.addAction(WEATHER_ERROR); - if (DEBUG) Log.d(TAG, "registerReceiver"); - mContext.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED); - mWeatherReceiverRegistered = true; - } - } - - private void unregisterReceiver() { - if (!mWeatherReceiverRegistered) return; - mContext.unregisterReceiver(mReceiver); - mWeatherReceiverRegistered = false; - } }