0
0
mirror of https://github.com/ponces/treble_aosp.git synced 2025-05-08 21:17:34 +00:00
Files
treble_aosp/patches/personal/platform_frameworks_base/0005-feat-Add-Lockscreen-Weather-with-OmniJaws-1-2.patch
2025-03-28 14:12:11 +00:00

764 lines
30 KiB
Diff

From 2dc23bc310657d27325742332b13ba88d7a1931b Mon Sep 17 00:00:00 2001
From: maxwen <max.weninger@gmail.com>
Date: Fri, 22 Oct 2021 14:55:26 +0200
Subject: [PATCH 5/8] feat: Add Lockscreen Weather with OmniJaws (1/2)
Based on OmniROM's implementation, updated by @maxwen and adapted by @neobuddy89.
Change-Id: I138c0dc94f08142f6614659037a501d6ae8909b1
Co-authored-by: maxwen <max.weninger@gmail.com>
Co-authored-by: Pranav Vashi <neobuddy89@gmail.com>
---
core/java/android/provider/Settings.java | 5 +
.../internal/util/crdroid/OmniJawsClient.java | 441 ++++++++++++++++++
data/etc/com.android.systemui.xml | 1 +
packages/SystemUI/AndroidManifest.xml | 4 +
.../android/keyguard/KeyguardSliceView.java | 13 +
.../keyguard/KeyguardSliceProvider.java | 103 +++-
6 files changed, 566 insertions(+), 1 deletion(-)
create mode 100644 core/java/com/android/internal/util/crdroid/OmniJawsClient.java
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4acb6312f..fc1bb4eb3 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6445,6 +6445,11 @@ public final class Settings {
* the setting value. See an example above.
*/
+ /**
+ * @hide
+ */
+ public static final String LOCKSCREEN_WEATHER_ENABLED = "lockscreen_weather_enabled";
+
/**
* Keys we no longer back up under the current schema, but want to continue to
* process when restoring historical backup datasets.
diff --git a/core/java/com/android/internal/util/crdroid/OmniJawsClient.java b/core/java/com/android/internal/util/crdroid/OmniJawsClient.java
new file mode 100644
index 000000000..2bbd51ffa
--- /dev/null
+++ b/core/java/com/android/internal/util/crdroid/OmniJawsClient.java
@@ -0,0 +1,441 @@
+/*
+* 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 <http://www.gnu.org/licenses/>.
+*
+*/
+package com.android.internal.util.crdroid;
+
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+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;
+
+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");
+
+ private static final String ICON_PACKAGE_DEFAULT = "org.omnirom.omnijaws";
+ private static final String ICON_PREFIX_DEFAULT = "google_new_light";
+ private static final String ICON_PREFIX_OUTLINE = "outline";
+ private static final String EXTRA_ERROR = "error";
+ public static final int EXTRA_ERROR_NETWORK = 0;
+ public static final int EXTRA_ERROR_LOCATION = 1;
+ public static final int EXTRA_ERROR_DISABLED = 2;
+
+ 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[] SETTINGS_PROJECTION = new String[] {
+ "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");
+
+ public static class WeatherInfo {
+ public String city;
+ public String windSpeed;
+ public String windDirection;
+ public int conditionCode;
+ public String temp;
+ public String humidity;
+ public String condition;
+ public Long timeStamp;
+ public List<DayForecast> forecasts;
+ public String tempUnits;
+ public String windUnits;
+ public String provider;
+ 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() {
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+ return sdf.format(new Date(timeStamp));
+ }
+ }
+
+ public static class DayForecast {
+ public String low;
+ public String high;
+ public int conditionCode;
+ 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();
+ }
+ if (action.equals(WEATHER_ERROR)) {
+ int errorReason = intent.getIntExtra(EXTRA_ERROR, 0);
+ observer.weatherError(errorReason);
+ }
+ }
+ }
+ }
+
+ private Context mContext;
+ private WeatherInfo mCachedInfo;
+ private Resources mRes;
+ private String mPackageName;
+ private String mIconPrefix;
+ private String mSettingIconPackage;
+ private boolean mMetric;
+ private List<OmniJawsObserver> mObserver;
+ private WeatherUpdateReceiver mReceiver;
+
+ public OmniJawsClient(Context context) {
+ mContext = context;
+ mObserver = new ArrayList<OmniJawsObserver>();
+ }
+
+ 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<DayForecast> forecastList = new ArrayList<DayForecast>();
+ 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 (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.size() == 0) {
+ 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);
+ }
+ mObserver.add(observer);
+ }
+
+ public void removeObserver(OmniJawsObserver observer) {
+ mObserver.remove(observer);
+ if (mObserver.size() == 0 && mReceiver != null) {
+ try {
+ if (DEBUG) Log.d(TAG, "unregisterReceiver");
+ mContext.unregisterReceiver(mReceiver);
+ } catch (Exception e) {
+ }
+ mReceiver = null;
+ }
+ }
+
+ public boolean isOutlineIconPackage() {
+ return mIconPrefix.equals(ICON_PREFIX_OUTLINE);
+ }
+}
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 38ea4ac8d..0ceaa3d4f 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -16,6 +16,7 @@
-->
<permissions>
<privapp-permissions package="com.android.systemui">
+ <permission name="android.permission.ACCESS_FINE_LOCATION"/>
<permission name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
<permission name="android.permission.ALLOW_SLIPPERY_TOUCHES"/>
<permission name="android.permission.BATTERY_STATS"/>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 11cb0703d..88db8a0de 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -394,6 +394,10 @@
<protected-broadcast android:name="com.android.systemui.action.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG" />
<protected-broadcast android:name="com.android.systemui.STARTED" />
+ <!-- OmniJaws -->
+ <uses-permission android:name="org.omnirom.omnijaws.READ_WEATHER" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+
<application
android:name=".SystemUIApplication"
android:persistent="true"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index d8be862e1..130f984be 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -163,14 +163,18 @@ public class KeyguardSliceView extends LinearLayout {
RowContent rc = (RowContent) subItems.get(i);
SliceItem item = rc.getSliceItem();
final Uri itemTag = item.getSlice().getUri();
+ final boolean isWeatherSlice = itemTag.toString().equals(KeyguardSliceProvider.KEYGUARD_WEATHER_URI);
// Try to reuse the view if already exists in the layout
KeyguardSliceTextView button = mRow.findViewWithTag(itemTag);
if (button == null) {
button = new KeyguardSliceTextView(mContext);
+ button.setShouldTintDrawable(!isWeatherSlice);
button.setTextColor(blendedColor);
button.setTag(itemTag);
final int viewIndex = i - (mHasHeader ? 1 : 0);
mRow.addView(button, viewIndex);
+ } else {
+ button.setShouldTintDrawable(!isWeatherSlice);
}
PendingIntent pendingIntent = null;
@@ -424,12 +428,18 @@ public class KeyguardSliceView extends LinearLayout {
@StyleRes
private static int sStyleId = R.style.TextAppearance_Keyguard_Secondary;
+ private boolean shouldTintDrawable = true;
+
KeyguardSliceTextView(Context context) {
super(context, null /* attrs */, 0 /* styleAttr */, sStyleId);
onDensityOrFontScaleChanged();
setEllipsize(TruncateAt.END);
}
+ public void setShouldTintDrawable(boolean shouldTintDrawable){
+ this.shouldTintDrawable = shouldTintDrawable;
+ }
+
public void onDensityOrFontScaleChanged() {
updatePadding();
}
@@ -472,6 +482,9 @@ public class KeyguardSliceView extends LinearLayout {
}
private void updateDrawableColors() {
+ if (!shouldTintDrawable) {
+ return;
+ }
final int color = getCurrentTextColor();
for (Drawable drawable : getCompoundDrawables()) {
if (drawable != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 3b85b5710..659381910 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -24,6 +24,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.ContentObserver;
import android.graphics.Typeface;
import android.graphics.drawable.Icon;
import android.icu.text.DateFormat;
@@ -33,6 +34,7 @@ import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Handler;
import android.os.Trace;
+import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.TextUtils;
@@ -45,8 +47,10 @@ import androidx.slice.SliceProvider;
import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.ListBuilder.RowBuilder;
import androidx.slice.builders.SliceAction;
+import androidx.slice.widget.SliceViewUtil;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.crdroid.OmniJawsClient;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SystemUIAppComponentFactoryBase;
@@ -80,7 +84,7 @@ import javax.inject.Inject;
public class KeyguardSliceProvider extends SliceProvider implements
NextAlarmController.NextAlarmChangeCallback, ZenModeController.Callback,
NotificationMediaManager.MediaListener, StatusBarStateController.StateListener,
- SystemUIAppComponentFactoryBase.ContextInitializer {
+ SystemUIAppComponentFactoryBase.ContextInitializer, OmniJawsClient.OmniJawsObserver {
private static final String TAG = "KgdSliceProvider";
@@ -96,6 +100,8 @@ public class KeyguardSliceProvider extends SliceProvider implements
"content://com.android.systemui.keyguard/media";
public static final String KEYGUARD_ACTION_URI =
"content://com.android.systemui.keyguard/action";
+ public static final String KEYGUARD_WEATHER_URI =
+ "content://com.android.systemui.keyguard/weather";
/**
* Only show alarms that will ring within N hours.
@@ -157,6 +163,12 @@ public class KeyguardSliceProvider extends SliceProvider implements
@Background
Handler mBgHandler;
+ protected final Uri mWeatherUri;
+ private OmniJawsClient mWeatherClient;
+ private OmniJawsClient.WeatherInfo mWeatherData;
+ private SettingsObserver mSettingsObserver;
+ private boolean mShowWeatherSlice;
+
/**
* Receiver responsible for time ticking and updating the date format.
*/
@@ -195,6 +207,34 @@ public class KeyguardSliceProvider extends SliceProvider implements
}
};
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_WEATHER_ENABLED), false, this,
+ UserHandle.USER_ALL);
+ updateShowWeatherSlice();
+ }
+
+ void unobserve() {
+ mContentResolver.unregisterContentObserver(this);
+ }
+
+ void updateShowWeatherSlice() {
+ mShowWeatherSlice = Settings.System.getIntForUser(mContentResolver,
+ Settings.System.LOCKSCREEN_WEATHER_ENABLED,
+ 0, UserHandle.USER_CURRENT) != 0;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateShowWeatherSlice();
+ }
+ }
+
public static KeyguardSliceProvider getAttachedInstance() {
return KeyguardSliceProvider.sInstance;
}
@@ -208,6 +248,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
mAlarmUri = Uri.parse(KEYGUARD_NEXT_ALARM_URI);
mDndUri = Uri.parse(KEYGUARD_DND_URI);
mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI);
+ mWeatherUri = Uri.parse(KEYGUARD_WEATHER_URI);
}
@AnyThread
@@ -224,6 +265,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
} else {
builder.addRow(new RowBuilder(mDateUri).setTitle(mLastText));
}
+ addWeatherLocked(builder);
addNextAlarmLocked(builder);
addZenModeLocked(builder);
addPrimaryActionLocked(builder);
@@ -292,6 +334,17 @@ public class KeyguardSliceProvider extends SliceProvider implements
builder.addRow(alarmRowBuilder);
}
+ protected void addWeatherLocked(ListBuilder builder) {
+ if (!mShowWeatherSlice || !mWeatherClient.isOmniJawsEnabled() || mWeatherData == null) {
+ return;
+ }
+ IconCompat weatherIcon = SliceViewUtil.createIconFromDrawable(mWeatherClient.getWeatherConditionImage(mWeatherData.conditionCode));
+ RowBuilder weatherRowBuilder = new RowBuilder(mWeatherUri)
+ .setTitle(mWeatherData.temp + mWeatherData.tempUnits)
+ .addEndItem(weatherIcon, ListBuilder.ICON_IMAGE);
+ builder.addRow(weatherRowBuilder);
+ }
+
/**
* Add zen mode (DND) icon to slice if it's enabled.
* @param builder The slice builder.
@@ -342,6 +395,9 @@ public class KeyguardSliceProvider extends SliceProvider implements
KeyguardSliceProvider.sInstance = this;
registerClockUpdate();
updateClockLocked();
+ mSettingsObserver = new SettingsObserver(mHandler);
+ mSettingsObserver.observe();
+ enableWeatherUpdates();
}
return true;
}
@@ -358,6 +414,8 @@ public class KeyguardSliceProvider extends SliceProvider implements
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
getContext().unregisterReceiver(mIntentReceiver);
}
+ disableWeatherUpdates();
+ mSettingsObserver.unobserve();
KeyguardSliceProvider.sInstance = null;
}
}
@@ -560,4 +618,47 @@ public class KeyguardSliceProvider extends SliceProvider implements
SystemUIAppComponentFactoryBase.ContextAvailableCallback callback) {
mContextAvailableCallback = callback;
}
+
+ private void enableWeatherUpdates() {
+ mWeatherClient = new OmniJawsClient(getContext());
+ mWeatherClient.addObserver(this);
+ queryAndUpdateWeather();
+ }
+
+ private void disableWeatherUpdates() {
+ if (mWeatherClient != null) {
+ mWeatherClient.removeObserver(this);
+ }
+ }
+
+ @Override
+ public void weatherError(int errorReason) {
+ // since this is shown in ambient and lock screen
+ // it would look bad to show every error since the
+ // screen-on revovery of the service had no chance
+ // to run fast enough
+ // so only show the disabled state
+ if (errorReason == OmniJawsClient.EXTRA_ERROR_DISABLED) {
+ mWeatherData = null;
+ notifyChange();
+ }
+ }
+
+ @Override
+ public void weatherUpdated() {
+ queryAndUpdateWeather();
+ }
+
+ @Override
+ public void updateSettings() {
+ queryAndUpdateWeather();
+ }
+
+ private void queryAndUpdateWeather() {
+ if (mWeatherClient != null) {
+ mWeatherClient.queryWeather();
+ mWeatherData = mWeatherClient.getWeatherInfo();
+ notifyChange();
+ }
+ }
}
--
2.34.1