diff options
Diffstat (limited to 'sdk/src/java/cyanogenmod/app/ProfileGroup.java')
-rw-r--r-- | sdk/src/java/cyanogenmod/app/ProfileGroup.java | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/sdk/src/java/cyanogenmod/app/ProfileGroup.java b/sdk/src/java/cyanogenmod/app/ProfileGroup.java new file mode 100644 index 0000000..56ec507 --- /dev/null +++ b/sdk/src/java/cyanogenmod/app/ProfileGroup.java @@ -0,0 +1,395 @@ +/* + * Copyright (C) 2015 The CyanogenMod 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.app; + +import android.app.Notification; +import android.app.NotificationGroup; + +import android.content.Context; +import android.database.Cursor; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.ParcelUuid; +import android.text.TextUtils; +import android.util.Log; + +import cyanogenmod.os.Build; + +import cyanogenmod.os.Concierge; +import cyanogenmod.os.Concierge.ParcelInfo; + +import java.io.IOException; +import java.util.UUID; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +/** + * @hide + * TODO: This isn't ready for public use + */ +public final class ProfileGroup implements Parcelable { + private static final String TAG = "ProfileGroup"; + + private String mName; + private int mNameResId; + + private UUID mUuid; + + private Uri mSoundOverride = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + private Uri mRingerOverride = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); + + private Mode mSoundMode = Mode.DEFAULT; + private Mode mRingerMode = Mode.DEFAULT; + private Mode mVibrateMode = Mode.DEFAULT; + private Mode mLightsMode = Mode.DEFAULT; + + private boolean mDefaultGroup = false; + private boolean mDirty; + + /** @hide */ + public static final Parcelable.Creator<ProfileGroup> CREATOR + = new Parcelable.Creator<ProfileGroup>() { + public ProfileGroup createFromParcel(Parcel in) { + return new ProfileGroup(in); + } + + @Override + public ProfileGroup[] newArray(int size) { + return new ProfileGroup[size]; + } + }; + + /** @hide */ + public ProfileGroup(UUID uuid, boolean defaultGroup) { + this(null, uuid, defaultGroup); + } + + private ProfileGroup(String name, UUID uuid, boolean defaultGroup) { + mName = name; + mUuid = (uuid != null) ? uuid : UUID.randomUUID(); + mDefaultGroup = defaultGroup; + mDirty = uuid == null; + } + + /** @hide */ + private ProfileGroup(Parcel in) { + readFromParcel(in); + } + + /** @hide */ + public boolean matches(NotificationGroup group, boolean defaultGroup) { + if (mUuid.equals(group.getUuid())) { + return true; + } + + /* fallback matches for backwards compatibility */ + boolean matches = false; + + /* fallback attempt 1: match name */ + if (mName != null && mName.equals(group.getName())) { + matches = true; + /* fallback attempt 2: match for the 'defaultGroup' flag to match the wildcard group */ + } else if (mDefaultGroup && defaultGroup) { + matches = true; + } + + if (!matches) { + return false; + } + + mName = null; + mUuid = group.getUuid(); + mDirty = true; + + return true; + } + + public UUID getUuid() { + return mUuid; + } + + public boolean isDefaultGroup() { + return mDefaultGroup; + } + + /** @hide */ + public boolean isDirty() { + return mDirty; + } + + /** @hide */ + public void setSoundOverride(Uri sound) { + mSoundOverride = sound; + mDirty = true; + } + + public Uri getSoundOverride() { + return mSoundOverride; + } + + /** @hide */ + public void setRingerOverride(Uri ringer) { + mRingerOverride = ringer; + mDirty = true; + } + + public Uri getRingerOverride() { + return mRingerOverride; + } + + /** @hide */ + public void setSoundMode(Mode soundMode) { + mSoundMode = soundMode; + mDirty = true; + } + + public Mode getSoundMode() { + return mSoundMode; + } + + /** @hide */ + public void setRingerMode(Mode ringerMode) { + mRingerMode = ringerMode; + mDirty = true; + } + + public Mode getRingerMode() { + return mRingerMode; + } + + /** @hide */ + public void setVibrateMode(Mode vibrateMode) { + mVibrateMode = vibrateMode; + mDirty = true; + } + + public Mode getVibrateMode() { + return mVibrateMode; + } + + /** @hide */ + public void setLightsMode(Mode lightsMode) { + mLightsMode = lightsMode; + mDirty = true; + } + + public Mode getLightsMode() { + return mLightsMode; + } + + // TODO : add support for LEDs / screen etc. + + /** @hide */ + public void applyOverridesToNotification(Notification notification) { + switch (mSoundMode) { + case OVERRIDE: + notification.sound = mSoundOverride; + break; + case SUPPRESS: + notification.defaults &= ~Notification.DEFAULT_SOUND; + notification.sound = null; + break; + case DEFAULT: + break; + } + switch (mVibrateMode) { + case OVERRIDE: + notification.defaults |= Notification.DEFAULT_VIBRATE; + break; + case SUPPRESS: + notification.defaults &= ~Notification.DEFAULT_VIBRATE; + notification.vibrate = null; + break; + case DEFAULT: + break; + } + switch (mLightsMode) { + case OVERRIDE: + notification.defaults |= Notification.DEFAULT_LIGHTS; + break; + case SUPPRESS: + notification.defaults &= ~Notification.DEFAULT_LIGHTS; + notification.flags &= ~Notification.FLAG_SHOW_LIGHTS; + break; + case DEFAULT: + break; + } + } + + private boolean validateOverrideUri(Context context, Uri uri) { + if (RingtoneManager.isDefault(uri)) { + return true; + } + Cursor cursor = context.getContentResolver().query(uri, null, null, null, null); + boolean valid = false; + + if (cursor != null) { + valid = cursor.moveToFirst(); + cursor.close(); + } + return valid; + } + + void validateOverrideUris(Context context) { + if (!validateOverrideUri(context, mSoundOverride)) { + mSoundOverride = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + mSoundMode = Mode.DEFAULT; + mDirty = true; + } + if (!validateOverrideUri(context, mRingerOverride)) { + mRingerOverride = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); + mRingerMode = Mode.DEFAULT; + mDirty = true; + } + } + + /** @hide */ + @Override + public int describeContents() { + return 0; + } + + /** @hide */ + @Override + public void writeToParcel(Parcel dest, int flags) { + // Tell the concierge to prepare the parcel + ParcelInfo parcelInfo = Concierge.prepareParcel(dest); + + // === BOYSENBERRY === + dest.writeString(mName); + new ParcelUuid(mUuid).writeToParcel(dest, 0); + dest.writeInt(mDefaultGroup ? 1 : 0); + dest.writeInt(mDirty ? 1 : 0); + dest.writeParcelable(mSoundOverride, flags); + dest.writeParcelable(mRingerOverride, flags); + dest.writeString(mSoundMode.name()); + dest.writeString(mRingerMode.name()); + dest.writeString(mVibrateMode.name()); + dest.writeString(mLightsMode.name()); + + // Complete the parcel info for the concierge + parcelInfo.complete(); + } + + /** @hide */ + public void readFromParcel(Parcel in) { + // Read parcelable version via the Concierge + ParcelInfo parcelInfo = Concierge.receiveParcel(in); + int parcelableVersion = parcelInfo.getParcelVersion(); + + // Pattern here is that all new members should be added to the end of + // the writeToParcel method. Then we step through each version, until the latest + // API release to help unravel this parcel + if (parcelableVersion >= Build.CM_VERSION_CODES.BOYSENBERRY) { + mName = in.readString(); + mUuid = ParcelUuid.CREATOR.createFromParcel(in).getUuid(); + mDefaultGroup = in.readInt() != 0; + mDirty = in.readInt() != 0; + mSoundOverride = in.readParcelable(null); + mRingerOverride = in.readParcelable(null); + + mSoundMode = Mode.valueOf(Mode.class, in.readString()); + mRingerMode = Mode.valueOf(Mode.class, in.readString()); + mVibrateMode = Mode.valueOf(Mode.class, in.readString()); + mLightsMode = Mode.valueOf(Mode.class, in.readString()); + } + + // Complete parcel info for the concierge + parcelInfo.complete(); + } + + public enum Mode { + SUPPRESS, DEFAULT, OVERRIDE; + } + + /** @hide */ + public void getXmlString(StringBuilder builder, Context context) { + builder.append("<profileGroup uuid=\""); + builder.append(TextUtils.htmlEncode(mUuid.toString())); + if (mName != null) { + builder.append("\" name=\""); + builder.append(mName); + } + builder.append("\" default=\""); + builder.append(isDefaultGroup()); + builder.append("\">\n<sound>"); + builder.append(TextUtils.htmlEncode(mSoundOverride.toString())); + builder.append("</sound>\n<ringer>"); + builder.append(TextUtils.htmlEncode(mRingerOverride.toString())); + builder.append("</ringer>\n<soundMode>"); + builder.append(mSoundMode); + builder.append("</soundMode>\n<ringerMode>"); + builder.append(mRingerMode); + builder.append("</ringerMode>\n<vibrateMode>"); + builder.append(mVibrateMode); + builder.append("</vibrateMode>\n<lightsMode>"); + builder.append(mLightsMode); + builder.append("</lightsMode>\n</profileGroup>\n"); + mDirty = false; + } + + /** @hide */ + public static ProfileGroup fromXml(XmlPullParser xpp, Context context) + throws XmlPullParserException, IOException { + String name = xpp.getAttributeValue(null, "name"); + UUID uuid = null; + String value = xpp.getAttributeValue(null, "uuid"); + + if (value != null) { + try { + uuid = UUID.fromString(value); + } catch (IllegalArgumentException e) { + Log.w(TAG, "UUID not recognized for " + name + ", using new one."); + } + } + + value = xpp.getAttributeValue(null, "default"); + boolean defaultGroup = TextUtils.equals(value, "true"); + + ProfileGroup profileGroup = new ProfileGroup(name, uuid, defaultGroup); + int event = xpp.next(); + while (event != XmlPullParser.END_TAG || !xpp.getName().equals("profileGroup")) { + if (event == XmlPullParser.START_TAG) { + name = xpp.getName(); + if (name.equals("sound")) { + profileGroup.setSoundOverride(Uri.parse(xpp.nextText())); + } else if (name.equals("ringer")) { + profileGroup.setRingerOverride(Uri.parse(xpp.nextText())); + } else if (name.equals("soundMode")) { + profileGroup.setSoundMode(Mode.valueOf(xpp.nextText())); + } else if (name.equals("ringerMode")) { + profileGroup.setRingerMode(Mode.valueOf(xpp.nextText())); + } else if (name.equals("vibrateMode")) { + profileGroup.setVibrateMode(Mode.valueOf(xpp.nextText())); + } else if (name.equals("lightsMode")) { + profileGroup.setLightsMode(Mode.valueOf(xpp.nextText())); + } + } else if (event == XmlPullParser.END_DOCUMENT) { + throw new IOException("Premature end of file while parsing profleGroup:" + name); + } + event = xpp.next(); + } + + /* we just loaded from XML, no need to save */ + profileGroup.mDirty = false; + + return profileGroup; + } +} |