/* * Copyright (C) 2011 The Android Open Source 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 android.app; import android.content.Context; import android.media.AudioManager; import android.os.Parcel; import android.os.ParcelUuid; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @hide */ public final class Profile implements Parcelable, Comparable { private String mName; private int mNameResId; private UUID mUuid; private Map profileGroups = new HashMap(); private ProfileGroup mDefaultGroup; private boolean mStatusBarIndicator = false; private boolean mDirty; private static final String TAG = "Profile"; private int mProfileType; private static final int CONDITIONAL_TYPE = 1; private static final int TOGGLE_TYPE = 0; private Map streams = new HashMap(); private Map connections = new HashMap(); private int mScreenLockMode = LockMode.DEFAULT; /** @hide */ public static class LockMode { public static final int DEFAULT = 0; public static final int INSECURE = 1; public static final int DISABLE = 2; } /** @hide */ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public Profile createFromParcel(Parcel in) { return new Profile(in); } @Override public Profile[] newArray(int size) { return new Profile[size]; } }; /** @hide */ public Profile(String name) { this(name, -1, UUID.randomUUID()); } private Profile(String name, int nameResId, UUID uuid) { mName = name; mNameResId = nameResId; mUuid = uuid; mProfileType = TOGGLE_TYPE; //Default to toggle type mDirty = false; } private Profile(Parcel in) { readFromParcel(in); } public int compareTo(Object obj) { Profile tmp = (Profile) obj; if (mName.compareTo(tmp.mName) < 0) { return -1; } else if (mName.compareTo(tmp.mName) > 0) { return 1; } return 0; } /** @hide */ public void addProfileGroup(ProfileGroup value) { if (value.isDefaultGroup()) { /* we must not have more than one default group */ if (mDefaultGroup != null) { return; } mDefaultGroup = value; } profileGroups.put(value.getUuid(), value); mDirty = true; } /** @hide */ public void removeProfileGroup(UUID uuid) { if (!profileGroups.get(uuid).isDefaultGroup()) { profileGroups.remove(uuid); } else { Log.e(TAG, "Cannot remove default group: " + uuid); } } public ProfileGroup[] getProfileGroups() { return profileGroups.values().toArray(new ProfileGroup[profileGroups.size()]); } public ProfileGroup getProfileGroup(UUID uuid) { return profileGroups.get(uuid); } public ProfileGroup getDefaultGroup() { return mDefaultGroup; } /** @hide */ @Override public int describeContents() { return 0; } /** @hide */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mName); dest.writeInt(mNameResId); new ParcelUuid(mUuid).writeToParcel(dest, 0); dest.writeInt(mStatusBarIndicator ? 1 : 0); dest.writeInt(mProfileType); dest.writeInt(mDirty ? 1 : 0); dest.writeParcelableArray( profileGroups.values().toArray(new Parcelable[profileGroups.size()]), flags); dest.writeParcelableArray( streams.values().toArray(new Parcelable[streams.size()]), flags); dest.writeParcelableArray( connections.values().toArray(new Parcelable[connections.size()]), flags); dest.writeInt(mScreenLockMode); } /** @hide */ public void readFromParcel(Parcel in) { mName = in.readString(); mNameResId = in.readInt(); mUuid = ParcelUuid.CREATOR.createFromParcel(in).getUuid(); mStatusBarIndicator = (in.readInt() == 1); mProfileType = in.readInt(); mDirty = (in.readInt() == 1); for (Parcelable group : in.readParcelableArray(null)) { ProfileGroup grp = (ProfileGroup) group; profileGroups.put(grp.getUuid(), grp); if (grp.isDefaultGroup()) { mDefaultGroup = grp; } } for (Parcelable parcel : in.readParcelableArray(null)) { StreamSettings stream = (StreamSettings) parcel; streams.put(stream.getStreamId(), stream); } for (Parcelable parcel : in.readParcelableArray(null)) { ConnectionSettings connection = (ConnectionSettings) parcel; connections.put(connection.getConnectionId(), connection); } mScreenLockMode = in.readInt(); } public String getName() { return mName; } /** @hide */ public void setName(String name) { mName = name; mNameResId = -1; mDirty = true; } public int getProfileType() { return mProfileType; } /** @hide */ public void setProfileType(int type) { mProfileType = type; mDirty = true; } public UUID getUuid() { if (this.mUuid == null) this.mUuid = UUID.randomUUID(); return this.mUuid; } public boolean getStatusBarIndicator() { return mStatusBarIndicator; } public void setStatusBarIndicator(boolean newStatusBarIndicator) { mStatusBarIndicator = newStatusBarIndicator; mDirty = true; } public boolean isConditionalType() { return(mProfileType == CONDITIONAL_TYPE ? true : false); } public void setConditionalType() { mProfileType = CONDITIONAL_TYPE; mDirty = true; } public int getScreenLockMode() { return mScreenLockMode; } public void setScreenLockMode(int screenLockMode) { if (screenLockMode < LockMode.DEFAULT || screenLockMode > LockMode.DISABLE) { mScreenLockMode = LockMode.DEFAULT; } else { mScreenLockMode = screenLockMode; } mDirty = true; } /** @hide */ public boolean isDirty() { if (mDirty) { return true; } for (ProfileGroup group : profileGroups.values()) { if (group.isDirty()) { return true; } } for (StreamSettings stream : streams.values()) { if (stream.isDirty()) { return true; } } for (ConnectionSettings conn : connections.values()) { if (conn.isDirty()) { return true; } } return false; } /** @hide */ public void getXmlString(StringBuilder builder, Context context) { builder.append(" 0) { builder.append("nameres=\""); builder.append(context.getResources().getResourceEntryName(mNameResId)); } else { builder.append("name=\""); builder.append(TextUtils.htmlEncode(getName())); } builder.append("\" uuid=\""); builder.append(TextUtils.htmlEncode(getUuid().toString())); builder.append("\">\n"); builder.append(""); builder.append(getProfileType() == TOGGLE_TYPE ? "toggle" : "conditional"); builder.append("\n"); builder.append(""); builder.append(getStatusBarIndicator() ? "yes" : "no"); builder.append("\n"); builder.append(""); builder.append(mScreenLockMode); builder.append(""); for (ProfileGroup pGroup : profileGroups.values()) { pGroup.getXmlString(builder, context); } for (StreamSettings sd : streams.values()) { sd.getXmlString(builder, context); } for (ConnectionSettings cs : connections.values()) { cs.getXmlString(builder, context); } builder.append("\n"); mDirty = false; } /** @hide */ public static Profile fromXml(XmlPullParser xpp, Context context) throws XmlPullParserException, IOException { String value = xpp.getAttributeValue(null, "nameres"); int profileNameResId = -1; String profileName = null; if (value != null) { profileNameResId = context.getResources().getIdentifier(value, "string", "android"); if (profileNameResId > 0) { profileName = context.getResources().getString(profileNameResId); } } if (profileName == null) { profileName = xpp.getAttributeValue(null, "name"); } UUID profileUuid = UUID.randomUUID(); try { profileUuid = UUID.fromString(xpp.getAttributeValue(null, "uuid")); } catch (NullPointerException e) { Log.w(TAG, "Null Pointer - UUID not found for " + profileName + ". New UUID generated: " + profileUuid.toString() ); } catch (IllegalArgumentException e) { Log.w(TAG, "UUID not recognized for " + profileName + ". New UUID generated: " + profileUuid.toString() ); } Profile profile = new Profile(profileName, profileNameResId, profileUuid); int event = xpp.next(); while (event != XmlPullParser.END_TAG) { if (event == XmlPullParser.START_TAG) { String name = xpp.getName(); if (name.equals("statusbar")) { profile.setStatusBarIndicator(xpp.nextText().equals("yes")); } if (name.equals("profiletype")) { profile.setProfileType(xpp.nextText().equals("toggle") ? TOGGLE_TYPE : CONDITIONAL_TYPE); } if (name.equals("screen-lock-mode")) { profile.setScreenLockMode(Integer.valueOf(xpp.nextText())); } if (name.equals("profileGroup")) { ProfileGroup pg = ProfileGroup.fromXml(xpp, context); profile.addProfileGroup(pg); } if (name.equals("streamDescriptor")) { StreamSettings sd = StreamSettings.fromXml(xpp, context); profile.setStreamSettings(sd); } if (name.equals("connectionDescriptor")) { ConnectionSettings cs = ConnectionSettings.fromXml(xpp, context); profile.connections.put(cs.getConnectionId(), cs); } } event = xpp.next(); } /* we just loaded from XML, so nothing needs saving */ profile.mDirty = false; return profile; } /** @hide */ public void doSelect(Context context) { // Set stream volumes AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); for (StreamSettings sd : streams.values()) { if (sd.isOverride()) { am.setStreamVolume(sd.getStreamId(), sd.getValue(), 0); } } // Set connections for (ConnectionSettings cs : connections.values()) { if (cs.isOverride()) { cs.processOverride(context); } } } /** @hide */ public StreamSettings getSettingsForStream(int streamId){ return streams.get(streamId); } /** @hide */ public void setStreamSettings(StreamSettings descriptor){ streams.put(descriptor.getStreamId(), descriptor); mDirty = true; } /** @hide */ public Collection getStreamSettings(){ return streams.values(); } /** @hide */ public ConnectionSettings getSettingsForConnection(int connectionId){ return connections.get(connectionId); } /** @hide */ public void setConnectionSettings(ConnectionSettings descriptor){ connections.put(descriptor.getConnectionId(), descriptor); } /** @hide */ public Collection getConnectionSettings(){ return connections.values(); } }