summaryrefslogtreecommitdiffstats
path: root/sdk/src/java/cyanogenmod/weather/WeatherInfo.java
diff options
context:
space:
mode:
Diffstat (limited to 'sdk/src/java/cyanogenmod/weather/WeatherInfo.java')
-rwxr-xr-xsdk/src/java/cyanogenmod/weather/WeatherInfo.java524
1 files changed, 524 insertions, 0 deletions
diff --git a/sdk/src/java/cyanogenmod/weather/WeatherInfo.java b/sdk/src/java/cyanogenmod/weather/WeatherInfo.java
new file mode 100755
index 0000000..7d8686e
--- /dev/null
+++ b/sdk/src/java/cyanogenmod/weather/WeatherInfo.java
@@ -0,0 +1,524 @@
+/*
+ * Copyright (C) 2016 The CyanongenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cyanogenmod.weather;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import cyanogenmod.os.Build;
+import cyanogenmod.os.Concierge;
+import cyanogenmod.os.Concierge.ParcelInfo;
+import cyanogenmod.providers.WeatherContract;
+import cyanogenmod.weatherservice.ServiceRequest;
+import cyanogenmod.weatherservice.ServiceRequestResult;
+
+import java.util.ArrayList;
+
+/**
+ * This class represents the weather information that a
+ * {@link cyanogenmod.weatherservice.WeatherProviderService} will use to update the weather content
+ * provider. A weather provider service will be called by the system to process an update
+ * request at any time. If the service successfully processes the request, then the weather provider
+ * service is responsible of calling
+ * {@link ServiceRequest#complete(ServiceRequestResult)} to notify the
+ * system that the request was completed and that the weather content provider should be updated
+ * with the supplied weather information.
+ */
+public final class WeatherInfo implements Parcelable {
+
+ private String mCityId;
+ private String mCity;
+ private int mConditionCode;
+ private float mTemperature;
+ private int mTempUnit;
+ private float mHumidity;
+ private float mWindSpeed;
+ private float mWindDirection;
+ private int mWindSpeedUnit;
+ private long mTimestamp;
+ private ArrayList<DayForecast> mForecastList;
+ int mKey;
+
+ private WeatherInfo() {}
+
+ public static class Builder {
+ private String mCityId;
+ private String mCity;
+ private int mConditionCode;
+ private float mTemperature;
+ private int mTempUnit;
+ private float mHumidity;
+ private float mWindSpeed;
+ private float mWindDirection;
+ private int mWindSpeedUnit;
+ private long mTimestamp;
+ private ArrayList<DayForecast> mForecastList;
+
+ public Builder(long timestamp) {
+ mTimestamp = timestamp;
+ }
+
+ public Builder setCity(String cityId, @NonNull String cityName) {
+ if (cityName == null || cityId == null) {
+ throw new IllegalArgumentException("City name and id can't be null");
+ }
+ mCityId = cityId;
+ mCity = cityName;
+ return this;
+ }
+
+ public Builder setTemperature(float temperature, int tempUnit) {
+ if (!isValidTempUnit(tempUnit)) {
+ throw new IllegalArgumentException("Invalid temperature unit");
+ }
+
+ if (Float.isNaN(temperature)) {
+ throw new IllegalArgumentException("Invalid temperature value");
+ }
+
+ mTemperature = temperature;
+ mTempUnit = tempUnit;
+ return this;
+ }
+
+ public Builder setHumidity(float humidity) {
+ if (Float.isNaN(humidity)) {
+ throw new IllegalArgumentException("Invalid humidity value");
+ }
+
+ mHumidity = humidity;
+ return this;
+ }
+
+ public Builder setWind(float windSpeed, float windDirection, int windSpeedUnit) {
+ if (Float.isNaN(windSpeed)) {
+ throw new IllegalArgumentException("Invalid wind speed value");
+ }
+ if (Float.isNaN(windDirection)) {
+ throw new IllegalArgumentException("Invalid wind direction value");
+ }
+ if (!isValidWindSpeedUnit(windSpeedUnit)) {
+ throw new IllegalArgumentException("Invalid speed unit");
+ }
+ mWindSpeed = windSpeed;
+ mWindSpeedUnit = windSpeedUnit;
+ mWindDirection = windDirection;
+ return this;
+ }
+
+ public Builder setWeatherCondition(int conditionCode) {
+ if (!isValidWeatherCode(conditionCode)) {
+ throw new IllegalArgumentException("Invalid weather condition code");
+ }
+ mConditionCode = conditionCode;
+ return this;
+ }
+
+ public Builder setForecast(@NonNull ArrayList<DayForecast> forecasts) {
+ if (forecasts == null) {
+ throw new IllegalArgumentException("Forecast list can't be null");
+ }
+ mForecastList = forecasts;
+ return this;
+ }
+
+ public WeatherInfo build() {
+ WeatherInfo info = new WeatherInfo();
+ info.mCityId = this.mCityId;
+ info.mCity = this.mCity;
+ info.mConditionCode = this.mConditionCode;
+ info.mTemperature = this.mTemperature;
+ info.mTempUnit = this.mTempUnit;
+ info.mHumidity = this.mHumidity;
+ info.mWindSpeed = this.mWindSpeed;
+ info.mWindDirection = this.mWindDirection;
+ info.mWindSpeedUnit = this.mWindSpeedUnit;
+ info.mTimestamp = this.mTimestamp;
+ info.mForecastList = this.mForecastList;
+ info.mKey = this.hashCode();
+ return info;
+ }
+
+ private boolean isValidTempUnit(int unit) {
+ switch (unit) {
+ case WeatherContract.WeatherColumns.TempUnit.CELSIUS:
+ case WeatherContract.WeatherColumns.TempUnit.FAHRENHEIT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private boolean isValidWindSpeedUnit(int unit) {
+ switch (unit) {
+ case WeatherContract.WeatherColumns.WindSpeedUnit.KPH:
+ case WeatherContract.WeatherColumns.WindSpeedUnit.MPH:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+
+
+ private static boolean isValidWeatherCode(int code) {
+ if (code < WeatherContract.WeatherColumns.WeatherCode.WEATHER_CODE_MIN
+ || code > WeatherContract.WeatherColumns.WeatherCode.WEATHER_CODE_MAX) {
+ if (code != WeatherContract.WeatherColumns.WeatherCode.NOT_AVAILABLE) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return city id
+ */
+ public String getCityId() {
+ return mCityId;
+ }
+
+ /**
+ * @return city name
+ */
+ public String getCity() {
+ return mCity;
+ }
+
+ /**
+ * @return An implementation specific weather condition code
+ */
+ public int getConditionCode() {
+ return mConditionCode;
+ }
+
+ /**
+ * @return humidity
+ */
+ public float getHumidity() {
+ return mHumidity;
+ }
+
+ /**
+ * @return time stamp when the request was processed
+ */
+ public long getTimestamp() {
+ return mTimestamp;
+ }
+
+ /**
+ * @return wind direction (degrees)
+ */
+ public float getWindDirection() {
+ return mWindDirection;
+ }
+
+ /**
+ * @return wind speed
+ */
+ public float getWindSpeed() {
+ return mWindSpeed;
+ }
+
+ /**
+ * @return wind speed unit
+ */
+ public int getWindSpeedUnit() {
+ return mWindSpeedUnit;
+ }
+
+ /**
+ * @return current temperature
+ */
+ public float getTemperature() {
+ return mTemperature;
+ }
+
+ /**
+ * @return temperature unit
+ */
+ public int getTemperatureUnit() {
+ return mTempUnit;
+ }
+
+ /**
+ * @return List of {@link cyanogenmod.weather.WeatherInfo.DayForecast}
+ */
+ public ArrayList<DayForecast> getForecasts() {
+ return mForecastList;
+ }
+
+ private WeatherInfo(Parcel parcel) {
+ // Read parcelable version via the Concierge
+ ParcelInfo parcelInfo = Concierge.receiveParcel(parcel);
+ int parcelableVersion = parcelInfo.getParcelVersion();
+
+ if (parcelableVersion >= Build.CM_VERSION_CODES.ELDERBERRY) {
+ mKey = parcel.readInt();
+ mCityId = parcel.readString();
+ mCity = parcel.readString();
+ mConditionCode = parcel.readInt();
+ mTemperature = parcel.readFloat();
+ mTempUnit = parcel.readInt();
+ mHumidity = parcel.readFloat();
+ mWindSpeed = parcel.readFloat();
+ mWindDirection = parcel.readFloat();
+ mWindSpeedUnit = parcel.readInt();
+ mTimestamp = parcel.readLong();
+ int forecastListSize = parcel.readInt();
+ mForecastList = new ArrayList<>();
+ while (forecastListSize > 0) {
+ mForecastList.add(DayForecast.CREATOR.createFromParcel(parcel));
+ forecastListSize--;
+ }
+ }
+
+ // Complete parcel info for the concierge
+ parcelInfo.complete();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // Tell the concierge to prepare the parcel
+ ParcelInfo parcelInfo = Concierge.prepareParcel(dest);
+
+ // ==== ELDERBERRY =====
+ dest.writeInt(mKey);
+ dest.writeString(mCityId);
+ dest.writeString(mCity);
+ dest.writeInt(mConditionCode);
+ dest.writeFloat(mTemperature);
+ dest.writeInt(mTempUnit);
+ dest.writeFloat(mHumidity);
+ dest.writeFloat(mWindSpeed);
+ dest.writeFloat(mWindDirection);
+ dest.writeInt(mWindSpeedUnit);
+ dest.writeLong(mTimestamp);
+ dest.writeInt(mForecastList.size());
+ for (DayForecast dayForecast : mForecastList) {
+ dayForecast.writeToParcel(dest, 0);
+ }
+
+ // Complete parcel info for the concierge
+ parcelInfo.complete();
+ }
+
+ public static final Parcelable.Creator<WeatherInfo> CREATOR =
+ new Parcelable.Creator<WeatherInfo>() {
+
+ @Override
+ public WeatherInfo createFromParcel(Parcel source) {
+ return new WeatherInfo(source);
+ }
+
+ @Override
+ public WeatherInfo[] newArray(int size) {
+ return new WeatherInfo[size];
+ }
+ };
+
+ /**
+ * This class represents the weather forecast for a given day
+ */
+ public static class DayForecast implements Parcelable{
+ float mLow;
+ float mHigh;
+ int mConditionCode;
+ int mKey;
+
+ private DayForecast() {}
+
+ public static class Builder {
+ float mLow;
+ float mHigh;
+ int mConditionCode;
+
+ public Builder() {}
+ public Builder setHigh(float high) {
+ if (Float.isNaN(high)) {
+ throw new IllegalArgumentException("Invalid high forecast temperature");
+ }
+ mHigh = high;
+ return this;
+ }
+ public Builder setLow(float low) {
+ if (Float.isNaN(low)) {
+ throw new IllegalArgumentException("Invalid low forecast temperature");
+ }
+ mLow = low;
+ return this;
+ }
+
+ public Builder setWeatherCondition(int code) {
+ if (!isValidWeatherCode(code)) {
+ throw new IllegalArgumentException("Invalid weather condition code");
+ }
+ mConditionCode = code;
+ return this;
+ }
+
+ public DayForecast build() {
+ DayForecast forecast = new DayForecast();
+ forecast.mLow = this.mLow;
+ forecast.mHigh = this.mHigh;
+ forecast.mConditionCode = this.mConditionCode;
+ forecast.mKey = this.hashCode();
+ return forecast;
+ }
+ }
+
+ /**
+ * @return forecasted low temperature
+ */
+ public float getLow() {
+ return mLow;
+ }
+
+ /**
+ * @return not what you think. Returns the forecasted high temperature
+ */
+ public float getHigh() {
+ return mHigh;
+ }
+
+ /**
+ * @return forecasted weather condition code. Implementation specific
+ */
+ public int getConditionCode() {
+ return mConditionCode;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // Tell the concierge to prepare the parcel
+ ParcelInfo parcelInfo = Concierge.prepareParcel(dest);
+
+ // ==== ELDERBERRY =====
+ dest.writeInt(mKey);
+ dest.writeFloat(mLow);
+ dest.writeFloat(mHigh);
+ dest.writeInt(mConditionCode);
+
+ // Complete parcel info for the concierge
+ parcelInfo.complete();
+ }
+
+ public static final Parcelable.Creator<DayForecast> CREATOR =
+ new Parcelable.Creator<DayForecast>() {
+ @Override
+ public DayForecast createFromParcel(Parcel source) {
+ return new DayForecast(source);
+ }
+
+ @Override
+ public DayForecast[] newArray(int size) {
+ return new DayForecast[size];
+ }
+ };
+
+ private DayForecast(Parcel parcel) {
+ // Read parcelable version via the Concierge
+ ParcelInfo parcelInfo = Concierge.receiveParcel(parcel);
+ int parcelableVersion = parcelInfo.getParcelVersion();
+
+ if (parcelableVersion >= Build.CM_VERSION_CODES.ELDERBERRY) {
+ mKey = parcel.readInt();
+ mLow = parcel.readFloat();
+ mHigh = parcel.readFloat();
+ mConditionCode = parcel.readInt();
+ }
+
+ // Complete parcel info for the concierge
+ parcelInfo.complete();
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("{Low temp: ").append(mLow)
+ .append(" High temp: ").append(mHigh)
+ .append(" Condition code: ").append(mConditionCode)
+ .append("}").toString();
+ }
+
+ @Override
+ public int hashCode() {
+ //The hashcode of this object was stored when it was built. This is an
+ //immutable object but we need to preserve the hashcode since this object is parcelable
+ //and it's reconstructed over IPC, and clients of this object might want to store it in
+ //a collection that relies on this code to identify the object
+ return mKey;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof DayForecast) {
+ DayForecast forecast = (DayForecast) obj;
+ return (forecast.hashCode() == this.mKey);
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder()
+ .append("{CityId: ").append(mCityId)
+ .append(" City Name: ").append(mCity)
+ .append(" Condition Code: ").append(mConditionCode)
+ .append(" Temperature: ").append(mTemperature)
+ .append(" Temperature Unit: ").append(mTempUnit)
+ .append(" Humidity: ").append(mHumidity)
+ .append(" Wind speed: ").append(mWindSpeed)
+ .append(" Wind direction: ").append(mWindDirection)
+ .append(" Wind Speed Unit: ").append(mWindSpeedUnit)
+ .append(" Timestamp: ").append(mTimestamp).append(" Forecasts: [");
+ for (DayForecast dayForecast : mForecastList) {
+ builder.append(dayForecast.toString());
+ }
+ return builder.append("]}").toString();
+ }
+
+ @Override
+ public int hashCode() {
+ //The hashcode of this object was stored when it was built. This is an
+ //immutable object but we need to preserve the hashcode since this object is parcelable and
+ //it's reconstructed over IPC, and clients of this object might want to store it in a
+ //collection that relies on this code to identify the object
+ return mKey;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof WeatherInfo) {
+ WeatherInfo info = (WeatherInfo) obj;
+ return (info.hashCode() == this.mKey);
+ }
+ return false;
+ }
+} \ No newline at end of file