summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rwxr-xr-xcore/java/android/app/ConnectionSettings.java216
-rw-r--r--core/java/android/app/ContextImpl.java6
-rw-r--r--core/java/android/app/IProfileManager.aidl50
-rw-r--r--core/java/android/app/Notification.java9
-rw-r--r--core/java/android/app/NotificationGroup.aidl19
-rw-r--r--core/java/android/app/NotificationGroup.java201
-rw-r--r--core/java/android/app/Profile.aidl19
-rw-r--r--core/java/android/app/Profile.java595
-rw-r--r--core/java/android/app/ProfileGroup.java348
-rw-r--r--core/java/android/app/ProfileManager.java260
-rw-r--r--core/java/android/app/StreamSettings.java130
-rw-r--r--core/java/android/app/VibratorSettings.java150
-rw-r--r--core/java/android/content/Context.java12
-rw-r--r--core/java/android/net/wimax/WimaxHelper.java188
-rw-r--r--core/java/android/net/wimax/WimaxManagerConstants.java15
-rw-r--r--core/java/android/preference/ListPreferenceMultiSelect.java112
-rw-r--r--core/java/android/preference/VolumePreference.java17
-rw-r--r--core/java/android/provider/Settings.java700
-rw-r--r--core/java/android/view/VolumePanel.java147
-rw-r--r--core/java/android/view/WindowManagerPolicy.java1
20 files changed, 3174 insertions, 21 deletions
diff --git a/core/java/android/app/ConnectionSettings.java b/core/java/android/app/ConnectionSettings.java
new file mode 100755
index 0000000..00af439
--- /dev/null
+++ b/core/java/android/app/ConnectionSettings.java
@@ -0,0 +1,216 @@
+package android.app;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.location.LocationManager;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.net.wimax.WimaxHelper;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.Settings;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/** @hide */
+public final class ConnectionSettings implements Parcelable {
+
+ private int mConnectionId;
+ private int mValue;
+ private boolean mOverride;
+ private boolean mDirty;
+
+ public static final int PROFILE_CONNECTION_MOBILEDATA = 0;
+ public static final int PROFILE_CONNECTION_WIFI = 1;
+ public static final int PROFILE_CONNECTION_WIFIAP = 2;
+ public static final int PROFILE_CONNECTION_WIMAX = 3;
+ public static final int PROFILE_CONNECTION_GPS = 4;
+ public static final int PROFILE_CONNECTION_SYNC = 5;
+ public static final int PROFILE_CONNECTION_BLUETOOTH = 7;
+
+ /** @hide */
+ public static final Parcelable.Creator<ConnectionSettings> CREATOR = new Parcelable.Creator<ConnectionSettings>() {
+ public ConnectionSettings createFromParcel(Parcel in) {
+ return new ConnectionSettings(in);
+ }
+
+ @Override
+ public ConnectionSettings[] newArray(int size) {
+ return new ConnectionSettings[size];
+ }
+ };
+
+
+ public ConnectionSettings(Parcel parcel) {
+ readFromParcel(parcel);
+ }
+
+ public ConnectionSettings(int connectionId) {
+ this(connectionId, 0, false);
+ }
+
+ public ConnectionSettings(int connectionId, int value, boolean override) {
+ mConnectionId = connectionId;
+ mValue = value;
+ mOverride = override;
+ mDirty = false;
+ }
+
+ public int getConnectionId() {
+ return mConnectionId;
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+
+ public void setValue(int value) {
+ mValue = value;
+ mDirty = true;
+ }
+
+ public void setOverride(boolean override) {
+ mOverride = override;
+ mDirty = true;
+ }
+
+ public boolean isOverride() {
+ return mOverride;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ public void processOverride(Context context) {
+ BluetoothAdapter bta = BluetoothAdapter.getDefaultAdapter();
+ LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ boolean forcedState = getValue() == 1;
+ boolean currentState;
+
+ switch (getConnectionId()) {
+ case PROFILE_CONNECTION_MOBILEDATA:
+ currentState = cm.getMobileDataEnabled();
+ if (forcedState != currentState) {
+ cm.setMobileDataEnabled(forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_BLUETOOTH:
+ currentState = bta.isEnabled();
+ if (forcedState && !currentState) {
+ bta.enable();
+ } else if (!forcedState && currentState) {
+ bta.disable();
+ }
+ break;
+ case PROFILE_CONNECTION_GPS:
+ currentState = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
+ if (currentState != forcedState) {
+ Settings.Secure.setLocationProviderEnabled(context.getContentResolver(),
+ LocationManager.GPS_PROVIDER, forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_SYNC:
+ currentState = ContentResolver.getMasterSyncAutomatically();
+ if (forcedState != currentState) {
+ ContentResolver.setMasterSyncAutomatically(forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_WIFI:
+ int wifiApState = wm.getWifiApState();
+ currentState = wm.isWifiEnabled();
+ if (currentState != forcedState) {
+ // Disable wifi tether
+ if (forcedState && (wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
+ (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED)) {
+ wm.setWifiApEnabled(null, false);
+ }
+ wm.setWifiEnabled(forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_WIFIAP:
+ int wifiState = wm.getWifiState();
+ currentState = wm.isWifiApEnabled();
+ if (currentState != forcedState) {
+ // Disable wifi
+ if (forcedState && (wifiState == WifiManager.WIFI_STATE_ENABLING) || (wifiState == WifiManager.WIFI_STATE_ENABLED)) {
+ wm.setWifiEnabled(false);
+ }
+ wm.setWifiApEnabled(null, forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_WIMAX:
+ if (WimaxHelper.isWimaxSupported(context)) {
+ currentState = WimaxHelper.isWimaxEnabled(context);
+ if (currentState != forcedState) {
+ WimaxHelper.setWimaxEnabled(context, forcedState);
+ }
+ }
+ break;
+ }
+ }
+
+ /** @hide */
+ public static ConnectionSettings fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ int event = xpp.next();
+ ConnectionSettings connectionDescriptor = new ConnectionSettings(0);
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("connectionDescriptor")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("connectionId")) {
+ connectionDescriptor.mConnectionId = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("value")) {
+ connectionDescriptor.mValue = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("override")) {
+ connectionDescriptor.mOverride = Boolean.parseBoolean(xpp.nextText());
+ }
+ }
+ event = xpp.next();
+ }
+ return connectionDescriptor;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<connectionDescriptor>\n<connectionId>");
+ builder.append(mConnectionId);
+ builder.append("</connectionId>\n<value>");
+ builder.append(mValue);
+ builder.append("</value>\n<override>");
+ builder.append(mOverride);
+ builder.append("</override>\n</connectionDescriptor>\n");
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mConnectionId);
+ dest.writeInt(mOverride ? 1 : 0);
+ dest.writeInt(mValue);
+ dest.writeInt(mDirty ? 1 : 0);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mConnectionId = in.readInt();
+ mOverride = in.readInt() != 0;
+ mValue = in.readInt();
+ mDirty = in.readInt() != 0;
+ }
+
+
+}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 95b6bed..20ed560 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -535,6 +535,12 @@ class ContextImpl extends Context {
IUserManager service = IUserManager.Stub.asInterface(b);
return new UserManager(ctx, service);
}});
+
+ registerService(PROFILE_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ final Context outerContext = ctx.getOuterContext();
+ return new ProfileManager (outerContext, ctx.mMainThread.getHandler());
+ }});
}
static ContextImpl getImpl(Context context) {
diff --git a/core/java/android/app/IProfileManager.aidl b/core/java/android/app/IProfileManager.aidl
new file mode 100644
index 0000000..c7c6744
--- /dev/null
+++ b/core/java/android/app/IProfileManager.aidl
@@ -0,0 +1,50 @@
+/* //device/java/android/android/app/IProfileManager.aidl
+**
+** Copyright 2007, 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.app.Profile;
+import android.app.NotificationGroup;
+import android.os.ParcelUuid;
+
+/** {@hide} */
+interface IProfileManager
+{
+ boolean setActiveProfile(in ParcelUuid profileParcelUuid);
+ boolean setActiveProfileByName(String profileName);
+ Profile getActiveProfile();
+
+ boolean addProfile(in Profile profile);
+ boolean removeProfile(in Profile profile);
+ void updateProfile(in Profile profile);
+
+ Profile getProfile(in ParcelUuid profileParcelUuid);
+ Profile getProfileByName(String profileName);
+ Profile[] getProfiles();
+ boolean profileExists(in ParcelUuid profileUuid);
+ boolean profileExistsByName(String profileName);
+ boolean notificationGroupExistsByName(String notificationGroupName);
+
+ NotificationGroup[] getNotificationGroups();
+ void addNotificationGroup(in NotificationGroup group);
+ void removeNotificationGroup(in NotificationGroup group);
+ void updateNotificationGroup(in NotificationGroup group);
+ NotificationGroup getNotificationGroupForPackage(in String pkg);
+ NotificationGroup getNotificationGroup(in ParcelUuid groupParcelUuid);
+
+ void resetAll();
+}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e79b214..238a63e 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -437,6 +437,15 @@ public class Notification implements Parcelable
*/
public static final String EXTRA_PEOPLE = "android.people";
+ /**
+ * Bit to be bitwise-ored into the {@link #flags} field that should be
+ * set if this notification should force the led to pulse even if the
+ * screen has been shut off while the notification was active.
+ *
+ * @hide
+ */
+ public static final int FLAG_FORCE_LED_SCREEN_OFF = 0x00000100;
+
private Bundle extras;
/**
diff --git a/core/java/android/app/NotificationGroup.aidl b/core/java/android/app/NotificationGroup.aidl
new file mode 100644
index 0000000..44b6290
--- /dev/null
+++ b/core/java/android/app/NotificationGroup.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2012, 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 android.app;
+
+parcelable NotificationGroup;
diff --git a/core/java/android/app/NotificationGroup.java b/core/java/android/app/NotificationGroup.java
new file mode 100644
index 0000000..bcb70d3
--- /dev/null
+++ b/core/java/android/app/NotificationGroup.java
@@ -0,0 +1,201 @@
+/*
+ * 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 org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+/** @hide */
+public class NotificationGroup implements Parcelable {
+ private static final String TAG = "NotificationGroup";
+
+ private String mName;
+ private int mNameResId;
+
+ private UUID mUuid;
+
+ private Set<String> mPackages = new HashSet<String>();
+
+ private boolean mDirty;
+
+ public static final Parcelable.Creator<NotificationGroup> CREATOR = new Parcelable.Creator<NotificationGroup>() {
+ public NotificationGroup createFromParcel(Parcel in) {
+ return new NotificationGroup(in);
+ }
+
+ @Override
+ public NotificationGroup[] newArray(int size) {
+ return new NotificationGroup[size];
+ }
+ };
+
+ public NotificationGroup(String name) {
+ this(name, -1, null);
+ }
+
+ public NotificationGroup(String name, int nameResId, UUID uuid) {
+ mName = name;
+ mNameResId = nameResId;
+ mUuid = (uuid != null) ? uuid : UUID.randomUUID();
+ mDirty = uuid == null;
+ }
+
+ private NotificationGroup(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ mNameResId = -1;
+ mDirty = true;
+ }
+
+ public UUID getUuid() {
+ return mUuid;
+ }
+
+ public void addPackage(String pkg) {
+ mPackages.add(pkg);
+ mDirty = true;
+ }
+
+ public String[] getPackages() {
+ return mPackages.toArray(new String[mPackages.size()]);
+ }
+
+ public void removePackage(String pkg) {
+ mPackages.remove(pkg);
+ mDirty = true;
+ }
+
+ public boolean hasPackage(String pkg) {
+ return mPackages.contains(pkg);
+ }
+
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mName);
+ dest.writeInt(mNameResId);
+ dest.writeInt(mDirty ? 1 : 0);
+ new ParcelUuid(mUuid).writeToParcel(dest, 0);
+ dest.writeStringArray(getPackages());
+ }
+
+ public void readFromParcel(Parcel in) {
+ mName = in.readString();
+ mNameResId = in.readInt();
+ mDirty = in.readInt() != 0;
+ mUuid = ParcelUuid.CREATOR.createFromParcel(in).getUuid();
+ mPackages.addAll(Arrays.asList(in.readStringArray()));
+ }
+
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<notificationGroup ");
+ if (mNameResId > 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");
+ for (String pkg : mPackages) {
+ builder.append("<package>" + TextUtils.htmlEncode(pkg) + "</package>\n");
+ }
+ builder.append("</notificationGroup>\n");
+ mDirty = false;
+ }
+
+ public static NotificationGroup fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ String value = xpp.getAttributeValue(null, "nameres");
+ int nameResId = -1;
+ String name = null;
+ UUID uuid = null;
+
+ if (value != null) {
+ nameResId = context.getResources().getIdentifier(value, "string", "android");
+ if (nameResId > 0) {
+ name = context.getResources().getString(nameResId);
+ }
+ }
+
+ if (name == null) {
+ name = xpp.getAttributeValue(null, "name");
+ }
+
+ 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.");
+ }
+ }
+
+ NotificationGroup notificationGroup = new NotificationGroup(name, nameResId, uuid);
+ int event = xpp.next();
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("notificationGroup")) {
+ if (event == XmlPullParser.START_TAG) {
+ if (xpp.getName().equals("package")) {
+ String pkg = xpp.nextText();
+ notificationGroup.addPackage(pkg);
+ }
+ }
+ event = xpp.next();
+ }
+
+ /* we just loaded from XML, no need to save */
+ notificationGroup.mDirty = false;
+
+ return notificationGroup;
+ }
+}
diff --git a/core/java/android/app/Profile.aidl b/core/java/android/app/Profile.aidl
new file mode 100644
index 0000000..d75bd76
--- /dev/null
+++ b/core/java/android/app/Profile.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2007, 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;
+
+parcelable Profile;
diff --git a/core/java/android/app/Profile.java b/core/java/android/app/Profile.java
new file mode 100644
index 0000000..54e187d
--- /dev/null
+++ b/core/java/android/app/Profile.java
@@ -0,0 +1,595 @@
+/*
+ * 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.content.Intent;
+import android.media.AudioManager;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import android.provider.Settings;
+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.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+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 ArrayList<UUID> mSecondaryUuids = new ArrayList<UUID>();
+
+ private Map<UUID, ProfileGroup> profileGroups = new HashMap<UUID, ProfileGroup>();
+
+ 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<Integer, StreamSettings> streams = new HashMap<Integer, StreamSettings>();
+
+ private Map<Integer, ConnectionSettings> connections = new HashMap<Integer, ConnectionSettings>();
+
+ private Map<Integer, VibratorSettings> vibrators = new HashMap<Integer, VibratorSettings>();
+
+ private int mScreenLockMode = LockMode.DEFAULT;
+
+ private int mAirplaneMode = AirplaneMode.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 class AirplaneMode {
+ public static final int DEFAULT = 0;
+ public static final int ENABLE = 1;
+ public static final int DISABLE = 2;
+ }
+
+ /** @hide */
+ public static final Parcelable.Creator<Profile> CREATOR = new Parcelable.Creator<Profile>() {
+ 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);
+ ArrayList<ParcelUuid> uuids = new ArrayList<ParcelUuid>(mSecondaryUuids.size());
+ for (UUID u : mSecondaryUuids) {
+ uuids.add(new ParcelUuid(u));
+ }
+ dest.writeParcelableArray(uuids.toArray(new Parcelable[uuids.size()]), flags);
+ 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.writeParcelableArray(vibrators.values().toArray(new Parcelable[vibrators.size()]), flags);
+ dest.writeInt(mScreenLockMode);
+ dest.writeInt(mAirplaneMode);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mName = in.readString();
+ mNameResId = in.readInt();
+ mUuid = ParcelUuid.CREATOR.createFromParcel(in).getUuid();
+ for (Parcelable parcel : in.readParcelableArray(null)) {
+ ParcelUuid u = (ParcelUuid) parcel;
+ mSecondaryUuids.add(u.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);
+ }
+ for (Parcelable parcel : in.readParcelableArray(null)) {
+ VibratorSettings vibrator = (VibratorSettings) parcel;
+ vibrators.put(vibrator.getVibratorId(), vibrator);
+ }
+ mScreenLockMode = in.readInt();
+ mAirplaneMode = 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 UUID[] getSecondaryUuids() {
+ return mSecondaryUuids.toArray(new UUID[mSecondaryUuids.size()]);
+ }
+
+ public void setSecondaryUuids(List<UUID> uuids) {
+ mSecondaryUuids.clear();
+ if (uuids != null) {
+ mSecondaryUuids.addAll(uuids);
+ mDirty = true;
+ }
+ }
+
+ public void addSecondaryUuid(UUID uuid) {
+ if (uuid != null) {
+ mSecondaryUuids.add(uuid);
+ mDirty = true;
+ }
+ }
+
+ 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;
+ }
+
+ public int getAirplaneMode() {
+ return mAirplaneMode;
+ }
+
+ public void setAirplaneMode(int airplaneMode) {
+ if (airplaneMode < AirplaneMode.DEFAULT || airplaneMode > AirplaneMode.DISABLE) {
+ mAirplaneMode = AirplaneMode.DEFAULT;
+ } else {
+ mAirplaneMode = airplaneMode;
+ }
+ 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;
+ }
+ }
+ for (VibratorSettings vibrator : vibrators.values()) {
+ if (vibrator.isDirty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<profile ");
+ if (mNameResId > 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("<uuids>");
+ for (UUID u : mSecondaryUuids) {
+ builder.append("<uuid>");
+ builder.append(TextUtils.htmlEncode(u.toString()));
+ builder.append("</uuid>");
+ }
+ builder.append("</uuids>\n");
+
+ builder.append("<profiletype>");
+ builder.append(getProfileType() == TOGGLE_TYPE ? "toggle" : "conditional");
+ builder.append("</profiletype>\n");
+
+ builder.append("<statusbar>");
+ builder.append(getStatusBarIndicator() ? "yes" : "no");
+ builder.append("</statusbar>\n");
+
+ builder.append("<screen-lock-mode>");
+ builder.append(mScreenLockMode);
+ builder.append("</screen-lock-mode>\n");
+
+ builder.append("<airplane-mode>");
+ builder.append(mAirplaneMode);
+ builder.append("</airplane-mode>\n");
+
+ 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);
+ }
+ for (VibratorSettings vs : vibrators.values()) {
+ vs.getXmlString(builder, context);
+ }
+ builder.append("</profile>\n");
+ mDirty = false;
+ }
+
+ private static List<UUID> readSecondaryUuidsFromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException,
+ IOException {
+ ArrayList<UUID> uuids = new ArrayList<UUID>();
+ int event = xpp.next();
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("uuids")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("uuid")) {
+ try {
+ uuids.add(UUID.fromString(xpp.nextText()));
+ } catch (NullPointerException e) {
+ Log.w(TAG, "Null Pointer - invalid UUID");
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "UUID not recognized");
+ }
+ }
+ }
+ event = xpp.next();
+ }
+ return uuids;
+ }
+
+ /** @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("uuids")) {
+ profile.setSecondaryUuids(readSecondaryUuidsFromXml(xpp, context));
+ }
+ 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("airplane-mode")) {
+ profile.setAirplaneMode(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);
+ }
+ if (name.equals("vibratorDescriptor")) {
+ VibratorSettings vs = VibratorSettings.fromXml(xpp, context);
+ profile.setVibratorSettings(vs);
+ }
+ }
+ 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);
+ }
+ }
+ // Set vibrators
+ for (VibratorSettings vs : vibrators.values()) {
+ if (vs.isOverride()) {
+ vs.processOverride(context);
+ }
+ }
+ // Set airplane mode
+ doSelectAirplaneMode(context);
+ }
+
+ private void doSelectAirplaneMode(Context context) {
+ if (getAirplaneMode() != AirplaneMode.DEFAULT) {
+ int current = Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0);
+ int target = getAirplaneMode();
+ if (current == 1 && target == AirplaneMode.DISABLE || current == 0 && target == AirplaneMode.ENABLE) {
+ Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 1 - current);
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", target != AirplaneMode.DISABLE);
+ context.sendBroadcast(intent);
+ }
+ }
+ }
+
+ /** @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<StreamSettings> getStreamSettings(){
+ return streams.values();
+ }
+
+ /** @hide */
+ public VibratorSettings getSettingsForVibrator(int vibratorId) {
+ return vibrators.get(vibratorId);
+ }
+
+ /** @hide */
+ public void setVibratorSettings(VibratorSettings descriptor) {
+ vibrators.put(descriptor.getVibratorId(), descriptor);
+ mDirty = true;
+ }
+
+ /** @hide */
+ public Collection<VibratorSettings> getVibratorSettings() {
+ return vibrators.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<ConnectionSettings> getConnectionSettings(){
+ return connections.values();
+ }
+
+}
diff --git a/core/java/android/app/ProfileGroup.java b/core/java/android/app/ProfileGroup.java
new file mode 100644
index 0000000..b3b70d6
--- /dev/null
+++ b/core/java/android/app/ProfileGroup.java
@@ -0,0 +1,348 @@
+/*
+ * 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 org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+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 java.io.IOException;
+import java.util.UUID;
+
+/**
+ * @hide
+ */
+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 Notification processNotification(Notification notification) {
+
+ switch (mSoundMode) {
+ case OVERRIDE:
+ notification.sound = mSoundOverride;
+ break;
+ case SUPPRESS:
+ silenceNotification(notification);
+ break;
+ case DEFAULT:
+ }
+ switch (mVibrateMode) {
+ case OVERRIDE:
+ notification.defaults |= Notification.DEFAULT_VIBRATE;
+ break;
+ case SUPPRESS:
+ suppressVibrate(notification);
+ break;
+ case DEFAULT:
+ }
+ switch (mLightsMode) {
+ case OVERRIDE:
+ notification.defaults |= Notification.DEFAULT_LIGHTS;
+ break;
+ case SUPPRESS:
+ suppressLights(notification);
+ break;
+ case DEFAULT:
+ }
+ return notification;
+ }
+
+ private void silenceNotification(Notification notification) {
+ notification.defaults &= (~Notification.DEFAULT_SOUND);
+ notification.sound = null;
+ }
+
+ private void suppressVibrate(Notification notification) {
+ notification.defaults &= (~Notification.DEFAULT_VIBRATE);
+ notification.vibrate = null;
+ }
+
+ private void suppressLights(Notification notification) {
+ notification.defaults &= (~Notification.DEFAULT_LIGHTS);
+ notification.flags &= (~Notification.FLAG_SHOW_LIGHTS);
+ }
+
+ /** @hide */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ 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());
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ 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());
+ }
+
+ 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()));
+ }
+ }
+ event = xpp.next();
+ }
+
+ /* we just loaded from XML, no need to save */
+ profileGroup.mDirty = false;
+
+ return profileGroup;
+ }
+}
diff --git a/core/java/android/app/ProfileManager.java b/core/java/android/app/ProfileManager.java
new file mode 100644
index 0000000..4a0f1b7
--- /dev/null
+++ b/core/java/android/app/ProfileManager.java
@@ -0,0 +1,260 @@
+/*
+ * 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 java.util.UUID;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class ProfileManager {
+
+ private static IProfileManager sService;
+
+ private Context mContext;
+
+ private static final String TAG = "ProfileManager";
+
+ /** @hide */
+ static public IProfileManager getService() {
+ if (sService != null) {
+ return sService;
+ }
+ IBinder b = ServiceManager.getService(Context.PROFILE_SERVICE);
+ sService = IProfileManager.Stub.asInterface(b);
+ return sService;
+ }
+
+ /** @hide */
+ ProfileManager(Context context, Handler handler) {
+ mContext = context;
+ }
+
+ @Deprecated
+ public void setActiveProfile(String profileName) {
+ try {
+ getService().setActiveProfileByName(profileName);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ public void setActiveProfile(UUID profileUuid) {
+ try {
+ getService().setActiveProfile(new ParcelUuid(profileUuid));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ public Profile getActiveProfile() {
+ try {
+ return getService().getActiveProfile();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ /** @hide */
+ public void addProfile(Profile profile) {
+ try {
+ getService().addProfile(profile);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public void removeProfile(Profile profile) {
+ try {
+ getService().removeProfile(profile);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public void updateProfile(Profile profile) {
+ try {
+ getService().updateProfile(profile);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ @Deprecated
+ public Profile getProfile(String profileName) {
+ try {
+ return getService().getProfileByName(profileName);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ public Profile getProfile(UUID profileUuid) {
+ try {
+ return getService().getProfile(new ParcelUuid(profileUuid));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ public String[] getProfileNames() {
+ try {
+ Profile[] profiles = getService().getProfiles();
+ String[] names = new String[profiles.length];
+ for (int i = 0; i < profiles.length; i++) {
+ names[i] = profiles[i].getName();
+ }
+ return names;
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ public Profile[] getProfiles() {
+ try {
+ return getService().getProfiles();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ public boolean profileExists(String profileName) {
+ try {
+ return getService().profileExistsByName(profileName);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ // To be on the safe side, we'll return "true", to prevent duplicate profiles
+ // from being created.
+ return true;
+ }
+ }
+
+ public boolean profileExists(UUID profileUuid) {
+ try {
+ return getService().profileExists(new ParcelUuid(profileUuid));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ // To be on the safe side, we'll return "true", to prevent duplicate profiles
+ // from being created.
+ return true;
+ }
+ }
+
+ public boolean notificationGroupExists(String notificationGroupName) {
+ try {
+ return getService().notificationGroupExistsByName(notificationGroupName);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ // To be on the safe side, we'll return "true", to prevent duplicate notification
+ // groups from being created.
+ return true;
+ }
+ }
+
+ /** @hide */
+ public NotificationGroup[] getNotificationGroups() {
+ try {
+ return getService().getNotificationGroups();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ /** @hide */
+ public void addNotificationGroup(NotificationGroup group) {
+ try {
+ getService().addNotificationGroup(group);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public void removeNotificationGroup(NotificationGroup group) {
+ try {
+ getService().removeNotificationGroup(group);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public void updateNotificationGroup(NotificationGroup group) {
+ try {
+ getService().updateNotificationGroup(group);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public NotificationGroup getNotificationGroupForPackage(String pkg) {
+ try {
+ return getService().getNotificationGroupForPackage(pkg);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ /** @hide */
+ public NotificationGroup getNotificationGroup(UUID uuid) {
+ try {
+ return getService().getNotificationGroup(new ParcelUuid(uuid));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ /** @hide */
+ public ProfileGroup getActiveProfileGroup(String packageName) {
+ NotificationGroup notificationGroup = getNotificationGroupForPackage(packageName);
+ if(notificationGroup == null){
+ ProfileGroup defaultGroup = getActiveProfile().getDefaultGroup();
+ return defaultGroup;
+ }
+ return getActiveProfile().getProfileGroup(notificationGroup.getUuid());
+ }
+
+ /** @hide */
+ public void resetAll() {
+ try {
+ getService().resetAll();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ } catch (SecurityException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+}
diff --git a/core/java/android/app/StreamSettings.java b/core/java/android/app/StreamSettings.java
new file mode 100644
index 0000000..2f3bf27
--- /dev/null
+++ b/core/java/android/app/StreamSettings.java
@@ -0,0 +1,130 @@
+
+package android.app;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.IOException;
+
+/** @hide */
+public final class StreamSettings implements Parcelable{
+
+ private int mStreamId;
+ private int mValue;
+ private boolean mOverride;
+ private boolean mDirty;
+
+ /** @hide */
+ public static final Parcelable.Creator<StreamSettings> CREATOR = new Parcelable.Creator<StreamSettings>() {
+ public StreamSettings createFromParcel(Parcel in) {
+ return new StreamSettings(in);
+ }
+
+ @Override
+ public StreamSettings[] newArray(int size) {
+ return new StreamSettings[size];
+ }
+ };
+
+
+ public StreamSettings(Parcel parcel) {
+ readFromParcel(parcel);
+ }
+
+ public StreamSettings(int streamId) {
+ this(streamId, 0, false);
+ }
+
+ public StreamSettings(int streamId, int value, boolean override) {
+ mStreamId = streamId;
+ mValue = value;
+ mOverride = override;
+ mDirty = false;
+ }
+
+ public int getStreamId() {
+ return mStreamId;
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+
+ public void setValue(int value) {
+ mValue = value;
+ mDirty = true;
+ }
+
+ public void setOverride(boolean override) {
+ mOverride = override;
+ mDirty = true;
+ }
+
+ public boolean isOverride() {
+ return mOverride;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ /** @hide */
+ public static StreamSettings fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ int event = xpp.next();
+ StreamSettings streamDescriptor = new StreamSettings(0);
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("streamDescriptor")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("streamId")) {
+ streamDescriptor.mStreamId = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("value")) {
+ streamDescriptor.mValue = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("override")) {
+ streamDescriptor.mOverride = Boolean.parseBoolean(xpp.nextText());
+ }
+ }
+ event = xpp.next();
+ }
+ return streamDescriptor;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<streamDescriptor>\n<streamId>");
+ builder.append(mStreamId);
+ builder.append("</streamId>\n<value>");
+ builder.append(mValue);
+ builder.append("</value>\n<override>");
+ builder.append(mOverride);
+ builder.append("</override>\n</streamDescriptor>\n");
+ mDirty = false;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mStreamId);
+ dest.writeInt(mOverride ? 1 : 0);
+ dest.writeInt(mValue);
+ dest.writeInt(mDirty ? 1 : 0);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mStreamId = in.readInt();
+ mOverride = in.readInt() != 0;
+ mValue = in.readInt();
+ mDirty = in.readInt() != 0;
+ }
+}
diff --git a/core/java/android/app/VibratorSettings.java b/core/java/android/app/VibratorSettings.java
new file mode 100644
index 0000000..10e5ca2
--- /dev/null
+++ b/core/java/android/app/VibratorSettings.java
@@ -0,0 +1,150 @@
+
+package android.app;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.IOException;
+
+/** @hide */
+public final class VibratorSettings implements Parcelable{
+
+ public static final int OFF = 0;
+ public static final int SILENT = 1;
+ public static final int ON = 2;
+
+ private int mVibratorId;
+ private int mValue;
+ private boolean mOverride;
+ private boolean mDirty;
+
+ /** @hide */
+ public static final Parcelable.Creator<VibratorSettings> CREATOR = new Parcelable.Creator<VibratorSettings>() {
+ public VibratorSettings createFromParcel(Parcel in) {
+ return new VibratorSettings(in);
+ }
+
+ @Override
+ public VibratorSettings[] newArray(int size) {
+ return new VibratorSettings[size];
+ }
+ };
+
+
+ public VibratorSettings(Parcel parcel) {
+ readFromParcel(parcel);
+ }
+
+ public VibratorSettings(int vibratorId) {
+ this(vibratorId, 0, false);
+ }
+
+ public VibratorSettings(int vibratorId, int value, boolean override) {
+ mVibratorId = vibratorId;
+ mValue = value;
+ mOverride = override;
+ mDirty = false;
+ }
+
+ public int getVibratorId() {
+ return mVibratorId;
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+
+ public void setValue(int value) {
+ mValue = value;
+ mDirty = true;
+ }
+
+ public void setOverride(boolean override) {
+ mOverride = override;
+ mDirty = true;
+ }
+
+ public boolean isOverride() {
+ return mOverride;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ /** @hide */
+ public static VibratorSettings fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ int event = xpp.next();
+ VibratorSettings vibratorDescriptor = new VibratorSettings(0);
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("vibratorDescriptor")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("vibratorId")) {
+ vibratorDescriptor.mVibratorId = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("value")) {
+ vibratorDescriptor.mValue = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("override")) {
+ vibratorDescriptor.mOverride = Boolean.parseBoolean(xpp.nextText());
+ }
+ }
+ event = xpp.next();
+ }
+ return vibratorDescriptor;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<vibratorDescriptor>\n<vibratorId>");
+ builder.append(mVibratorId);
+ builder.append("</vibratorId>\n<value>");
+ builder.append(mValue);
+ builder.append("</value>\n<override>");
+ builder.append(mOverride);
+ builder.append("</override>\n</vibratorDescriptor>\n");
+ mDirty = false;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mVibratorId);
+ dest.writeInt(mOverride ? 1 : 0);
+ dest.writeInt(mValue);
+ dest.writeInt(mDirty ? 1 : 0);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mVibratorId = in.readInt();
+ mOverride = in.readInt() != 0;
+ mValue = in.readInt();
+ mDirty = in.readInt() != 0;
+ }
+
+ /** @hide */
+ public void processOverride(Context context) {
+ AudioManager amgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ switch (mValue) {
+ case OFF:
+ amgr.setVibrateSetting(mVibratorId, AudioManager.VIBRATE_SETTING_OFF);
+ break;
+ case SILENT:
+ amgr.setVibrateSetting(mVibratorId, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
+ default:
+ amgr.setVibrateSetting(mVibratorId, AudioManager.VIBRATE_SETTING_ON);
+ break;
+ }
+ }
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7aa2507..f0c6ce8 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1890,6 +1890,18 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
+ * {@link android.app.ProfileManager} for setting
+ * notification profiles.
+ *
+ * @see #getSystemService
+ * @see android.app.ProfileManager
+ *
+ * @hide
+ */
+ public static final String PROFILE_SERVICE = "profile";
+
+ /**
+ * Use with {@link #getSystemService} to retrieve a
* {@link android.view.accessibility.AccessibilityManager} for giving the user
* feedback for UI events through the registered event listeners.
*
diff --git a/core/java/android/net/wimax/WimaxHelper.java b/core/java/android/net/wimax/WimaxHelper.java
new file mode 100644
index 0000000..f6c7a40
--- /dev/null
+++ b/core/java/android/net/wimax/WimaxHelper.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2011 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 android.net.wimax;
+
+import dalvik.system.DexClassLoader;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.provider.Settings;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/**
+ * {@hide}
+ */
+public class WimaxHelper {
+
+ private static final String TAG = "WimaxHelper";
+
+ private static final String WIMAX_CONTROLLER_CLASSNAME = "com.htc.net.wimax.WimaxController";
+ private static final String WIMAX_MANAGER_CLASSNAME = "android.net.fourG.wimax.Wimax4GManager";
+
+ private static DexClassLoader sWimaxClassLoader;
+ private static String sWimaxManagerClassname, sIsWimaxEnabledMethodname,
+ sSetWimaxEnabledMethodname, sGetWimaxStateMethodname;
+
+ public static boolean isWimaxSupported(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_wimaxEnabled);
+ }
+
+ public static DexClassLoader getWimaxClassLoader(Context context) {
+ if (isWimaxSupported(context)) {
+ if (sWimaxClassLoader == null) {
+ sWimaxManagerClassname = context.getResources().getString(
+ com.android.internal.R.string.config_wimaxManagerClassname);
+
+ // WimaxController::getWimaxState == Wimax4GManager::get4GState.
+ // However, Wimax4GManager also implements a different getWimaxState
+ // method, which returns a WimaxState object describing the connection
+ // state, not the enabled state. Other methods are similarly renamed.
+ if (sWimaxManagerClassname.equals(WIMAX_CONTROLLER_CLASSNAME)) {
+ sIsWimaxEnabledMethodname = "isWimaxEnabled";
+ sSetWimaxEnabledMethodname = "setWimaxEnabled";
+ sGetWimaxStateMethodname = "getWimaxState";
+ } else if (sWimaxManagerClassname.equals(WIMAX_MANAGER_CLASSNAME)) {
+ sIsWimaxEnabledMethodname = "is4GEnabled";
+ sSetWimaxEnabledMethodname = "set4GEnabled";
+ sGetWimaxStateMethodname = "get4GState";
+ }
+
+ String wimaxJarLocation = context.getResources().getString(
+ com.android.internal.R.string.config_wimaxServiceJarLocation);
+ String wimaxLibLocation = context.getResources().getString(
+ com.android.internal.R.string.config_wimaxNativeLibLocation);
+ sWimaxClassLoader = new DexClassLoader(wimaxJarLocation,
+ new ContextWrapper(context).getCacheDir().getAbsolutePath(),
+ wimaxLibLocation,ClassLoader.getSystemClassLoader());
+ }
+ return sWimaxClassLoader;
+ }
+ return null;
+ }
+
+ public static Object createWimaxService(Context context, Handler handler) {
+ Object controller = null;
+
+ try {
+ DexClassLoader wimaxClassLoader = getWimaxClassLoader(context);
+ if (sWimaxManagerClassname.equals(WIMAX_CONTROLLER_CLASSNAME)) {
+ // Load supersonic's and speedy's WimaxController.
+ IBinder b = ServiceManager.getService(WimaxManagerConstants.WIMAX_SERVICE);
+ if (b != null) {
+ Class<?> klass = wimaxClassLoader.loadClass("com.htc.net.wimax.IWimaxController$Stub");
+ if (klass != null) {
+ Method asInterface = klass.getMethod("asInterface", IBinder.class);
+ Object wc = asInterface.invoke(null, b);
+ if (wc != null) {
+ klass = wimaxClassLoader.loadClass(WIMAX_CONTROLLER_CLASSNAME);
+ if (klass != null) {
+ Constructor<?> ctor = klass.getDeclaredConstructors()[1];
+ controller = ctor.newInstance(wc, handler);
+ }
+ }
+ }
+ }
+ } else if (sWimaxManagerClassname.equals(WIMAX_MANAGER_CLASSNAME)) {
+ // Load crespo4g's (and epicmtd's) Wimax4GManager.
+ // Note that crespo4g's implementation grabs WIMAX_SERVICE internally, so
+ // it doesn't need to be passed in. Other implementations (may) require
+ // WIMAX_SERVICE to be grabbed externally, so check Wimax4GManager::<init>.
+ Class<?> klass = wimaxClassLoader.loadClass(WIMAX_MANAGER_CLASSNAME);
+ if (klass != null) {
+ Constructor<?> ctor = klass.getDeclaredConstructors()[0];
+ controller = ctor.newInstance();
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to create WimaxController instance", e);
+ }
+
+ return controller;
+ }
+
+ public static boolean isWimaxEnabled(Context context) {
+ boolean ret = false;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method m = wimaxService.getClass().getMethod(sIsWimaxEnabledMethodname);
+ ret = (Boolean) m.invoke(wimaxService);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to get WiMAX enabled state!", e);
+ }
+ return ret;
+ }
+
+ public static boolean setWimaxEnabled(Context context, boolean enabled) {
+ boolean ret = false;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method m = wimaxService.getClass().getMethod(sSetWimaxEnabledMethodname, boolean.class);
+ ret = (Boolean) m.invoke(wimaxService, enabled);
+ if (ret)
+ Settings.Secure.putInt(context.getContentResolver(),
+ Settings.Secure.WIMAX_ON, (Boolean) enabled ? 1 : 0);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to set WiMAX state!", e);
+ }
+ return ret;
+ }
+
+ public static int getWimaxState(Context context) {
+ int ret = 0;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method m = wimaxService.getClass().getMethod(sGetWimaxStateMethodname);
+ ret = (Integer) m.invoke(wimaxService);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to get WiMAX state!", e);
+ }
+ return ret;
+ }
+
+ public static boolean wimaxRescan(Context context) {
+ boolean ret = false;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method wimaxRescan = wimaxService.getClass().getMethod("wimaxRescan");
+ if (wimaxRescan != null) {
+ wimaxRescan.invoke(wimaxService);
+ ret = true;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to perform WiMAX rescan!", e);
+ }
+ return ret;
+ }
+
+ private static Object getWimaxInfo(Context context) {
+ Object wimaxInfo = null;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method getConnectionInfo = wimaxService.getClass().getMethod("getConnectionInfo");
+ wimaxInfo = getConnectionInfo.invoke(wimaxService);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to get a WimaxInfo object!", e);
+ }
+ return wimaxInfo;
+ }
+}
diff --git a/core/java/android/net/wimax/WimaxManagerConstants.java b/core/java/android/net/wimax/WimaxManagerConstants.java
index b4aaf5b..a8239ba 100644
--- a/core/java/android/net/wimax/WimaxManagerConstants.java
+++ b/core/java/android/net/wimax/WimaxManagerConstants.java
@@ -67,11 +67,21 @@ public class WimaxManagerConstants
public static final int NET_4G_STATE_DISABLED = 1;
/**
+ * Indicatates Wimax is disabling.
+ */
+ public static final int NET_4G_STATE_DISABLING = 0;
+
+ /**
* Indicatates Wimax is enabled.
*/
public static final int NET_4G_STATE_ENABLED = 3;
/**
+ * Indicatates Wimax is enabling.
+ */
+ public static final int NET_4G_STATE_ENABLING = 2;
+
+ /**
* Indicatates Wimax status is known.
*/
public static final int NET_4G_STATE_UNKNOWN = 4;
@@ -101,4 +111,9 @@ public class WimaxManagerConstants
*/
public static final int WIMAX_STATE_DISCONNECTED = 9;
+ /**
+ * Constants for HTC/SQN WiMAX implementation
+ */
+ public static final String WIMAX_ENABLED_CHANGED_ACTION = "com.htc.net.wimax.WIMAX_ENABLED_CHANGED";
+ public static final String CURRENT_WIMAX_ENABLED_STATE = "curWimaxEnabledState";
}
diff --git a/core/java/android/preference/ListPreferenceMultiSelect.java b/core/java/android/preference/ListPreferenceMultiSelect.java
new file mode 100644
index 0000000..83edc72
--- /dev/null
+++ b/core/java/android/preference/ListPreferenceMultiSelect.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 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 android.preference;
+
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+
+/**
+ * This Preference type is required for the Power Widget functionality. It should
+ * not be used for any other multi select lists, use the Android MultiselectListPreference
+ * instead
+ * @hide
+ */
+public class ListPreferenceMultiSelect extends ListPreference {
+
+ private static final String SEPARATOR = "OV=I=XseparatorX=I=VO";
+
+ private boolean[] mClickedDialogEntryIndices;
+
+ public ListPreferenceMultiSelect(Context context) {
+ super(context);
+ }
+
+ public ListPreferenceMultiSelect(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(Builder builder) {
+ CharSequence[] entries = getEntries();
+ CharSequence[] entryValues = getEntryValues();
+
+ if (entries == null || entryValues == null || entries.length != entryValues.length) {
+ throw new IllegalStateException(
+ this.getClass().getSimpleName()
+ + " requires an entries array and an entryValues array which are both the same length");
+ }
+
+ mClickedDialogEntryIndices = new boolean[entryValues.length];
+ restoreCheckedEntries();
+ builder.setMultiChoiceItems(entries, mClickedDialogEntryIndices, new DialogInterface.OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ mClickedDialogEntryIndices[which] = isChecked;
+ }
+ });
+ }
+
+ public static String[] parseStoredValue(CharSequence val) {
+ if (TextUtils.isEmpty(val)) {
+ return null;
+ } else {
+ return val.toString().split(SEPARATOR);
+ }
+ }
+
+ private void restoreCheckedEntries() {
+ CharSequence[] entryValues = getEntryValues();
+
+ String[] vals = parseStoredValue(getValue());
+ if (vals != null) {
+ for (String val : vals) {
+ for (int i = 0; i < entryValues.length; i++) {
+ CharSequence entry = entryValues[i];
+ if (entry.equals(val)) {
+ mClickedDialogEntryIndices[i] = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ CharSequence[] entryValues = getEntryValues();
+
+ if (positiveResult && entryValues != null) {
+ StringBuilder value = new StringBuilder();
+ for (int i = 0; i < entryValues.length; i++) {
+ if (mClickedDialogEntryIndices[i]) {
+ if (value.length() > 0) {
+ value.append(SEPARATOR);
+ }
+ value.append(entryValues[i]);
+ }
+ }
+
+ String val = value.toString();
+ if (callChangeListener(val)) {
+ setValue(val);
+ }
+ }
+ }
+}
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index caf55d7..b763022 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -146,6 +146,11 @@ public class VolumePreference extends SeekBarDialogPreference implements
}
}
+ /** @hide */
+ protected boolean onVolumeChange(SeekBarVolumizer volumizer, int value) {
+ return true;
+ }
+
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
@@ -305,10 +310,14 @@ public class VolumePreference extends SeekBarDialogPreference implements
}
void postSetVolume(int progress) {
- // Do the volume changing separately to give responsive UI
- mLastProgress = progress;
- mHandler.removeCallbacks(this);
- mHandler.post(this);
+ if (onVolumeChange(this, progress)) {
+ // Do the volume changing separately to give responsive UI
+ mLastProgress = progress;
+ mHandler.removeCallbacks(this);
+ mHandler.post(this);
+ } else {
+ mSeekBar.setProgress(mLastProgress);
+ }
}
public void onStartTrackingTouch(SeekBar seekBar) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2a3f916..99db53c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1688,6 +1688,148 @@ public final class Settings {
public static final int SCREEN_BRIGHTNESS_MODE_AUTOMATIC = 1;
/**
+ * Indicates that custom light sensor settings has changed.
+ * The value is random and changes reloads light settings.
+ *
+ * @hide
+ */
+ public static final String LIGHTS_CHANGED = "lights_changed";
+
+ /**
+ * Whether custom light sensor levels & values are enabled. The value is
+ * boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_CUSTOM = "light_sensor_custom";
+
+ /**
+ * Screen dim value to use if LIGHT_SENSOR_CUSTOM is set. The value is int.
+ * Default is android.os.BRIGHTNESS_DIM.
+ *
+ * @hide
+ */
+ public static final String LIGHT_SCREEN_DIM = "light_screen_dim";
+
+ /**
+ * Custom light sensor levels. The value is a comma separated int array
+ * with length N.
+ * Example: "100,300,3000".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_LEVELS = "light_sensor_levels";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_LCD_VALUES = "light_sensor_lcd_values";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_BUTTON_VALUES = "light_sensor_button_values";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_KEYBOARD_VALUES = "light_sensor_keyboard_values";
+
+ /**
+ * Whether light sensor is allowed to decrease when calculating automatic
+ * backlight. The value is boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_DECREASE = "light_decrease";
+
+ /**
+ * Light sensor hysteresis for decreasing backlight. The value is
+ * int (0-99) representing % (0-0.99 as float). Example:
+ *
+ * Levels Output
+ * 0 - 100 50
+ * 100 - 200 100
+ * 200 - Inf 255
+ *
+ * Current sensor value is 150 which gives light value 100. Hysteresis is 50.
+ * Current level lower bound is 100 and previous lower bound is 0.
+ * Sensor value must drop below 100-(100-0)*(50/100)=50 for output to become 50
+ * (corresponding to the 0 - 100 level).
+ * @hide
+ */
+ public static final String LIGHT_HYSTERESIS = "light_hysteresis";
+
+ /**
+ * Whether light sensor used when calculating automatic backlight should
+ * be filtered through an moving average filter.
+ * The value is boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER = "light_filter";
+
+ /**
+ * Window length of filter used when calculating automatic backlight.
+ * One minute means that the average sensor value last minute is used.
+ * The value is integer (milliseconds)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_WINDOW = "light_filter_window";
+
+ /**
+ * Reset threshold of filter used when calculating automatic backlight.
+ * Sudden large jumps in sensor value resets the filter. This is used
+ * to make the filter respond quickly to large enough changes in input
+ * while still filtering small changes. Example:
+ *
+ * Current filter value (average) is 100 and sensor value is changing to
+ * 10, 150, 100, 30, 50. The filter is continously taking the average of
+ * the samples. Now the user goes outside and the value jumps over 1000.
+ * The difference between current average and new sample is larger than
+ * the reset threshold and filter is reset. It begins calculating a new
+ * average on samples around 1000 (say, 800, 1200, 1000, 1100 etc.)
+ *
+ * The value is integer (lux)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_RESET = "light_filter_reset";
+
+ /**
+ * Sample interval of filter used when calculating automatic backlight.
+ * The value is integer (milliseconds)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_INTERVAL = "light_filter_interval";
+
+ /**
+ * Whether to enable the electron beam animation when turning screen on
+ *
+ * @hide */
+ public static final String ELECTRON_BEAM_ANIMATION_ON = "electron_beam_animation_on";
+
+ /**
+ * Whether to enable the electron beam animation when turning screen off
+ *
+ * @hide */
+ public static final String ELECTRON_BEAM_ANIMATION_OFF = "electron_beam_animation_off";
+
+ /**
* Control whether the process CPU usage meter should be shown.
*
* @deprecated Use {@link Global#SHOW_PROCESSES} instead
@@ -1706,6 +1848,22 @@ public final class Settings {
public static final String ALWAYS_FINISH_ACTIVITIES = Global.ALWAYS_FINISH_ACTIVITIES;
/**
+ * Volume Overlay Mode, This is behaviour of the volume overlay panel
+ * Defaults to 0 - which is simple
+ * @hide
+ */
+ public static final String MODE_VOLUME_OVERLAY = "mode_volume_overlay";
+
+ /** @hide */
+ public static final int VOLUME_OVERLAY_SINGLE = 0;
+ /** @hide */
+ public static final int VOLUME_OVERLAY_EXPANDABLE = 1;
+ /** @hide */
+ public static final int VOLUME_OVERLAY_EXPANDED = 2;
+ /** @hide */
+ public static final int VOLUME_OVERLAY_NONE = 3;
+
+ /**
* Determines which streams are affected by ringer mode changes. The
* stream type's bit should be set to 1 if it should be muted when going
* into an inaudible ringer mode.
@@ -1782,6 +1940,12 @@ public final class Settings {
public static final String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
/**
+ * Whether to prevent loud volume levels when headset is first plugged in.
+ * @hide
+ */
+ public static final String SAFE_HEADSET_VOLUME_RESTORE = "safe_headset_volume_restore";
+
+ /**
* Master volume (float in the range 0.0f to 1.0f).
* @hide
*/
@@ -1813,6 +1977,24 @@ public final class Settings {
"notifications_use_ring_volume";
/**
+ * Whether the phone ringtone should be played in an increasing manner
+ * @hide
+ */
+ public static final String INCREASING_RING = "increasing_ring";
+
+ /**
+ * Minimum volume index for increasing ring volume
+ * @hide
+ */
+ public static final String INCREASING_RING_MIN_VOLUME = "increasing_ring_min_vol";
+
+ /**
+ * Time (in ms) between ringtone volume increases
+ * @hide
+ */
+ public static final String INCREASING_RING_INTERVAL = "increasing_ring_interval";
+
+ /**
* Whether silent mode should allow vibration feedback. This is used
* internally in AudioService and the Sound settings activity to
* coordinate decoupling of vibrate and silent modes. This setting
@@ -2008,6 +2190,19 @@ public final class Settings {
public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
/**
+ * Control the type of rotation which can be performed using the accelerometer
+ * if ACCELEROMETER_ROTATION is enabled.
+ * Value is a bitwise combination of
+ * 1 = 0 degrees (portrait)
+ * 2 = 90 degrees (left)
+ * 4 = 180 degrees (inverted portrait)
+ * 8 = 270 degrees (right)
+ * Setting to 0 is effectively orientation lock
+ * @hide
+ */
+ public static final String ACCELEROMETER_ROTATION_ANGLES = "accelerometer_rotation_angles";
+
+ /**
* Default screen rotation when no other policy applies.
* When {@link #ACCELEROMETER_ROTATION} is zero and no on-screen Activity expresses a
* preference, this rotation value will be used. Must be one of the
@@ -2079,6 +2274,13 @@ public final class Settings {
public static final String TTY_MODE = "tty_mode";
/**
+ * Whether noise suppression is enabled. The value is
+ * boolean (1 or 0).
+ * @hide
+ */
+ public static final String NOISE_SUPPRESSION = "noise_suppression";
+
+ /**
* Whether the sounds effects (key clicks, lid open ...) are enabled. The value is
* boolean (1 or 0).
*/
@@ -2105,6 +2307,109 @@ public final class Settings {
public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
/**
+ * What color to use for the notification LED by default
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR = "notification_light_pulse_default_color";
+
+ /**
+ * How long to flash the notification LED by default
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON = "notification_light_pulse_default_led_on";
+
+ /**
+ * How long to wait between flashes for the notification LED by default
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF = "notification_light_pulse_default_led_off";
+
+ /**
+ * What color to use for the missed call notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CALL_COLOR = "notification_light_pulse_call_color";
+
+ /**
+ * How long to flash the missed call notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CALL_LED_ON = "notification_light_pulse_call_led_on";
+
+ /**
+ * How long to wait between flashes for the missed call notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CALL_LED_OFF = "notification_light_pulse_call_led_off";
+
+ /**
+ * What color to use for the voicemail notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR = "notification_light_pulse_vmail_color";
+
+ /**
+ * How long to flash the voicemail notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_LED_ON = "notification_light_pulse_vmail_led_on";
+
+ /**
+ * How long to wait between flashes for the voicemail notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_LED_OFF = "notification_light_pulse_vmail_led_off";
+
+ /**
+ * Whether to use the custom LED values for the notification pulse LED.
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE = "notification_light_pulse_custom_enable";
+
+ /**
+ * Which custom LED values to use for the notification pulse LED.
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES = "notification_light_pulse_custom_values";
+
+ /**
+ * Whether the battery light should be enabled (if hardware supports it)
+ * The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_ENABLED = "battery_light_enabled";
+
+ /**
+ * Whether the battery LED should repeatedly flash when the battery is low
+ * on charge. The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_PULSE = "battery_light_pulse";
+
+ /**
+ * What color to use for the battery LED while charging - low
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_LOW_COLOR = "battery_light_low_color";
+
+ /**
+ * What color to use for the battery LED while charging - medium
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_MEDIUM_COLOR = "battery_light_medium_color";
+
+ /**
+ * What color to use for the battery LED while charging - full
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_FULL_COLOR = "battery_light_full_color";
+
+ /** Sprint MWI Quirk: Show message wait indicator notifications
+ * @hide
+ */
+ public static final String ENABLE_MWI_NOTIFICATION = "enable_mwi_notification";
+
+ /**
* Show pointer location on screen?
* 0 = no
* 1 = yes
@@ -2265,6 +2570,362 @@ public final class Settings {
public static final String POINTER_SPEED = "pointer_speed";
/**
+ * Use the Notification Power Widget? (Who wouldn't!)
+ *
+ * @hide
+ */
+ public static final String EXPANDED_VIEW_WIDGET = "expanded_view_widget";
+
+ /**
+ * Whether to hide the notification screen after clicking on a widget
+ * button
+ *
+ * @hide
+ */
+ public static final String EXPANDED_HIDE_ONCHANGE = "expanded_hide_onchange";
+
+ /**
+ * Hide scroll bar in power widget
+ *
+ * @hide
+ */
+ public static final String EXPANDED_HIDE_SCROLLBAR = "expanded_hide_scrollbar";
+
+ /**
+ * Hide indicator in status bar widget
+ *
+ * @hide
+ */
+ public static final String EXPANDED_HIDE_INDICATOR = "expanded_hide_indicator";
+
+ /**
+ * Haptic feedback in power widget
+ *
+ * @hide
+ */
+ public static final String EXPANDED_HAPTIC_FEEDBACK = "expanded_haptic_feedback";
+
+ /**
+ * Notification Indicator Color
+ *
+ * @hide
+ */
+ public static final String EXPANDED_VIEW_WIDGET_COLOR = "expanded_widget_color";
+
+ /**
+ * Widget Buttons to Use
+ *
+ * @hide
+ */
+ public static final String WIDGET_BUTTONS = "expanded_widget_buttons";
+
+ /**
+ * Widget Buttons to Use - Tablet
+ *
+ * @hide
+ */
+ public static final String WIDGET_BUTTONS_TABLET = "expanded_widget_buttons_tablet";
+
+ /**
+ * Navigation controls to Use
+ *
+ * @hide
+ */
+ public static final String NAV_BUTTONS = "nav_buttons";
+
+ /**
+ * Notification Power Widget - Custom Brightness Mode
+ * @hide
+ */
+ public static final String EXPANDED_BRIGHTNESS_MODE = "expanded_brightness_mode";
+
+ /**
+ * Notification Power Widget - Custom Network Mode
+ * @hide
+ */
+ public static final String EXPANDED_NETWORK_MODE = "expanded_network_mode";
+
+ /**
+ * Notification Power Widget - Custom LTE Toggle
+ * 1 - lte on, 0 - lte off
+ * @hide
+ */
+ public static final String LTE_MODE = "lte_mode";
+
+ /**
+ * Notification Power Widget - Custom Screen Timeout
+ * @hide
+ */
+ public static final String EXPANDED_SCREENTIMEOUT_MODE = "expanded_screentimeout_mode";
+
+ /**
+ * Notification Power Widget - Custom Ring Mode
+ * @hide
+ */
+ public static final String EXPANDED_RING_MODE = "expanded_ring_mode";
+
+ /**
+ * Notification Power Widget - Custom Torch Mode
+ * @hide
+ */
+ public static final String EXPANDED_FLASH_MODE = "expanded_flash_mode";
+
+ /**
+ * AutoHide CombinedBar on tablets.
+ * @hide
+ */
+ public static final String COMBINED_BAR_AUTO_HIDE = "combined_bar_auto_hide";
+
+ /**
+ * Display style of AM/PM next to clock in status bar
+ * 0: Normal display (Eclair stock)
+ * 1: Small display (Froyo stock)
+ * 2: No display (Gingerbread/ICS stock)
+ * default: 2
+ * @hide
+ */
+ public static final String STATUS_BAR_AM_PM = "status_bar_am_pm";
+
+ /**
+ * Display style of the status bar battery information
+ * 0: Display the stock battery information
+ * 1: Display cm battery percentage implementation / dont show stock icon
+ * 2: Hide the battery information
+ * default: 0
+ * @hide
+ */
+ public static final String STATUS_BAR_BATTERY = "status_bar_battery";
+
+ /**
+ * Whether to show the clock in status bar
+ * of the stock battery icon
+ * 0: don't show the clock
+ * 1: show the clock
+ * default: 1
+ * @hide
+ */
+ public static final String STATUS_BAR_CLOCK = "status_bar_clock";
+
+ /**
+ * Whether to show the signal text or signal bars.
+ * default: 0
+ * 0: show signal bars
+ * 1: show signal text numbers
+ * 2: show signal text numbers w/small dBm appended
+ * @hide
+ */
+ public static final String STATUS_BAR_SIGNAL_TEXT = "status_bar_signal";
+
+ /**
+ * Whether to control brightness from status bar
+ *
+ * @hide
+ */
+ public static final String STATUS_BAR_BRIGHTNESS_CONTROL = "status_bar_brightness_control";
+
+ /**
+ * Whether to show the IME switcher in the status bar
+ * @hide
+ */
+ public static final String STATUS_BAR_IME_SWITCHER = "status_bar_ime_switcher";
+
+ /**
+ * Whether to use a separate delay for "slide to unlock" and security
+ * lock
+ * @hide
+ */
+ public static final String SCREEN_LOCK_SLIDE_DELAY_TOGGLE = "screen_lock_slide_delay_toggle";
+
+ /**
+ * How many ms to delay before enabling the "slide to unlock" screen
+ * lock when the screen goes off due to timeout
+ * @hide
+ */
+ public static final String SCREEN_LOCK_SLIDE_TIMEOUT_DELAY = "screen_lock_slide_timeout_delay";
+
+ /**
+ * How many ms to delay before enabling the "slide to unlock" screen
+ * lock when the screen is turned off by the user
+ * @hide
+ */
+ public static final String SCREEN_LOCK_SLIDE_SCREENOFF_DELAY = "screen_lock_slide_screenoff_delay";
+
+ /**
+ * Whether to use the custom quick unlock screen control
+ * @hide
+ */
+ public static final String LOCKSCREEN_QUICK_UNLOCK_CONTROL = "lockscreen_quick_unlock_control";
+
+ /**
+ * Boolean value whether to link ringtone and notification volumes
+ *
+ * @hide
+ */
+ public static final String VOLUME_LINK_NOTIFICATION = "volume_link_notification";
+
+ /**
+ * Whether to unlock the menu key. The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String MENU_UNLOCK_SCREEN = "menu_unlock_screen";
+
+ /**
+ * Whether to wake the screen with the volume keys, the value is boolean.
+ * @hide
+ */
+ public static final String VOLUME_WAKE_SCREEN = "volume_wake_screen";
+
+ /**
+ * Whether or not volume button music controls should be enabled to seek media tracks
+ * @hide
+ */
+ public static final String VOLBTN_MUSIC_CONTROLS = "volbtn_music_controls";
+
+ /**
+ * Whether national data roaming should be used.
+ * @hide
+ */
+ public static final String MVNO_ROAMING = "mvno_roaming";
+
+ /**
+ * Whether to enable quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_ENABLED = "quiet_hours_enabled";
+
+ /**
+ * Sets when quiet hours starts. This is stored in minutes from the start of the day.
+ * @hide
+ */
+ public static final String QUIET_HOURS_START = "quiet_hours_start";
+
+ /**
+ * Sets when quiet hours end. This is stored in minutes from the start of the day.
+ * @hide
+ */
+ public static final String QUIET_HOURS_END = "quiet_hours_end";
+
+ /**
+ * Whether to remove the sound from outgoing notifications during quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_MUTE = "quiet_hours_mute";
+
+ /**
+ * Whether to disable haptic feedback during quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_HAPTIC = "quiet_hours_haptic";
+
+ /**
+ * Whether to remove the vibration from outgoing notifications during quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_STILL = "quiet_hours_still";
+
+ /**
+ * Whether to attempt to dim the LED color during quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_DIM = "quiet_hours_dim";
+
+ /**
+ * Sets the lockscreen background style
+ * @hide
+ */
+ public static final String LOCKSCREEN_BACKGROUND = "lockscreen_background";
+
+ /**
+ * Show the weather on the lock screen
+ * @hide
+ */
+ public static final String LOCKSCREEN_WEATHER = "lockscreen_weather";
+
+ /**
+ * Show the current weather location on the lock screen
+ * @hide
+ */
+ public static final String WEATHER_SHOW_LOCATION = "weather_show_location";
+
+ /**
+ * Show the current weather location on the lock screen
+ * @hide
+ */
+ public static final String WEATHER_SHOW_TIMESTAMP = "weather_show_timestamp";
+
+ /**
+ * Use the custom/manually configured weather location
+ * @hide
+ */
+ public static final String WEATHER_USE_CUSTOM_LOCATION = "weather_use_custom_location";
+
+ /**
+ * Stores the custom/manually configured weather location
+ * @hide
+ */
+ public static final String WEATHER_CUSTOM_LOCATION = "weather_custom_location";
+
+ /**
+ * Stores the weather update frequency
+ * @hide
+ */
+ public static final String WEATHER_UPDATE_INTERVAL = "weather_update_interval";
+
+ /**
+ * Use Metric measurements (celcius, km/h) for weather data
+ * @hide
+ */
+ public static final String WEATHER_USE_METRIC = "weather_use_metric";
+
+ /**
+ * Invert low/high temperature display
+ * @hide
+ */
+ public static final String WEATHER_INVERT_LOWHIGH = "weather_invert_lowhigh";
+
+ /**
+ * Whether to show the next calendar event
+ * @hide
+ */
+ public static final String LOCKSCREEN_CALENDAR = "lockscreen_calendar";
+
+ /**
+ * Whether to show the next calendar event's location
+ * @hide
+ */
+ public static final String LOCKSCREEN_CALENDAR_SHOW_LOCATION = "lockscreen_calendar_show_location";
+
+ /**
+ * Whether to show the next calendar event's description
+ * @hide
+ */
+ public static final String LOCKSCREEN_CALENDAR_SHOW_DESCRIPTION = "lockscreen_calendar_show_description";
+
+ /**
+ * Which calendars to look for events
+ * @hide
+ */
+ public static final String LOCKSCREEN_CALENDARS = "lockscreen_calendars";
+
+ /**
+ * How far in the future to look for events
+ * @hide
+ */
+ public static final String LOCKSCREEN_CALENDAR_LOOKAHEAD = "lockscreen_calendar_lookahead";
+
+ /**
+ * Whether to find only events with reminders
+ * @hide
+ */
+ public static final String LOCKSCREEN_CALENDAR_REMINDERS_ONLY = "lockscreen_calendar_reminders_only";
+
+ /**
+ * Show the pending notification counts as overlays on the status bar
+ * @hide
+ */
+ public static final String STATUS_BAR_NOTIF_COUNT = "status_bar_notif_count";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
@@ -2315,10 +2976,13 @@ public final class Settings {
AUTO_TIME_ZONE, // moved to global
TIME_12_24,
DATE_FORMAT,
+ ACCELEROMETER_ROTATION,
+ USER_ROTATION,
DTMF_TONE_WHEN_DIALING,
DTMF_TONE_TYPE_WHEN_DIALING,
HEARING_AID,
TTY_MODE,
+ NOISE_SUPPRESSION,
SOUND_EFFECTS_ENABLED,
HAPTIC_FEEDBACK_ENABLED,
POWER_SOUNDS_ENABLED, // moved to global
@@ -2326,10 +2990,18 @@ public final class Settings {
LOCKSCREEN_SOUNDS_ENABLED,
SHOW_WEB_SUGGESTIONS,
NOTIFICATION_LIGHT_PULSE,
+ NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR,
+ NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON,
+ NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF,
SIP_CALL_OPTIONS,
SIP_RECEIVE_CALLS,
POINTER_SPEED,
- VIBRATE_WHEN_RINGING
+ QUIET_HOURS_ENABLED,
+ QUIET_HOURS_START,
+ QUIET_HOURS_END,
+ QUIET_HOURS_MUTE,
+ QUIET_HOURS_STILL,
+ QUIET_HOURS_DIM,
};
// Settings moved to Settings.Secure
@@ -3082,6 +3754,12 @@ public final class Settings {
public static final String ADB_ENABLED = Global.ADB_ENABLED;
/**
+ * The TCP/IP port to run ADB on, or -1 for USB
+ * @hide
+ */
+ public static final String ADB_PORT = "adb_port";
+
+ /**
* The hostname for this device
* @hide
*/
@@ -3261,6 +3939,13 @@ public final class Settings {
"lock_screen_owner_info_enabled";
/**
+ * Whether the unsecure widget screen will be shown before a secure
+ * lock screen
+ * @hide
+ */
+ public static final String LOCK_BEFORE_UNLOCK =
+ "lock_before_unlock";
+ /**
* The Logging ID (a unique 64-bit value) as a hex string.
* Used as a pseudonymous identifier for logging.
* @deprecated This identifier is poorly initialized and has
@@ -3679,6 +4364,12 @@ public final class Settings {
Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS;
/**
+ * Whether the Wimax should be on. Only the WiMAX service should touch this.
+ * @hide
+ */
+ public static final String WIMAX_ON = "wimax_on";
+
+ /**
* Whether background data usage is allowed.
*
* @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH},
@@ -4292,6 +4983,13 @@ public final class Settings {
public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled";
/**
+ * Whether to allow killing of the foreground app by long-pressing the Back button
+ * @hide
+ */
+ public static final String KILL_APP_LONGPRESS_BACK = "kill_app_longpress_back";
+
+
+ /**
* Whether we keep the device on while the device is plugged in.
* Supported values are:
* <ul>
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index d7c7f46..2497e95 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -35,7 +35,10 @@ import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
+import android.os.RemoteException;
import android.os.Vibrator;
+import android.provider.Settings;
+import android.provider.Settings.System;
import android.util.Log;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageView;
@@ -99,12 +102,16 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
private static final int STREAM_MASTER = -100;
// Pseudo stream type for remote volume is defined in AudioService.STREAM_REMOTE_MUSIC
+ public static final String ACTION_VOLUME_OVERLAY_CHANGED
+ = "android.intent.action.VOLUME_OVERLAY_CHANGED";
+
protected Context mContext;
private AudioManager mAudioManager;
protected AudioService mAudioService;
private boolean mRingIsSilent;
private boolean mShowCombinedVolumes;
private boolean mVoiceCapable;
+ private int mCurrentOverlayStyle = -1;
// True if we want to play tones on the system stream when the master stream is specified.
private final boolean mPlayMasterStreamTones;
@@ -326,12 +333,26 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
mPlayMasterStreamTones = masterVolumeOnly && masterVolumeKeySounds;
+ // get the users preference
+ int choosenStyle = Settings.System.getInt(context.getContentResolver(),Settings.System.MODE_VOLUME_OVERLAY, -1);
+ // by default -1 is expected - deal with choosing the right default
+ if (choosenStyle == -1) {
+ if (mVoiceCapable) {
+ choosenStyle = Settings.System.VOLUME_OVERLAY_SINGLE;
+ } else {
+ choosenStyle = Settings.System.VOLUME_OVERLAY_EXPANDABLE;
+ }
+ }
+ changeOverlayStyle(choosenStyle);
+ mMoreButton.setOnClickListener(this);
+
listenToRingerMode();
}
private void listenToRingerMode() {
final IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ filter.addAction(ACTION_VOLUME_OVERLAY_CHANGED);
mContext.registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
@@ -340,18 +361,45 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
removeMessages(MSG_RINGER_MODE_CHANGED);
sendMessage(obtainMessage(MSG_RINGER_MODE_CHANGED));
+ } else if (ACTION_VOLUME_OVERLAY_CHANGED.equals(action)) {
+ int state = (Integer) intent.getExtra("state");
+ changeOverlayStyle(state);
}
}
}, filter);
}
- private boolean isMuted(int streamType) {
- if (streamType == STREAM_MASTER) {
- return mAudioManager.isMasterMute();
- } else if (streamType == AudioService.STREAM_REMOTE_MUSIC) {
- return (mAudioService.getRemoteStreamVolume() <= 0);
- } else {
- return mAudioManager.isStreamMute(streamType);
+ private void changeOverlayStyle(int newStyle) {
+ Log.i("VolumePanel", "changeOverlayStyle : " + newStyle);
+ // Don't change to the same style
+ if (newStyle == mCurrentOverlayStyle) return;
+ switch (newStyle) {
+ case Settings.System.VOLUME_OVERLAY_SINGLE :
+ mMoreButton.setVisibility(View.GONE);
+ mDivider.setVisibility(View.GONE);
+ mShowCombinedVolumes = false;
+ mCurrentOverlayStyle = Settings.System.VOLUME_OVERLAY_SINGLE;
+ break;
+ case Settings.System.VOLUME_OVERLAY_EXPANDABLE :
+ mMoreButton.setVisibility(View.VISIBLE);
+ mDivider.setVisibility(View.VISIBLE);
+ mShowCombinedVolumes = true;
+ mCurrentOverlayStyle = Settings.System.VOLUME_OVERLAY_EXPANDABLE;
+ break;
+ case Settings.System.VOLUME_OVERLAY_EXPANDED :
+ mMoreButton.setVisibility(View.GONE);
+ mDivider.setVisibility(View.GONE);
+ mShowCombinedVolumes = true;
+ if (mCurrentOverlayStyle == Settings.System.VOLUME_OVERLAY_NONE) {
+ addOtherVolumes();
+ expand();
+ }
+ mCurrentOverlayStyle = Settings.System.VOLUME_OVERLAY_EXPANDED;
+ break;
+ case Settings.System.VOLUME_OVERLAY_NONE :
+ mShowCombinedVolumes = false;
+ mCurrentOverlayStyle = Settings.System.VOLUME_OVERLAY_NONE;
+ break;
}
}
@@ -385,6 +433,10 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
}
}
+ private boolean isMuted(int streamType) {
+ return mAudioManager.isStreamMute(streamType);
+ }
+
private void createSliders() {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -406,6 +458,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
sc.iconRes = streamRes.iconRes;
sc.iconMuteRes = streamRes.iconMuteRes;
sc.icon.setImageResource(sc.iconRes);
+ sc.icon.setOnClickListener(this);
sc.seekbarView = (SeekBar) sc.group.findViewById(R.id.seekbar);
int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
streamType == AudioSystem.STREAM_VOICE_CALL) ? 1 : 0;
@@ -442,6 +495,10 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
if (!STREAMS[i].show || streamType == mActiveStreamType) {
continue;
}
+ // Skip ring volume for non-phone devices
+ if (!mVoiceCapable && streamType == AudioManager.STREAM_RING) {
+ continue;
+ }
StreamControl sc = mStreamControls.get(streamType);
mSliderGroup.addView(sc.group);
updateSlider(sc);
@@ -475,10 +532,22 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
private void expand() {
final int count = mSliderGroup.getChildCount();
for (int i = 0; i < count; i++) {
- mSliderGroup.getChildAt(i).setVisibility(View.VISIBLE);
+ if (mSliderGroup.getChildAt(i).getVisibility() != View.VISIBLE) {
+ mSliderGroup.getChildAt(i).setVisibility(View.VISIBLE);
+ }
+ }
+ mMoreButton.setVisibility(View.GONE);
+ mDivider.setVisibility(View.GONE);
+ }
+
+ private void hideSlider(int mActiveStreamType) {
+ final int count = mSliderGroup.getChildCount();
+ for (int i = 0; i < count; i++) {
+ StreamControl sc = (StreamControl) mSliderGroup.getChildAt(i).getTag();
+ if (mActiveStreamType == sc.streamType) {
+ mSliderGroup.getChildAt(i).setVisibility(View.GONE);
+ }
}
- mMoreButton.setVisibility(View.INVISIBLE);
- mDivider.setVisibility(View.INVISIBLE);
}
private void collapse() {
@@ -578,8 +647,12 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
synchronized (this) {
- if (mActiveStreamType != streamType) {
- reorderSliders(streamType);
+ if (mActiveStreamType == -1 || streamType != mActiveStreamType) {
+ if (streamType != mActiveStreamType &&
+ mCurrentOverlayStyle == Settings.System.VOLUME_OVERLAY_EXPANDABLE) {
+ hideSlider(mActiveStreamType);
+ }
+ reorderSliders(streamType);
}
onShowVolumeChanged(streamType, flags);
}
@@ -709,17 +782,32 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
} else {
sc.seekbarView.setEnabled(true);
}
+ // If adjusting Ring volume and preference is to link it to Notification
+ if (streamType == mAudioManager.STREAM_RING &&
+ System.getInt(mContext.getContentResolver(),System.VOLUME_LINK_NOTIFICATION, 1) == 1) {
+ StreamControl notifySc = mStreamControls.get(mAudioManager.STREAM_NOTIFICATION);
+ if (index > notifySc.seekbarView.getMax()) {
+ notifySc.seekbarView.setProgress(notifySc.seekbarView.getMax());
+ } else {
+ notifySc.seekbarView.setProgress(index);
+ }
+ }
}
- if (!mDialog.isShowing()) {
+ // Only Show if style needs it
+ if (!mDialog.isShowing() && mCurrentOverlayStyle != Settings.System.VOLUME_OVERLAY_NONE) {
int stream = (streamType == AudioService.STREAM_REMOTE_MUSIC) ? -1 : streamType;
// when the stream is for remote playback, use -1 to reset the stream type evaluation
mAudioManager.forceVolumeControlStream(stream);
mDialog.setContentView(mView);
// Showing dialog - use collapsed state
- if (mShowCombinedVolumes) {
+ if (mShowCombinedVolumes && mCurrentOverlayStyle != Settings.System.VOLUME_OVERLAY_EXPANDED) {
collapse();
}
+ // If just changed the style and we need to expand
+ if (mCurrentOverlayStyle == Settings.System.VOLUME_OVERLAY_EXPANDED) {
+ expand();
+ }
mDialog.show();
}
@@ -995,13 +1083,34 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
sendMessage(obtainMessage(MSG_TIMEOUT));
}
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
final Object tag = seekBar.getTag();
if (fromUser && tag instanceof StreamControl) {
StreamControl sc = (StreamControl) tag;
if (getStreamVolume(sc.streamType) != progress) {
setStreamVolume(sc.streamType, progress, 0);
+ // if audio is linked then adjust other one if change made by user
+ if (fromUser && System.getInt(mContext.getContentResolver(),System.VOLUME_LINK_NOTIFICATION, 1) == 1) {
+ if (sc.streamType == AudioManager.STREAM_RING) {
+ StreamControl notifySc = mStreamControls.get(AudioManager.STREAM_NOTIFICATION);
+ if (notifySc != null) {
+ if (progress > notifySc.seekbarView.getMax()) {
+ notifySc.seekbarView.setProgress(notifySc.seekbarView.getMax());
+ } else {
+ notifySc.seekbarView.setProgress(progress);
+ }
+ }
+ } else if (sc.streamType == AudioManager.STREAM_NOTIFICATION) {
+ StreamControl phoneSc = mStreamControls.get(AudioManager.STREAM_RING);
+ if (phoneSc != null) {
+ if (progress > phoneSc.seekbarView.getMax()) {
+ phoneSc.seekbarView.setProgress(phoneSc.seekbarView.getMax());
+ } else {
+ phoneSc.seekbarView.setProgress(progress);
+ }
+ }
+ }
+ }
}
}
resetTimeout();
@@ -1027,6 +1136,12 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
public void onClick(View v) {
if (v == mMoreButton) {
expand();
+ } else if (v instanceof ImageView) {
+ Intent volumeSettings = new Intent(android.provider.Settings.ACTION_SOUND_SETTINGS);
+ volumeSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ forceTimeout();
+ mContext.startActivity(volumeSettings);
+ return;
}
resetTimeout();
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 26739b3..fd5449c 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -399,6 +399,7 @@ public interface WindowManagerPolicy {
public void shutdown(boolean confirm);
public void rebootSafeMode(boolean confirm);
+ public void reboot();
}
/**