diff options
203 files changed, 5869 insertions, 600 deletions
@@ -72,6 +72,7 @@ LOCAL_SRC_FILES += \ core/java/android/app/IBackupAgent.aidl \ core/java/android/app/IInstrumentationWatcher.aidl \ core/java/android/app/INotificationManager.aidl \ + core/java/android/app/IProfileManager.aidl \ core/java/android/app/IProcessObserver.aidl \ core/java/android/app/ISearchManager.aidl \ core/java/android/app/ISearchManagerCallback.aidl \ @@ -250,6 +251,8 @@ aidl_files := \ frameworks/base/core/java/android/accounts/IAccountAuthenticator.aidl \ frameworks/base/core/java/android/accounts/IAccountAuthenticatorResponse.aidl \ frameworks/base/core/java/android/app/Notification.aidl \ + frameworks/base/core/java/android/app/NotificationGroup.aidl \ + frameworks/base/core/java/android/app/Profile.aidl \ frameworks/base/core/java/android/app/PendingIntent.aidl \ frameworks/base/core/java/android/bluetooth/BluetoothDevice.aidl \ frameworks/base/core/java/android/bluetooth/BluetoothHealthAppConfiguration.aidl \ diff --git a/api/current.txt b/api/current.txt index a885ce4..ddf5baf 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12722,18 +12722,6 @@ package android.nfc.tech { method public byte[] transceive(byte[]) throws java.io.IOException; } - public final class IsoPcdA extends android.nfc.tech.BasicTagTechnology { - method public static android.nfc.tech.IsoPcdA get(android.nfc.Tag); - method public int getMaxTransceiveLength(); - method public byte[] transceive(byte[]) throws java.io.IOException; - } - - public final class IsoPcdB extends android.nfc.tech.BasicTagTechnology { - method public static android.nfc.tech.IsoPcdB get(android.nfc.Tag); - method public int getMaxTransceiveLength(); - method public byte[] transceive(byte[]) throws java.io.IOException; - } - public final class MifareClassic extends android.nfc.tech.BasicTagTechnology { method public boolean authenticateSectorWithKeyA(int, byte[]) throws java.io.IOException; method public boolean authenticateSectorWithKeyB(int, byte[]) throws java.io.IOException; @@ -15375,12 +15363,6 @@ package android.preference { method public void setValueIndex(int); } - public class ListPreferenceMultiSelect extends android.preference.ListPreference { - ctor public ListPreferenceMultiSelect(android.content.Context); - ctor public ListPreferenceMultiSelect(android.content.Context, android.util.AttributeSet); - method public static java.lang.String[] parseStoredValue(java.lang.CharSequence); - } - public class MultiSelectListPreference extends android.preference.DialogPreference { ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet); ctor public MultiSelectListPreference(android.content.Context); diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp index 5f8b744..161ba44 100644 --- a/cmds/bootanimation/bootanimation_main.cpp +++ b/cmds/bootanimation/bootanimation_main.cpp @@ -45,7 +45,7 @@ int main(int argc, char** argv) #endif char value[PROPERTY_VALUE_MAX]; - property_get("debug.sf.nobootanimation", value, "0"); + property_get("persist.sys.nobootanimation", value, "0"); int noBootAnimation = atoi(value); LOGI_IF(noBootAnimation, "boot animation disabled"); if (!noBootAnimation) { diff --git a/core/java/android/app/ConnectionSettings.java b/core/java/android/app/ConnectionSettings.java new file mode 100755 index 0000000..f707947 --- /dev/null +++ b/core/java/android/app/ConnectionSettings.java @@ -0,0 +1,207 @@ +package android.app; + +import android.bluetooth.BluetoothAdapter; +import android.content.Context; +import android.location.LocationManager; +import android.net.wifi.WifiManager; +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_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_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); + Boolean state; + + switch (getConnectionId()) { + case PROFILE_CONNECTION_BLUETOOTH: + state = bta.isEnabled(); + if (getValue() == 1) { + if (!state) { + bta.enable(); + } + } else { + if (state) { + bta.disable(); + } + } + break; + case PROFILE_CONNECTION_GPS: + state = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); + if (getValue() == 1) { + if (!state) { + Settings.Secure.setLocationProviderEnabled(context.getContentResolver(), LocationManager.GPS_PROVIDER, true); + } + } else { + if (state) { + Settings.Secure.setLocationProviderEnabled(context.getContentResolver(), LocationManager.GPS_PROVIDER, false); + } + } + break; + case PROFILE_CONNECTION_WIFI: + int wifiApState = wm.getWifiApState(); + state = wm.isWifiEnabled(); + if (getValue() == 1) { + if ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) || (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED)) { + wm.setWifiApEnabled(null, false); + } + if (!state) { + wm.setWifiEnabled(true); + } + } else { + if (state) { + wm.setWifiEnabled(false); + } + } + break; + case PROFILE_CONNECTION_WIFIAP: + int wifiState = wm.getWifiState(); + state = wm.isWifiApEnabled(); + if (getValue() == 1) { + if ((wifiState == WifiManager.WIFI_STATE_ENABLING) || (wifiState == WifiManager.WIFI_STATE_ENABLED)) { + wm.setWifiEnabled(false); + } + if (!state) { + wm.setWifiApEnabled(null, true); + } + } else { + if (state) { + wm.setWifiApEnabled(null, false); + } + } + break; + default: 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 97c3d93..9d972b9 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -459,6 +459,12 @@ class ContextImpl extends Context { public Object createService(ContextImpl ctx) { return WimaxHelper.createWimaxService(ctx, ctx.mMainThread.getHandler()); }}); + + 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..f02a991 --- /dev/null +++ b/core/java/android/app/IProfileManager.aidl @@ -0,0 +1,49 @@ +/* //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); + + 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 f5add25..6073d0d 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -305,6 +305,15 @@ public class Notification implements Parcelable */ public static final int FLAG_HIGH_PRIORITY = 0x00000080; + /** + * 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; + public int flags; /** 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..65cb64a --- /dev/null +++ b/core/java/android/app/NotificationGroup.java @@ -0,0 +1,194 @@ +/* + * 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.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 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..96409b7 --- /dev/null +++ b/core/java/android/app/Profile.java @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.content.Context; +import android.media.AudioManager; +import android.os.Parcel; +import android.os.ParcelUuid; +import android.os.Parcelable; +import android.text.TextUtils; +import android.util.Log; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @hide + */ +public final class Profile implements Parcelable, Comparable { + + private String mName; + + private int mNameResId; + + private UUID mUuid; + + private Map<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>(); + + /** @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); + 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); + } + + /** @hide */ + public void readFromParcel(Parcel in) { + mName = in.readString(); + mNameResId = in.readInt(); + mUuid = ParcelUuid.CREATOR.createFromParcel(in).getUuid(); + mStatusBarIndicator = (in.readInt() == 1); + mProfileType = in.readInt(); + mDirty = (in.readInt() == 1); + for (Parcelable group : in.readParcelableArray(null)) { + ProfileGroup grp = (ProfileGroup) group; + profileGroups.put(grp.getUuid(), grp); + if (grp.isDefaultGroup()) { + mDefaultGroup = grp; + } + } + for (Parcelable parcel : in.readParcelableArray(null)) { + StreamSettings stream = (StreamSettings) parcel; + streams.put(stream.getStreamId(), stream); + } + for (Parcelable parcel : in.readParcelableArray(null)) { + ConnectionSettings connection = (ConnectionSettings) parcel; + connections.put(connection.getConnectionId(), connection); + } + } + + public String getName() { + return mName; + } + + /** @hide */ + public void setName(String name) { + mName = name; + mNameResId = -1; + mDirty = true; + } + + public int getProfileType() { + return mProfileType; + } + + /** @hide */ + public void setProfileType(int type) { + mProfileType = type; + mDirty = true; + } + + public UUID getUuid() { + if (this.mUuid == null) this.mUuid = UUID.randomUUID(); + return this.mUuid; + } + + public boolean getStatusBarIndicator() { + return mStatusBarIndicator; + } + + public void setStatusBarIndicator(boolean newStatusBarIndicator) { + mStatusBarIndicator = newStatusBarIndicator; + mDirty = true; + } + + public boolean isConditionalType() { + return(mProfileType == CONDITIONAL_TYPE ? true : false); + } + + public void setConditionalType() { + mProfileType = CONDITIONAL_TYPE; + mDirty = true; + } + + /** @hide */ + public boolean isDirty() { + if (mDirty) { + return true; + } + for (ProfileGroup group : profileGroups.values()) { + if (group.isDirty()) { + return true; + } + } + for (StreamSettings stream : streams.values()) { + if (stream.isDirty()) { + return true; + } + } + for (ConnectionSettings conn : connections.values()) { + if (conn.isDirty()) { + return true; + } + } + return false; + } + + /** @hide */ + public void getXmlString(StringBuilder builder, Context context) { + builder.append("<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("<profiletype>"); + builder.append(getProfileType() == TOGGLE_TYPE ? "toggle" : "conditional"); + builder.append("</profiletype>\n"); + + builder.append("<statusbar>"); + builder.append(getStatusBarIndicator() ? "yes" : "no"); + builder.append("</statusbar>\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); + } + builder.append("</profile>\n"); + mDirty = false; + } + + /** @hide */ + public static Profile fromXml(XmlPullParser xpp, Context context) + throws XmlPullParserException, IOException { + String value = xpp.getAttributeValue(null, "nameres"); + int profileNameResId = -1; + String profileName = null; + + if (value != null) { + profileNameResId = context.getResources().getIdentifier(value, "string", "android"); + if (profileNameResId > 0) { + profileName = context.getResources().getString(profileNameResId); + } + } + + if (profileName == null) { + profileName = xpp.getAttributeValue(null, "name"); + } + + UUID profileUuid = UUID.randomUUID(); + try { + profileUuid = UUID.fromString(xpp.getAttributeValue(null, "uuid")); + } catch (NullPointerException e) { + Log.w(TAG, + "Null Pointer - UUID not found for " + + profileName + + ". New UUID generated: " + + profileUuid.toString() + ); + } catch (IllegalArgumentException e) { + Log.w(TAG, + "UUID not recognized for " + + profileName + + ". New UUID generated: " + + profileUuid.toString() + ); + } + + Profile profile = new Profile(profileName, profileNameResId, profileUuid); + int event = xpp.next(); + while (event != XmlPullParser.END_TAG) { + if (event == XmlPullParser.START_TAG) { + String name = xpp.getName(); + if (name.equals("statusbar")) { + profile.setStatusBarIndicator(xpp.nextText() == "yes"); + } + if (name.equals("profiletype")) { + profile.setProfileType(xpp.nextText() == "toggle" ? TOGGLE_TYPE : CONDITIONAL_TYPE); + } + if (name.equals("profileGroup")) { + ProfileGroup pg = ProfileGroup.fromXml(xpp, context); + profile.addProfileGroup(pg); + } + if (name.equals("streamDescriptor")) { + StreamSettings sd = StreamSettings.fromXml(xpp, context); + profile.setStreamSettings(sd); + } + if (name.equals("connectionDescriptor")) { + ConnectionSettings cs = ConnectionSettings.fromXml(xpp, context); + profile.connections.put(cs.getConnectionId(), cs); + } + } + event = xpp.next(); + } + + /* we just loaded from XML, so nothing needs saving */ + profile.mDirty = false; + + return profile; + } + + /** @hide */ + public void doSelect(Context context) { + // Set stream volumes + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + for (StreamSettings sd : streams.values()) { + if (sd.isOverride()) { + am.setStreamVolume(sd.getStreamId(), sd.getValue(), 0); + } + } + // Set connections + for (ConnectionSettings cs : connections.values()) { + if (cs.isOverride()) { + cs.processOverride(context); + } + } + } + + /** @hide */ + public StreamSettings getSettingsForStream(int streamId){ + return streams.get(streamId); + } + + /** @hide */ + public void setStreamSettings(StreamSettings descriptor){ + streams.put(descriptor.getStreamId(), descriptor); + mDirty = true; + } + + /** @hide */ + public Collection<StreamSettings> getStreamSettings(){ + return streams.values(); + } + + /** @hide */ + public ConnectionSettings getSettingsForConnection(int connectionId){ + return connections.get(connectionId); + } + + /** @hide */ + public void setConnectionSettings(ConnectionSettings descriptor){ + connections.put(descriptor.getConnectionId(), descriptor); + } + + /** @hide */ + public Collection<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..f9713ae --- /dev/null +++ b/core/java/android/app/ProfileManager.java @@ -0,0 +1,247 @@ +/* + * 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; + } + } + + /** @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/content/Context.java b/core/java/android/content/Context.java index bfbd0ac..0d0402e 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1513,6 +1513,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/nfc/tech/IsoPcdA.java b/core/java/android/nfc/tech/IsoPcdA.java index 5d266de..6018ceb 100755 --- a/core/java/android/nfc/tech/IsoPcdA.java +++ b/core/java/android/nfc/tech/IsoPcdA.java @@ -28,6 +28,7 @@ import android.util.Log; import java.io.IOException; /** + * @hide * Provides access to ISO-PCD type A (ISO 14443-4) properties and I/O operations on a {@link Tag}. * * <p>Acquire an {@link IsoPcdA} object using {@link #get}. diff --git a/core/java/android/nfc/tech/IsoPcdB.java b/core/java/android/nfc/tech/IsoPcdB.java index f8658a9..e3334b1 100755 --- a/core/java/android/nfc/tech/IsoPcdB.java +++ b/core/java/android/nfc/tech/IsoPcdB.java @@ -28,6 +28,7 @@ import android.util.Log; import java.io.IOException; /** + * @hide * Provides access to ISO-PCD type B (ISO 14443-4) properties and I/O operations on a {@link Tag}. * * <p>Acquire an {@link IsoPcdB} object using {@link #get}. diff --git a/core/java/android/preference/ListPreferenceMultiSelect.java b/core/java/android/preference/ListPreferenceMultiSelect.java index ffd72cf..a7dc1bd6 100644 --- a/core/java/android/preference/ListPreferenceMultiSelect.java +++ b/core/java/android/preference/ListPreferenceMultiSelect.java @@ -22,6 +22,9 @@ import android.content.DialogInterface; import android.text.TextUtils; import android.util.AttributeSet; +/** + * @hide + */ public class ListPreferenceMultiSelect extends ListPreference { private static final String SEPARATOR = "OV=I=XseparatorX=I=VO"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index d808ab1..00d5245 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1805,6 +1805,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 @@ -1891,6 +1904,43 @@ public final class Settings { public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse"; /** + * 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 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"; + + /** + * 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_enable"; + + /** * Show pointer location on screen? * 0 = no * 1 = yes @@ -2089,6 +2139,13 @@ public final class Settings { 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 */ @@ -2150,7 +2207,7 @@ public final class Settings { * 2: show signal text numbers w/small dBm appended * @hide */ - public static final String STATUS_BAR_CM_SIGNAL_TEXT = "status_bar_cm_signal"; + public static final String STATUS_BAR_SIGNAL_TEXT = "status_bar_signal"; /** * Whether to control brightness from status bar @@ -2187,12 +2244,73 @@ public final class Settings { 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 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"; + + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. * @@ -2261,6 +2379,12 @@ public final class Settings { SIP_CALL_OPTIONS, SIP_RECEIVE_CALLS, POINTER_SPEED, + QUIET_HOURS_ENABLED, + QUIET_HOURS_START, + QUIET_HOURS_END, + QUIET_HOURS_MUTE, + QUIET_HOURS_STILL, + QUIET_HOURS_DIM, }; // Settings moved to Settings.Secure diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index a99ac03..d289d11 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -741,6 +741,9 @@ public abstract class Window { * @param mask Which of the window flag bits to modify. */ public void setFlags(int flags, int mask) { + if ((flags & mask & WindowManager.LayoutParams.PREVENT_POWER_KEY) != 0){ + mContext.enforceCallingOrSelfPermission("android.permission.PREVENT_POWER_KEY", "No permission to prevent power key"); + } final WindowManager.LayoutParams attrs = getAttributes(); attrs.flags = (attrs.flags&~mask) | (flags&mask); if ((mask&WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0) { @@ -780,6 +783,9 @@ public abstract class Window { * current values. */ public void setAttributes(WindowManager.LayoutParams a) { + if ((a.flags & WindowManager.LayoutParams.PREVENT_POWER_KEY) != 0){ + mContext.enforceCallingOrSelfPermission("android.permission.PREVENT_POWER_KEY", "No permission to prevent power key"); + } mWindowAttributes.copyFrom(a); if (mCallback != null) { mCallback.onWindowAttributesChanged(mWindowAttributes); diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index c0eb65b..42460d5 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -699,6 +699,10 @@ public interface WindowManager extends ViewManager { * {@hide} */ public static final int FLAG_SYSTEM_ERROR = 0x40000000; + /** Window flag: Overrides default power key behavior + * {@hide} */ + public static final int PREVENT_POWER_KEY = 0x80000000; + /** * Various behavioral options/flags. Default is none. * diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 38bb2e1..4167812 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -567,6 +567,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private Runnable mClearScrollingCache; private int mMinimumVelocity; private int mMaximumVelocity; + private int mDecacheThreshold; private float mVelocityScale = 1.0f; final boolean[] mIsScrap = new boolean[1]; @@ -786,6 +787,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchSlop = configuration.getScaledTouchSlop(); mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); + mDecacheThreshold = mMaximumVelocity / 2; mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverflingDistance = configuration.getScaledOverflingDistance(); @@ -3650,7 +3652,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te // Keep the fling alive a little longer postDelayed(this, FLYWHEEL_TIMEOUT); } else { - endFling(); + endFling(false); // Don't disable the scrolling cache right after it was enabled mTouchMode = TOUCH_MODE_SCROLL; reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); } @@ -3664,6 +3666,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } void start(int initialVelocity) { + if (Math.abs(initialVelocity) > mDecacheThreshold) { + // For long flings, scrolling cache causes stutter, so don't use it + clearScrollingCache(); + } + int initialY = initialVelocity < 0 ? Integer.MAX_VALUE : 0; mLastFlingY = initialY; mScroller.fling(0, initialY, 0, initialVelocity, @@ -3733,13 +3740,18 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } void endFling() { + endFling(true); + } + + void endFling(boolean clearCache) { mTouchMode = TOUCH_MODE_REST; removeCallbacks(this); removeCallbacks(mCheckFlywheel); reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); - clearScrollingCache(); + if (clearCache) + clearScrollingCache(); mScroller.abortAnimation(); if (mFlingStrictSpan != null) { diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java index d445ab4..82a3296 100644 --- a/core/java/com/android/internal/app/ShutdownThread.java +++ b/core/java/com/android/internal/app/ShutdownThread.java @@ -66,6 +66,7 @@ public final class ShutdownThread extends Thread { // Provides shutdown assurance in case the system_server is killed public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested"; + public static final String RADIO_SHUTDOWN_PROPERTY = "sys.radio.shutdown"; // static instance of this thread private static final ShutdownThread sInstance = new ShutdownThread(); @@ -364,6 +365,7 @@ public final class ShutdownThread extends Thread { radioOff = true; } + SystemProperties.set(RADIO_SHUTDOWN_PROPERTY, "true"); Log.i(TAG, "Waiting for Bluetooth and Radio..."); // Wait a max of 32 seconds for clean shutdown diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 97658a1..2e5dd50 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -541,6 +541,14 @@ android:label="@string/permlab_camera" android:description="@string/permdesc_camera" /> + <!-- Allows an application to override the power key action + @hide --> + <permission android:name="android.permission.PREVENT_POWER_KEY" + android:permissionGroup="android.permission-group.HARDWARE_CONTROLS" + android:protectionLevel="dangerous" + android:label="@string/permlab_preventpower" + android:description="@string/permdesc_preventpower" /> + <!-- Allows access to the vibrator --> <permission android:name="android.permission.VIBRATE" android:permissionGroup="android.permission-group.HARDWARE_CONTROLS" diff --git a/core/res/res/drawable-hdpi/ic_lock_profile.png b/core/res/res/drawable-hdpi/ic_lock_profile.png Binary files differnew file mode 100644 index 0000000..b4e3370 --- /dev/null +++ b/core/res/res/drawable-hdpi/ic_lock_profile.png diff --git a/core/res/res/drawable-mdpi/ic_lock_profile.png b/core/res/res/drawable-mdpi/ic_lock_profile.png Binary files differnew file mode 100644 index 0000000..22e670e --- /dev/null +++ b/core/res/res/drawable-mdpi/ic_lock_profile.png diff --git a/core/res/res/drawable-xhdpi/ic_lock_profile.png b/core/res/res/drawable-xhdpi/ic_lock_profile.png Binary files differnew file mode 100644 index 0000000..4da6bf9 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ic_lock_profile.png diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 97b5a50..14dc72b 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -139,7 +139,8 @@ <string name="power_off" msgid="4266614107412865048">"Ausschalten"</string> <!-- Button to reboot the phone, within the Phone Options dialog --> - <string name="reboot_system">Neu starten</string> + <string name="reboot_system" product="tablet">Tablet neu starten</string> + <string name="reboot_system" product="default">Telefon neu starten</string> <!-- Button to reboot the phone, within the Reboot Options dialog --> <string name="reboot_reboot">Neu starten</string> @@ -1051,8 +1052,8 @@ <string name="extmedia_format_message" product="nosdcard" msgid="8296908079722897772">"USB-Speicher formatieren und alle darin befindlichen Dateien löschen? Diese Aktion kann nicht rückgängig gemacht werden!"</string> <string name="extmedia_format_message" product="default" msgid="3621369962433523619">"Möchten Sie die SD-Karte wirklich formatieren? Alle Daten auf Ihrer Karte gehen dann verloren."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"Android-Debugging eingeschaltet"</string> + <string name="adb_active_notification_message" msgid="8470296818270110396">"Android-Debugging deaktivieren: auswählen"</string> <string name="select_input_method" msgid="6865512749462072765">"Eingabemethode auswählen"</string> <string name="configure_input_methods" msgid="6324843080254191535">"Eingabemethoden konfigurieren"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> @@ -1254,4 +1255,7 @@ <string name="sending" msgid="8715108995741758718">"Wird gesendet..."</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string> <string name="SetupCallDefault" msgid="6870275517518479651">"Anruf annehmen?"</string> + + <!--Application killed toast --> + <string name="app_killed_message">Anwendung beendet</string> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index d0953b0..9d1dd0f 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1230,4 +1230,5 @@ <string name="sending" msgid="8715108995741758718">"Lähetetään..."</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string> <string name="SetupCallDefault" msgid="6870275517518479651">"Vastataanko puheluun?"</string> + <string name="global_action_screenshot">Kuvakaappaus</string> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index c2ad9a4..d366420 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -898,8 +898,8 @@ <string name="no" msgid="5141531044935541497">"Odustani"</string> <string name="dialog_alert_title" msgid="2049658708609043103">"Pažnja"</string> <string name="loading" msgid="1760724998928255250">"Učitavanje..."</string> - <string name="capital_on" msgid="1544682755514494298">"Uključeno"</string> - <string name="capital_off" msgid="6815870386972805832">"Isključeno"</string> + <string name="capital_on" msgid="1544682755514494298">"Uklj"</string> + <string name="capital_off" msgid="6815870386972805832">"Isklj"</string> <string name="whichApplication" msgid="4533185947064773386">"Radnju dovrši pomoću stavke"</string> <string name="alwaysUse" msgid="4583018368000610438">"Koristi se kao zadana postavka za ovu lokaciju."</string> <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Izbrišite zadane postavke u izborniku Početne postavke > Aplikacije > Upravljanje aplikacijama."</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 9752240..224bdf1 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1230,4 +1230,44 @@ <string name="sending" msgid="8715108995741758718">"送信しています..."</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string> <string name="SetupCallDefault" msgid="6870275517518479651">"通話を受けますか?"</string> + + <!-- CM Extra entries --> + <!-- Button to reboot the phone, within the Phone Options dialog --> + <string name="reboot_system" product="tablet">タブレットを再起動</string> + <string name="reboot_system" product="default">携帯電話を再起動</string> + + <!-- label for item that screenshots in phone options dialog --> + <string name="global_action_screenshot">スクリーンショット</string> + + <!-- Button to reboot the phone, within the Reboot Options dialog --> + <string name="reboot_reboot">再起動</string> + <!-- Button to reboot the phone into recovery, within the Reboot Options dialog --> + <string name="reboot_recovery">リカバリー</string> + <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog --> + <string name="reboot_bootloader">ブートローダー</string> + <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog --> + <string name="reboot_bootmenu">ブートメニュー</string> + <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog --> + <string name="reboot_fastboot">ファストブート</string> + <!-- Button to reboot the phone into download, within the Reboot Options dialog --> + <string name="reboot_download">ダウンロード</string> + + <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. --> + <string name="reboot_progress">再起動中\u2026</string> + <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. --> + <string name="reboot_confirm">端末は再起動します</string> + + <!-- Spoken description for ringer silent option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_silent">着信音 OFF</string> + <!-- Spoken description for ringer vibrate option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_vibrate">着信振動</string> + <!-- Spoken description for ringer normal option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_ring">着信音 ON</string> + <!-- label for item that reboots the phone in phone options dialog --> + <string name="global_action_reboot">再起動</string> + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_preventpower">電源キーを保護</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_preventpower">アプリケーションが電源キーを置き換えるのを許可する</string> + </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index e81a86a..09970fb 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1027,8 +1027,8 @@ <string name="extmedia_format_message" product="nosdcard" msgid="8296908079722897772">"USB 저장소를 포맷하여 저장된 파일을 모두 지우시겠습니까? 수행한 후에는 작업을 취소할 수 없습니다."</string> <string name="extmedia_format_message" product="default" msgid="3621369962433523619">"SD 카드를 포맷하시겠습니까? 포맷하면 카드의 모든 데이터를 잃게 됩니다."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"포맷"</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"디버깅 연결됨"</string> + <string name="adb_active_notification_message" msgid="8470296818270110396">"디버깅을 사용하지 않으려면 선택합니다."</string> <string name="select_input_method" msgid="6865512749462072765">"입력 방법 선택"</string> <string name="configure_input_methods" msgid="6324843080254191535">"입력 방법 구성"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> @@ -1230,4 +1230,44 @@ <string name="sending" msgid="8715108995741758718">"보내는 중..."</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"브라우저를 실행하시겠습니까?"</string> <string name="SetupCallDefault" msgid="6870275517518479651">"통화를 수락하시겠습니까?"</string> + <!--Application killed toast --> + <string name="app_killed_message">어플리케이션 종료됨</string> + + <!-- Button to reboot the phone, within the Phone Options dialog --> + <string name="reboot_system" product="tablet">태블릿 다시 시작</string> + <string name="reboot_system" product="default">휴대전화 다시 시작</string> + + <!-- label for item that screenshots in phone options dialog --> + <string name="global_action_screenshot">스크린샷</string> + + <!-- Button to reboot the phone, within the Reboot Options dialog --> + <string name="reboot_reboot">다시 시작</string> + <!-- Button to reboot the phone into recovery, within the Reboot Options dialog --> + <string name="reboot_recovery">복구 모드</string> + <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog --> + <string name="reboot_bootloader">부트로더</string> + <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog --> + <string name="reboot_bootmenu">부트 메뉴</string> + <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog --> + <string name="reboot_fastboot">Fastboot</string> + <!-- Button to reboot the phone into download, within the Reboot Options dialog --> + <string name="reboot_download">Download</string> + + <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. --> + <string name="reboot_progress">다시 시작하는 중\u2026</string> + <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. --> + <string name="reboot_confirm">휴대전화가 다시 시작됩니다.</string> + + <!-- Spoken description for ringer silent option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_silent">소리 끄기</string> + <!-- Spoken description for ringer vibrate option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_vibrate">진동 모드</string> + <!-- Spoken description for ringer normal option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_ring">소리 켜기</string> + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_preventpower">전원 버튼 작동 제한</string> + + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_preventpower">어플리케이션이 전원 버튼의 작동을 제한 할 수 있도록 허용합니다.</string> + </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 9dca538..08c6fed 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1,23 +1,19 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -/* //device/apps/common/assets/res/any/strings.xml -** -** Copyright 2006, 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. -*/ - --> +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<!-- //device/apps/common/assets/res/any/strings.xml --> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> @@ -128,7 +124,7 @@ <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchroniseren"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Te veel verwijderen voor <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> <string name="low_memory" product="tablet" msgid="2292820184396262278">"Tabletgeheugen is vol. Verwijder enkele bestanden om ruimte vrij te maken."</string> - <string name="low_memory" product="default" msgid="6632412458436461203">"Telefoongeheugen is vol! Verwijder enkele bestanden om ruimte vrij te maken."</string> + <string name="low_memory" product="default" msgid="6632412458436461203">"Telefoongeheugen is vol. Verwijder enkele bestanden om ruimte vrij te maken."</string> <string name="me" msgid="6545696007631404292">"Ik"</string> <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tabletopties"</string> <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefoonopties"</string> @@ -137,13 +133,10 @@ <string name="turn_off_radio" msgid="8198784949987062346">"Draadloos uitschakelen"</string> <string name="screen_lock" msgid="799094655496098153">"Schermvergrendeling"</string> <string name="power_off" msgid="4266614107412865048">"Uitschakelen"</string> - <!-- no translation found for silent_mode_silent (319298163018473078) --> - <skip /> - <!-- no translation found for silent_mode_vibrate (7072043388581551395) --> - <skip /> - <!-- no translation found for silent_mode_ring (8592241816194074353) --> - <skip /> - <string name="shutdown_progress" msgid="2281079257329981203">"Uitschakelen..."</string> + <string name="silent_mode_silent" msgid="319298163018473078">Beltoon uit</string> + <string name="silent_mode_vibrate" msgid="7072043388581551395">Beltoon wordt trilsignaal</string> + <string name="silent_mode_ring" msgid="8592241816194074353">Beltoon aan</string> + <string name="shutdown_progress" msgid="2281079257329981203">"Uitschakelen\u2026"</string> <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Uw tablet wordt uitgeschakeld."</string> <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Uw telefoon wordt uitgeschakeld."</string> <string name="shutdown_confirm_question" msgid="6656441286856415014">"Wilt u afsluiten?"</string> @@ -241,21 +234,21 @@ <string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"alle startende apps bijhouden en beheren"</string> <string name="permdesc_runSetActivityWatcher" msgid="2149363027173451218">"Hiermee kan een app de manier waarop het systeem activiteiten start, bijhouden en beheren. Schadelijke apps kunnen het systeem volledig in gevaar brengen. Deze machtiging is alleen voor ontwikkeling vereist, nooit voor normaal gebruik."</string> <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"melding verzenden dat pakket is verwijderd"</string> - <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"Hiermee kan een app een melding verzenden dat een applicatiepakket (APK) is verwijderd. Schadelijke apps kunnen hiervan gebruik maken om alle andere actieve apps af te sluiten."</string> + <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"Hiermee kan een app een melding verzenden dat een app-pakket (APK) is verwijderd. Schadelijke apps kunnen hiervan gebruik maken om alle andere actieve apps af te sluiten."</string> <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"melding over ontvangen SMS-bericht verzenden"</string> <string name="permdesc_broadcastSmsReceived" msgid="9122419277306740155">"Hiermee kan een app een melding verzenden dat een SMS-bericht is ontvangen. Schadelijke apps kunnen hiervan gebruik maken om inkomende SMS-berichten te vervalsen."</string> <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"melding over ontvangen WAP-PUSH-bericht verzenden"</string> <string name="permdesc_broadcastWapPush" msgid="3955303669461378091">"Hiermee kan een app een melding verzenden dat een WAP PUSH-bericht is ontvangen. Schadelijke apps kunnen hiervan gebruik maken om een valse MMS-ontvangst te melden of de inhoud van willekeurige webpagina\'s door schadelijke varianten te vervangen."</string> <string name="permlab_setProcessLimit" msgid="2451873664363662666">"aantal actieve processen beperken"</string> <string name="permdesc_setProcessLimit" msgid="7824786028557379539">"Hiermee kan een app het maximum aantal processen bepalen dat wordt uitgevoerd. Nooit vereist voor normale apps."</string> - <string name="permlab_setAlwaysFinish" msgid="5342837862439543783">"alle achtergrondapplicaties sluiten"</string> + <string name="permlab_setAlwaysFinish" msgid="5342837862439543783">"alle achtergrondapps sluiten"</string> <string name="permdesc_setAlwaysFinish" msgid="8773936403987091620">"Hiermee kan een app bepalen of activiteiten altijd worden afgesloten zodra deze naar de achtergrond gaan. Nooit nodig voor normale apps."</string> <string name="permlab_batteryStats" msgid="7863923071360031652">"accustatistieken aanpassen"</string> <string name="permdesc_batteryStats" msgid="5847319823772230560">"Hiermee kunnen verzamelde accustatistieken worden gewijzigd. Niet voor gebruik door normale apps."</string> <string name="permlab_backup" msgid="470013022865453920">"systeemback-up en -herstel beheren"</string> <string name="permdesc_backup" msgid="4837493065154256525">"Hiermee kan de app het mechanisme voor systeemback-up en -herstel beheren. Niet voor gebruik door normale apps."</string> <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"een volledige back-up- of herstelbewerking bevestigen"</string> - <string name="permdesc_confirm_full_backup" msgid="9005017754175897954">"Hiermee kan de applicatie de gebruikersinterface voor bevestiging van de volledige back-up starten. Moet niet worden gebruikt door een applicatie."</string> + <string name="permdesc_confirm_full_backup" msgid="9005017754175897954">"Hiermee kan een app de gebruikersinterface voor bevestiging van de volledige back-up starten. Moet niet worden gebruikt door een app."</string> <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"niet-geautoriseerde vensters weergeven"</string> <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Hiermee kunnen vensters worden gemaakt die door de interne systeemgebruikersinterface worden gebruikt. Niet voor gebruik door normale apps."</string> <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"waarschuwingen op systeemniveau weergeven"</string> @@ -373,10 +366,10 @@ <string name="permlab_brick" product="default" msgid="8337817093326370537">"telefoon permanent uitschakelen"</string> <string name="permdesc_brick" product="tablet" msgid="7379164636920817963">"Hiermee kan de app de tablet permanent uitschakelen. Dit is erg gevaarlijk."</string> <string name="permdesc_brick" product="default" msgid="5569526552607599221">"Hiermee kan de app de telefoon permanent uitschakelen. Dit is erg gevaarlijk."</string> - <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"opnieuw opstarten van tablet afdwingen"</string> - <string name="permlab_reboot" product="default" msgid="2898560872462638242">"telefoon nu opnieuw opstarten"</string> - <string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"Hiermee kan de app de tablet opnieuw opstarten."</string> - <string name="permdesc_reboot" product="default" msgid="7914933292815491782">"Hiermee kan de app de telefoon nu opnieuw opstarten."</string> + <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"herstarten van tablet afdwingen"</string> + <string name="permlab_reboot" product="default" msgid="2898560872462638242">"telefoon nu herstarten"</string> + <string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"Hiermee kan de app de tablet herstarten."</string> + <string name="permdesc_reboot" product="default" msgid="7914933292815491782">"Hiermee kan de app de telefoon nu herstarten."</string> <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"bestandssystemen koppelen en ontkoppelen"</string> <string name="permdesc_mount_unmount_filesystems" msgid="6253263792535859767">"Hiermee kan de app bestandssystemen koppelen en ontkoppelen voor verwisselbare opslagruimte."</string> <string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"externe opslag formatteren"</string> @@ -513,7 +506,7 @@ <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"netwerkbeleid beheren"</string> <string name="permdesc_manageNetworkPolicy" msgid="3723795285132803958">"Hiermee kan een app het netwerkbeleid beheren en app-specifieke regels definiëren."</string> <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"verrekening van netwerkgebruik aanpassen"</string> - <string name="permdesc_modifyNetworkAccounting" msgid="8702285686629184404">"Toestaan dat de manier waarop het netwerkgebruik wordt verrekend met applicaties, wordt aangepast. Niet voor gebruik door normale applicaties."</string> + <string name="permdesc_modifyNetworkAccounting" msgid="8702285686629184404">"Toestaan dat de manier waarop het netwerkgebruik wordt verrekend met apps, wordt aangepast. Niet voor gebruik door normale apps."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string> <string name="policydesc_limitPassword" msgid="9083400080861728056">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling"</string> <string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string> @@ -687,7 +680,7 @@ <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-kaart is vergrendeld met PUK-code."</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="635967534992394321">"Raadpleeg de gebruikershandleiding of neem contact op met de klantenservice."</string> <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart is vergrendeld."</string> - <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaart ontgrendelen..."</string> + <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaart ontgrendelen\u2026"</string> <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="3514742106066877476">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="4906034376425175381">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist ingevoerd. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string> <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6827749231465145590">"U heeft uw PIN-code <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist ingevoerd. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string> @@ -707,7 +700,7 @@ <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Aanmelden"</string> <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Gebruikersnaam of wachtwoord ongeldig."</string> <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Bent u uw gebruikersnaam of wachtwoord vergeten?"\n"Ga naar "<b>"https://www.google.com/accounts/recovery?hl=nl"</b></string> - <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Controleren..."</string> + <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Controleren\u2026"</string> <string name="lockscreen_unlock_label" msgid="737440483220667054">"Ontgrendelen"</string> <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Geluid aan"</string> <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Geluid uit"</string> @@ -723,7 +716,7 @@ <string name="factorytest_failed" msgid="5410270329114212041">"Fabriekstest mislukt"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"De actie FACTORY_TEST wordt alleen ondersteund voor pakketten die zijn geïnstalleerd in /system/app."</string> <string name="factorytest_no_action" msgid="872991874799998561">"Er is geen pakket gevonden dat de actie FACTORY_TEST levert."</string> - <string name="factorytest_reboot" msgid="6320168203050791643">"Opnieuw opstarten"</string> + <string name="factorytest_reboot" msgid="6320168203050791643">"Herstarten"</string> <string name="js_dialog_title" msgid="8143918455087008109">"De pagina op \'<xliff:g id="TITLE">%s</xliff:g>\' zegt:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Wilt u deze pagina verlaten?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Kies OK om door te gaan of Annuleren om op de huidige pagina te blijven."</string> @@ -880,10 +873,10 @@ <string name="cut" msgid="3092569408438626261">"Knippen"</string> <string name="copy" msgid="2681946229533511987">"Kopiëren"</string> <string name="paste" msgid="5629880836805036433">"Plakken"</string> - <string name="replace" msgid="5781686059063148930">"Vervangen..."</string> + <string name="replace" msgid="5781686059063148930">"Vervangen\u2026"</string> <string name="delete" msgid="6098684844021697789">"Verwijderen"</string> <string name="copyUrl" msgid="2538211579596067402">"URL kopiëren"</string> - <string name="selectTextMode" msgid="6738556348861347240">"Tekst selecteren..."</string> + <string name="selectTextMode" msgid="6738556348861347240">"Tekst selecteren\u2026"</string> <string name="textSelectionCABTitle" msgid="5236850394370820357">"Tekstselectie"</string> <string name="addToDictionary" msgid="9090375111134433012">"toevoegen aan woordenboek"</string> <string name="deleteText" msgid="7070985395199629156">"verwijderen"</string> @@ -897,7 +890,7 @@ <string name="yes" msgid="5362982303337969312">"OK"</string> <string name="no" msgid="5141531044935541497">"Annuleren"</string> <string name="dialog_alert_title" msgid="2049658708609043103">"Let op"</string> - <string name="loading" msgid="1760724998928255250">"Laden..."</string> + <string name="loading" msgid="1760724998928255250">"Laden\u2026"</string> <string name="capital_on" msgid="1544682755514494298">"AAN"</string> <string name="capital_off" msgid="6815870386972805832">"UIT"</string> <string name="whichApplication" msgid="4533185947064773386">"Actie voltooien met"</string> @@ -925,8 +918,8 @@ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Dit opnieuw inschakelen via \'Instellingen\' > \'Apps\' > \'Apps beheren\'."</string> <string name="smv_application" msgid="295583804361236288">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) heeft het zelf afgedwongen StrictMode-beleid geschonden."</string> <string name="smv_process" msgid="5120397012047462446">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> heeft het zelf afgedwongen StrictMode-beleid geschonden."</string> - <string name="android_upgrading_title" msgid="378740715658358071">"Android wordt bijgewerkt..."</string> - <string name="android_upgrading_apk" msgid="274409861603566003">"Applicatie <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g> optimaliseren."</string> + <string name="android_upgrading_title" msgid="378740715658358071">"Android wordt bijgewerkt\u2026"</string> + <string name="android_upgrading_apk" msgid="274409861603566003">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g> optimaliseren."</string> <string name="android_upgrading_starting_apps" msgid="7959542881906488763">"Apps starten."</string> <string name="android_upgrading_complete" msgid="1405954754112999229">"Opstarten afronden."</string> <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> wordt uitgevoerd"</string> @@ -1111,10 +1104,10 @@ <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> van <xliff:g id="TOTAL">%d</xliff:g>"</item> </plurals> <string name="action_mode_done" msgid="7217581640461922289">"Gereed"</string> - <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USB-opslag ontkoppelen..."</string> - <string name="progress_unmounting" product="default" msgid="5556813978958789471">"SD-kaart ontkoppelen..."</string> - <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USB-opslag wissen..."</string> - <string name="progress_erasing" product="default" msgid="2115214724367534095">"SD-kaart wissen..."</string> + <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USB-opslag ontkoppelen\u2026"</string> + <string name="progress_unmounting" product="default" msgid="5556813978958789471">"SD-kaart ontkoppelen\u2026"</string> + <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USB-opslag wissen\u2026"</string> + <string name="progress_erasing" product="default" msgid="2115214724367534095">"SD-kaart wissen\u2026"</string> <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Kan USB-opslag niet wissen."</string> <string name="format_error" product="default" msgid="7315248696644510935">"Kan SD-kaart niet wissen."</string> <string name="media_bad_removal" msgid="7960864061016603281">"SD-kaart is verwijderd voordat deze is ontkoppeld."</string> @@ -1172,7 +1165,7 @@ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modus wijzigen"</string> <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string> <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string> - <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Een applicatie kiezen"</string> + <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Een app kiezen"</string> <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delen met"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delen met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="7311938669217173870">"Schuifgreep. Tikken en blijven aanraken."</string> @@ -1193,7 +1186,7 @@ <string name="storage_internal" msgid="7556050805474115618">"Interne opslag"</string> <string name="storage_sd_card" msgid="8921771478629812343">"SD-kaart"</string> <string name="storage_usb" msgid="3017954059538517278">"USB-opslag"</string> - <string name="extract_edit_menu_button" msgid="302060189057163906">"Bewerken..."</string> + <string name="extract_edit_menu_button" msgid="302060189057163906">"Bewerken\u2026"</string> <string name="data_usage_warning_title" msgid="1955638862122232342">"Waarschuwing v. gegevensgebruik"</string> <string name="data_usage_warning_body" msgid="7217480745540055170">"Aanraken: gebruik/inst. bekijken"</string> <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-/3G-gegevens uitgeschakeld"</string> @@ -1222,12 +1215,22 @@ <string name="fingerprints" msgid="4516019619850763049">"Vingerafdrukken:"</string> <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256-vingerafdruk"</string> <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1-vingerafdruk:"</string> - <string name="activity_chooser_view_see_all" msgid="180268188117163072">"Alle bekijken..."</string> + <string name="activity_chooser_view_see_all" msgid="180268188117163072">"Alle bekijken\u2026"</string> <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Activiteit selecteren"</string> - <string name="share_action_provider_share_with" msgid="1791316789651185229">"Delen met..."</string> + <string name="share_action_provider_share_with" msgid="1791316789651185229">"Delen met\u2026"</string> <string name="status_bar_device_locked" msgid="3092703448690669768">"Apparaat vergrendeld."</string> <string name="list_delimeter" msgid="3975117572185494152">", "</string> - <string name="sending" msgid="8715108995741758718">"Verzenden..."</string> + <string name="sending" msgid="8715108995741758718">"Verzenden\u2026"</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string> <string name="SetupCallDefault" msgid="6870275517518479651">"Oproep accepteren?"</string> + + <!-- CyanogenMod additions --> + <string name="reboot_system" product="tablet">Tablet herstarten</string> + <string name="reboot_system" product="default">Telefoon herstarten</string> + <string name="global_action_screenshot">Beeldschermafdruk</string> + <string name="reboot_reboot">Normaal herstarten</string> + <string name="reboot_progress">Herstarten\u2026</string> + <string name="reboot_confirm">Uw telefoon zal worden herstart.</string> + <string name="global_action_reboot">Herstarten</string> + <string name="app_killed_message">App geforceerd afgesloten</string> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 92ebb83..7e9c375 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -28,7 +28,7 @@ <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="7670819340156489359">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="6071602020171759109">"<sem título>"</string> - <string name="ellipsis" msgid="7899829516048813237">"…"</string> + <string name="ellipsis" msgid="7899829516048813237">"\u2026"</string> <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string> <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nenhum número de telefone)"</string> <string name="unknownName" msgid="2277556546742746522">"(Desconhecido)"</string> @@ -143,7 +143,7 @@ <skip /> <!-- no translation found for silent_mode_ring (8592241816194074353) --> <skip /> - <string name="shutdown_progress" msgid="2281079257329981203">"Encerrando…"</string> + <string name="shutdown_progress" msgid="2281079257329981203">"Encerrando\u2026"</string> <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Seu tablet será desligado."</string> <string name="shutdown_confirm" product="default" msgid="649792175242821353">"O seu telefone será desligado."</string> <string name="shutdown_confirm_question" msgid="6656441286856415014">"Gostaria de desligar?"</string> @@ -687,7 +687,7 @@ <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"O cartão SIM está bloqueado pelo PUK."</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="635967534992394321">"Consulte o Guia do Usuário ou entre em contato com o Serviço de atendimento ao cliente."</string> <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"O cartão SIM está bloqueado."</string> - <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando o cartão SIM…"</string> + <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando o cartão SIM\u2026"</string> <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="3514742106066877476">"Você desenhou incorretamente o seu padrão de desbloqueio <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="4906034376425175381">"Você inseriu incorretamente a sua senha <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6827749231465145590">"Você digitou incorretamente o seu PIN <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> @@ -707,7 +707,7 @@ <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Fazer login"</string> <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de usuário ou senha inválidos."</string> <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Esqueceu seu nome de usuário ou senha?"\n"Acesse "<b>"google.com/accounts/recovery"</b></string> - <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Verificando..."</string> + <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Verificando\u2026"</string> <string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string> <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Som ativado"</string> <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Som desativado"</string> @@ -880,10 +880,10 @@ <string name="cut" msgid="3092569408438626261">"Recortar"</string> <string name="copy" msgid="2681946229533511987">"Copiar"</string> <string name="paste" msgid="5629880836805036433">"Colar"</string> - <string name="replace" msgid="5781686059063148930">"Substituir..."</string> + <string name="replace" msgid="5781686059063148930">"Substituir\u2026"</string> <string name="delete" msgid="6098684844021697789">"Excluir"</string> <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string> - <string name="selectTextMode" msgid="6738556348861347240">"Selecionar texto..."</string> + <string name="selectTextMode" msgid="6738556348861347240">"Selecionar texto\u2026"</string> <string name="textSelectionCABTitle" msgid="5236850394370820357">"Seleção de texto"</string> <string name="addToDictionary" msgid="9090375111134433012">"adicionar ao dicionário"</string> <string name="deleteText" msgid="7070985395199629156">"excluir"</string> @@ -897,7 +897,7 @@ <string name="yes" msgid="5362982303337969312">"OK"</string> <string name="no" msgid="5141531044935541497">"Cancelar"</string> <string name="dialog_alert_title" msgid="2049658708609043103">"Atenção"</string> - <string name="loading" msgid="1760724998928255250">"Carregando..."</string> + <string name="loading" msgid="1760724998928255250">"Carregando\u2026"</string> <string name="capital_on" msgid="1544682755514494298">"LIG"</string> <string name="capital_off" msgid="6815870386972805832">"DESL"</string> <string name="whichApplication" msgid="4533185947064773386">"Complete a ação usando"</string> @@ -925,7 +925,7 @@ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Reativar em Configurações > Aplicativos > Gerenciar aplicativos."</string> <string name="smv_application" msgid="295583804361236288">"O aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) violou a política StrictMode imposta automaticamente."</string> <string name="smv_process" msgid="5120397012047462446">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> violou a política StrictMode imposta automaticamente."</string> - <string name="android_upgrading_title" msgid="378740715658358071">"O Android está sendo atualizado..."</string> + <string name="android_upgrading_title" msgid="378740715658358071">"O Android está sendo atualizado\u2026"</string> <string name="android_upgrading_apk" msgid="274409861603566003">"Otimizando aplicativo <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string> <string name="android_upgrading_starting_apps" msgid="7959542881906488763">"Iniciando os aplicativos."</string> <string name="android_upgrading_complete" msgid="1405954754112999229">"Concluindo a inicialização."</string> @@ -1111,10 +1111,10 @@ <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g>"</item> </plurals> <string name="action_mode_done" msgid="7217581640461922289">"Concluído"</string> - <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Desconectando armazenamento USB..."</string> - <string name="progress_unmounting" product="default" msgid="5556813978958789471">"Desconectando cartão SD..."</string> - <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Apagando o armazenamento USB..."</string> - <string name="progress_erasing" product="default" msgid="2115214724367534095">"Apagando cartão SD..."</string> + <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Desconectando armazenamento USB\u2026"</string> + <string name="progress_unmounting" product="default" msgid="5556813978958789471">"Desconectando cartão SD\u2026"</string> + <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Apagando o armazenamento USB\u2026"</string> + <string name="progress_erasing" product="default" msgid="2115214724367534095">"Apagando cartão SD\u2026"</string> <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Não foi possível apagar o armazenamento USB."</string> <string name="format_error" product="default" msgid="7315248696644510935">"Não foi possível apagar o cartão SD."</string> <string name="media_bad_removal" msgid="7960864061016603281">"O cartão SD foi removido antes de ser desconectado."</string> @@ -1193,7 +1193,7 @@ <string name="storage_internal" msgid="7556050805474115618">"Armazenamento interno"</string> <string name="storage_sd_card" msgid="8921771478629812343">"Cartão SD"</string> <string name="storage_usb" msgid="3017954059538517278">"Armazenamento USB"</string> - <string name="extract_edit_menu_button" msgid="302060189057163906">"Editar..."</string> + <string name="extract_edit_menu_button" msgid="302060189057163906">"Editar\u2026"</string> <string name="data_usage_warning_title" msgid="1955638862122232342">"Aviso sobre uso de dados"</string> <string name="data_usage_warning_body" msgid="7217480745540055170">"Toque p/ ver uso e configurações"</string> <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Dados 2G e 3G desativados"</string> @@ -1222,12 +1222,60 @@ <string name="fingerprints" msgid="4516019619850763049">"Impressões digitais"</string> <string name="sha256_fingerprint" msgid="4391271286477279263">"Impressão digital SHA-256"</string> <string name="sha1_fingerprint" msgid="7930330235269404581">"Impressão digital SHA-1"</string> - <string name="activity_chooser_view_see_all" msgid="180268188117163072">"Ver todos..."</string> + <string name="activity_chooser_view_see_all" msgid="180268188117163072">"Ver todos\u2026"</string> <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Selecionar atividade"</string> - <string name="share_action_provider_share_with" msgid="1791316789651185229">"Compartilhar com..."</string> + <string name="share_action_provider_share_with" msgid="1791316789651185229">"Compartilhar com\u2026"</string> <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado."</string> <string name="list_delimeter" msgid="3975117572185494152">", "</string> - <string name="sending" msgid="8715108995741758718">"Enviando..."</string> + <string name="sending" msgid="8715108995741758718">"Enviando\u2026"</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"Abrir Navegador?"</string> <string name="SetupCallDefault" msgid="6870275517518479651">"Aceitar chamada?"</string> + + <!-- Names of default profiles. --> + <string name="profileNameDefault">Padrão</string> + <string name="profileNameWork">Trabalho</string> + <string name="profileNameHome">Casa</string> + <string name="profileNameSilent">Silêncio</string> + <string name="profileNameNight">Noite</string> + + <!-- Names of application groups. --> + <string name="profileGroupPhone">Telefone</string> + <string name="profileGroupCalendar">Agenda</string> + <string name="profileGroupGmail">Gmail</string> + <string name="profileGroupEmail">Email</string> + <string name="profileGroupSMS">SMS</string> + + <!-- Name of wildcard profile. --> + <string name="wildcardProfile">Outro</string> + + <!-- label for item that reboots the phone in phone options dialog --> + <string name="global_action_choose_profile">Escolher perfil</string> + + <!-- Button to reboot the phone, within the Phone Options dialog --> + <string name="reboot_system" product="tablet">Reiniciar tablet</string> + <string name="reboot_system" product="default">Reiniciar telefone</string> + + <!-- label for item that screenshots in phone options dialog --> + <string name="global_action_screenshot">Capturar tela</string> + + <!-- label for item that reboots the phone in phone options dialog --> + <string name="global_action_reboot">Reiniciar</string> + + <!-- Button to reboot the phone, within the Reboot Options dialog --> + <string name="reboot_reboot">Reiniciar</string> + <!-- Button to reboot the phone into recovery, within the Reboot Options dialog --> + <string name="reboot_recovery">Recuperação</string> + <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog --> + <string name="reboot_bootloader">Bootloader</string> + <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog --> + <string name="reboot_bootmenu">Menu de boot</string> + <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog --> + <string name="reboot_fastboot">Fastboot</string> + <!-- Button to reboot the phone into download, within the Reboot Options dialog --> + <string name="reboot_download">Download</string> + + <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. --> + <string name="reboot_progress">Reiniciando\u2026</string> + <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. --> + <string name="reboot_confirm">Seu telefone vai reiniciar.</string> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 9d7c1a7..465363e 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -137,12 +137,27 @@ <string name="turn_off_radio" msgid="8198784949987062346">"Отключить беспроводное соединение"</string> <string name="screen_lock" msgid="799094655496098153">"Блокировка экрана"</string> <string name="power_off" msgid="4266614107412865048">"Выключение"</string> - <!-- no translation found for silent_mode_silent (319298163018473078) --> - <skip /> - <!-- no translation found for silent_mode_vibrate (7072043388581551395) --> - <skip /> - <!-- no translation found for silent_mode_ring (8592241816194074353) --> - <skip /> + <!-- Button to reboot the phone, within the Phone Options dialog --> + <string name="reboot_system" product="tablet">Перезагрузить планшетный ПК</string> + <string name="reboot_system" product="default">Перезагрузить телефон</string> + + <!-- label for item that screenshots in phone options dialog --> + <string name="global_action_screenshot">Скриншот</string> + + <!-- Button to reboot the phone, within the Reboot Options dialog --> + <string name="reboot_reboot">Перезагрузка</string> + + <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. --> + <string name="reboot_progress">Перезагрузка\u2026</string> + <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. --> + <string name="reboot_confirm">Ваш телефон будет перезагружен</string> + + <!-- Spoken description for ringer silent option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_silent">Звонок выключен</string> + <!-- Spoken description for ringer vibrate option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_vibrate">Виброзвонок</string> + <!-- Spoken description for ringer normal option. [CHAR LIMIT=NONE] --> + <string name="silent_mode_ring">Звонок включен</string> <string name="shutdown_progress" msgid="2281079257329981203">"Выключение..."</string> <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string> <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефон будет выключен."</string> @@ -1230,4 +1245,8 @@ <string name="sending" msgid="8715108995741758718">"Отправка..."</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустить браузер?"</string> <string name="SetupCallDefault" msgid="6870275517518479651">"Принять вызов?"</string> + + <!--Application killed toast --> + <string name="app_killed_message">Приложения закрыты</string> + </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index c0e0046..b8da5ee 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -898,8 +898,8 @@ <string name="no" msgid="5141531044935541497">"Zrušiť"</string> <string name="dialog_alert_title" msgid="2049658708609043103">"Pozor"</string> <string name="loading" msgid="1760724998928255250">"Prebieha načítavanie..."</string> - <string name="capital_on" msgid="1544682755514494298">"ZAPNUTÉ"</string> - <string name="capital_off" msgid="6815870386972805832">"VYPNUTÉ"</string> + <string name="capital_on" msgid="1544682755514494298">"ZAP"</string> + <string name="capital_off" msgid="6815870386972805832">"VYP"</string> <string name="whichApplication" msgid="4533185947064773386">"Dokončiť akciu pomocou aplikácie"</string> <string name="alwaysUse" msgid="4583018368000610438">"Použiť ako predvolené nastavenie pre túto akciu."</string> <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Vymazanie predvolených hodnôt v časti Nastavenia plochy > Aplikácie > Správa aplikácií."</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 15f734d..30d6db8 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -898,8 +898,8 @@ <string name="no" msgid="5141531044935541497">"Откажи"</string> <string name="dialog_alert_title" msgid="2049658708609043103">"Пажња"</string> <string name="loading" msgid="1760724998928255250">"Учитавање..."</string> - <string name="capital_on" msgid="1544682755514494298">"УКЉУЧЕНО"</string> - <string name="capital_off" msgid="6815870386972805832">"ИСКЉУЧЕНО"</string> + <string name="capital_on" msgid="1544682755514494298">"УКЉ"</string> + <string name="capital_off" msgid="6815870386972805832">"ИСКЉ"</string> <string name="whichApplication" msgid="4533185947064773386">"Довршавање радње помоћу"</string> <string name="alwaysUse" msgid="4583018368000610438">"Подразумевано користи за ову радњу."</string> <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Обришите подразумевана подешавања у оквиру ставки Подешавања почетне странице > Апликације > Управљање апликацијама."</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 09180b5..d5a9643 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -437,6 +437,9 @@ <!-- Is the notification LED intrusive? Used to decide if there should be a disable option --> <bool name="config_intrusiveNotificationLed">false</bool> + <!-- Is the battery LED intrusive? Used to decide if there should be a disable option --> + <bool name="config_intrusiveBatteryLed">false</bool> + <!-- Default value for LED off time when the battery is low on charge in miliseconds --> <integer name="config_notificationsBatteryLedOff">2875</integer> @@ -491,6 +494,10 @@ <integer-array name="config_autoBrightnessLcdBacklightValues"> </integer-array> + <!-- Flag indicating whether we should enable automatic brightness for + the button and keyboard backlights. --> + <bool name="config_autoBrightnessButtonKeyboard">true</bool> + <!-- Array of output values for button backlight corresponding to the LUX values in the config_autoBrightnessLevels array. This array should have size one greater than the size of the config_autoBrightnessLevels array. diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index f9fd5f5..655ffee 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -68,6 +68,23 @@ could not be performed because FDN is enabled. This will be displayed in a toast. --> <string name="mmiFdnError">Operation is restricted to fixed dialing numbers only.</string> + <!-- Names of default profiles. --> + <string name="profileNameDefault">Default</string> + <string name="profileNameWork">Work</string> + <string name="profileNameHome">Home</string> + <string name="profileNameSilent">Silent</string> + <string name="profileNameNight">Night</string> + + <!-- Names of application groups. --> + <string name="profileGroupPhone">Phone</string> + <string name="profileGroupCalendar">Calendar</string> + <string name="profileGroupGmail">Gmail</string> + <string name="profileGroupEmail">Email</string> + <string name="profileGroupSMS">SMS</string> + + <!-- Name of wildcard profile. --> + <string name="wildcardProfile">Other</string> + <!-- Displayed when a phone feature such as call barring was activated. --> <string name="serviceEnabled">Service was enabled.</string> <!-- Displayed in front of the list of a set of service classes @@ -360,6 +377,9 @@ <!-- label for item that reboots the phone in phone options dialog --> <string name="global_action_reboot">Reboot</string> + <!-- label for item that reboots the phone in phone options dialog --> + <string name="global_action_choose_profile">Choose profile</string> + <!-- label for item that enables silent mode in phone options dialog --> <string name="global_action_toggle_silent_mode">Silent mode</string> @@ -853,6 +873,11 @@ <string name="permdesc_movePackage">Allows an application to move application resources from internal to external media and vice versa.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_preventpower">prevent power key</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_preventpower">Allows an application to override the power key</string> + + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_readLogs">read sensitive log data</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_readLogs" product="tablet">Allows an application to read from the diff --git a/core/res/res/xml/profile_default.xml b/core/res/res/xml/profile_default.xml new file mode 100644 index 0000000..824a73c --- /dev/null +++ b/core/res/res/xml/profile_default.xml @@ -0,0 +1,267 @@ +<profiles> + <profile nameres="profileNameDefault"> + <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>DEFAULT</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>DEFAULT</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>DEFAULT</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>DEFAULT</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>DEFAULT</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>DEFAULT</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + </profile> + <profile nameres="profileNameWork"> + <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>OVERRIDE</soundMode> + <ringerMode>OVERRIDE</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>OVERRIDE</lightsMode> + </profileGroup> + <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>OVERRIDE</lightsMode> + </profileGroup> + <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>SUPPRESS</vibrateMode> + <lightsMode>SUPPRESS</lightsMode> + </profileGroup> + <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>OVERRIDE</soundMode> + <ringerMode>OVERRIDE</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>DEFAULT</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + </profile> + <profile nameres="profileNameHome"> + <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1"> + <sound>content://media/external/audio/media/11</sound> + <ringer>content://media/external/audio/media/5</ringer> + <soundMode>OVERRIDE</soundMode> + <ringerMode>OVERRIDE</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>OVERRIDE</soundMode> + <ringerMode>OVERRIDE</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>OVERRIDE</lightsMode> + </profileGroup> + <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>OVERRIDE</soundMode> + <ringerMode>OVERRIDE</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>OVERRIDE</lightsMode> + </profileGroup> + <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>OVERRIDE</soundMode> + <ringerMode>OVERRIDE</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>DEFAULT</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + </profile> + <profile nameres="profileNameSilent"> + <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>SUPPRESS</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + </profile> + <profile nameres="profileNameNight"> + <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>OVERRIDE</soundMode> + <ringerMode>OVERRIDE</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>SUPPRESS</lightsMode> + </profileGroup> + <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>SUPPRESS</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>SUPPRESS</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>SUPPRESS</ringerMode> + <vibrateMode>OVERRIDE</vibrateMode> + <lightsMode>SUPPRESS</lightsMode> + </profileGroup> + <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true"> + <sound>content://settings/system/notification_sound</sound> + <ringer>content://settings/system/ringtone</ringer> + <soundMode>SUPPRESS</soundMode> + <ringerMode>DEFAULT</ringerMode> + <vibrateMode>DEFAULT</vibrateMode> + <lightsMode>DEFAULT</lightsMode> + </profileGroup> + </profile> + <notificationGroup nameres="profileGroupPhone" uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1"> + <package>com.android.phone</package> + </notificationGroup> + <notificationGroup nameres="profileGroupCalendar" uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf"> + <package>com.android.calendar</package> + </notificationGroup> + <notificationGroup nameres="profileGroupGmail" uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a"> + <package>com.google.android.gm</package> + </notificationGroup> + <notificationGroup nameres="profileGroupEmail" uuid="db3318cd-1964-4732-b913-1f83d73a3dea"> + <package>com.android.email</package> + </notificationGroup> + <notificationGroup nameres="profileGroupSMS" uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b"> + <package>com.android.mms</package> + </notificationGroup> +</profiles> diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index 7edf6b4..3f434e0 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -127,7 +127,7 @@ public: // Example value: "(10500,26623),(15000,26623),(30000,30000)" static const char KEY_SUPPORTED_PREVIEW_FPS_RANGE[]; // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in - // frameworks/base/include/camera/Camera.h. + // system/core/include/system/camera.h. // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read/write. static const char KEY_PREVIEW_FORMAT[]; // Supported image formats for preview frames. @@ -147,7 +147,7 @@ public: // Example value: "2048x1536,1024x768". Read only. static const char KEY_SUPPORTED_PICTURE_SIZES[]; // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE - // in frameworks/base/include/camera/Camera.h. + // in system/core/include/system/camera.h. // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write. static const char KEY_PICTURE_FORMAT[]; // Supported image formats for captured pictures. @@ -408,7 +408,7 @@ public: // value is "true". It is not supported if the value is not "true" or the // key does not exist. // See CAMERA_CMD_START_SMOOTH_ZOOM, CAMERA_CMD_STOP_SMOOTH_ZOOM, and - // CAMERA_MSG_ZOOM in frameworks/base/include/camera/Camera.h. + // CAMERA_MSG_ZOOM in system/core/include/system/camera.h. // Example value: "true". Read only. static const char KEY_SMOOTH_ZOOM_SUPPORTED[]; @@ -442,7 +442,7 @@ public: static const char KEY_VIDEO_SIZE[]; // A list of the supported dimensions in pixels (width x height) // for video frames. See CAMERA_MSG_VIDEO_FRAME for details in - // frameworks/base/include/camera/Camera.h. + // system/core/include/system/camera.h. // Example: "176x144,1280x720". Read only. static const char KEY_SUPPORTED_VIDEO_SIZES[]; @@ -471,7 +471,7 @@ public: static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[]; // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in - // frameworks/base/include/camera/Camera.h. + // system/core/include/system/camera.h. // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only. static const char KEY_VIDEO_FRAME_FORMAT[]; diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index 6ab01f4..2a18731 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -64,6 +64,9 @@ public: USAGE_HW_2D = GRALLOC_USAGE_HW_2D, USAGE_HW_COMPOSER = GRALLOC_USAGE_HW_COMPOSER, USAGE_HW_VIDEO_ENCODER = GRALLOC_USAGE_HW_VIDEO_ENCODER, +#ifdef SAMSUNG_CODEC_SUPPORT + USAGE_HW_FIMC1 = GRALLOC_USAGE_HW_FIMC1, +#endif USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK }; diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h index dffa788..3682ea3 100644 --- a/include/ui/GraphicBufferAllocator.h +++ b/include/ui/GraphicBufferAllocator.h @@ -56,6 +56,9 @@ public: USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE, USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER, USAGE_HW_2D = GRALLOC_USAGE_HW_2D, +#ifdef SAMSUNG_CODEC_SUPPORT + USAGE_HW_FIMC1 = GRALLOC_USAGE_HW_FIMC1, +#endif USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK }; diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h index 697a02a..d2ae6c2 100644 --- a/include/ui/GraphicBufferMapper.h +++ b/include/ui/GraphicBufferMapper.h @@ -46,7 +46,11 @@ public: int usage, const Rect& bounds, void** vaddr); status_t unlock(buffer_handle_t handle); - + +#ifdef EXYNOS4210_ENHANCEMENTS + status_t getphys(buffer_handle_t handle, int *paddr); +#endif + // dumps information about the mapping of this handle void dump(buffer_handle_t handle); diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp index 8bf20e9..d448787 100644 --- a/libs/ui/GraphicBufferMapper.cpp +++ b/libs/ui/GraphicBufferMapper.cpp @@ -102,5 +102,18 @@ status_t GraphicBufferMapper::unlock(buffer_handle_t handle) return err; } +#ifdef EXYNOS4210_ENHANCEMENTS +status_t GraphicBufferMapper::getphys(buffer_handle_t handle, int *paddr) +{ + status_t err; + + err = mAllocMod->getphys(mAllocMod, handle, paddr); + + LOGW_IF(err, "getphys(%p) fail %d(%s)", + handle, err, strerror(-err)); + return err; +} +#endif + // --------------------------------------------------------------------------- }; // namespace android diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 9a66039..19e19ad 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -272,6 +272,11 @@ public class LocationManager { return provider; } + /** + * Set the source from which to read gps info + * + * {@hide} + */ public void setGPSSource(String device) { try { mService.setGPSSource(device); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index a0881a7..b71f8e0 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -19,6 +19,8 @@ package android.media; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.PendingIntent; +import android.app.ProfileGroup; +import android.app.ProfileManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -54,6 +56,7 @@ public class AudioManager { private int mVolumeControlStream = -1; private static String TAG = "AudioManager"; private static boolean localLOGV = false; + private final ProfileManager mProfileManager; /** * Broadcast intent, a hint for applications that audio is about to become @@ -360,6 +363,7 @@ public class AudioManager { public AudioManager(Context context) { mContext = context; mHandler = new Handler(context.getMainLooper()); + mProfileManager = (ProfileManager) context.getSystemService(Context.PROFILE_SERVICE); } private static IAudioService getService() @@ -751,6 +755,26 @@ public class AudioManager { * @see #getVibrateSetting(int) */ public boolean shouldVibrate(int vibrateType) { + String packageName = mContext.getPackageName(); + // Don't apply profiles for "android" context, as these could + // come from the NotificationManager, and originate from a real package. + if (!packageName.equals("android")) { + ProfileGroup profileGroup = mProfileManager.getActiveProfileGroup(packageName); + if (profileGroup != null) { + Log.v(TAG, "shouldVibrate, group: " + profileGroup.getUuid() + + " mode: " + profileGroup.getVibrateMode()); + switch (profileGroup.getVibrateMode()) { + case OVERRIDE : + return true; + case SUPPRESS : + return false; + case DEFAULT : + // Drop through + } + } + } else { + Log.v(TAG, "Not applying override for 'android' package"); + } IAudioService service = getService(); try { return service.shouldVibrate(vibrateType); diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 37aacab..4912731 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -459,6 +459,15 @@ public class AudioService extends IAudioService.Stub { } else { mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_MUSIC); } + + boolean linkNotificationWithVolume = Settings.System.getInt(mContentResolver, + Settings.System.VOLUME_LINK_NOTIFICATION, 1) == 1; + if (linkNotificationWithVolume) { + STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING; + } else { + STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION; + } + Settings.System.putInt(cr, Settings.System.MODE_RINGER_STREAMS_AFFECTED, mRingerModeAffectedStreams); @@ -2315,6 +2324,8 @@ public class AudioService extends IAudioService.Stub { super(new Handler()); mContentResolver.registerContentObserver(Settings.System.getUriFor( Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); + mContentResolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.VOLUME_LINK_NOTIFICATION), false, this); } @Override @@ -2338,6 +2349,13 @@ public class AudioService extends IAudioService.Stub { mRingerModeAffectedStreams = ringerModeAffectedStreams; setRingerModeInt(getRingerMode(), false); } + boolean linkNotificationWithVolume = Settings.System.getInt(mContentResolver, + Settings.System.VOLUME_LINK_NOTIFICATION, 1) == 1; + if (linkNotificationWithVolume) { + STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING; + } else { + STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION; + } } } } diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 9c0819f..7aa4109 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -22,6 +22,8 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.Activity; import android.content.ContentUris; +import android.app.ProfileGroup; +import android.app.ProfileManager; import android.content.Context; import android.content.res.AssetFileDescriptor; import android.database.Cursor; @@ -55,29 +57,29 @@ public class RingtoneManager { // Make sure these are in sync with attrs.xml: // <attr name="ringtoneType"> - + /** * Type that refers to sounds that are used for the phone ringer. */ public static final int TYPE_RINGTONE = 1; - + /** * Type that refers to sounds that are used for notifications. */ public static final int TYPE_NOTIFICATION = 2; - + /** * Type that refers to sounds that are used for the alarm. */ public static final int TYPE_ALARM = 4; - + /** * All types of sounds. */ public static final int TYPE_ALL = TYPE_RINGTONE | TYPE_NOTIFICATION | TYPE_ALARM; // </attr> - + /** * Activity Action: Shows a ringtone picker. * <p> @@ -131,7 +133,7 @@ public class RingtoneManager { */ public static final String EXTRA_RINGTONE_EXISTING_URI = "android.intent.extra.ringtone.EXISTING_URI"; - + /** * Given to the ringtone picker as a {@link Uri}. The {@link Uri} of the * ringtone to play when the user attempts to preview the "Default" @@ -144,7 +146,7 @@ public class RingtoneManager { */ public static final String EXTRA_RINGTONE_DEFAULT_URI = "android.intent.extra.ringtone.DEFAULT_URI"; - + /** * Given to the ringtone picker as an int. Specifies which ringtone type(s) should be * shown in the picker. One or more of {@link #TYPE_RINGTONE}, @@ -194,7 +196,7 @@ public class RingtoneManager { "\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\"", MediaStore.Audio.Media.TITLE_KEY }; - + /** * The column index (in the cursor returned by {@link #getCursor()} for the * row ID. @@ -215,11 +217,11 @@ public class RingtoneManager { private Activity mActivity; private Context mContext; - + private Cursor mCursor; private int mType = TYPE_RINGTONE; - + /** * If a column (item from this list) exists in the Cursor, its value must * be true (value of 1) for the row to be returned. @@ -230,7 +232,7 @@ public class RingtoneManager { private Ringtone mPreviousRingtone; private boolean mIncludeDrm; - + /** * Constructs a RingtoneManager. This constructor is recommended as its * constructed instance manages cursor(s). @@ -322,7 +324,7 @@ public class RingtoneManager { mPreviousRingtone.stop(); } } - + /** * Returns whether DRM ringtones will be included. * @@ -401,12 +403,12 @@ public class RingtoneManager { return getUriFromCursor(cursor); } - + private static Uri getUriFromCursor(Cursor cursor) { return ContentUris.withAppendedId(Uri.parse(cursor.getString(URI_COLUMN_INDEX)), cursor .getLong(ID_COLUMN_INDEX)); } - + /** * Gets the position of a {@link Uri} within this {@link RingtoneManager}. * @@ -510,7 +512,7 @@ public class RingtoneManager { MediaStore.Audio.Media.DEFAULT_SORT_ORDER) : null; } - + private void setFilterColumnsList(int type) { List<String> columns = mFilterColumns; columns.clear(); @@ -527,7 +529,7 @@ public class RingtoneManager { columns.add(MediaStore.Audio.AudioColumns.IS_ALARM); } } - + /** * Constructs a where clause that consists of at least one column being 1 * (true). This is used to find all matching sounds for the given sound @@ -539,7 +541,7 @@ public class RingtoneManager { private static String constructBooleanTrueWhereClause(List<String> columns, boolean includeDrm) { if (columns == null) return null; - + StringBuilder sb = new StringBuilder(); sb.append("("); @@ -562,10 +564,9 @@ public class RingtoneManager { sb.append("=0"); } - return sb.toString(); } - + private Cursor query(Uri uri, String[] projection, String selection, @@ -578,7 +579,7 @@ public class RingtoneManager { sortOrder); } } - + /** * Returns a {@link Ringtone} for a given sound URI. * <p> @@ -606,21 +607,36 @@ public class RingtoneManager { * @see #getRingtone(Context, Uri) */ private static Ringtone getRingtone(final Context context, Uri ringtoneUri, int streamType) { + ProfileManager pm = (ProfileManager)context.getSystemService(context.PROFILE_SERVICE); + ProfileGroup profileGroup = pm.getActiveProfileGroup(context.getPackageName()); try { Ringtone r = new Ringtone(context); if (streamType >= 0) { r.setStreamType(streamType); } + + if (profileGroup != null) { + switch (profileGroup.getRingerMode()) { + case OVERRIDE : + r.open(profileGroup.getRingerOverride()); + return r; + case SUPPRESS : + r = null; + return r; + } + } + r.open(ringtoneUri); return r; + } catch (Exception ex) { Log.e(TAG, "Failed to open ringtone " + ringtoneUri); } return null; } - + /** * Gets the current default sound's {@link Uri}. This will give the actual * sound {@link Uri}, instead of using this, most clients can use @@ -639,7 +655,7 @@ public class RingtoneManager { final String uriString = Settings.System.getString(context.getContentResolver(), setting); return uriString != null ? Uri.parse(uriString) : null; } - + /** * Sets the {@link Uri} of the default sound for a given sound type. * @@ -656,7 +672,7 @@ public class RingtoneManager { Settings.System.putString(context.getContentResolver(), setting, ringtoneUri != null ? ringtoneUri.toString() : null); } - + private static String getSettingForType(int type) { if ((type & TYPE_RINGTONE) != 0) { return Settings.System.RINGTONE; @@ -668,7 +684,7 @@ public class RingtoneManager { return null; } } - + /** * Returns whether the given {@link Uri} is one of the default ringtones. * @@ -678,7 +694,7 @@ public class RingtoneManager { public static boolean isDefault(Uri ringtoneUri) { return getDefaultType(ringtoneUri) != -1; } - + /** * Returns the type of a default {@link Uri}. * @@ -701,7 +717,7 @@ public class RingtoneManager { return -1; } } - + /** * Returns the {@link Uri} for the default ringtone of a particular type. * Rather than returning the actual ringtone's sound {@link Uri}, this will @@ -722,5 +738,4 @@ public class RingtoneManager { return null; } } - } diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 690deac..c050851 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -89,6 +89,14 @@ LOCAL_STATIC_LIBRARIES := \ libstagefright_id3 \ libFLAC \ +ifeq ($(BOARD_HAVE_CODEC_SUPPORT),SAMSUNG_CODEC_SUPPORT) +LOCAL_CFLAGS += -DSAMSUNG_CODEC_SUPPORT +endif + +ifeq ($(BOARD_USES_PROPRIETARY_OMX),SAMSUNG) +LOCAL_CFLAGS += -DSAMSUNG_OMX +endif + ################################################################################ # The following was shamelessly copied from external/webkit/Android.mk and diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 86b3fe4..1eb0801 100755 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -45,9 +45,19 @@ #include <OMX_Component.h> #include "include/avc_utils.h" +#ifdef SAMSUNG_CODEC_SUPPORT +#include "include/ColorFormat.h" +#endif namespace android { +#ifdef SAMSUNG_CODEC_SUPPORT +static const int OMX_SEC_COLOR_FormatNV12TPhysicalAddress = 0x7F000001; +static const int OMX_SEC_COLOR_FormatNV12LPhysicalAddress = 0x7F000002; +static const int OMX_SEC_COLOR_FormatNV12LVirtualAddress = 0x7F000003; +static const int OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002; +#endif + // Treat time out as an error if we have not received any output // buffers after 3 seconds. const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL; @@ -106,6 +116,22 @@ static sp<MediaSource> InstantiateSoftwareEncoder( #undef FACTORY_CREATE static const CodecInfo kDecoderInfo[] = { +#ifdef SAMSUNG_OMX + { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.SEC.mp3.dec" }, + { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.SEC.amr.dec" }, + { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.SEC.amr.dec" }, + { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.SEC.aac.dec" }, + { MEDIA_MIMETYPE_AUDIO_FLAC, "OMX.SEC.flac.dec" }, + { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.mpeg4.dec" }, + { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.h263.dec" }, + { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.h263sr.dec" }, + { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.avc.dec" }, + { MEDIA_MIMETYPE_CONTAINER_WVM, "OMX.SEC.vc1.dec" }, + { MEDIA_MIMETYPE_CONTAINER_WVM, "OMX.SEC.wma.dec" }, + { MEDIA_MIMETYPE_CONTAINER_WVM, "OMX.SEC.wmv7.dec" }, + { MEDIA_MIMETYPE_CONTAINER_WVM, "OMX.SEC.wmv8.dec" }, + { MEDIA_MIMETYPE_VIDEO_VPX, "OMX.SEC.vp8.dec" }, +#endif { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" }, // { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" }, { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.google.mp3.decoder" }, @@ -148,6 +174,14 @@ static const CodecInfo kDecoderInfo[] = { }; static const CodecInfo kEncoderInfo[] = { +#ifdef SAMSUNG_OMX + { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.SEC.amr.enc" }, + { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.SEC.amr.enc" }, + { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.SEC.aac.enc" }, + { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.mpeg4.enc" }, + { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.h263.enc" }, + { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.avc.enc" }, +#endif { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" }, { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" }, { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" }, @@ -875,6 +909,12 @@ status_t OMXCodec::setVideoPortFormatType( return err; } +#ifdef SAMSUNG_CODEC_SUPPORT +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#endif static size_t getFrameSize( OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) { switch (colorFormat) { @@ -894,8 +934,21 @@ static size_t getFrameSize( * this part in the future */ case OMX_COLOR_FormatAndroidOpaque: +#ifdef SAMSUNG_CODEC_SUPPORT + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: +#endif return (width * height * 3) / 2; +#ifdef SAMSUNG_CODEC_SUPPORT + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + return ALIGN((ALIGN(width, 16) * ALIGN(height, 16)), 2048) + ALIGN((ALIGN(width, 16) * ALIGN(height >> 1, 8)), 2048); + + case OMX_SEC_COLOR_FormatNV12Tiled: + static unsigned int frameBufferYSise = ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)); + static unsigned int frameBufferUVSise = ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height/2)); + return (frameBufferYSise + frameBufferUVSise); +#endif default: CHECK(!"Should not be here. Unsupported color format."); break; @@ -1403,7 +1456,23 @@ status_t OMXCodec::setVideoOutputFormat( || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || format.eColorFormat == OMX_COLOR_FormatCbYCrY || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar - || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); + || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar +#ifdef SAMSUNG_CODEC_SUPPORT + || format.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress + || format.eColorFormat == OMX_SEC_COLOR_FormatNV12Tiled +#endif + ); +#ifdef SAMSUNG_CODEC_SUPPORT + if (!strcmp("OMX.SEC.FP.AVC.Decoder", mComponentName) || + !strcmp("OMX.SEC.AVC.Decoder", mComponentName) || + !strcmp("OMX.SEC.MPEG4.Decoder", mComponentName) || + !strcmp("OMX.SEC.H263.Decoder", mComponentName)) { + if (mNativeWindow == NULL) + format.eColorFormat = OMX_COLOR_FormatYUV420Planar; + else + format.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + } +#endif err = mOMX->setParameter( mNode, OMX_IndexParamVideoPortFormat, @@ -1841,13 +1910,34 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { if (err != OK) { return err; } - +#ifndef SAMSUNG_CODEC_SUPPORT err = native_window_set_buffers_geometry( mNativeWindow.get(), def.format.video.nFrameWidth, def.format.video.nFrameHeight, def.format.video.eColorFormat); +#else + OMX_COLOR_FORMATTYPE eColorFormat; + + switch (def.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + eColorFormat = (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + eColorFormat = (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YCbCr_420_SP; + break; + case OMX_COLOR_FormatYUV420Planar: + default: + eColorFormat = (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + } + err = native_window_set_buffers_geometry( + mNativeWindow.get(), + def.format.video.nFrameWidth, + def.format.video.nFrameHeight, + eColorFormat); +#endif if (err != 0) { LOGE("native_window_set_buffers_geometry failed: %s (%d)", strerror(-err), -err); @@ -1891,8 +1981,13 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { } LOGV("native_window_set_usage usage=0x%lx", usage); +#ifndef SAMSUNG_CODEC_SUPPORT err = native_window_set_usage( mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); +#else + err = native_window_set_usage( + mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP | GRALLOC_USAGE_HW_FIMC1 | GRALLOC_USAGE_HWC_HWOVERLAY); +#endif if (err != 0) { LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); return err; @@ -3238,11 +3333,47 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { CHECK(info->mMediaBuffer == NULL); info->mMediaBuffer = srcBuffer; } else { +#ifndef SAMSUNG_CODEC_SUPPORT CHECK(srcBuffer->data() != NULL) ; memcpy((uint8_t *)info->mData + offset, (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), srcBuffer->range_length()); +#else + OMX_PARAM_PORTDEFINITIONTYPE def; + InitOMXParams(&def); + def.nPortIndex = kPortIndexInput; + + status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, + &def, sizeof(def)); + CHECK_EQ(err, (status_t)OK); + + if (def.eDomain == OMX_PortDomainVideo) { + OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; + switch (videoDef->eColorFormat) { + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: { + CHECK(srcBuffer->data() != NULL); + void *pSharedMem = (void *)(srcBuffer->data()); + memcpy((uint8_t *)info->mData + offset, + (const void *)&pSharedMem, sizeof(void *)); + break; + } + default: + CHECK(srcBuffer->data() != NULL); + memcpy((uint8_t *)info->mData + offset, + (const uint8_t *)srcBuffer->data() + + srcBuffer->range_offset(), + srcBuffer->range_length()); + break; + } + } else { + CHECK(srcBuffer->data() != NULL); + memcpy((uint8_t *)info->mData + offset, + (const uint8_t *)srcBuffer->data() + + srcBuffer->range_offset(), + srcBuffer->range_length()); + } +#endif } } @@ -4130,7 +4261,22 @@ static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; - } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { + } +#ifdef SAMSUNG_CODEC_SUPPORT + if (type == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { + return "OMX_SEC_COLOR_FormatNV12TPhysicalAddress"; + } + if (type == OMX_SEC_COLOR_FormatNV12LPhysicalAddress) { + return "OMX_SEC_COLOR_FormatNV12LPhysicalAddress"; + } + if (type == OMX_SEC_COLOR_FormatNV12LVirtualAddress) { + return "OMX_SEC_COLOR_FormatNV12LVirtualAddress"; + } + if (type == OMX_SEC_COLOR_FormatNV12Tiled) { + return "OMX_SEC_COLOR_FormatNV12Tiled"; + } +#endif + else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; } else if (type < 0 || (size_t)type >= numNames) { return "UNKNOWN"; @@ -4571,6 +4717,13 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { video_def->nFrameWidth, video_def->nFrameHeight); if (err == OK) { +#ifdef SAMSUNG_CODEC_SUPPORT + /* Hack GetConfig */ + rect.nLeft = 0; + rect.nTop = 0; + rect.nWidth = video_def->nFrameWidth; + rect.nHeight = video_def->nFrameHeight; +#endif CHECK_GE(rect.nLeft, 0); CHECK_GE(rect.nTop, 0); CHECK_GE(rect.nWidth, 0u); diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index aa07e57..ddced5f 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -421,13 +421,8 @@ void SoftMPEG4::onQueueFilled(OMX_U32 portIndex) { int32_t bufferSize = inHeader->nFilledLen; - // The PV decoder is lying to us, sometimes it'll claim to only have - // consumed a subset of the buffer when it clearly consumed all of it. - // ignore whatever it says... - int32_t tmp = bufferSize; - if (PVDecodeVideoFrame( - mHandle, &bitstream, ×tamp, &tmp, + mHandle, &bitstream, ×tamp, &bufferSize, &useExtTimestamp, outHeader->pBuffer) != PV_TRUE) { LOGE("failed to decode video frame."); diff --git a/media/libstagefright/include/ColorFormat.h b/media/libstagefright/include/ColorFormat.h new file mode 100644 index 0000000..6b66a2b --- /dev/null +++ b/media/libstagefright/include/ColorFormat.h @@ -0,0 +1,30 @@ +/************************************************* + Author: Annamalai Lakshmanan + Added Color formats for Samsung OMX Decode +*************************************************/ + +enum { + HAL_PIXEL_FORMAT_YCbCr_422_P = 0x100, + HAL_PIXEL_FORMAT_YCbCr_420_P = 0x101, + HAL_PIXEL_FORMAT_YCbCr_420_I = 0x102, + HAL_PIXEL_FORMAT_CbYCrY_422_I = 0x103, + HAL_PIXEL_FORMAT_CbYCrY_420_I = 0x104, + HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x105, + HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x106, + // support custom format for zero copy + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP = 0x110, + HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP = 0x111, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED = 0x112, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP = 0x113, + HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP = 0x114, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I = 0x115, + HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I = 0x116, + HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I = 0x117, + HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I = 0x118, + HAL_PIXEL_FORMAT_CUSTOM_CbYCr_422_I = 0x11B, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR = 0x11C, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL = 0x11D, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR = 0x11E, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL = 0x11F, + HAL_PIXEL_FORMAT_CUSTOM_MAX +}; diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk index d844f3d..bb14f64 100644 --- a/media/libstagefright/omx/Android.mk +++ b/media/libstagefright/omx/Android.mk @@ -25,6 +25,10 @@ LOCAL_SHARED_LIBRARIES := \ libstagefright_foundation \ libdl +ifeq ($(BOARD_USES_PROPRIETARY_OMX),SAMSUNG) +LOCAL_CFLAGS += -DSAMSUNG_OMX +endif + LOCAL_MODULE:= libstagefright_omx include $(BUILD_SHARED_LIBRARY) diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp index c8278ab..1594dcc 100644 --- a/media/libstagefright/omx/OMXMaster.cpp +++ b/media/libstagefright/omx/OMXMaster.cpp @@ -44,13 +44,18 @@ OMXMaster::~OMXMaster() { } void OMXMaster::addVendorPlugin() { +#ifdef SAMSUNG_OMX + addPlugin("libsomxcore.so"); +#else addPlugin("libstagefrighthw.so"); +#endif } void OMXMaster::addPlugin(const char *libname) { mVendorLibHandle = dlopen(libname, RTLD_NOW); if (mVendorLibHandle == NULL) { + LOGE("dlopen() failed."); return; } diff --git a/packages/SystemUI/res/drawable-hdpi/stat_lte_off.png b/packages/SystemUI/res/drawable-hdpi/stat_lte_off.png Binary files differnew file mode 100644 index 0000000..ffc5d7b --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_lte_off.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_lte_on.png b/packages/SystemUI/res/drawable-hdpi/stat_lte_on.png Binary files differnew file mode 100644 index 0000000..72c6b38 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_lte_on.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim0.png Binary files differnew file mode 100755 index 0000000..a9dc546 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim0.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim100.png Binary files differnew file mode 100755 index 0000000..ea49dd7 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim100.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim15.png Binary files differnew file mode 100755 index 0000000..f1b97e1 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim15.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim28.png Binary files differnew file mode 100755 index 0000000..7a9123e --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim28.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim43.png Binary files differnew file mode 100755 index 0000000..1b2d22c --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim43.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim57.png Binary files differnew file mode 100755 index 0000000..e4a3457 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim57.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim71.png Binary files differnew file mode 100755 index 0000000..6ce4554 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim71.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim85.png Binary files differnew file mode 100755 index 0000000..5685685 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim85.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_0.png Binary files differnew file mode 100755 index 0000000..bdfe108 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_0.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_100.png Binary files differnew file mode 100755 index 0000000..9fdaf23 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_100.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_15.png Binary files differnew file mode 100755 index 0000000..f424636 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_15.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_28.png Binary files differnew file mode 100755 index 0000000..3237b05 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_28.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_43.png Binary files differnew file mode 100755 index 0000000..6d72129 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_43.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_57.png Binary files differnew file mode 100755 index 0000000..6e10476 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_57.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_71.png Binary files differnew file mode 100755 index 0000000..fe0c8b3 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_71.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_85.png Binary files differnew file mode 100755 index 0000000..172e00c --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_85.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_min.png Binary files differnew file mode 100644 index 0000000..c3f79ce --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_min.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_lte_off.png b/packages/SystemUI/res/drawable-mdpi/stat_lte_off.png Binary files differnew file mode 100644 index 0000000..3161b57 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_lte_off.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_lte_on.png b/packages/SystemUI/res/drawable-mdpi/stat_lte_on.png Binary files differnew file mode 100644 index 0000000..234dfde --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_lte_on.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim0.png Binary files differnew file mode 100755 index 0000000..78d2384 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim0.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim100.png Binary files differnew file mode 100755 index 0000000..5aca171 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim100.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim15.png Binary files differnew file mode 100755 index 0000000..7c06ef7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim15.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim28.png Binary files differnew file mode 100755 index 0000000..1fce2fc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim28.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim43.png Binary files differnew file mode 100755 index 0000000..28294dd --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim43.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim57.png Binary files differnew file mode 100755 index 0000000..c905ddc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim57.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim71.png Binary files differnew file mode 100755 index 0000000..dc5184b --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim71.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim85.png Binary files differnew file mode 100755 index 0000000..3af272c --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim85.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_0.png Binary files differnew file mode 100755 index 0000000..cd042a7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_0.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_100.png Binary files differnew file mode 100755 index 0000000..1d506b2 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_100.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_15.png Binary files differnew file mode 100755 index 0000000..cc3a01a --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_15.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_28.png Binary files differnew file mode 100755 index 0000000..937e384 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_28.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_43.png Binary files differnew file mode 100755 index 0000000..41d02db --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_43.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_57.png Binary files differnew file mode 100755 index 0000000..ed90158 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_57.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_71.png Binary files differnew file mode 100755 index 0000000..a195b26 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_71.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_85.png Binary files differnew file mode 100755 index 0000000..690979d --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_85.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_min.png Binary files differnew file mode 100755 index 0000000..51a4c4c --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_min.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim0.png Binary files differnew file mode 100755 index 0000000..979b733 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim0.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim100.png Binary files differnew file mode 100755 index 0000000..599bd42 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim100.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim15.png Binary files differnew file mode 100755 index 0000000..ed4dd8a --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim15.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim28.png Binary files differnew file mode 100755 index 0000000..d4e1b5d --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim28.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim43.png Binary files differnew file mode 100755 index 0000000..763eb3f --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim43.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim57.png Binary files differnew file mode 100755 index 0000000..f2294d4 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim57.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim71.png Binary files differnew file mode 100755 index 0000000..4fa3cea --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim71.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim85.png Binary files differnew file mode 100755 index 0000000..1ed832f --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_min_anim85.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_0.png Binary files differnew file mode 100755 index 0000000..1b3d49e --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_0.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_100.png Binary files differnew file mode 100755 index 0000000..a73398a --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_100.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_15.png Binary files differnew file mode 100755 index 0000000..37cc5a2 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_15.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_28.png Binary files differnew file mode 100755 index 0000000..f3b35d8 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_28.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_43.png Binary files differnew file mode 100755 index 0000000..abdbec2 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_43.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_57.png Binary files differnew file mode 100755 index 0000000..68da4b7 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_57.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_71.png Binary files differnew file mode 100755 index 0000000..c0d35cb --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_71.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_85.png Binary files differnew file mode 100755 index 0000000..72976dd --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_min_85.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_min.png Binary files differnew file mode 100755 index 0000000..5f17531 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_min.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim0.png Binary files differnew file mode 100755 index 0000000..24bb1e0 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim0.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim100.png Binary files differnew file mode 100755 index 0000000..8115db1 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim100.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim15.png Binary files differnew file mode 100755 index 0000000..b90f5e3 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim15.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim28.png Binary files differnew file mode 100755 index 0000000..c0d3204 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim28.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim43.png Binary files differnew file mode 100755 index 0000000..adc37d3 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim43.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim57.png Binary files differnew file mode 100755 index 0000000..7c771c4 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim57.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim71.png Binary files differnew file mode 100755 index 0000000..8f32043 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim71.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim85.png Binary files differnew file mode 100755 index 0000000..42b71b2 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_min_anim85.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_0.png Binary files differnew file mode 100755 index 0000000..f3f1a19 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_0.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_100.png Binary files differnew file mode 100755 index 0000000..23be933 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_100.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_15.png Binary files differnew file mode 100755 index 0000000..9cb4909 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_15.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_28.png Binary files differnew file mode 100755 index 0000000..80ec7c7 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_28.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_43.png Binary files differnew file mode 100755 index 0000000..c892bd3 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_43.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_57.png Binary files differnew file mode 100755 index 0000000..45822b0 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_57.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_71.png Binary files differnew file mode 100755 index 0000000..465db1e --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_71.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_85.png Binary files differnew file mode 100755 index 0000000..b3f08d4 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_min_85.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_min.png Binary files differnew file mode 100755 index 0000000..fd0f879 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_min.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim0.png Binary files differnew file mode 100755 index 0000000..5aebefc --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim0.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim100.png Binary files differnew file mode 100755 index 0000000..1f556ab --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim100.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim15.png Binary files differnew file mode 100755 index 0000000..7522d25 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim15.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim28.png Binary files differnew file mode 100755 index 0000000..189305e --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim28.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim43.png Binary files differnew file mode 100755 index 0000000..6cb2b3d --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim43.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim57.png Binary files differnew file mode 100755 index 0000000..ac79f19 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim57.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim71.png Binary files differnew file mode 100755 index 0000000..4073111 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim71.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim85.png Binary files differnew file mode 100755 index 0000000..83f36cb --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_min_anim85.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_0.png Binary files differnew file mode 100755 index 0000000..7cf1065 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_0.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_100.png Binary files differnew file mode 100755 index 0000000..041000b --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_100.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_15.png Binary files differnew file mode 100755 index 0000000..7625a1a --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_15.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_28.png Binary files differnew file mode 100755 index 0000000..122e4d5 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_28.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_43.png Binary files differnew file mode 100755 index 0000000..761c280 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_43.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_57.png Binary files differnew file mode 100755 index 0000000..58ed133 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_57.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_71.png Binary files differnew file mode 100755 index 0000000..0423f11 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_71.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_85.png Binary files differnew file mode 100755 index 0000000..fd41402 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_min_85.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_min.png Binary files differnew file mode 100755 index 0000000..cd7d4db --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_min.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_lte_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_lte_off.png Binary files differnew file mode 100644 index 0000000..e587da9 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_lte_off.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_lte_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_lte_on.png Binary files differnew file mode 100644 index 0000000..1631cd2 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_lte_on.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim0.png Binary files differnew file mode 100755 index 0000000..223c4d3 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim0.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim100.png Binary files differnew file mode 100755 index 0000000..1a518c4 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim100.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim15.png Binary files differnew file mode 100755 index 0000000..e32069a --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim15.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim28.png Binary files differnew file mode 100755 index 0000000..7eef777 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim28.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim43.png Binary files differnew file mode 100755 index 0000000..359a020 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim43.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim57.png Binary files differnew file mode 100755 index 0000000..15225e2 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim57.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim71.png Binary files differnew file mode 100755 index 0000000..e401d01 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim71.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim85.png Binary files differnew file mode 100755 index 0000000..147c51c --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim85.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_0.png Binary files differnew file mode 100755 index 0000000..3389306 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_0.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_100.png Binary files differnew file mode 100755 index 0000000..2176d9b --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_100.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_15.png Binary files differnew file mode 100755 index 0000000..f34033d --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_15.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_28.png Binary files differnew file mode 100755 index 0000000..fff6b28 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_28.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_43.png Binary files differnew file mode 100755 index 0000000..17e4937 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_43.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_57.png Binary files differnew file mode 100755 index 0000000..acc555f --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_57.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_71.png Binary files differnew file mode 100755 index 0000000..82127eb --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_71.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_85.png Binary files differnew file mode 100755 index 0000000..2ccba10 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_85.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_min.png Binary files differnew file mode 100755 index 0000000..1203d7e --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_min.png diff --git a/packages/SystemUI/res/drawable/stat_sys_battery_charge_min.xml b/packages/SystemUI/res/drawable/stat_sys_battery_charge_min.xml new file mode 100644 index 0000000..3ee6b7c --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_battery_charge_min.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<level-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:maxLevel="4" android:drawable="@drawable/stat_sys_battery_charge_min_anim0" /> + <item android:maxLevel="15" android:drawable="@drawable/stat_sys_battery_charge_min_anim15" /> + <item android:maxLevel="35" android:drawable="@drawable/stat_sys_battery_charge_min_anim28" /> + <item android:maxLevel="49" android:drawable="@drawable/stat_sys_battery_charge_min_anim43" /> + <item android:maxLevel="60" android:drawable="@drawable/stat_sys_battery_charge_min_anim57" /> + <item android:maxLevel="75" android:drawable="@drawable/stat_sys_battery_charge_min_anim71" /> + <item android:maxLevel="90" android:drawable="@drawable/stat_sys_battery_charge_min_anim85" /> + <item android:maxLevel="100" android:drawable="@drawable/stat_sys_battery_charge_min_anim100" /> +</level-list> + diff --git a/packages/SystemUI/res/drawable/stat_sys_battery_min.xml b/packages/SystemUI/res/drawable/stat_sys_battery_min.xml new file mode 100644 index 0000000..d7daea0 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_battery_min.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/drawable/stat_sys_battery.xml +** +** 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. +*/ +--> + +<level-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:maxLevel="4" android:drawable="@drawable/stat_sys_battery_min_0" /> + <item android:maxLevel="15" android:drawable="@drawable/stat_sys_battery_min_15" /> + <item android:maxLevel="35" android:drawable="@drawable/stat_sys_battery_min_28" /> + <item android:maxLevel="49" android:drawable="@drawable/stat_sys_battery_min_43" /> + <item android:maxLevel="60" android:drawable="@drawable/stat_sys_battery_min_57" /> + <item android:maxLevel="75" android:drawable="@drawable/stat_sys_battery_min_71" /> + <item android:maxLevel="90" android:drawable="@drawable/stat_sys_battery_min_85" /> + <item android:maxLevel="100" android:drawable="@drawable/stat_sys_battery_min_100" /> +</level-list> + diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml index 739f3aa..3fbe348 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml @@ -121,6 +121,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" /> + <include layout="@layout/signal_cluster_text_view" + android:id="@+id/signal_cluster_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> <ImageView android:id="@+id/bluetooth" android:layout_height="wrap_content" @@ -128,6 +133,17 @@ android:paddingLeft="4dip" android:visibility="gone" /> + <TextView + android:id="@+id/battery_text" + android:textAppearance="@style/TextAppearance.StatusBar.Battery" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:singleLine="true" + android:textSize="20sp" + android:paddingLeft="4dip" + android:layout_marginRight="-3dip" + android:gravity="center_vertical|left" + /> <ImageView android:id="@+id/battery" android:layout_height="wrap_content" diff --git a/packages/SystemUI/res/layout/signal_cluster_text_view.xml b/packages/SystemUI/res/layout/signal_cluster_text_view.xml new file mode 100644 index 0000000..9428ca2 --- /dev/null +++ b/packages/SystemUI/res/layout/signal_cluster_text_view.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 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. +*/ +--> + +<com.android.systemui.statusbar.SignalClusterTextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:orientation="horizontal" + > + <LinearLayout + android:id="@+id/mobile_signal_text_combo" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="horizontal" + android:gravity="center" + android:layout_marginRight="-3dip" + > + <TextView + android:id="@+id/mobile_signal_text" + android:textAppearance="@style/TextAppearance.StatusBar.Signal" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:singleLine="true" + android:layout_marginRight="-3dip" + android:gravity="center_vertical|left" + /> + <ImageView + android:id="@+id/mobile_signal_text_icon" + android:src="@drawable/stat_sys_signal_min" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginLeft="1dip" + android:paddingRight="2dip" + /> + </LinearLayout> +</com.android.systemui.statusbar.SignalClusterTextView> diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml index b1aaade..cfc48ee 100644 --- a/packages/SystemUI/res/layout/status_bar.xml +++ b/packages/SystemUI/res/layout/status_bar.xml @@ -71,11 +71,26 @@ android:orientation="horizontal" android:gravity="center" > - <include layout="@layout/signal_cluster_view" + <include layout="@layout/signal_cluster_view" android:id="@+id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" /> + <include layout="@layout/signal_cluster_text_view" + android:id="@+id/signal_cluster_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + <TextView + android:id="@+id/battery_text" + android:textAppearance="@style/TextAppearance.StatusBar.Battery" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:singleLine="true" + android:paddingLeft="4dip" + android:layout_marginRight="-3dip" + android:gravity="center_vertical|left" + /> <ImageView android:id="@+id/battery" android:layout_height="wrap_content" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 28e5ca0..7861775 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -126,6 +126,11 @@ <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g> </string> + <!-- Text to display next to the minimal graphical battery meter. [CHAR LIMIT=3] --> + <string name="status_bar_settings_battery_meter_min_format" translatable="false"> + <xliff:g id="number">%d</xliff:g> + </string> + <!-- Separator for PLMN and SPN in network name. --> <string name="status_bar_network_name_separator" translatable="false">"\n"</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index dc5c540..51bd0cf 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -40,6 +40,13 @@ <item name="android:textColor">#FFFFFFFF</item> </style> + <style name="TextAppearance.StatusBar.Battery" parent="@*android:style/TextAppearance.StatusBar.Icon"> + <!-- Note: must be dp to fit in status bar --> + <item name="android:textSize">12dp</item> + <item name="android:textStyle">normal</item> + <item name="android:textColor">@android:color/holo_blue_light</item> + </style> + <style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon"> <!-- Note: must be dp to fit in status bar --> <item name="android:textSize">16dp</item> @@ -53,6 +60,13 @@ <item name="android:textColor">@android:color/holo_blue_light</item> </style> + <style name="TextAppearance.StatusBar.Signal" parent="@*android:style/TextAppearance.StatusBar.Icon"> + <!-- Note: must be dp to fit in status bar --> + <item name="android:textSize">12dp</item> + <item name="android:textStyle">normal</item> + <item name="android:textColor">@android:color/holo_blue_light</item> + </style> + <style name="Animation" /> <style name="Animation.ShirtPocketPanel"> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java new file mode 100644 index 0000000..65ac030 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java @@ -0,0 +1,177 @@ +/* + * 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 com.android.systemui.statusbar; + +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.database.ContentObserver; +import android.os.Handler; +import android.provider.Settings; +import android.telephony.PhoneStateListener; +import android.telephony.ServiceState; +import android.telephony.SignalStrength; +import android.telephony.TelephonyManager; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.style.CharacterStyle; +import android.text.style.RelativeSizeSpan; +import android.util.AttributeSet; +import android.util.Slog; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.systemui.statusbar.SignalClusterView.SettingsObserver; +import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.R; + +// Intimately tied to the design of res/layout/signal_cluster_text_view.xml +public class SignalClusterTextView + extends LinearLayout { + + private static final int SIGNAL_CLUSTER_STYLE_NORMAL = 0; + private static final int SIGNAL_CLUSTER_STYLE_TEXT = 1; + private static final int SIGNAL_CLUSTER_STYLE_HIDDEN = 2; + + private boolean mAttached; + private boolean mAirplaneMode; + private int mSignalClusterStyle; + private int mPhoneState; + + private SignalStrength signalStrength; + + ViewGroup mMobileGroup; + TextView mMobileSignalText; + + Handler mHandler; + + int dBm = 0; + + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.STATUS_BAR_SIGNAL_TEXT), false, this); + } + + @Override public void onChange(boolean selfChange) { + updateSettings(); + } + } + + public SignalClusterTextView(Context context) { + this(context, null); + } + + public SignalClusterTextView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SignalClusterTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + mHandler = new Handler(); + + SettingsObserver settingsObserver = new SettingsObserver(mHandler); + settingsObserver.observe(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + mMobileGroup = (ViewGroup) findViewById(R.id.mobile_signal_text_combo); + mMobileSignalText = (TextView) findViewById(R.id.mobile_signal_text); + + if (!mAttached) { + mAttached = true; + ((TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE)).listen( + mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + + updateSettings(); + } + } + + @Override + protected void onDetachedFromWindow() { + if (mAttached) { + mAttached = false; + } + super.onDetachedFromWindow(); + } + + private String getSignalLevelString(int dBm) { + if (dBm == 0) { + return "-\u221e"; // -oo ('minus infinity') + } + return Integer.toString(dBm); + } + + final void updateSignalText() { + + if (mAirplaneMode || dBm == 0) { + mMobileGroup.setVisibility(View.GONE); + return; + } else if (mSignalClusterStyle == SIGNAL_CLUSTER_STYLE_TEXT) { + mMobileGroup.setVisibility(View.VISIBLE); + mMobileSignalText.setText(getSignalLevelString(dBm)); + } else { + mMobileGroup.setVisibility(View.GONE); + } + } + + /* + * Phone listener to update signal information + */ + private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { + @Override + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + if (signalStrength != null) { + dBm = signalStrength.getDbm(); + } else { + dBm = 0; + } + + // update text if it's visible + if (mAttached) { + updateSettings(); + } + } + + public void onServiceStateChanged(ServiceState serviceState) { + mAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF; + updateSettings(); + } + }; + + private void updateSettings() { + ContentResolver resolver = mContext.getContentResolver(); + mSignalClusterStyle = (Settings.System.getInt(resolver, + Settings.System.STATUS_BAR_SIGNAL_TEXT, SIGNAL_CLUSTER_STYLE_NORMAL)); + updateSignalText(); + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index 744a46b..b9ecc8b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -16,17 +16,19 @@ package com.android.systemui.statusbar; +import android.content.ContentResolver; import android.content.Context; +import android.database.ContentObserver; +import android.os.Handler; +import android.provider.Settings; import android.util.AttributeSet; import android.util.Slog; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.TextView; import com.android.systemui.statusbar.policy.NetworkController; - import com.android.systemui.R; // Intimately tied to the design of res/layout/signal_cluster_view.xml @@ -34,9 +36,11 @@ public class SignalClusterView extends LinearLayout implements NetworkController.SignalCluster { + private static final int SIGNAL_CLUSTER_STYLE_NORMAL = 0; + static final boolean DEBUG = false; static final String TAG = "SignalClusterView"; - + NetworkController mNC; private boolean mWifiVisible = false; @@ -46,10 +50,31 @@ public class SignalClusterView private boolean mIsAirplaneMode = false; private String mWifiDescription, mMobileDescription, mMobileTypeDescription; + private int mSignalClusterStyle; + ViewGroup mWifiGroup, mMobileGroup; ImageView mWifi, mMobile, mWifiActivity, mMobileActivity, mMobileType; View mSpacer; + Handler mHandler; + + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.STATUS_BAR_SIGNAL_TEXT), false, this); + } + + @Override + public void onChange(boolean selfChange) { + updateSettings(); + } + } + public SignalClusterView(Context context) { this(context, null); } @@ -60,6 +85,11 @@ public class SignalClusterView public SignalClusterView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + + mHandler = new Handler(); + + SettingsObserver settingsObserver = new SettingsObserver(mHandler); + settingsObserver.observe(); } public void setNetworkController(NetworkController nc) { @@ -163,6 +193,19 @@ public class SignalClusterView mMobileType.setVisibility( !mWifiVisible ? View.VISIBLE : View.GONE); + + updateSettings(); + } + + private void updateSignalClusterStyle() { + mMobileGroup.setVisibility(mSignalClusterStyle != SIGNAL_CLUSTER_STYLE_NORMAL ? View.GONE : View.VISIBLE); + } + + private void updateSettings() { + ContentResolver resolver = mContext.getContentResolver(); + mSignalClusterStyle = (Settings.System.getInt(resolver, + Settings.System.STATUS_BAR_SIGNAL_TEXT, SIGNAL_CLUSTER_STYLE_NORMAL)); + updateSignalClusterStyle(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 0175f13..e72a741 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -33,6 +33,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.Configuration; +import android.database.ContentObserver; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -123,6 +124,8 @@ public class PhoneStatusBar extends StatusBar { private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true; private boolean mShowClock; + private boolean mBrightnessControl; + private boolean mAutoBrightness; // fling gesture tuning parameters, scaled to display density private float mSelfExpandVelocityPx; // classic value: 2000px/s @@ -241,6 +244,35 @@ public class PhoneStatusBar extends StatusBar { DisplayMetrics mDisplayMetrics = new DisplayMetrics(); + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.STATUS_BAR_BRIGHTNESS_TOGGLE), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.SCREEN_BRIGHTNESS_MODE), false, this); + update(); + } + + @Override + public void onChange(boolean selfChange) { + update(); + } + + public void update() { + ContentResolver resolver = mContext.getContentResolver(); + mBrightnessControl = Settings.System.getInt(resolver, + Settings.System.STATUS_BAR_BRIGHTNESS_TOGGLE, 0) != 0; + mAutoBrightness = Settings.System.getInt(resolver, + Settings.System.SCREEN_BRIGHTNESS_MODE, 0) == + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; + } + } + private class ExpandedDialog extends Dialog { ExpandedDialog(Context context) { super(context, com.android.internal.R.style.Theme_Translucent_NoTitleBar); @@ -274,6 +306,9 @@ public class PhoneStatusBar extends StatusBar { //addIntruderView(); + SettingsObserver observer = new SettingsObserver(mHandler); + observer.observe(); + // Lastly, call to the icon policy to install/update all the icons. mIconPolicy = new PhoneStatusBarPolicy(mContext); } @@ -383,6 +418,7 @@ public class PhoneStatusBar extends StatusBar { mLocationController = new LocationController(mContext); // will post a notification mBatteryController = new BatteryController(mContext); mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery)); + mBatteryController.addLabelView((TextView)sb.findViewById(R.id.battery_text)); mNetworkController = new NetworkController(mContext); final SignalClusterView signalCluster = (SignalClusterView)sb.findViewById(R.id.signal_cluster); @@ -1530,40 +1566,33 @@ public class PhoneStatusBar extends StatusBar { final int minY = statusBarSize + mCloseView.getHeight(); if (action == MotionEvent.ACTION_MOVE) { if (mAnimatingReveal && y < minY) { - boolean brightnessControl = Settings.System.getInt(mStatusBarView.getContext().getContentResolver(), - Settings.System.STATUS_BAR_BRIGHTNESS_TOGGLE, 0) == 1; - if (brightnessControl){ - mVelocityTracker.computeCurrentVelocity(1000); - float yVel = mVelocityTracker.getYVelocity(); - yVel = Math.abs(yVel); - if (yVel < 50.0f) { - if (mLinger > 20) { - Context context = mStatusBarView.getContext(); - boolean autoBrightness = Settings.System.getInt(context.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_MODE, 0) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; - if (!autoBrightness) { - float x = (float) event.getRawX(); - int newBrightness = (int) Math.round(((x/mScreenWidth) * android.os.Power.BRIGHTNESS_ON)); - newBrightness = Math.min(newBrightness, android.os.Power.BRIGHTNESS_ON); - newBrightness = Math.max(newBrightness, mMinBrightness); - try { - IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager.getService("power")); - if (power != null) { - power.setBacklightBrightness(newBrightness); - Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, - newBrightness); - } - } catch (RemoteException e) { - Slog.w(TAG, "Setting Brightness failed: " + e); - } + if (mBrightnessControl && !mAutoBrightness) { + mVelocityTracker.computeCurrentVelocity(1000); + float yVel = mVelocityTracker.getYVelocity(); + yVel = Math.abs(yVel); + if (yVel < 50.0f) { + if (mLinger > 20) { + float x = (float) event.getRawX(); + int newBrightness = (int) Math.round(((x / mScreenWidth) * android.os.Power.BRIGHTNESS_ON)); + newBrightness = Math.min(newBrightness, android.os.Power.BRIGHTNESS_ON); + newBrightness = Math.max(newBrightness, mMinBrightness); + try { + IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager.getService("power")); + if (power != null) { + power.setBacklightBrightness(newBrightness); + Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, + newBrightness); } - } else { - mLinger++; + } catch (RemoteException e) { + Slog.w(TAG, "Setting Brightness failed: " + e); } } else { - mLinger = 0; + mLinger++; } + } else { + mLinger = 0; } + } } else { mAnimatingReveal = false; updateExpandedViewPos(y + mViewDelta); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java index ff418c4..ed91d47 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java @@ -19,11 +19,15 @@ package com.android.systemui.statusbar.policy; import java.util.ArrayList; import android.content.BroadcastReceiver; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.database.ContentObserver; import android.os.BatteryManager; -import android.util.Slog; +import android.os.Handler; +import android.provider.Settings; +import android.view.View; import android.widget.ImageView; import android.widget.TextView; @@ -36,8 +40,47 @@ public class BatteryController extends BroadcastReceiver { private ArrayList<ImageView> mIconViews = new ArrayList<ImageView>(); private ArrayList<TextView> mLabelViews = new ArrayList<TextView>(); + private static final int BATTERY_STYLE_NORMAL = 0; + private static final int BATTERY_STYLE_TEXT = 1; + private static final int BATTERY_STYLE_GONE = 2; + + private static final int BATTERY_ICON_STYLE_NORMAL = R.drawable.stat_sys_battery; + private static final int BATTERY_ICON_STYLE_CHARGE = R.drawable.stat_sys_battery_charge; + private static final int BATTERY_ICON_STYLE_NORMAL_MIN = R.drawable.stat_sys_battery_min; + private static final int BATTERY_ICON_STYLE_CHARGE_MIN = R.drawable.stat_sys_battery_charge_min; + + private static final int BATTERY_TEXT_STYLE_NORMAL = R.string.status_bar_settings_battery_meter_format; + private static final int BATTERY_TEXT_STYLE_MIN = R.string.status_bar_settings_battery_meter_min_format; + + private boolean mBatteryPlugged = false; + private int mBatteryStyle; + private int mBatteryIcon = BATTERY_ICON_STYLE_NORMAL; + + Handler mHandler; + + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.STATUS_BAR_BATTERY), false, this); + } + + @Override public void onChange(boolean selfChange) { + updateSettings(); + } + } + public BatteryController(Context context) { mContext = context; + mHandler = new Handler(); + + SettingsObserver settingsObserver = new SettingsObserver(mHandler); + settingsObserver.observe(); + updateSettings(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); @@ -56,13 +99,11 @@ public class BatteryController extends BroadcastReceiver { final String action = intent.getAction(); if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); - final boolean plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0; - final int icon = plugged ? R.drawable.stat_sys_battery_charge - : R.drawable.stat_sys_battery; + mBatteryPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0; + int N = mIconViews.size(); for (int i=0; i<N; i++) { ImageView v = mIconViews.get(i); - v.setImageResource(icon); v.setImageLevel(level); v.setContentDescription(mContext.getString(R.string.accessibility_battery_level, level)); @@ -70,9 +111,47 @@ public class BatteryController extends BroadcastReceiver { N = mLabelViews.size(); for (int i=0; i<N; i++) { TextView v = mLabelViews.get(i); - v.setText(mContext.getString(R.string.status_bar_settings_battery_meter_format, + v.setText(mContext.getString(BATTERY_TEXT_STYLE_MIN, level)); } + updateBattery(); + } + } + + private void updateBattery() { + int mIcon = View.GONE; + int mText = View.GONE; + int mIconStyle = BATTERY_ICON_STYLE_NORMAL; + + if (mBatteryStyle == 0) { + mIcon = (View.VISIBLE); + mIconStyle = mBatteryPlugged ? BATTERY_ICON_STYLE_CHARGE + : BATTERY_ICON_STYLE_NORMAL; + } else if (mBatteryStyle == 1) { + mIcon = (View.VISIBLE); + mText = (View.VISIBLE); + mIconStyle = mBatteryPlugged ? BATTERY_ICON_STYLE_CHARGE_MIN + : BATTERY_ICON_STYLE_NORMAL_MIN; } + + int N = mIconViews.size(); + for (int i=0; i<N; i++) { + ImageView v = mIconViews.get(i); + v.setVisibility(mIcon); + v.setImageResource(mIconStyle); + } + N = mLabelViews.size(); + for (int i=0; i<N; i++) { + TextView v = mLabelViews.get(i); + v.setVisibility(mText); + } + } + + private void updateSettings() { + ContentResolver resolver = mContext.getContentResolver(); + + mBatteryStyle = (Settings.System.getInt(resolver, + Settings.System.STATUS_BAR_BATTERY, 0)); + updateBattery(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LTEButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LTEButton.java new file mode 100644 index 0000000..ae9799e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LTEButton.java @@ -0,0 +1,85 @@ +package com.android.systemui.statusbar.powerwidget; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.provider.Settings; +import android.provider.Settings.SettingNotFoundException; +import android.telephony.TelephonyManager; + +import com.android.internal.telephony.Phone; +import com.android.systemui.R; + +import java.util.ArrayList; +import java.util.List; + +public class LTEButton extends PowerButton{ + + private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>(); + static { + OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.LTE_MODE)); + } + + public LTEButton() { mType = BUTTON_LTE; } + + @Override + protected void updateState() { + ContentResolver resolver = mView.getContext().getContentResolver(); + int network = getCurrentPreferredNetworkMode(mView.getContext()); + switch(network) { + case Phone.NT_MODE_GLOBAL: + mIcon = R.drawable.stat_lte_on; + mState = STATE_ENABLED; + Settings.System.putInt(resolver, Settings.System.LTE_MODE, 1); + break; + case Phone.NT_MODE_CDMA: + mIcon = R.drawable.stat_lte_off; + mState = STATE_DISABLED; + Settings.System.putInt(resolver, Settings.System.LTE_MODE, 0); + break; + } + } + + @Override + protected void toggleState() { + TelephonyManager tm = (TelephonyManager) mView.getContext() + .getSystemService(Context.TELEPHONY_SERVICE); + int network = getCurrentPreferredNetworkMode(mView.getContext()); + ContentResolver resolver = mView.getContext().getContentResolver(); + if (Phone.NT_MODE_GLOBAL == network) { + tm.toggleLTE(false); + mState = STATE_DISABLED; + Settings.System.putInt(resolver, Settings.System.LTE_MODE, 0); + } else if (Phone.NT_MODE_CDMA == network) { + tm.toggleLTE(true); + mState = STATE_ENABLED; + Settings.System.putInt(resolver, Settings.System.LTE_MODE, 1); + } + } + + @Override + protected boolean handleLongClick() { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClassName("com.android.phone", "com.android.phone.Settings"); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mView.getContext().startActivity(intent); + return true; + } + + @Override + protected List<Uri> getObservedUris() { + return OBSERVED_URIS; + } + + private static int getCurrentPreferredNetworkMode(Context context) { + int network = -1; + try { + network = Settings.Secure.getInt(context.getContentResolver(), + Settings.Secure.PREFERRED_NETWORK_MODE); + } catch (SettingNotFoundException e) { + e.printStackTrace(); + } + return network; + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerButton.java index c319fae..17aa578 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerButton.java @@ -50,6 +50,7 @@ public abstract class PowerButton { public static final String BUTTON_MEDIA_PLAY_PAUSE = "toggleMediaPlayPause"; public static final String BUTTON_MEDIA_PREVIOUS = "toggleMediaPrevious"; public static final String BUTTON_MEDIA_NEXT = "toggleMediaNext"; + public static final String BUTTON_LTE = "toggleLte"; public static final String BUTTON_WIMAX = "toggleWimax"; public static final String BUTTON_UNKNOWN = "unknown"; @@ -76,6 +77,7 @@ public abstract class PowerButton { BUTTONS.put(BUTTON_MEDIA_PLAY_PAUSE, MediaPlayPauseButton.class); BUTTONS.put(BUTTON_MEDIA_PREVIOUS, MediaPreviousButton.class); BUTTONS.put(BUTTON_MEDIA_NEXT, MediaNextButton.class); + BUTTONS.put(BUTTON_LTE, LTEButton.class); BUTTONS.put(BUTTON_WIMAX, WimaxButton.class); } // this is a list of our currently loaded buttons diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HoloClock.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HoloClock.java index f98caa2..2e143ae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HoloClock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HoloClock.java @@ -17,22 +17,25 @@ package com.android.systemui.statusbar.tablet; import android.content.BroadcastReceiver; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.AssetManager; import android.content.res.Resources; import android.content.res.TypedArray; +import android.database.ContentObserver; import android.graphics.Canvas; import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.provider.Settings; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.format.DateFormat; import android.text.style.CharacterStyle; import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; -import android.text.style.RelativeSizeSpan; import android.text.style.StyleSpan; import android.util.AttributeSet; import android.view.View; @@ -52,6 +55,12 @@ public class HoloClock extends FrameLayout { private String mClockFormatString; private SimpleDateFormat mClockFormat; + private static final int AM_PM_STYLE_NORMAL = 0; + private static final int AM_PM_STYLE_SMALL = 1; + private static final int AM_PM_STYLE_GONE = 2; + + private static int AM_PM_STYLE = AM_PM_STYLE_GONE; + private static final String FONT_DIR = "/system/fonts/"; private static final String CLOCK_FONT = FONT_DIR + "AndroidClock_Solid.ttf"; private static final String CLOCK_FG_FONT = FONT_DIR + "AndroidClock.ttf"; @@ -60,6 +69,29 @@ public class HoloClock extends FrameLayout { private static Typeface sBackgroundType, sForegroundType, sSolidType; private TextView mSolidText, mBgText, mFgText; + private int mAmPmStyle; + private boolean mShowClock; + + Handler mHandler; + + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.STATUS_BAR_AM_PM), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.STATUS_BAR_CLOCK), false, this); + } + + @Override public void onChange(boolean selfChange) { + updateSettings(); + } + } + public HoloClock(Context context) { this(context, null); } @@ -70,6 +102,12 @@ public class HoloClock extends FrameLayout { public HoloClock(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + + mHandler = new Handler(); + SettingsObserver settingsObserver = new SettingsObserver(mHandler); + settingsObserver.observe(); + + updateSettings(); } @Override @@ -161,10 +199,43 @@ public class HoloClock extends FrameLayout { ? com.android.internal.R.string.twenty_four_hour_time_format : com.android.internal.R.string.twelve_hour_time_format; + final char MAGIC1 = '\uEF00'; + final char MAGIC2 = '\uEF01'; + SimpleDateFormat sdf; String format = context.getString(res); if (!format.equals(mClockFormatString)) { - // we don't want AM/PM showing up in our statusbar, even in 12h mode + /* + * Search for an unquoted "a" in the format string, so we can + * add dummy characters around it to let us find it again after + * formatting and change its size. + */ + if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) { + int a = -1; + boolean quoted = false; + for (int i = 0; i < format.length(); i++) { + char c = format.charAt(i); + + if (c == '\'') { + quoted = !quoted; + } + if (!quoted && c == 'a') { + a = i; + break; + } + } + + if (a >= 0) { + // Move a back so any whitespace before AM/PM is also in the alternate size. + final int b = a; + while (a > 0 && Character.isWhitespace(format.charAt(a-1))) { + a--; + } + format = format.substring(0, a) + MAGIC1 + format.substring(a, b) + + "a" + MAGIC2 + format.substring(b + 1); + } + } + format = format.replaceAll("a", "").trim(); mClockFormat = sdf = new SimpleDateFormat(format); mClockFormatString = format; @@ -172,7 +243,52 @@ public class HoloClock extends FrameLayout { sdf = mClockFormat; } String result = sdf.format(mCalendar.getTime()); + + if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) { + int magic1 = result.indexOf(MAGIC1); + int magic2 = result.indexOf(MAGIC2); + if (magic1 >= 0 && magic2 > magic1) { + SpannableStringBuilder formatted = new SpannableStringBuilder(result); + if (AM_PM_STYLE == AM_PM_STYLE_GONE) { + formatted.delete(magic1, magic2+1); + } else { + if (AM_PM_STYLE == AM_PM_STYLE_SMALL) { + CharacterStyle style = new RelativeSizeSpan(0.7f); + formatted.setSpan(style, magic1, magic2, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + } + formatted.delete(magic2, magic2 + 1); + formatted.delete(magic1, magic1 + 1); + } + return formatted; + } + } + return result; } + + private void updateSettings(){ + ContentResolver resolver = mContext.getContentResolver(); + + mAmPmStyle = (Settings.System.getInt(resolver, + Settings.System.STATUS_BAR_AM_PM, 2)); + + if (mAmPmStyle != AM_PM_STYLE) { + AM_PM_STYLE = mAmPmStyle; + mClockFormatString = ""; + + if (mAttached) { + updateClock(); + } + } + + mShowClock = (Settings.System.getInt(resolver, + Settings.System.STATUS_BAR_CLOCK, 1) == 1); + + if(mShowClock) + setVisibility(View.VISIBLE); + else + setVisibility(View.GONE); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index de16604..3fe486b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -505,6 +505,8 @@ public class TabletStatusBar extends StatusBar implements mBatteryController = new BatteryController(mContext); mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery)); + mBatteryController.addLabelView( + (TextView)sb.findViewById(R.id.battery_text)); mBluetoothController = new BluetoothController(mContext); mBluetoothController.addIconView((ImageView)sb.findViewById(R.id.bluetooth)); diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java index dfece30..17e8826 100644 --- a/policy/src/com/android/internal/policy/impl/GlobalActions.java +++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2008 The Android Open Source Project - * Copyright (C) 2011 David van Tonder + * Copyright (C) 2010-2012 CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,10 @@ package com.android.internal.policy.impl; import android.app.Activity; import android.app.AlertDialog; +import android.app.Dialog; +import android.app.Profile; +import android.app.ProfileManager; +import android.app.StatusBarManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; @@ -47,6 +51,7 @@ import com.android.internal.telephony.TelephonyProperties; import com.google.android.collect.Lists; import java.util.ArrayList; +import java.util.UUID; /** * Needed for takeScreenshot @@ -85,6 +90,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac private ToggleAction.State mAirplaneState = ToggleAction.State.Off; private boolean mIsWaitingForEcmExit = false; + private Profile mChosenProfile; + /** * @param context everything needs a context :( */ @@ -206,6 +213,22 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac } }); + // next: profile + mItems.add( + new ProfileChooseAction() { + public void onPress() { + createProfileDialog(); + } + + public boolean showDuringKeyguard() { + return false; + } + + public boolean showBeforeProvisioning() { + return false; + } + }); + // next: screenshot mItems.add( new SinglePressAction(com.android.internal.R.drawable.ic_lock_screenshot, R.string.global_action_screenshot) { @@ -247,6 +270,51 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac return dialog; } + private void createProfileDialog(){ + final ProfileManager profileManager = (ProfileManager)mContext.getSystemService(Context.PROFILE_SERVICE); + + final Profile[] profiles = profileManager.getProfiles(); + UUID activeProfile = profileManager.getActiveProfile().getUuid(); + final CharSequence[] names = new CharSequence[profiles.length]; + + int i=0; + int checkedItem = 0; + + for(Profile profile : profiles) { + if(profile.getUuid().equals(activeProfile)) { + checkedItem = i; + mChosenProfile = profile; + } + names[i++] = profile.getName(); + } + + final AlertDialog.Builder ab = new AlertDialog.Builder(mContext); + + AlertDialog dialog = ab + .setTitle(R.string.global_action_choose_profile) + .setSingleChoiceItems(names, checkedItem, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + if (which < 0) + return; + mChosenProfile = profiles[which]; + } + }) + .setPositiveButton(com.android.internal.R.string.yes, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + profileManager.setActiveProfile(mChosenProfile.getUuid()); + } + }) + .setNegativeButton(com.android.internal.R.string.no, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }).create(); + dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); + dialog.show(); + } + /** * functions needed for taking screenhots. * This leverages the built in ICS screenshot functionality @@ -306,7 +374,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac msg.arg2 = 1; */ - /* wait for the dislog box to close */ + /* wait for the dialog box to close */ try { Thread.sleep(1000); } catch (InterruptedException ie) { @@ -499,6 +567,42 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac } /** + * A single press action maintains no state, just responds to a press + * and takes an action. + */ + private abstract class ProfileChooseAction implements Action { + private ProfileManager mProfileManager; + + protected ProfileChooseAction() { + mProfileManager = (ProfileManager)mContext.getSystemService(Context.PROFILE_SERVICE); + } + + public boolean isEnabled() { + return true; + } + + abstract public void onPress(); + + public View create( + Context context, View convertView, ViewGroup parent, LayoutInflater inflater) { + View v = (convertView != null) ? + convertView : + inflater.inflate(R.layout.global_actions_item, parent, false); + + ImageView icon = (ImageView) v.findViewById(R.id.icon); + TextView messageView = (TextView) v.findViewById(R.id.message); + TextView statusView = (TextView) v.findViewById(R.id.status); + statusView.setVisibility(View.VISIBLE); + statusView.setText(mProfileManager.getActiveProfile().getName()); + + icon.setImageDrawable(context.getResources().getDrawable(com.android.internal.R.drawable.ic_lock_profile)); + messageView.setText(R.string.global_action_choose_profile); + + return v; + } + } + + /** * A toggle action knows whether it is on or off, and displays an icon * and status message accordingly. */ diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index 24a2420..c87afe4 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -298,7 +298,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen { final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen); final boolean isTestHarness = ActivityManager.isRunningInTestHarness(); final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists(); - return !configDisabled || isTestHarness || fileOverride; + final boolean menuOverride = Settings.System.getInt(getContext().getContentResolver(), Settings.System.MENU_UNLOCK_SCREEN, 0) == 1; + return !configDisabled || isTestHarness || fileOverride || menuOverride; } /** diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 0322658..f9b80b5 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -329,6 +329,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE; int mUserRotation = Surface.ROTATION_0; + int mUserRotationAngles = -1; int mAllowAllRotations = -1; boolean mCarDockEnablesAccelerometer; @@ -352,6 +353,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mFocusedWindow; IApplicationToken mFocusedApp; + // Behavior of volume wake + boolean mVolumeWakeScreen; + private final InputHandler mPointerLocationInputHandler = new BaseInputHandler() { @Override public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) { @@ -479,6 +483,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this); resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.VOLUME_WAKE_SCREEN), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.ACCELEROMETER_ROTATION), false, this); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.USER_ROTATION), false, this); @@ -492,6 +498,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { Settings.Secure.DEFAULT_INPUT_METHOD), false, this); resolver.registerContentObserver(Settings.System.getUriFor( "fancy_rotation_anim"), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.ACCELEROMETER_ROTATION_ANGLES), false, this); updateSettings(); } @@ -949,6 +957,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { mIncallPowerBehavior = Settings.Secure.getInt(resolver, Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT); + mVolumeWakeScreen = (Settings.System.getInt(resolver, + Settings.System.VOLUME_WAKE_SCREEN, 0) == 1); int accelerometerDefault = Settings.System.getInt(resolver, Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION); @@ -959,6 +969,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { mUserRotation = Settings.System.getInt(resolver, Settings.System.USER_ROTATION, Surface.ROTATION_0); + mUserRotationAngles = Settings.System.getInt(resolver, + Settings.System.ACCELEROMETER_ROTATION_ANGLES, -1); if (mAccelerometerDefault != accelerometerDefault) { mAccelerometerDefault = accelerometerDefault; @@ -2745,7 +2757,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) { final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; final boolean canceled = event.isCanceled(); - final int keyCode = event.getKeyCode(); + int keyCode = event.getKeyCode(); final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0; @@ -2790,7 +2802,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { result = 0; final boolean isWakeKey = (policyFlags - & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0; + & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0 + || ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) && mVolumeWakeScreen) + || ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) && mVolumeWakeScreen); + + // make sure keyevent get's handled as power key on volume-wake + if(!isScreenOn && mVolumeWakeScreen && isWakeKey && ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) + || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN))) + keyCode=KeyEvent.KEYCODE_POWER; + if (down && isWakeKey) { if (keyguardActive) { // If the keyguard is showing, let it decide what to do with the wake key. @@ -2911,6 +2931,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { } case KeyEvent.KEYCODE_POWER: { + if ((mTopFullscreenOpaqueWindowState.getAttrs().flags & WindowManager.LayoutParams.PREVENT_POWER_KEY) != 0){ + return result; + } result &= ~ACTION_PASS_TO_USER; if (down) { if (isScreenOn && !mPowerKeyTriggered @@ -3258,9 +3281,30 @@ public class PhoneWindowManager implements WindowManagerPolicy { mAllowAllRotations = mContext.getResources().getBoolean( com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0; } - if (sensorRotation != Surface.ROTATION_180 - || mAllowAllRotations == 1 - || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) { + // Rotation setting bitmask + // 1=0 2=90 4=180 8=270 + boolean allowed = true; + if (mUserRotationAngles < 0) { + // Not set by user so use these defaults + mUserRotationAngles = mAllowAllRotations == 1 ? + (1 | 2 | 4 | 8) : // All angles + (1 | 2 | 8); // All except 180 + } + switch (sensorRotation) { + case Surface.ROTATION_0: + allowed = (mUserRotationAngles & 1) != 0; + break; + case Surface.ROTATION_90: + allowed = (mUserRotationAngles & 2) != 0; + break; + case Surface.ROTATION_180: + allowed = (mUserRotationAngles & 4) != 0; + break; + case Surface.ROTATION_270: + allowed = (mUserRotationAngles & 8) != 0; + break; + } + if (allowed) { preferredRotation = sensorRotation; } else { preferredRotation = lastRotation; diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index fa49592..71ac5b0 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -30,4 +30,8 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_MODULE:= libaudioflinger +ifeq ($(BOARD_USE_MOTO_DOCK_HACK),true) + LOCAL_CFLAGS += -DMOTO_DOCK_HACK +endif + include $(BUILD_SHARED_LIBRARY) diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index e9ac3f9..d5c1319 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -779,7 +779,21 @@ status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs) mBtNrecIsOff = btNrecIsOff; } } + +#ifdef MOTO_DOCK_HACK + String8 key = String8("DockState"); + int device; + if (NO_ERROR != param.getInt(key, device)) { + LOGD("setParameters(): DockState not present"); + return final_result; + } else { + /* We also need to pass routing=int */ + ioHandle = 1; + LOGD("setParameters(): DockState %d trick done!", device); + } +#else return final_result; +#endif } // hold a strong ref on thread in case closeOutput() or closeInput() is called diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java index ab9ae69..1a8e555 100644 --- a/services/java/com/android/server/BatteryService.java +++ b/services/java/com/android/server/BatteryService.java @@ -24,9 +24,11 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.database.ContentObserver; import android.os.BatteryManager; import android.os.Binder; import android.os.FileUtils; +import android.os.Handler; import android.os.IBinder; import android.os.DropBoxManager; import android.os.RemoteException; @@ -122,6 +124,7 @@ class BatteryService extends Binder { private int mDischargeStartLevel; private Led mLed; + private boolean mLedPulseEnabled; private boolean mSentLowBatteryBroadcast = false; @@ -144,6 +147,9 @@ class BatteryService extends Binder { mInvalidChargerObserver.startObserving("DEVPATH=/devices/virtual/switch/invalid_charger"); } + SettingsObserver observer = new SettingsObserver(new Handler()); + observer.observe(); + // set initial status update(); } @@ -542,6 +548,10 @@ class BatteryService extends Binder { } } + private synchronized void updateLedPulse() { + mLed.updateLightsLocked(); + } + class Led { private LightsService mLightsService; private LightsService.Light mBatteryLight; @@ -582,10 +592,13 @@ class BatteryService extends Binder { if (status == BatteryManager.BATTERY_STATUS_CHARGING) { // Solid red when battery is charging mBatteryLight.setColor(mBatteryLowARGB); - } else { + } else if (mLedPulseEnabled) { // Flash red when battery is low and not charging mBatteryLight.setFlashing(mBatteryLowARGB, LightsService.LIGHT_FLASH_TIMED, mBatteryLedOn, mBatteryLedOff); + } else { + // "Pulse low battery light" is disabled, no lights. + mBatteryLight.turnOff(); } } else if (status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL) { @@ -602,5 +615,32 @@ class BatteryService extends Binder { } } } + + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.BATTERY_LIGHT_PULSE), false, this); + update(); + } + + @Override public void onChange(boolean selfChange) { + update(); + } + + public void update() { + ContentResolver resolver = mContext.getContentResolver(); + boolean pulseEnabled = Settings.System.getInt(resolver, + Settings.System.BATTERY_LIGHT_PULSE, 1) != 0; + if (mLedPulseEnabled != pulseEnabled) { + mLedPulseEnabled = pulseEnabled; + updateLedPulse(); + } + } + } } diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index 5039294..f266894 100755 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -23,8 +23,12 @@ import android.app.IActivityManager; import android.app.INotificationManager; import android.app.ITransientNotification; import android.app.Notification; +import android.app.NotificationGroup; import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.Profile; +import android.app.ProfileGroup; +import android.app.ProfileManager; import android.app.StatusBarManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -60,6 +64,8 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; +import java.util.Calendar; /** {@hide} */ public class NotificationManagerService extends INotificationManager.Stub @@ -102,8 +108,10 @@ public class NotificationManagerService extends INotificationManager.Stub // for enabling and disabling notification pulse behavior private boolean mScreenOn = true; + private boolean mWasScreenOn = false; private boolean mInCall = false; private boolean mNotificationPulseEnabled; + private HashMap<String, NotificationLedValues> mNotificationPulseCustomLedValues; private final ArrayList<NotificationRecord> mNotificationList = new ArrayList<NotificationRecord>(); @@ -113,6 +121,18 @@ public class NotificationManagerService extends INotificationManager.Stub private ArrayList<NotificationRecord> mLights = new ArrayList<NotificationRecord>(); private NotificationRecord mLedNotification; + private boolean mQuietHoursEnabled = false; + // Minutes from midnight when quiet hours begin. + private int mQuietHoursStart = 0; + // Minutes from midnight when quiet hours end. + private int mQuietHoursEnd = 0; + // Don't play sounds. + private boolean mQuietHoursMute = true; + // Don't vibrate. + private boolean mQuietHoursStill = true; + // Dim LED if hardware supports it. + private boolean mQuietHoursDim = true; + private static String idDebugString(Context baseContext, String packageName, int id) { Context c = null; @@ -225,6 +245,12 @@ public class NotificationManagerService extends INotificationManager.Stub } } + class NotificationLedValues { + public int color; + public int onMS; + public int offMS; + } + private StatusBarManagerService.NotificationCallbacks mNotificationCallbacks = new StatusBarManagerService.NotificationCallbacks() { @@ -351,6 +377,8 @@ public class NotificationManagerService extends INotificationManager.Stub mScreenOn = true; } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { mScreenOn = false; + mWasScreenOn = true; + updateLightsLocked(); } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { mInCall = (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals( TelephonyManager.EXTRA_STATE_OFFHOOK)); @@ -362,8 +390,8 @@ public class NotificationManagerService extends INotificationManager.Stub } }; - class SettingsObserver extends ContentObserver { - SettingsObserver(Handler handler) { + class LEDSettingsObserver extends ContentObserver { + LEDSettingsObserver(Handler handler) { super(handler); } @@ -371,24 +399,96 @@ public class NotificationManagerService extends INotificationManager.Stub ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.NOTIFICATION_LIGHT_PULSE), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES), false, this); update(); } @Override public void onChange(boolean selfChange) { update(); + updateNotificationPulse(); } public void update() { ContentResolver resolver = mContext.getContentResolver(); - boolean pulseEnabled = Settings.System.getInt(resolver, - Settings.System.NOTIFICATION_LIGHT_PULSE, 0) != 0; - if (mNotificationPulseEnabled != pulseEnabled) { - mNotificationPulseEnabled = pulseEnabled; - updateNotificationPulse(); + // LED enabled + mNotificationPulseEnabled = Settings.System.getInt(resolver, + Settings.System.NOTIFICATION_LIGHT_PULSE, 0) != 0; + + // LED default color + mDefaultNotificationColor = Settings.System.getInt(resolver, + Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, mDefaultNotificationColor); + + // LED default on MS + mDefaultNotificationLedOn = Settings.System.getInt(resolver, + Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, mDefaultNotificationLedOn); + + // LED default off MS + mDefaultNotificationLedOff = Settings.System.getInt(resolver, + Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, mDefaultNotificationLedOff); + + // LED custom notification colors + mNotificationPulseCustomLedValues.clear(); + if (Settings.System.getInt(resolver, + Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE, 0) != 0) { + parseNotificationPulseCustomValuesString(Settings.System.getString(resolver, + Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES)); } } } + class QuietHoursSettingsObserver extends ContentObserver { + QuietHoursSettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.QUIET_HOURS_ENABLED), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.QUIET_HOURS_START), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.QUIET_HOURS_END), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.QUIET_HOURS_MUTE), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.QUIET_HOURS_STILL), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.QUIET_HOURS_DIM), false, this); + update(); + } + + @Override public void onChange(boolean selfChange) { + update(); + updateNotificationPulse(); + } + + public void update() { + ContentResolver resolver = mContext.getContentResolver(); + mQuietHoursEnabled = Settings.System.getInt(resolver, + Settings.System.QUIET_HOURS_ENABLED, 0) != 0; + mQuietHoursStart = Settings.System.getInt(resolver, + Settings.System.QUIET_HOURS_START, 0); + mQuietHoursEnd = Settings.System.getInt(resolver, + Settings.System.QUIET_HOURS_END, 0); + mQuietHoursMute = Settings.System.getInt(resolver, + Settings.System.QUIET_HOURS_MUTE, 0) != 0; + mQuietHoursStill = Settings.System.getInt(resolver, + Settings.System.QUIET_HOURS_STILL, 0) != 0; + mQuietHoursDim = Settings.System.getInt(resolver, + Settings.System.QUIET_HOURS_DIM, 0) != 0; + } + } + NotificationManagerService(Context context, StatusBarManagerService statusBar, LightsService lights) { @@ -414,6 +514,8 @@ public class NotificationManagerService extends INotificationManager.Stub mDefaultNotificationLedOff = resources.getInteger( com.android.internal.R.integer.config_defaultNotificationLedOff); + mNotificationPulseCustomLedValues = new HashMap<String, NotificationLedValues>(); + // Don't start allowing notifications until the setup wizard has run once. // After that, including subsequent boots, init with notifications turned on. // This works on the first boot because the setup wizard will toggle this @@ -440,8 +542,10 @@ public class NotificationManagerService extends INotificationManager.Stub IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); mContext.registerReceiver(mIntentReceiver, sdFilter); - SettingsObserver observer = new SettingsObserver(mHandler); - observer.observe(); + LEDSettingsObserver ledObserver = new LEDSettingsObserver(mHandler); + ledObserver.observe(); + QuietHoursSettingsObserver qhObserver = new QuietHoursSettingsObserver(mHandler); + qhObserver.observe(); } void systemReady() { @@ -723,6 +827,8 @@ public class NotificationManagerService extends INotificationManager.Stub } synchronized (mNotificationList) { + final boolean inQuietHours = inQuietHours(); + NotificationRecord r = new NotificationRecord(pkg, tag, id, callingUid, callingPid, priority, @@ -787,6 +893,16 @@ public class NotificationManagerService extends INotificationManager.Stub } } + try { + final ProfileManager profileManager = + (ProfileManager) mContext.getSystemService(Context.PROFILE_SERVICE); + + ProfileGroup group = profileManager.getActiveProfileGroup(pkg); + notification = group.processNotification(notification); + } catch(Throwable th) { + Log.e(TAG, "An error occurred profiling the notification.", th); + } + // If we're not supposed to beep, vibrate, etc. then don't. if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0) && (!(old != null @@ -798,7 +914,8 @@ public class NotificationManagerService extends INotificationManager.Stub // sound final boolean useDefaultSound = (notification.defaults & Notification.DEFAULT_SOUND) != 0; - if (useDefaultSound || notification.sound != null) { + if (!(inQuietHours && mQuietHoursMute) + && (useDefaultSound || notification.sound != null)) { Uri uri; if (useDefaultSound) { uri = Settings.System.DEFAULT_NOTIFICATION_URI; @@ -829,7 +946,8 @@ public class NotificationManagerService extends INotificationManager.Stub // vibrate final boolean useDefaultVibrate = (notification.defaults & Notification.DEFAULT_VIBRATE) != 0; - if ((useDefaultVibrate || notification.vibrate != null) + if (!(inQuietHours && mQuietHoursStill) + && (useDefaultVibrate || notification.vibrate != null) && audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_NOTIFICATION)) { mVibrateNotification = r; @@ -863,6 +981,21 @@ public class NotificationManagerService extends INotificationManager.Stub idOut[0] = id; } + private boolean inQuietHours() { + if (mQuietHoursEnabled && (mQuietHoursStart != mQuietHoursEnd)) { + // Get the date in "quiet hours" format. + Calendar calendar = Calendar.getInstance(); + int minutes = calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE); + if (mQuietHoursEnd < mQuietHoursStart) { + // Starts at night, ends in the morning. + return (minutes > mQuietHoursStart) || (minutes < mQuietHoursEnd); + } else { + return (minutes > mQuietHoursStart) && (minutes < mQuietHoursEnd); + } + } + return false; + } + private void sendAccessibilityEvent(Notification notification, CharSequence packageName) { AccessibilityManager manager = AccessibilityManager.getInstance(mContext); if (!manager.isEnabled()) { @@ -1072,17 +1205,45 @@ public class NotificationManagerService extends INotificationManager.Stub } } - // Don't flash while we are in a call or screen is on - if (mLedNotification == null || mInCall || mScreenOn) { + boolean wasScreenOn = mWasScreenOn; + mWasScreenOn = false; + + if (mLedNotification == null) { + mNotificationLight.turnOff(); + return; + } + + // We can assume that if the user turned the screen off while there was + // still an active notification then they wanted to keep the notification + // for later. In this case we shouldn't flash the notification light. + // For special notifications that automatically turn the screen on (such + // as missed calls), we use this flag to force the notification light + // even if the screen was turned off. + boolean forceWithScreenOff = (mLedNotification.notification.flags & + Notification.FLAG_FORCE_LED_SCREEN_OFF) != 0; + + // Don't flash while we are in a call, screen is on or we are in quiet hours with light dimmed + if (mInCall || mScreenOn || (inQuietHours() && mQuietHoursDim) || (wasScreenOn && !forceWithScreenOff)) { mNotificationLight.turnOff(); } else { - int ledARGB = mLedNotification.notification.ledARGB; - int ledOnMS = mLedNotification.notification.ledOnMS; - int ledOffMS = mLedNotification.notification.ledOffMS; - if ((mLedNotification.notification.defaults & Notification.DEFAULT_LIGHTS) != 0) { - ledARGB = mDefaultNotificationColor; - ledOnMS = mDefaultNotificationLedOn; - ledOffMS = mDefaultNotificationLedOff; + int ledARGB; + int ledOnMS; + int ledOffMS; + NotificationLedValues ledValues = getLedValuesForNotification(mLedNotification); + if (ledValues != null) { + ledARGB = ledValues.color; + ledOnMS = ledValues.onMS; + ledOffMS = ledValues.offMS; + } else { + if ((mLedNotification.notification.defaults & Notification.DEFAULT_LIGHTS) != 0) { + ledARGB = mDefaultNotificationColor; + ledOnMS = mDefaultNotificationLedOn; + ledOffMS = mDefaultNotificationLedOff; + } else { + ledARGB = mLedNotification.notification.ledARGB; + ledOnMS = mLedNotification.notification.ledOnMS; + ledOffMS = mLedNotification.notification.ledOffMS; + } } if (mNotificationPulseEnabled) { // pulse repeatedly @@ -1092,6 +1253,40 @@ public class NotificationManagerService extends INotificationManager.Stub } } + private void parseNotificationPulseCustomValuesString(String customLedValuesString) { + if (TextUtils.isEmpty(customLedValuesString)) { + return; + } + + for (String packageValuesString : customLedValuesString.split("|")) { + String[] packageValues = packageValuesString.split("="); + if (packageValues.length != 2) { + Log.e(TAG, "Error parsing custom led values for unknown package"); + continue; + } + String packageName = packageValues[0]; + String[] values = packageValues[1].split(";"); + if (values.length != 3) { + Log.e(TAG, "Error parsing custom led values '" + packageValues[1] + "' for " + packageName); + continue; + } + NotificationLedValues ledValues = new NotificationLedValues(); + try { + ledValues.color = Integer.parseInt(values[0]); + ledValues.onMS = Integer.parseInt(values[1]); + ledValues.offMS = Integer.parseInt(values[2]); + } catch (Exception e) { + Log.e(TAG, "Error parsing custom led values '" + packageValues[1] + "' for " + packageName); + continue; + } + mNotificationPulseCustomLedValues.put(packageName, ledValues); + } + } + + private NotificationLedValues getLedValuesForNotification(NotificationRecord ledNotification) { + return mNotificationPulseCustomLedValues.get(ledNotification.pkg); + } + // lock on mNotificationList private int indexOfNotificationLocked(String pkg, String tag, int id) { diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 87597fc..251c32a 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -51,6 +51,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.WorkSource; +import android.os.SystemProperties; import android.provider.Settings.SettingNotFoundException; import android.provider.Settings; import android.util.EventLog; @@ -245,7 +246,7 @@ public class PowerManagerService extends IPowerManager.Stub private int mButtonBrightnessOverride = -1; private int mScreenBrightnessDim; private boolean mUseSoftwareAutoBrightness; - private boolean mAutoBrightessEnabled; + private boolean mAutoBrightessEnabled = true; private int[] mAutoBrightnessLevels; private int[] mLcdBacklightValues; private int[] mButtonBacklightValues; @@ -256,6 +257,13 @@ public class PowerManagerService extends IPowerManager.Stub private long mWarningSpewThrottleTime; private int mAnimationSetting = ANIM_SETTING_OFF; + // When using software auto-brightness, determines whether (true) button + // and keyboard backlights should also be under automatic brightness + // control (i.e., for dimmable backlights), or (false) if they should use + // hard-coded brightness settings that timeout-to-off in subsequent screen + // power states. + private boolean mAutoBrightnessButtonKeyboard; + // Must match with the ISurfaceComposer constants in C++. private static final int ANIM_SETTING_ON = 0x01; private static final int ANIM_SETTING_OFF = 0x10; @@ -479,6 +487,7 @@ public class PowerManagerService extends IPowerManager.Stub } public void update(Observable o, Object arg) { + synchronized (mLocks) { // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN, @@ -637,6 +646,8 @@ public class PowerManagerService extends IPowerManager.Stub // read settings for auto-brightness mUseSoftwareAutoBrightness = resources.getBoolean( com.android.internal.R.bool.config_automatic_brightness_available); + mAutoBrightnessButtonKeyboard = mUseSoftwareAutoBrightness && resources.getBoolean( + com.android.internal.R.bool.config_autoBrightnessButtonKeyboard); if (mUseSoftwareAutoBrightness) { mAutoBrightnessLevels = resources.getIntArray( com.android.internal.R.array.config_autoBrightnessLevels); @@ -840,7 +851,7 @@ public class PowerManagerService extends IPowerManager.Stub switch (wl.flags & LOCK_MASK) { case PowerManager.FULL_WAKE_LOCK: - if (mUseSoftwareAutoBrightness) { + if (mAutoBrightnessButtonKeyboard) { wl.minState = SCREEN_BRIGHT; } else { wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); @@ -1207,6 +1218,7 @@ public class PowerManagerService extends IPowerManager.Stub + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness); pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness); + pw.println(" mAutoBrightnessButtonKeyboard=" + mAutoBrightnessButtonKeyboard); pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled); mScreenBrightness.dump(pw, " mScreenBrightness: "); @@ -1749,6 +1761,13 @@ public class PowerManagerService extends IPowerManager.Stub lightFilterStop(); resetLastLightValues(); } + else if (!mAutoBrightessEnabled && SystemProperties.getBoolean( + "ro.hardware.respect_als", false)) { + /* Force a light sensor reset since we enabled it + when the screen came on */ + mAutoBrightessEnabled = true; + setScreenBrightnessMode(Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); + } } } return err; @@ -1788,7 +1807,7 @@ public class PowerManagerService extends IPowerManager.Stub return; } - if (!mBootCompleted && !mUseSoftwareAutoBrightness) { + if (!mBootCompleted && !mAutoBrightnessButtonKeyboard) { newState |= ALL_BRIGHT; } @@ -2301,7 +2320,7 @@ public class PowerManagerService extends IPowerManager.Stub } if (mButtonBrightnessOverride >= 0) { brightness = mButtonBrightnessOverride; - } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) { + } else if (mLightSensorButtonBrightness >= 0 && mAutoBrightnessButtonKeyboard) { brightness = mLightSensorButtonBrightness; } if (brightness > 0) { @@ -2323,7 +2342,7 @@ public class PowerManagerService extends IPowerManager.Stub brightness = 0; } else if (mButtonBrightnessOverride >= 0) { brightness = mButtonBrightnessOverride; - } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) { + } else if (mLightSensorKeyboardBrightness >= 0 && mAutoBrightnessButtonKeyboard) { brightness = mLightSensorKeyboardBrightness; } if (brightness > 0) { @@ -2446,9 +2465,11 @@ public class PowerManagerService extends IPowerManager.Stub if (mLastEventTime <= time || force) { mLastEventTime = time; if ((mUserActivityAllowed && !mProximitySensorActive) || force) { - // Only turn on button backlights if a button was pressed - // and auto brightness is disabled - if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) { + if (!mAutoBrightnessButtonKeyboard) { + // Turn on button (and keyboard) backlights on any event, so that they + // don't suddenly disappear when the lock screen is unlocked (OTHER_EVENT), + // and so capacitive buttons can be found on devices where they lack + // identifying surface features. mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); } else { // don't clear button/keyboard backlights when the screen is touched. @@ -2685,6 +2706,7 @@ public class PowerManagerService extends IPowerManager.Stub return; } + // do not allow light sensor value to decrease unless // user has actively permitted it if (mLightDecrease) { @@ -2912,6 +2934,7 @@ public class PowerManagerService extends IPowerManager.Stub boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC); if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) { mAutoBrightessEnabled = enabled; + enableLightSensorLocked(mAutoBrightessEnabled); if (isScreenOn()) { // force recompute of backlight values if (mLightSensorValue >= 0) { @@ -3208,7 +3231,7 @@ public class PowerManagerService extends IPowerManager.Stub // wait until sensors are enabled before turning on screen. // some devices will not activate the light sensor properly on boot // unless we do this. - if (mUseSoftwareAutoBrightness) { + if (mAutoBrightnessButtonKeyboard) { // turn the screen on setPowerState(SCREEN_BRIGHT); } else { diff --git a/services/java/com/android/server/ProfileManagerService.java b/services/java/com/android/server/ProfileManagerService.java new file mode 100644 index 0000000..8c3f452 --- /dev/null +++ b/services/java/com/android/server/ProfileManagerService.java @@ -0,0 +1,517 @@ +/* + * 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 com.android.server; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import android.app.IProfileManager; +import android.app.NotificationGroup; +import android.app.Profile; +import android.app.ProfileGroup; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.XmlResourceParser; +import android.os.RemoteException; +import android.text.TextUtils; +import android.util.Log; +import android.os.ParcelUuid; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** {@hide} */ +public class ProfileManagerService extends IProfileManager.Stub { + // Enable the below for detailed logging of this class + private static final boolean LOCAL_LOGV = false; + /** + * <p>Broadcast Action: A new profile has been selected. This can be triggered by the user + * or by calls to the ProfileManagerService / Profile.</p> + * @hide + */ + public static final String INTENT_ACTION_PROFILE_SELECTED = "android.intent.action.PROFILE_SELECTED"; + + public static final String PERMISSION_CHANGE_SETTINGS = "android.permission.WRITE_SETTINGS"; + + private static final String PROFILE_FILENAME = "/data/system/profiles.xml"; + + private static final String TAG = "ProfileService"; + + private Map<UUID, Profile> mProfiles; + + // Match UUIDs and names, used for reverse compatibility + private Map<String, UUID> mProfileNames; + + private Map<UUID, NotificationGroup> mGroups; + + private Profile mActiveProfile; + + // Well-known UUID of the wildcard group + private static final UUID mWildcardUUID = UUID.fromString("a126d48a-aaef-47c4-baed-7f0e44aeffe5"); + private NotificationGroup mWildcardGroup; + + private Context mContext; + private boolean mDirty; + + private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + if (action.equals(Intent.ACTION_LOCALE_CHANGED)) { + persistIfDirty(); + initialize(); + } else if (action.equals(Intent.ACTION_SHUTDOWN)) { + persistIfDirty(); + } + } + }; + + public ProfileManagerService(Context context) { + mContext = context; + + mWildcardGroup = new NotificationGroup( + context.getString(com.android.internal.R.string.wildcardProfile), + com.android.internal.R.string.wildcardProfile, + mWildcardUUID); + + initialize(); + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_LOCALE_CHANGED); + filter.addAction(Intent.ACTION_SHUTDOWN); + mContext.registerReceiver(mIntentReceiver, filter); + } + + private void initialize() { + initialize(false); + } + + private void initialize(boolean skipFile) { + mProfiles = new HashMap<UUID, Profile>(); + mProfileNames = new HashMap<String, UUID>(); + mGroups = new HashMap<UUID, NotificationGroup>(); + mDirty = false; + + boolean init = skipFile; + + if (! skipFile) { + try { + loadFromFile(); + } catch (RemoteException e) { + e.printStackTrace(); + } catch (XmlPullParserException e) { + init = true; + } catch (IOException e) { + init = true; + } + } + + if (init) { + try { + initialiseStructure(); + } catch (Throwable ex) { + Log.e(TAG, "Error loading xml from resource: ", ex); + } + } + } + + @Override + public void resetAll() { + enforceChangePermissions(); + initialize(true); + } + + @Override + @Deprecated + public boolean setActiveProfileByName(String profileName) throws RemoteException, SecurityException { + if (mProfileNames.containsKey(profileName)) { + if (LOCAL_LOGV) Log.v(TAG, "setActiveProfile(String) found profile name in mProfileNames."); + return setActiveProfile(mProfiles.get(mProfileNames.get(profileName)), true); + } else { + // Since profileName could not be casted into a UUID, we can call it a string. + Log.w(TAG, "Unable to find profile to set active, based on string: " + profileName); + return false; + } + } + + @Override + public boolean setActiveProfile(ParcelUuid profileParcelUuid) throws RemoteException, SecurityException { + UUID profileUuid = profileParcelUuid.getUuid(); + if(mProfiles.containsKey(profileUuid)){ + if (LOCAL_LOGV) Log.v(TAG, "setActiveProfileByUuid(ParcelUuid) found profile UUID in mProfileNames."); + return setActiveProfile(mProfiles.get(profileUuid), true); + } else { + Log.e(TAG, "Cannot set active profile to: " + profileUuid.toString() + " - does not exist."); + return false; + } + } + + private boolean setActiveProfile(UUID profileUuid, boolean doinit) throws RemoteException { + if(mProfiles.containsKey(profileUuid)){ + if (LOCAL_LOGV) Log.v(TAG, "setActiveProfile(UUID, boolean) found profile UUID in mProfiles."); + return setActiveProfile(mProfiles.get(profileUuid), doinit); + } else { + Log.e(TAG, "Cannot set active profile to: " + profileUuid.toString() + " - does not exist."); + return false; + } + } + + private boolean setActiveProfile(Profile newActiveProfile, boolean doinit) throws RemoteException { + /* + * NOTE: Since this is not a public function, and all public functions + * take either a string or a UUID, the active profile should always be + * in the collection. If writing another setActiveProfile which receives + * a Profile object, run enforceChangePermissions, add the profile to the + * list, and THEN add it. + */ + + try { + enforceChangePermissions(); + Log.d(TAG, "Set active profile to: " + newActiveProfile.getUuid().toString() + " - " + newActiveProfile.getName()); + Profile lastProfile = mActiveProfile; + mActiveProfile = newActiveProfile; + mDirty = true; + if (doinit) { + if (LOCAL_LOGV) Log.v(TAG, "setActiveProfile(Profile, boolean) - Running init"); + + /* + * We need to clear the caller's identity in order to + * - allow the profile switch to execute actions not included in the caller's permissions + * - broadcast INTENT_ACTION_PROFILE_SELECTED + */ + long token = clearCallingIdentity(); + + // Call profile's "doSelect" + mActiveProfile.doSelect(mContext); + + // Notify other applications of newly selected profile. + Intent broadcast = new Intent(INTENT_ACTION_PROFILE_SELECTED); + broadcast.putExtra("name", mActiveProfile.getName()); + broadcast.putExtra("uuid", mActiveProfile.getUuid().toString()); + broadcast.putExtra("lastName", lastProfile.getName()); + broadcast.putExtra("lastUuid", lastProfile.getUuid().toString()); + mContext.sendBroadcast(broadcast); + + restoreCallingIdentity(token); + persistIfDirty(); + } + return true; + } catch (Exception ex) { + ex.printStackTrace(); + return false; + } + } + + @Override + public boolean addProfile(Profile profile) throws RemoteException, SecurityException { + enforceChangePermissions(); + addProfileInternal(profile); + persistIfDirty(); + return true; + } + + private void addProfileInternal(Profile profile) { + // Make sure this profile has all of the correct groups. + for (NotificationGroup group : mGroups.values()) { + ensureGroupInProfile(profile, group, false); + } + ensureGroupInProfile(profile, mWildcardGroup, true); + mProfiles.put(profile.getUuid(), profile); + mProfileNames.put(profile.getName(), profile.getUuid()); + mDirty = true; + } + + private void ensureGroupInProfile(Profile profile, NotificationGroup group, boolean defaultGroup) { + if (profile.getProfileGroup(group.getUuid()) != null) { + return; + } + + /* enforce a matchup between profile and notification group, which not only + * works by UUID, but also by name for backwards compatibility */ + for (ProfileGroup pg : profile.getProfileGroups()) { + if (pg.matches(group, defaultGroup)) { + return; + } + } + + /* didn't find any, create new group */ + profile.addProfileGroup(new ProfileGroup(group.getUuid(), defaultGroup)); + } + + @Override + @Deprecated + public Profile getProfileByName(String profileName) throws RemoteException { + if (mProfileNames.containsKey(profileName)) { + return mProfiles.get(mProfileNames.get(profileName)); + } else if (mProfiles.containsKey(UUID.fromString((profileName)))) { + return mProfiles.get(UUID.fromString(profileName)); + } else { + return null; + } + } + + @Override + public Profile getProfile(ParcelUuid profileParcelUuid) { + UUID profileUuid = profileParcelUuid.getUuid(); + return mProfiles.get(profileUuid); + } + + public Profile getProfile(UUID profileUuid) { + return mProfiles.get(profileUuid); + } + + @Override + public Profile[] getProfiles() throws RemoteException { + Profile[] tmpArr = mProfiles.values().toArray(new Profile[mProfiles.size()]); + Arrays.sort(tmpArr); + return tmpArr; + } + + @Override + public Profile getActiveProfile() throws RemoteException { + return mActiveProfile; + } + + @Override + public boolean removeProfile(Profile profile) throws RemoteException, SecurityException { + enforceChangePermissions(); + if (mProfileNames.remove(profile.getName()) != null && mProfiles.remove(profile.getUuid()) != null) { + mDirty = true; + persistIfDirty(); + return true; + } else{ + return false; + } + } + + @Override + public void updateProfile(Profile profile) throws RemoteException, SecurityException { + enforceChangePermissions(); + Profile old = mProfiles.get(profile.getUuid()); + if (old != null) { + mProfileNames.remove(old.getName()); + mProfileNames.put(profile.getName(), profile.getUuid()); + mProfiles.put(profile.getUuid(), profile); + /* no need to set mDirty, if the profile was actually changed, + * it's marked as dirty by itself */ + persistIfDirty(); + } + } + + @Override + public boolean profileExists(ParcelUuid profileUuid) throws RemoteException { + return mProfiles.containsKey(profileUuid.getUuid()); + } + + @Override + public boolean profileExistsByName(String profileName) throws RemoteException { + return mProfileNames.containsKey(profileName); + } + + @Override + public NotificationGroup[] getNotificationGroups() throws RemoteException { + return mGroups.values().toArray(new NotificationGroup[mGroups.size()]); + } + + @Override + public void addNotificationGroup(NotificationGroup group) throws RemoteException, SecurityException { + enforceChangePermissions(); + addNotificationGroupInternal(group); + persistIfDirty(); + } + + private void addNotificationGroupInternal(NotificationGroup group) { + if (mGroups.put(group.getUuid(), group) == null) { + // If the above is true, then the ProfileGroup shouldn't exist in + // the profile. Ensure it is added. + for (Profile profile : mProfiles.values()) { + ensureGroupInProfile(profile, group, false); + } + } + mDirty = true; + } + + @Override + public void removeNotificationGroup(NotificationGroup group) throws RemoteException, SecurityException { + enforceChangePermissions(); + mDirty |= (mGroups.remove(group.getUuid()) != null); + // Remove the corresponding ProfileGroup from all the profiles too if + // they use it. + for (Profile profile : mProfiles.values()) { + profile.removeProfileGroup(group.getUuid()); + } + persistIfDirty(); + } + + @Override + public void updateNotificationGroup(NotificationGroup group) throws RemoteException, SecurityException { + enforceChangePermissions(); + NotificationGroup old = mGroups.get(group.getUuid()); + if (old != null) { + mGroups.put(group.getUuid(), group); + /* no need to set mDirty, if the group was actually changed, + * it's marked as dirty by itself */ + persistIfDirty(); + } + } + + @Override + public NotificationGroup getNotificationGroupForPackage(String pkg) throws RemoteException { + for (NotificationGroup group : mGroups.values()) { + if (group.hasPackage(pkg)) { + return group; + } + } + return null; + } + + private void loadFromFile() throws RemoteException, XmlPullParserException, IOException { + XmlPullParserFactory xppf = XmlPullParserFactory.newInstance(); + XmlPullParser xpp = xppf.newPullParser(); + FileReader fr = new FileReader(PROFILE_FILENAME); + xpp.setInput(fr); + loadXml(xpp, mContext); + fr.close(); + persistIfDirty(); + } + + private void loadXml(XmlPullParser xpp, Context context) throws + XmlPullParserException, IOException, RemoteException { + int event = xpp.next(); + String active = null; + while (event != XmlPullParser.END_TAG || !"profiles".equals(xpp.getName())) { + if (event == XmlPullParser.START_TAG) { + String name = xpp.getName(); + if (name.equals("active")) { + active = xpp.nextText(); + Log.d(TAG, "Found active: " + active); + } else if (name.equals("profile")) { + Profile prof = Profile.fromXml(xpp, context); + addProfileInternal(prof); + // Failsafe if no active found + if (active == null) { + active = prof.getUuid().toString(); + } + } else if (name.equals("notificationGroup")) { + NotificationGroup ng = NotificationGroup.fromXml(xpp, context); + addNotificationGroupInternal(ng); + } + } else if (event == XmlPullParser.END_DOCUMENT) { + throw new IOException("Premature end of file while reading " + PROFILE_FILENAME); + } + event = xpp.next(); + } + // Don't do initialisation on startup. The AudioManager doesn't exist yet + // and besides, the volume settings will have survived the reboot. + try { + // Try / catch block to detect if XML file needs to be upgraded. + setActiveProfile(UUID.fromString(active), false); + } catch (IllegalArgumentException e) { + if (mProfileNames.containsKey(active)) { + setActiveProfile(mProfileNames.get(active), false); + } else { + // Final fail-safe: We must have SOME profile active. + // If we couldn't select one by now, we'll pick the first in the set. + setActiveProfile(mProfiles.values().iterator().next(), false); + } + // This is a hint that we probably just upgraded the XML file. Save changes. + mDirty = true; + } + } + + private void initialiseStructure() throws RemoteException, XmlPullParserException, IOException { + XmlResourceParser xml = mContext.getResources().getXml( + com.android.internal.R.xml.profile_default); + try { + loadXml(xml, mContext); + mDirty = true; + persistIfDirty(); + } finally { + xml.close(); + } + } + + private String getXmlString() throws RemoteException { + StringBuilder builder = new StringBuilder(); + builder.append("<profiles>\n<active>"); + builder.append(TextUtils.htmlEncode(getActiveProfile().getUuid().toString())); + builder.append("</active>\n"); + + for (Profile p : mProfiles.values()) { + p.getXmlString(builder, mContext); + } + for (NotificationGroup g : mGroups.values()) { + g.getXmlString(builder, mContext); + } + builder.append("</profiles>\n"); + return builder.toString(); + } + + @Override + public NotificationGroup getNotificationGroup(ParcelUuid uuid) throws RemoteException { + if (uuid.getUuid().equals(mWildcardGroup.getUuid())) { + return mWildcardGroup; + } + return mGroups.get(uuid.getUuid()); + } + + private synchronized void persistIfDirty() { + boolean dirty = mDirty; + if (!dirty) { + for (Profile profile : mProfiles.values()) { + if (profile.isDirty()) { + dirty = true; + break; + } + } + } + if (!dirty) { + for (NotificationGroup group : mGroups.values()) { + if (group.isDirty()) { + dirty = true; + break; + } + } + } + if (dirty) { + try { + Log.d(TAG, "Saving profile data..."); + FileWriter fw = new FileWriter(PROFILE_FILENAME); + fw.write(getXmlString()); + fw.close(); + Log.d(TAG, "Save completed."); + mDirty = false; + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + private void enforceChangePermissions() throws SecurityException { + mContext.enforceCallingOrSelfPermission(PERMISSION_CHANGE_SETTINGS, + "You do not have permissions to change the Profile Manager."); + } +} diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index e9e5ba2..bb1cebd 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -271,6 +271,7 @@ class ServerThread extends Thread { StatusBarManagerService statusBar = null; InputMethodManagerService imm = null; AppWidgetService appWidget = null; + ProfileManagerService profile = null; NotificationManagerService notification = null; WallpaperManagerService wallpaper = null; LocationManagerService location = null; @@ -425,6 +426,14 @@ class ServerThread extends Thread { } try { + Slog.i(TAG, "Profile Manager"); + profile = new ProfileManagerService(context); + ServiceManager.addService(Context.PROFILE_SERVICE, profile); + } catch (Throwable e) { + Slog.e(TAG, "Failure starting Profile Manager", e); + } + + try { Slog.i(TAG, "Notification Manager"); notification = new NotificationManagerService(context, statusBar, lights); ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification); diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java index de25747..0c17a00 100755 --- a/services/java/com/android/server/VibratorService.java +++ b/services/java/com/android/server/VibratorService.java @@ -30,8 +30,10 @@ import android.os.IBinder; import android.os.Binder; import android.os.SystemClock; import android.os.WorkSource; +import android.provider.Settings; import android.util.Slog; +import java.util.Calendar; import java.util.LinkedList; import java.util.ListIterator; @@ -115,7 +117,30 @@ public class VibratorService extends IVibratorService.Stub { public boolean hasVibrator() { return vibratorExists(); } - + + private boolean inQuietHours() { + boolean quietHoursEnabled = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.QUIET_HOURS_ENABLED, 0) != 0; + int quietHoursStart = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.QUIET_HOURS_START, 0); + int quietHoursEnd = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.QUIET_HOURS_END, 0); + boolean quietHoursHaptic = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.QUIET_HOURS_HAPTIC, 0) != 0; + if (quietHoursEnabled && quietHoursHaptic && (quietHoursStart != quietHoursEnd)) { + // Get the date in "quiet hours" format. + Calendar calendar = Calendar.getInstance(); + int minutes = calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE); + if (quietHoursEnd < quietHoursStart) { + // Starts at night, ends in the morning. + return (minutes > quietHoursStart) || (minutes < quietHoursEnd); + } else { + return (minutes > quietHoursStart) && (minutes < quietHoursEnd); + } + } + return false; + } + public void vibrate(long milliseconds, IBinder token) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { @@ -126,7 +151,7 @@ public class VibratorService extends IVibratorService.Stub { // timeout of 0 or negative. This will ensure that a vibration has // either a timeout of > 0 or a non-null pattern. if (milliseconds <= 0 || (mCurrentVibration != null - && mCurrentVibration.hasLongerTimeout(milliseconds))) { + && mCurrentVibration.hasLongerTimeout(milliseconds)) || inQuietHours()) { // Ignore this vibration since the current vibration will play for // longer than milliseconds. return; @@ -155,6 +180,9 @@ public class VibratorService extends IVibratorService.Stub { != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires VIBRATE permission"); } + if (inQuietHours()) { + return; + } int uid = Binder.getCallingUid(); // so wakelock calls will succeed long identity = Binder.clearCallingIdentity(); diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java index 6a63eac..7364978 100644 --- a/services/java/com/android/server/WiredAccessoryObserver.java +++ b/services/java/com/android/server/WiredAccessoryObserver.java @@ -114,6 +114,10 @@ class WiredAccessoryObserver extends UEventObserver { switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| BIT_USB_HEADSET_DGTL|BIT_USB_HEADSET_ANLG)) | ((state == 1) ? BIT_HDMI_AUDIO : 0)); + } else if (name.equals("Headset")) { + switchState = ((mHeadsetState & (BIT_HDMI_AUDIO|BIT_USB_HEADSET_ANLG| + BIT_USB_HEADSET_DGTL)) | + (state & (BIT_HEADSET|BIT_HEADSET_NO_MIC))); } else { switchState = ((mHeadsetState & (BIT_HDMI_AUDIO|BIT_USB_HEADSET_ANLG| BIT_USB_HEADSET_DGTL)) | diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index c344bc6..19ac909 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -218,18 +218,18 @@ public class Tethering extends INetworkManagementEventObserver.Stub { if (found == false) return; TetherInterfaceSM sm = mIfaces.get(iface); - if (up) { + if (up || usb) { + // Present-at-boot USB interfaces are discovered here, and only go up after + // RNDIS is enabled and a link is established. Keep track of USB + // interfaces even if they're in the down state, to avoid a race between + // tetherUsb(true) and when the link actually goes up. if (sm == null) { sm = new TetherInterfaceSM(iface, mLooper, usb); mIfaces.put(iface, sm); sm.start(); } } else { - if (isUsb(iface)) { - // ignore usb0 down after enabling RNDIS - // we will handle disconnect in interfaceRemoved instead - if (VDBG) Log.d(TAG, "ignore interface down for " + iface); - } else if (sm != null) { + if (sm != null) { sm.sendMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN); mIfaces.remove(iface); } diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 930842e..fbd0f92 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -1,6 +1,10 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +ifeq ($(BOARD_HAVE_CODEC_SUPPORT),SAMSUNG_CODEC_SUPPORT) +LOCAL_CFLAGS += -DSAMSUNG_CODEC_SUPPORT +endif + LOCAL_SRC_FILES:= \ Layer.cpp \ LayerBase.cpp \ diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 5b9ffbf..d414dd5 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -293,7 +293,11 @@ void Layer::onDraw(const Region& clip) const // if not everything below us is covered, we plug the holes! Region holes(clip.subtract(under)); if (!holes.isEmpty()) { +#ifdef SAMSUNG_CODEC_SUPPORT + clearWithOpenGL(holes, 0, 0, 0, 0); +#else clearWithOpenGL(holes, 0, 0, 0, 1); +#endif } return; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index db78e2e..9e3a3fd 100755 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -470,6 +470,17 @@ public class TelephonyManager { } } + /** + * {@hide} + */ + public void toggleLTE(boolean on) { + try { + getITelephony().toggleLTE(on); + } catch (RemoteException e) { + //Silently fail + } + } + /** Unknown network class. {@hide} */ public static final int NETWORK_CLASS_UNKNOWN = 0; /** Class of broadly defined "2G" networks. {@hide} */ diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 19441cd..cd92e93 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -44,6 +44,12 @@ interface ITelephony { void call(String number); /** + * Toggle between 3G and LTE (NT_MODE_CDMA, NT_MODE_GLOBAL) + * @param boolean to turn on and off LTE + */ + void toggleLTE(boolean on); + + /** * If there is currently a call in progress, show the call screen. * The DTMF dialpad may or may not be visible initially, depending on * whether it was up when the user last exited the InCallScreen. diff --git a/telephony/java/com/android/internal/telephony/LGEStarRIL.java b/telephony/java/com/android/internal/telephony/LGEStarRIL.java index 0606225..9fd00cf 100644 --- a/telephony/java/com/android/internal/telephony/LGEStarRIL.java +++ b/telephony/java/com/android/internal/telephony/LGEStarRIL.java @@ -1018,14 +1018,12 @@ public class LGEStarRIL extends RIL implements CommandsInterface { /* Infineon modems need some additional hax... */ if (isIfx) { - /* Store DST before cropping */ - parcelextra = parceldata.substring(parceldata.lastIndexOf(",")+1); - if (parcelextra != null) dst = Integer.parseInt(parcelextra); - parceldata = parceldata.substring(0,(parceldata.lastIndexOf(","))); + String [] parcelarray = parceldata.split(","); + parceldata = parcelarray[0] + "," + parcelarray[1]; // assuming there is always one comma at least + parcelextra = (parcelarray.length > 2 ? parcelarray[2] : "0"); + dst = Integer.parseInt(parcelextra); } - int offset = num*15*60*1000; // DST corrected - /* WTH... Date may come with 4 digits in the year, reduce to 2 */ try { dateFormatter = new SimpleDateFormat("yy/MM/dd,HH:mm:ss"); @@ -1034,6 +1032,7 @@ public class LGEStarRIL extends RIL implements CommandsInterface { /* Ifx delivers localtime, convert to UTC */ if (isIfx) { /* Directly calculate UTC time using DST Offset */ + int offset = num*15*60*1000; // DST corrected long when = dateParser.parse(parceldata).getTime() - offset; Date d = new Date(when); response = dateFormatter.format(d); diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index 042075d..8de4798 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -3601,7 +3601,7 @@ public class RIL extends BaseCommands implements CommandsInterface { case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS"; case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC"; case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW"; - case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG"; + case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE"; case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE"; case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "CDMA_SUBSCRIPTION_SOURCE_CHANGED"; case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED"; diff --git a/telephony/java/com/android/internal/telephony/SamsungRIL.java b/telephony/java/com/android/internal/telephony/SamsungRIL.java index 11ffa13..38ae600 100644 --- a/telephony/java/com/android/internal/telephony/SamsungRIL.java +++ b/telephony/java/com/android/internal/telephony/SamsungRIL.java @@ -31,6 +31,8 @@ import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.SmsResponse; import com.android.internal.telephony.cdma.CdmaCallWaitingNotification; import com.android.internal.telephony.cdma.CdmaInformationRecords; +import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec; +import com.android.internal.telephony.cdma.SignalToneUtil; import android.util.Log; @@ -47,6 +49,7 @@ public class SamsungRIL extends RIL implements CommandsInterface { static final int RIL_UNSOL_STK_SEND_SMS_RESULT = 11002; static final int RIL_UNSOL_O2_HOME_ZONE_INFO = 11007; static final int RIL_UNSOL_DEVICE_READY_NOTI = 11008; + static final int RIL_UNSOL_GPS_NOTI = 11009; static final int RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_3 = 11010; static final int RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_2 = 11011; static final int RIL_UNSOL_HSDPA_STATE_CHANGED = 11016; @@ -121,7 +124,7 @@ public class SamsungRIL extends RIL implements CommandsInterface { case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break; case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break; case RIL_REQUEST_UDUB: ret = responseVoid(p); break; - case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break; + case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseLastCallFailCause(p); break; case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break; case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseVoiceRegistrationState(p); break; case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break; @@ -144,7 +147,7 @@ public class SamsungRIL extends RIL implements CommandsInterface { case RIL_REQUEST_GET_IMEI: ret = responseString(p); break; case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break; case RIL_REQUEST_ANSWER: ret = responseVoid(p); break; - case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseDeactivateDataCall(p); break; + case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseVoid(p); break; case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break; case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break; case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break; @@ -343,6 +346,7 @@ public class SamsungRIL extends RIL implements CommandsInterface { case RIL_UNSOL_O2_HOME_ZONE_INFO: ret = responseVoid(p); break; case RIL_UNSOL_STK_SEND_SMS_RESULT: ret = responseVoid(p); break; case RIL_UNSOL_DEVICE_READY_NOTI: ret = responseVoid(p); break; + case RIL_UNSOL_GPS_NOTI: ret = responseVoid(p); break; // Ignored in TW RIL. case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST: ret = responseVoid(p); break; case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_2: ret = responseVoid(p); break; case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_3: ret = responseVoid(p); break; @@ -776,6 +780,22 @@ public class SamsungRIL extends RIL implements CommandsInterface { return response; } + + protected Object + responseLastCallFailCause(Parcel p) { + int response[] = (int[])responseInts(p); + + if (mIsSamsungCdma && response.length > 0 && + response[0] == com.android.internal.telephony.cdma.CallFailCause.ERROR_UNSPECIFIED) { + + // Far-end hangup returns ERROR_UNSPECIFIED, which shows "Call Lost" dialog. + Log.d(LOG_TAG, "Overriding ERROR_UNSPECIFIED fail cause with NORMAL_CLEARING."); + response[0] = com.android.internal.telephony.cdma.CallFailCause.NORMAL_CLEARING; + } + + return response; + } + @Override protected Object responseSignalStrength(Parcel p) { @@ -877,6 +897,14 @@ public class SamsungRIL extends RIL implements CommandsInterface { } } } else { + if (mIsSamsungCdma) { + // On rare occasion the pppd_cdma service is left active from a stale + // session, causing the data call setup to fail. Make sure that pppd_cdma + // is stopped now, so that the next setup attempt may succeed. + Log.d(LOG_TAG, "Set ril.cdma.data_state=0 to make sure pppd_cdma is stopped."); + SystemProperties.set("ril.cdma.data_state", "0"); + } + dataCall.status = FailCause.ERROR_UNSPECIFIED.getErrorCode(); // Who knows? } @@ -918,15 +946,16 @@ public class SamsungRIL extends RIL implements CommandsInterface { return false; } - protected Object - responseDeactivateDataCall(Parcel p) { + @Override + public void + deactivateDataCall(int cid, int reason, Message result) { if (mIsSamsungCdma) { // Disconnect: Set ril.cdma.data_state=0 to stop pppd_cdma service. Log.d(LOG_TAG, "Set ril.cdma.data_state=0."); SystemProperties.set("ril.cdma.data_state", "0"); } - return null; + super.deactivateDataCall(cid, reason, result); } protected Object @@ -943,6 +972,62 @@ public class SamsungRIL extends RIL implements CommandsInterface { return response; } + // Workaround for Samsung CDMA "ring of death" bug: + // + // Symptom: As soon as the phone receives notice of an incoming call, an + // audible "old fashioned ring" is emitted through the earpiece and + // persists through the duration of the call, or until reboot if the call + // isn't answered. + // + // Background: The CDMA telephony stack implements a number of "signal info + // tones" that are locally generated by ToneGenerator and mixed into the + // voice call path in response to radio RIL_UNSOL_CDMA_INFO_REC requests. + // One of these tones, IS95_CONST_IR_SIG_IS54B_L, is requested by the + // radio just prior to notice of an incoming call when the voice call + // path is muted. CallNotifier is responsible for stopping all signal + // tones (by "playing" the TONE_CDMA_SIGNAL_OFF tone) upon receipt of a + // "new ringing connection", prior to unmuting the voice call path. + // + // Problem: CallNotifier's incoming call path is designed to minimize + // latency to notify users of incoming calls ASAP. Thus, + // SignalInfoTonePlayer requests are handled asynchronously by spawning a + // one-shot thread for each. Unfortunately the ToneGenerator API does + // not provide a mechanism to specify an ordering on requests, and thus, + // unexpected thread interleaving may result in ToneGenerator processing + // them in the opposite order that CallNotifier intended. In this case, + // playing the "signal off" tone first, followed by playing the "old + // fashioned ring" indefinitely. + // + // Solution: An API change to ToneGenerator is required to enable + // SignalInfoTonePlayer to impose an ordering on requests (i.e., drop any + // request that's older than the most recent observed). Such a change, + // or another appropriate fix should be implemented in AOSP first. + // + // Workaround: Intercept RIL_UNSOL_CDMA_INFO_REC requests from the radio, + // check for a signal info record matching IS95_CONST_IR_SIG_IS54B_L, and + // drop it so it's never seen by CallNotifier. If other signal tones are + // observed to cause this problem, they should be dropped here as well. + @Override + protected void + notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) { + final int response = RIL_UNSOL_CDMA_INFO_REC; + + if (/* mIsSamsungCdma && */ infoRec.record instanceof CdmaSignalInfoRec) { + CdmaSignalInfoRec sir = (CdmaSignalInfoRec)infoRec.record; + if (sir != null && sir.isPresent && + sir.signalType == SignalToneUtil.IS95_CONST_IR_SIGNAL_IS54B && + sir.alertPitch == SignalToneUtil.IS95_CONST_IR_ALERT_MED && + sir.signal == SignalToneUtil.IS95_CONST_IR_SIG_IS54B_L) { + + Log.d(LOG_TAG, "Dropping \"" + responseToString(response) + " " + + retToString(response, sir) + "\" to prevent \"ring of death\" bug."); + return; + } + } + + super.notifyRegistrantsCdmaInfoRec(infoRec); + } + protected class SamsungDriverCall extends DriverCall { @Override public String diff --git a/telephony/java/com/android/internal/telephony/SemcRIL.java b/telephony/java/com/android/internal/telephony/SemcRIL.java index 9288aa1..837f148 100644 --- a/telephony/java/com/android/internal/telephony/SemcRIL.java +++ b/telephony/java/com/android/internal/telephony/SemcRIL.java @@ -1,8 +1,6 @@ /* * Copyright (C) 2011 The CyanogenMod Project * - * Diogo Ferreira, Andreas Makris, Alin Jerpelea - * * 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 @@ -20,247 +18,208 @@ package com.android.internal.telephony; import static com.android.internal.telephony.RILConstants.*; -import android.content.Context; -import android.content.res.Resources; -import android.os.Message; -import android.os.Parcel; -import android.os.SystemProperties; +import android.content.*; +import android.net.*; +import android.os.*; +import android.telephony.*; import android.text.TextUtils; import android.util.Log; -import android.net.ConnectivityManager; -import android.net.LocalSocket; -import android.net.LocalSocketAddress; - -import com.android.internal.telephony.DataCallState; -import com.android.internal.telephony.DataConnection.FailCause; -import com.android.internal.telephony.OperatorInfo; -import com.android.internal.telephony.IccCardApplication; -import com.android.internal.telephony.IccCardStatus; - -import java.util.ArrayList; - +import com.android.internal.telephony.cdma.CdmaCallWaitingNotification; +import com.android.internal.telephony.cdma.CdmaInformationRecords; +import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; +import com.android.internal.telephony.gsm.SuppServiceNotification; +import java.io.*; +import java.util.*; /** * Custom SEMC ril * * {@hide} */ -public class SemcRIL extends QualcommNoSimReadyRIL implements CommandsInterface { - protected String mAid; - - boolean RILJ_LOGV = true; - boolean RILJ_LOGD = true; +public class SemcRIL extends RIL { + String mAid = ""; + IccHandler mIccHandler; + HandlerThread mIccThread; public SemcRIL(Context context, int networkMode, int cdmaSubscription) { super(context, networkMode, cdmaSubscription); + mIccHandler = null; } @Override - public void - supplyIccPin(String pin, Message result) { - // but this request is also valid for SIM and RUIM - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result); - - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(0); - rr.mp.writeString(mAid); - rr.mp.writeString(pin); - - send(rr); + protected RadioState getRadioStateFromInt(int stateInt) { + RadioState state; + + /* RIL_RadioState ril.h */ + switch(stateInt) { + case 0: state = RadioState.RADIO_OFF; break; + case 1: state = RadioState.RADIO_UNAVAILABLE; break; + case 2: { + if (mIccHandler == null) + { + mIccThread = new HandlerThread("IccHandler"); + mIccThread.start(); + mIccHandler = new IccHandler(this, mIccThread.getLooper()); + } + mIccHandler.run(); + state = mPhoneType == RILConstants.CDMA_PHONE ? RadioState.RUIM_NOT_READY : RadioState.SIM_NOT_READY; + break; + } + case 3: state = RadioState.SIM_LOCKED_OR_ABSENT; break; + case 4: state = RadioState.SIM_READY; break; + case 5: state = RadioState.RUIM_NOT_READY; break; + case 6: state = RadioState.RUIM_READY; break; + case 7: state = RadioState.RUIM_LOCKED_OR_ABSENT; break; + case 8: state = RadioState.NV_NOT_READY; break; + case 9: state = RadioState.NV_READY; break; + + default: + throw new RuntimeException( + "Unrecognized RIL_RadioState: " + stateInt); + } + return state; } @Override - public void - supplyIccPuk(String puk, String newPin, Message result) { - //Note: This RIL request has not been renamed to ICC, - // but this request is also valid for SIM and RUIM - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(0); - rr.mp.writeString(mAid); - rr.mp.writeString(puk); - rr.mp.writeString(newPin); + protected Object + responseIccCardStatus(Parcel p) { + IccCardApplication ca; - send(rr); - } + IccCardStatus status = new IccCardStatus(); + status.setCardState(p.readInt()); + status.setUniversalPinState(p.readInt()); + status.setGsmUmtsSubscriptionAppIndex(p.readInt()); + status.setCdmaSubscriptionAppIndex(p.readInt()); + status.setImsSubscriptionAppIndex(p.readInt()); - @Override - public void - supplyIccPin2(String pin, Message result) { - //Note: This RIL request has not been renamed to ICC, - // but this request is also valid for SIM and RUIM - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result); + int numApplications = p.readInt(); - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + // limit to maximum allowed applications + if (numApplications > IccCardStatus.CARD_MAX_APPS) { + numApplications = IccCardStatus.CARD_MAX_APPS; + } + status.setNumApplications(numApplications); - rr.mp.writeInt(0); - rr.mp.writeString(mAid); - rr.mp.writeString(pin); + for (int i = 0 ; i < numApplications ; i++) { + ca = new IccCardApplication(); + ca.app_type = ca.AppTypeFromRILInt(p.readInt()); + ca.app_state = ca.AppStateFromRILInt(p.readInt()); + ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt()); + ca.aid = p.readString(); + ca.app_label = p.readString(); + ca.pin1_replaced = p.readInt(); + ca.pin1 = ca.PinStateFromRILInt(p.readInt()); + ca.pin2 = ca.PinStateFromRILInt(p.readInt()); + status.addApplication(ca); + } - send(rr); + updateIccType(status); + return status; } - @Override - public void - supplyIccPuk2(String puk, String newPin2, Message result) { - //Note: This RIL request has not been renamed to ICC, - // but this request is also valid for SIM and RUIM - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(0); - rr.mp.writeString(mAid); - rr.mp.writeString(puk); - rr.mp.writeString(newPin2); + private void updateIccType (IccCardStatus status) { + if (status.getNumApplications() > 0) + { + int appType; + if (mPhoneType == RILConstants.CDMA_PHONE) + { + appType = status.getCdmaSubscriptionAppIndex(); + } else { + appType = status.getGsmUmtsSubscriptionAppIndex(); + } - send(rr); + IccCardApplication application = status.getApplication(appType); + mAid = application.aid; + Log.d(LOG_TAG, "Picked default AID: " + mAid); + SystemProperties.set("ril.icctype", Integer.toString(application.app_type.ordinal())); + } } @Override - public void - changeIccPin(String oldPin, String newPin, Message result) { - //Note: This RIL request has not been renamed to ICC, - // but this request is also valid for SIM and RUIM - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(0); - rr.mp.writeString(mAid); - rr.mp.writeString(oldPin); - rr.mp.writeString(newPin); + protected DataCallState getDataCallState(Parcel p, int version) { + DataCallState dataCall = new DataCallState(); - send(rr); + dataCall.version = version; + if (version < 5) { + dataCall.cid = p.readInt(); + dataCall.active = p.readInt(); + dataCall.type = p.readString(); + String addresses = p.readString(); + if (!TextUtils.isEmpty(addresses)) { + dataCall.addresses = addresses.split(" "); + } + // DataCallState needs an ifname. Since we don't have one use the name from the ThrottleService resource (default=rmnet0). + dataCall.ifname = "rmnet0"; + } else { + dataCall.status = p.readInt(); + dataCall.suggestedRetryTime = p.readInt(); + dataCall.cid = p.readInt(); + dataCall.active = p.readInt(); + dataCall.type = p.readString(); + dataCall.ifname = p.readString(); + if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) && + TextUtils.isEmpty(dataCall.ifname)) { + throw new RuntimeException("getDataCallState, no ifname"); + } + String addresses = p.readString(); + if (!TextUtils.isEmpty(addresses)) { + dataCall.addresses = addresses.split(" "); + } + String dnses = p.readString(); + if (!TextUtils.isEmpty(dnses)) { + dataCall.dnses = dnses.split(" "); + } + String gateways = p.readString(); + if (!TextUtils.isEmpty(gateways)) { + dataCall.gateways = gateways.split(" "); + } + } + return dataCall; } - @Override - public void - changeIccPin2(String oldPin2, String newPin2, Message result) { - //Note: This RIL request has not been renamed to ICC, - // but this request is also valid for SIM and RUIM - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(0); - rr.mp.writeString(mAid); - rr.mp.writeString(oldPin2); - rr.mp.writeString(newPin2); - send(rr); + @Override public void + supplyIccPin(String pin, Message result) { + supplyIccPinForApp(pin, mAid, result); } - @Override - public void - supplyNetworkDepersonalization(String netpin, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(3); - rr.mp.writeString(netpin); - - send(rr); + @Override public void + changeIccPin(String oldPin, String newPin, Message result) { + changeIccPinForApp(oldPin, newPin, mAid, result); } - @Override - public void - changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(3); - rr.mp.writeString(facility); - rr.mp.writeString(oldPwd); - rr.mp.writeString(newPwd); - - send(rr); + @Override public void + supplyIccPin2(String pin, Message result) { + supplyIccPin2ForApp(pin, mAid, result); } - - @Override - public void - dial(String address, int clirMode, UUSInfo uusInfo, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); - - rr.mp.writeString(address); - rr.mp.writeInt(clirMode); - - if (uusInfo == null) { - rr.mp.writeInt(0); // UUS information is absent - } else { - rr.mp.writeInt(1); // UUS information is present - rr.mp.writeInt(uusInfo.getType()); - rr.mp.writeInt(uusInfo.getDcs()); - rr.mp.writeByteArray(uusInfo.getUserData()); - } - rr.mp.writeInt(0xff); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); + @Override public void + changeIccPin2(String oldPin2, String newPin2, Message result) { + changeIccPin2ForApp(oldPin2, newPin2, mAid, result); } - @Override - public void - getIMSI(Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result); - rr.mp.writeInt(0); - rr.mp.writeString(mAid); - if (RILJ_LOGD) riljLog(rr.serialString() + - "> getIMSI:RIL_REQUEST_GET_IMSI " + - RIL_REQUEST_GET_IMSI + - " " + requestToString(rr.mRequest)); + @Override public void + supplyIccPuk(String puk, String newPin, Message result) { + supplyIccPukForApp(puk, newPin, mAid, result); + } - send(rr); + @Override public void + supplyIccPuk2(String puk2, String newPin2, Message result) { + supplyIccPuk2ForApp(puk2, newPin2, mAid, result); } @Override public void - setupDataCall(String radioTechnology, String profile, String apn, - String user, String password, String authType, String ipVersion, - Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result); - - rr.mp.writeInt(7); - - rr.mp.writeString(radioTechnology); - rr.mp.writeString(profile); - rr.mp.writeString(apn); - rr.mp.writeString(user); - rr.mp.writeString(password); - rr.mp.writeString(authType); - rr.mp.writeString(ipVersion); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) + " " + radioTechnology + " " - + profile + " " + apn + " " + user + " " - + password + " " + authType + " " + ipVersion); - - send(rr); + queryFacilityLock(String facility, String password, int serviceClass, + Message response) { + queryFacilityLockForApp(facility, password, serviceClass, mAid, response); } @Override public void - deactivateDataCall(int cid, int reason, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result); - - rr.mp.writeInt(2); - rr.mp.writeString(Integer.toString(cid)); - rr.mp.writeString(Integer.toString(reason)); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + - requestToString(rr.mRequest) + " " + cid + " " + reason); - - send(rr); + setFacilityLock (String facility, boolean lockState, String password, + int serviceClass, Message response) { + setFacilityLockForApp(facility, lockState, password, serviceClass, mAid, response); } @Override @@ -272,8 +231,6 @@ public class SemcRIL extends QualcommNoSimReadyRIL implements CommandsInterface RILRequest rr = RILRequest.obtain(RIL_REQUEST_SIM_IO, result); - rr.mp.writeInt(0); - rr.mp.writeString(mAid); rr.mp.writeInt(command); rr.mp.writeInt(fileid); rr.mp.writeString(path); @@ -282,6 +239,7 @@ public class SemcRIL extends QualcommNoSimReadyRIL implements CommandsInterface rr.mp.writeInt(p3); rr.mp.writeString(data); rr.mp.writeString(pin2); + rr.mp.writeString(mAid); if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest) + " 0x" + Integer.toHexString(command) @@ -294,6 +252,17 @@ public class SemcRIL extends QualcommNoSimReadyRIL implements CommandsInterface @Override public void + getIMSI(Message result) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result); + rr.mp.writeString(mAid); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + send(rr); + } + + @Override + public void setNetworkSelectionModeAutomatic(Message response) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, @@ -303,6 +272,7 @@ public class SemcRIL extends QualcommNoSimReadyRIL implements CommandsInterface rr.mp.writeString(null); rr.mp.writeInt(-1); + send(rr); } @@ -323,179 +293,162 @@ public class SemcRIL extends QualcommNoSimReadyRIL implements CommandsInterface } @Override - public void - queryFacilityLock (String facility, String password, int serviceClass, - Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - // count strings - rr.mp.writeInt(5); - rr.mp.writeString("0"); - rr.mp.writeString(mAid); - rr.mp.writeString(facility); - rr.mp.writeString(password); - - rr.mp.writeString(Integer.toString(serviceClass)); - - send(rr); - } - - @Override - public void - setFacilityLock (String facility, boolean lockState, String password, - int serviceClass, Message response) { - String lockString; - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - // count strings - rr.mp.writeInt(6); - - rr.mp.writeString("0"); - rr.mp.writeString(mAid); - rr.mp.writeString(facility); - lockString = (lockState)?"1":"0"; - rr.mp.writeString(lockString); - rr.mp.writeString(password); - rr.mp.writeString(Integer.toString(serviceClass)); - - send(rr); - - } - - @Override protected Object - responseIccCardStatus(Parcel p) { - IccCardApplication ca; - - IccCardStatus status = new IccCardStatus(); - p.readInt(); // unknown first parameter - status.setCardState(p.readInt()); - status.setUniversalPinState(p.readInt()); - int gsmUmtsSubscriptionAppCount = p.readInt(); - - for (int i = 0; i < gsmUmtsSubscriptionAppCount; i++) { - if (i == 0) - status.setGsmUmtsSubscriptionAppIndex(p.readInt()); - else - p.readInt(); - } + responseOperatorInfos(Parcel p) { + String strings[] = (String [])responseStrings(p); + ArrayList<OperatorInfo> ret; - int cdmaSubscriptionAppCount = p.readInt(); - for (int i = 0; i < cdmaSubscriptionAppCount; i++) { - if (i == 0) - status.setCdmaSubscriptionAppIndex(p.readInt()); - else - p.readInt(); + if (strings.length % 5 != 0) { + throw new RuntimeException( + "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got " + + strings.length + " strings, expected multible of 5"); } - int numApplications = p.readInt(); + ret = new ArrayList<OperatorInfo>(strings.length / 4); - // limit to maximum allowed applications - if (numApplications > IccCardStatus.CARD_MAX_APPS) { - numApplications = IccCardStatus.CARD_MAX_APPS; + for (int i = 0 ; i < strings.length ; i += 5) { + ret.add ( + new OperatorInfo( + strings[i+0], + strings[i+1], + strings[i+2], + strings[i+3])); } - status.setNumApplications(numApplications); + return ret; + } - for (int i = 0 ; i < numApplications ; i++) { - ca = new IccCardApplication(); - ca.app_type = ca.AppTypeFromRILInt(p.readInt()); - ca.app_state = ca.AppStateFromRILInt(p.readInt()); - ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt()); - ca.aid = p.readString(); - ca.app_label = p.readString(); - ca.pin1_replaced = p.readInt(); - ca.pin1 = ca.PinStateFromRILInt(p.readInt()); - ca.pin2 = ca.PinStateFromRILInt(p.readInt()); - status.addApplication(ca); - p.readInt(); - p.readInt(); - p.readInt(); - p.readInt(); - } + @Override + public void + dial(String address, int clirMode, UUSInfo uusInfo, Message result) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); + rr.mp.writeString(address); + rr.mp.writeInt(clirMode); + rr.mp.writeInt(0); // UUS information is absent - int appIndex = -1; - if (mPhoneType == RILConstants.CDMA_PHONE) { - appIndex = status.getCdmaSubscriptionAppIndex(); - Log.d(LOG_TAG, "This is a CDMA PHONE " + appIndex); + if (uusInfo == null) { + rr.mp.writeInt(0); // UUS information is absent } else { - appIndex = status.getGsmUmtsSubscriptionAppIndex(); - Log.d(LOG_TAG, "This is a GSM PHONE " + appIndex); + rr.mp.writeInt(1); // UUS information is present + rr.mp.writeInt(uusInfo.getType()); + rr.mp.writeInt(uusInfo.getDcs()); + rr.mp.writeByteArray(uusInfo.getUserData()); } + rr.mp.writeInt(255); - IccCardApplication application = status.getApplication(appIndex); - mAid = application.aid; - - return status; - } + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - @Override - protected DataCallState getDataCallState(Parcel p, int version) { - DataCallState datacallstate = new DataCallState(); - datacallstate.version = 3; - datacallstate.cid = p.readInt(); - datacallstate.active = p.readInt(); - datacallstate.type = p.readString(); - String s1 = p.readString(); - if(!TextUtils.isEmpty(s1)) { - datacallstate.addresses = s1.split(" "); } - datacallstate.ifname = "rmnet0"; - p.readInt(); - p.readInt(); - return datacallstate; + send(rr); } - @Override - protected Object - responseSetupDataCall(Parcel p) { + class IccHandler extends Handler implements Runnable { + private static final int EVENT_RADIO_ON = 1; + private static final int EVENT_ICC_STATUS_CHANGED = 2; + private static final int EVENT_GET_ICC_STATUS_DONE = 3; + private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 4; - DataCallState dataCall; + private RIL mRil; + private boolean mRadioOn = false; - dataCall = new DataCallState(); - dataCall.version = 3; - dataCall.cid = 0; - p.readInt(); - dataCall.ifname = p.readString(); - if (TextUtils.isEmpty(dataCall.ifname)) { - throw new RuntimeException( - "RIL_REQUEST_SETUP_DATA_CALL response, no ifname"); - } + public IccHandler (RIL ril, Looper looper) { + super (looper); + mRil = ril; + } - String addresses = p.readString(); - if (!TextUtils.isEmpty(addresses)) { - dataCall.addresses = addresses.split(" "); + public void handleMessage (Message paramMessage) { + switch (paramMessage.what) { + case EVENT_RADIO_ON: + mRadioOn = true; + Log.d(LOG_TAG, "Radio on -> Forcing sim status update"); + sendMessage(obtainMessage(EVENT_ICC_STATUS_CHANGED)); + break; + case EVENT_GET_ICC_STATUS_DONE: + AsyncResult asyncResult = (AsyncResult) paramMessage.obj; + if (asyncResult.exception != null) { + Log.e (LOG_TAG, "IccCardStatusDone shouldn't return exceptions!", asyncResult.exception); + break; + } + IccCardStatus status = (IccCardStatus) asyncResult.result; + if (status.getNumApplications() == 0) { + if (!mRil.getRadioState().isOn()) { + break; + } + + if (mPhoneType == RILConstants.CDMA_PHONE) { + mRil.setRadioState(CommandsInterface.RadioState.RUIM_LOCKED_OR_ABSENT); + } else { + mRil.setRadioState(CommandsInterface.RadioState.SIM_LOCKED_OR_ABSENT); + } + } else { + int appIndex = -1; + if (mPhoneType == RILConstants.CDMA_PHONE) { + appIndex = status.getCdmaSubscriptionAppIndex(); + Log.d(LOG_TAG, "This is a CDMA PHONE " + appIndex); + } else { + appIndex = status.getGsmUmtsSubscriptionAppIndex(); + Log.d(LOG_TAG, "This is a GSM PHONE " + appIndex); + } + + IccCardApplication application = status.getApplication(appIndex); + IccCardApplication.AppState app_state = application.app_state; + IccCardApplication.AppType app_type = application.app_type; + + switch (app_state) { + case APPSTATE_PIN: + case APPSTATE_PUK: + switch (app_type) { + case APPTYPE_SIM: + case APPTYPE_USIM: + mRil.setRadioState(CommandsInterface.RadioState.SIM_LOCKED_OR_ABSENT); + break; + case APPTYPE_RUIM: + mRil.setRadioState(CommandsInterface.RadioState.RUIM_LOCKED_OR_ABSENT); + break; + default: + Log.e(LOG_TAG, "Currently we don't handle SIMs of type: " + app_type); + return; + } + break; + case APPSTATE_READY: + switch (app_type) { + case APPTYPE_SIM: + case APPTYPE_USIM: + mRil.setRadioState(CommandsInterface.RadioState.SIM_READY); + break; + case APPTYPE_RUIM: + mRil.setRadioState(CommandsInterface.RadioState.RUIM_READY); + break; + default: + Log.e(LOG_TAG, "Currently we don't handle SIMs of type: " + app_type); + return; + } + break; + default: + return; + } + } + break; + case EVENT_ICC_STATUS_CHANGED: + if (mRadioOn) { + Log.d(LOG_TAG, "Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus"); + mRil.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, paramMessage.obj)); + } else { + Log.d(LOG_TAG, "Received EVENT_ICC_STATUS_CHANGED while radio is not ON. Ignoring"); + } + break; + case EVENT_RADIO_OFF_OR_UNAVAILABLE: + mRadioOn = false; + // disposeCards(); // to be verified; + default: + Log.e(LOG_TAG, " Unknown Event " + paramMessage.what); + break; } - return dataCall; - } - - @Override - protected Object - responseOperatorInfos(Parcel p) { - String strings[] = (String [])responseStrings(p); - ArrayList<OperatorInfo> ret; - - if (strings.length % 5 != 0) { - throw new RuntimeException( - "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got " - + strings.length + " strings, expected multible of 5"); } - ret = new ArrayList<OperatorInfo>(strings.length / 5); - - for (int i = 0 ; i < strings.length ; i += 5) { - ret.add ( - new OperatorInfo( - strings[i+0], - strings[i+1], - strings[i+2], - strings[i+3])); + public void run () { + mRil.registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, null); + Message msg = obtainMessage(EVENT_RADIO_ON); + mRil.getIccCardStatus(msg); } - - return ret; } } diff --git a/telephony/java/com/android/internal/telephony/Smdk4210RIL.java b/telephony/java/com/android/internal/telephony/Smdk4210RIL.java new file mode 100644 index 0000000..49d1602 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/Smdk4210RIL.java @@ -0,0 +1,965 @@ +/*
+ * 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 com.android.internal.telephony;
+
+import static com.android.internal.telephony.RILConstants.*;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.PowerManager;
+import android.os.SystemProperties;
+import android.os.PowerManager.WakeLock;
+import android.telephony.NeighboringCellInfo;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+import com.android.internal.telephony.gsm.SuppServiceNotification;
+import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
+import com.android.internal.telephony.cdma.CdmaInformationRecords;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class Smdk4210RIL extends RIL implements CommandsInterface {
+
+ //SAMSUNG SMDK4210 STATES
+ static final int RIL_REQUEST_DIAL_EMERGENCY = 10016;
+ static final int RIL_UNSOL_STK_SEND_SMS_RESULT = 11002;
+ static final int RIL_UNSOL_O2_HOME_ZONE_INFO = 11007;
+ static final int RIL_UNSOL_DEVICE_READY_NOTI = 11008;
+ static final int RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_1 = 11010;
+ static final int RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_2 = 11011;
+ static final int RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_3 = 11012;
+ static final int RIL_UNSOL_HSDPA_STATE_CHANGED = 11016;
+
+ public Smdk4210RIL(Context context, int networkMode, int cdmaSubscription) {
+ super(context, networkMode, cdmaSubscription);
+ }
+
+ @Override
+ public void setCurrentPreferredNetworkType() {
+ if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType IGNORED");
+ /* Google added this as a fix for crespo loosing network type after
+ * taking an OTA. This messes up the data connection state for us
+ * due to the way we handle network type change (disable data
+ * then change then re-enable).
+ */
+ }
+
+ @Override
+ public void setPreferredNetworkType(int networkType , Message response) {
+ /* Samsung modem implementation does bad things when a datacall is running
+ * while switching the preferred networktype.
+ */
+ ConnectivityManager cm =
+ (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ if(cm.getMobileDataEnabled())
+ {
+ ConnectivityHandler handler = new ConnectivityHandler(mContext);
+ handler.setPreferedNetworkType(networkType, response);
+ } else {
+ sendPreferedNetworktype(networkType, response);
+ }
+ }
+
+ //Sends the real RIL request to the modem.
+ private void sendPreferedNetworktype(int networkType, Message response) {
+ RILRequest rr = RILRequest.obtain(
+ RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);
+
+ rr.mp.writeInt(1);
+ rr.mp.writeInt(networkType);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " : " + networkType);
+
+ send(rr);
+ }
+
+ /* private class that does the handling for the dataconnection
+ * dataconnection is done async, so we send the request for disabling it,
+ * wait for the response, set the prefered networktype and notify the
+ * real sender with its result.
+ */
+ private class ConnectivityHandler extends Handler{
+
+ private static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 30;
+ private Context mContext;
+ private int mDesiredNetworkType;
+ //the original message, we need it for calling back the original caller when done
+ private Message mNetworktypeResponse;
+ private ConnectivityBroadcastReceiver mConnectivityReceiver = new ConnectivityBroadcastReceiver();
+
+ public ConnectivityHandler(Context context)
+ {
+ mContext = context;
+ }
+
+ private void startListening() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ mContext.registerReceiver(mConnectivityReceiver, filter);
+ }
+
+ private synchronized void stopListening() {
+ mContext.unregisterReceiver(mConnectivityReceiver);
+ }
+
+ public void setPreferedNetworkType(int networkType, Message response)
+ {
+ Log.d(LOG_TAG, "Mobile Dataconnection is online setting it down");
+ mDesiredNetworkType = networkType;
+ mNetworktypeResponse = response;
+ ConnectivityManager cm =
+ (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ //start listening for the connectivity change broadcast
+ startListening();
+ cm.setMobileDataEnabled(false);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ //networktype was set, now we can enable the dataconnection again
+ case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
+ ConnectivityManager cm =
+ (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ Log.d(LOG_TAG, "preferred NetworkType set upping Mobile Dataconnection");
+
+ cm.setMobileDataEnabled(true);
+ //everything done now call back that we have set the networktype
+ AsyncResult.forMessage(mNetworktypeResponse, null, null);
+ mNetworktypeResponse.sendToTarget();
+ mNetworktypeResponse = null;
+ break;
+ default:
+ throw new RuntimeException("unexpected event not handled");
+ }
+ }
+
+ private class ConnectivityBroadcastReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ Log.w(LOG_TAG, "onReceived() called with " + intent);
+ return;
+ }
+ boolean noConnectivity =
+ intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
+
+ if (noConnectivity) {
+ //Ok dataconnection is down, now set the networktype
+ Log.w(LOG_TAG, "Mobile Dataconnection is now down setting preferred NetworkType");
+ stopListening();
+ sendPreferedNetworktype(mDesiredNetworkType, obtainMessage(MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+ mDesiredNetworkType = -1;
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void processSolicited (Parcel p) {
+ int serial, error;
+ boolean found = false;
+
+ serial = p.readInt();
+ error = p.readInt();
+
+ RILRequest rr;
+
+ rr = findAndRemoveRequestFromList(serial);
+
+ if (rr == null) {
+ Log.w(LOG_TAG, "Unexpected solicited response! sn: "
+ + serial + " error: " + error);
+ return;
+ }
+
+ Object ret = null;
+
+ if (error == 0 || p.dataAvail() > 0) {
+ // either command succeeds or command fails but with data payload
+ try {switch (rr.mRequest) {
+
+ case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break;
+ case RIL_REQUEST_ENTER_SIM_PIN: ret = responseInts(p); break;
+ case RIL_REQUEST_ENTER_SIM_PUK: ret = responseInts(p); break;
+ case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseInts(p); break;
+ case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseInts(p); break;
+ case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseInts(p); break;
+ case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseInts(p); break;
+ case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseInts(p); break;
+ case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break;
+ case RIL_REQUEST_DIAL: ret = responseVoid(p); break;
+ case RIL_REQUEST_GET_IMSI: ret = responseString(p); break;
+ case RIL_REQUEST_HANGUP: ret = responseVoid(p); break;
+ case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break;
+ case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: ret = responseVoid(p); break;
+ case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break;
+ case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break;
+ case RIL_REQUEST_UDUB: ret = responseVoid(p); break;
+ case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break;
+ case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
+ case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseStrings(p); break;
+ case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break;
+ case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break;
+ case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break;
+ case RIL_REQUEST_DTMF: ret = responseVoid(p); break;
+ case RIL_REQUEST_SEND_SMS: ret = responseSMS(p); break;
+ case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret = responseSMS(p); break;
+ case RIL_REQUEST_SETUP_DATA_CALL: ret = responseSetupDataCall(p); break;
+ case RIL_REQUEST_SIM_IO: ret = responseICC_IO(p); break;
+ case RIL_REQUEST_SEND_USSD: ret = responseVoid(p); break;
+ case RIL_REQUEST_CANCEL_USSD: ret = responseVoid(p); break;
+ case RIL_REQUEST_GET_CLIR: ret = responseInts(p); break;
+ case RIL_REQUEST_SET_CLIR: ret = responseVoid(p); break;
+ case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret = responseCallForward(p); break;
+ case RIL_REQUEST_SET_CALL_FORWARD: ret = responseVoid(p); break;
+ case RIL_REQUEST_QUERY_CALL_WAITING: ret = responseInts(p); break;
+ case RIL_REQUEST_SET_CALL_WAITING: ret = responseVoid(p); break;
+ case RIL_REQUEST_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
+ case RIL_REQUEST_GET_IMEI: ret = responseString(p); break;
+ case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break;
+ case RIL_REQUEST_ANSWER: ret = responseVoid(p); break;
+ case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseVoid(p); break;
+ case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break;
+ case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break;
+ case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break;
+ case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break;
+ case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret = responseVoid(p); break;
+ case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret = responseOperatorInfos(p); break;
+ case RIL_REQUEST_DTMF_START: ret = responseVoid(p); break;
+ case RIL_REQUEST_DTMF_STOP: ret = responseVoid(p); break;
+ case RIL_REQUEST_BASEBAND_VERSION: ret = responseString(p); break;
+ case RIL_REQUEST_SEPARATE_CONNECTION: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_MUTE: ret = responseVoid(p); break;
+ case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break;
+ case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break;
+ case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret = responseInts(p); break;
+ case RIL_REQUEST_DATA_CALL_LIST: ret = responseDataCallList(p); break;
+ case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break;
+ case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break;
+ case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break;
+ case RIL_REQUEST_SCREEN_STATE: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break;
+ case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break;
+ case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break;
+ case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break;
+ case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break;
+ case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break;
+ case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break;
+ case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break;
+ case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break;
+ case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseGetPreferredNetworkType(p); break;
+ case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break;
+ case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break;
+ case RIL_REQUEST_QUERY_TTY_MODE: ret = responseInts(p); break;
+ case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret = responseInts(p); break;
+ case RIL_REQUEST_CDMA_FLASH: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break;
+ case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
+ case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break;
+ case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
+ case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break;
+ case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break;
+ case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break;
+ case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break;
+ case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break;
+ case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
+ case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
+ case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
+ case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
+ case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break;
+ case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break;
+ default:
+ throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
+ //break;
+ }} catch (Throwable tr) {
+ // Exceptions here usually mean invalid RIL responses
+
+ Log.w(LOG_TAG, rr.serialString() + "< "
+ + requestToString(rr.mRequest)
+ + " exception, possible invalid RIL response", tr);
+
+ if (rr.mResult != null) {
+ AsyncResult.forMessage(rr.mResult, null, tr);
+ rr.mResult.sendToTarget();
+ }
+ rr.release();
+ return;
+ }
+ }
+
+ if (error != 0) {
+ //ugly fix for Samsung messing up SMS_SEND request fail in binary RIL
+ if(!(error == -1 && rr.mRequest == RIL_REQUEST_SEND_SMS))
+ {
+ rr.onError(error, ret);
+ rr.release();
+ return;
+ } else {
+ try
+ {
+ ret = responseSMS(p);
+ } catch (Throwable tr) {
+ Log.w(LOG_TAG, rr.serialString() + "< "
+ + requestToString(rr.mRequest)
+ + " exception, Processing Samsung SMS fix ", tr);
+ rr.onError(error, ret);
+ rr.release();
+ return;
+ }
+ }
+ }
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
+ + " " + retToString(rr.mRequest, ret));
+
+ if (rr.mResult != null) {
+ AsyncResult.forMessage(rr.mResult, ret, null);
+ rr.mResult.sendToTarget();
+ }
+
+ rr.release();
+ }
+
+ @Override
+ protected void
+ processUnsolicited (Parcel p) {
+ int response;
+ Object ret;
+
+ response = p.readInt();
+
+ try {switch(response) {
+
+ case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
+ case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break;
+ case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
+ case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;
+ case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break;
+ case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break;
+ case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break;
+ case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break;
+ case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
+ case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
+ case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
+ case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
+ case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
+ case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
+ case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
+ case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
+ case RIL_UNSOL_SIM_REFRESH: ret = responseInts(p); break;
+ case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break;
+ case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
+ case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
+ case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break;
+ case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseString(p); break;
+ case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
+ case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
+ case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
+ case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
+ case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
+ case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
+ case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
+ case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
+ case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break;
+ case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
+ case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
+ case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
+
+ // SAMSUNG STATES
+ case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_1: ret = responseVoid(p); break;
+ case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_2: ret = responseVoid(p); break;
+ case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_3: ret = responseVoid(p); break;
+
+ default:
+ throw new RuntimeException("Unrecognized unsol response: " + response);
+ //break; (implied)
+ }} catch (Throwable tr) {
+ Log.e(LOG_TAG, "Exception processing unsol response: " + response +
+ "Exception:" + tr.toString());
+ return;
+ }
+
+ switch(response) {
+ case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
+ /* has bonus radio state int */
+ RadioState newState = getRadioStateFromInt(p.readInt());
+ if (RILJ_LOGD) unsljLogMore(response, newState.toString());
+
+ switchToRadioState(newState);
+ break;
+ case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
+ if (RILJ_LOGD) unsljLog(response);
+
+ mCallStateRegistrants
+ .notifyRegistrants(new AsyncResult(null, null, null));
+ break;
+ case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
+ if (RILJ_LOGD) unsljLog(response);
+
+ mVoiceNetworkStateRegistrants
+ .notifyRegistrants(new AsyncResult(null, null, null));
+ break;
+ case RIL_UNSOL_RESPONSE_NEW_SMS: {
+ if (RILJ_LOGD) unsljLog(response);
+
+ // FIXME this should move up a layer
+ String a[] = new String[2];
+
+ a[1] = (String)ret;
+
+ SmsMessage sms;
+
+ sms = SmsMessage.newFromCMT(a);
+ if (mGsmSmsRegistrant != null) {
+ mGsmSmsRegistrant
+ .notifyRegistrant(new AsyncResult(null, sms, null));
+ }
+ break;
+ }
+ case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mSmsStatusRegistrant != null) {
+ mSmsStatusRegistrant.notifyRegistrant(
+ new AsyncResult(null, ret, null));
+ }
+ break;
+ case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ int[] smsIndex = (int[])ret;
+
+ if(smsIndex.length == 1) {
+ if (mSmsOnSimRegistrant != null) {
+ mSmsOnSimRegistrant.
+ notifyRegistrant(new AsyncResult(null, smsIndex, null));
+ }
+ } else {
+ if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length "
+ + smsIndex.length);
+ }
+ break;
+ case RIL_UNSOL_ON_USSD:
+ String[] resp = (String[])ret;
+
+ if (resp.length < 2) {
+ resp = new String[2];
+ resp[0] = ((String[])ret)[0];
+ resp[1] = null;
+ }
+ if (RILJ_LOGD) unsljLogMore(response, resp[0]);
+ if (mUSSDRegistrant != null) {
+ mUSSDRegistrant.notifyRegistrant(
+ new AsyncResult (null, resp, null));
+ }
+ break;
+ case RIL_UNSOL_NITZ_TIME_RECEIVED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ // has bonus long containing milliseconds since boot that the NITZ
+ // time was received
+ long nitzReceiveTime = p.readLong();
+
+ Object[] result = new Object[2];
+
+ result[0] = ret;
+ result[1] = Long.valueOf(nitzReceiveTime);
+
+ if (mNITZTimeRegistrant != null) {
+
+ mNITZTimeRegistrant
+ .notifyRegistrant(new AsyncResult (null, result, null));
+ } else {
+ // in case NITZ time registrant isnt registered yet
+ mLastNITZTimeInfo = result;
+ }
+ break;
+
+ case RIL_UNSOL_SIGNAL_STRENGTH:
+ // Note this is set to "verbose" because it happens
+ // frequently
+ if (RILJ_LOGV) unsljLogvRet(response, ret);
+
+ if (mSignalStrengthRegistrant != null) {
+ mSignalStrengthRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+ case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
+ break;
+
+ case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mSsnRegistrant != null) {
+ mSsnRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_STK_SESSION_END:
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mCatSessionEndRegistrant != null) {
+ mCatSessionEndRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_STK_PROACTIVE_COMMAND:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCatProCmdRegistrant != null) {
+ mCatProCmdRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_STK_EVENT_NOTIFY:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCatEventRegistrant != null) {
+ mCatEventRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_STK_CALL_SETUP:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCatCallSetUpRegistrant != null) {
+ mCatCallSetUpRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mIccSmsFullRegistrant != null) {
+ mIccSmsFullRegistrant.notifyRegistrant();
+ }
+ break;
+
+ case RIL_UNSOL_SIM_REFRESH:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mIccRefreshRegistrants != null) {
+ mIccRefreshRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_CALL_RING:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mRingRegistrant != null) {
+ mRingRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
+ if (RILJ_LOGD) unsljLogvRet(response, ret);
+ if (mRestrictedStateRegistrant != null) {
+ mRestrictedStateRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mIccStatusChangedRegistrants != null) {
+ mIccStatusChangedRegistrants.notifyRegistrants();
+ }
+ break;
+
+ case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
+ if (RILJ_LOGD) unsljLog(response);
+
+ SmsMessage sms = (SmsMessage) ret;
+
+ if (mCdmaSmsRegistrant != null) {
+ mCdmaSmsRegistrant
+ .notifyRegistrant(new AsyncResult(null, sms, null));
+ }
+ break;
+
+ case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mGsmBroadcastSmsRegistrant != null) {
+ mGsmBroadcastSmsRegistrant
+ .notifyRegistrant(new AsyncResult(null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mIccSmsFullRegistrant != null) {
+ mIccSmsFullRegistrant.notifyRegistrant();
+ }
+ break;
+
+ case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mEmergencyCallbackModeRegistrant != null) {
+ mEmergencyCallbackModeRegistrant.notifyRegistrant();
+ }
+ break;
+
+ case RIL_UNSOL_CDMA_CALL_WAITING:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCallWaitingInfoRegistrants != null) {
+ mCallWaitingInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mOtaProvisionRegistrants != null) {
+ mOtaProvisionRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_CDMA_INFO_REC:
+ ArrayList<CdmaInformationRecords> listInfoRecs;
+
+ try {
+ listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
+ } catch (ClassCastException e) {
+ Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
+ break;
+ }
+
+ for (CdmaInformationRecords rec : listInfoRecs) {
+ if (RILJ_LOGD) unsljLogRet(response, rec);
+ notifyRegistrantsCdmaInfoRec(rec);
+ }
+ break;
+
+ case RIL_UNSOL_OEM_HOOK_RAW:
+ if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret));
+ if (mUnsolOemHookRawRegistrant != null) {
+ mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_RINGBACK_TONE:
+ if (RILJ_LOGD) unsljLogvRet(response, ret);
+ if (mRingbackToneRegistrants != null) {
+ boolean playtone = (((int[])ret)[0] == 1);
+ mRingbackToneRegistrants.notifyRegistrants(
+ new AsyncResult (null, playtone, null));
+ }
+ break;
+
+ case RIL_UNSOL_RESEND_INCALL_MUTE:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mResendIncallMuteRegistrants != null) {
+ mResendIncallMuteRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCdmaSubscriptionChangedRegistrants != null) {
+ mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOl_CDMA_PRL_CHANGED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCdmaPrlChangedRegistrants != null) {
+ mCdmaPrlChangedRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mExitEmergencyCallbackModeRegistrants != null) {
+ mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
+ new AsyncResult (null, null, null));
+ }
+ break;
+
+ case RIL_UNSOL_RIL_CONNECTED: {
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ // Initial conditions
+ setRadioPower(false, null);
+ sendPreferedNetworktype(mPreferredNetworkType, null);
+ setCdmaSubscriptionSource(mCdmaSubscription, null);
+ notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Notifiy all registrants that the ril has connected or disconnected.
+ *
+ * @param rilVer is the version of the ril or -1 if disconnected.
+ */
+ private void notifyRegistrantsRilConnectionChanged(int rilVer) {
+ mRilVersion = rilVer;
+ if (mRilConnectedRegistrants != null) {
+ mRilConnectedRegistrants.notifyRegistrants(
+ new AsyncResult (null, new Integer(rilVer), null));
+ }
+ }
+
+ @Override
+ protected Object
+ responseCallList(Parcel p) {
+ int num;
+ int voiceSettings;
+ ArrayList<DriverCall> response;
+ DriverCall dc;
+ int dataAvail = p.dataAvail();
+ int pos = p.dataPosition();
+ int size = p.dataSize();
+
+ Log.d(LOG_TAG, "Parcel size = " + size);
+ Log.d(LOG_TAG, "Parcel pos = " + pos);
+ Log.d(LOG_TAG, "Parcel dataAvail = " + dataAvail);
+
+ //Samsung changes
+ num = p.readInt();
+
+ Log.d(LOG_TAG, "num = " + num);
+ response = new ArrayList<DriverCall>(num);
+
+ for (int i = 0 ; i < num ; i++) {
+
+ dc = new DriverCall();
+
+ dc.state = DriverCall.stateFromCLCC(p.readInt());
+ Log.d(LOG_TAG, "state = " + dc.state);
+ dc.index = p.readInt();
+ Log.d(LOG_TAG, "index = " + dc.index);
+ dc.TOA = p.readInt();
+ Log.d(LOG_TAG, "state = " + dc.TOA);
+ dc.isMpty = (0 != p.readInt());
+ Log.d(LOG_TAG, "isMpty = " + dc.isMpty);
+ dc.isMT = (0 != p.readInt());
+ Log.d(LOG_TAG, "isMT = " + dc.isMT);
+ dc.als = p.readInt();
+ Log.d(LOG_TAG, "als = " + dc.als);
+ voiceSettings = p.readInt();
+ dc.isVoice = (0 == voiceSettings) ? false : true;
+ Log.d(LOG_TAG, "isVoice = " + dc.isVoice);
+ dc.isVoicePrivacy = (0 != p.readInt());
+ //Some Samsung magic data for Videocalls
+ voiceSettings = p.readInt();
+ //printing it to cosole for later investigation
+ Log.d(LOG_TAG, "Samsung magic = " + voiceSettings);
+ dc.number = p.readString();
+ Log.d(LOG_TAG, "number = " + dc.number);
+ int np = p.readInt();
+ Log.d(LOG_TAG, "np = " + np);
+ dc.numberPresentation = DriverCall.presentationFromCLIP(np);
+ dc.name = p.readString();
+ Log.d(LOG_TAG, "name = " + dc.name);
+ dc.namePresentation = p.readInt();
+ Log.d(LOG_TAG, "namePresentation = " + dc.namePresentation);
+ int uusInfoPresent = p.readInt();
+ Log.d(LOG_TAG, "uusInfoPresent = " + uusInfoPresent);
+
+ if (uusInfoPresent == 1) {
+ dc.uusInfo = new UUSInfo();
+ dc.uusInfo.setType(p.readInt());
+ dc.uusInfo.setDcs(p.readInt());
+ byte[] userData = p.createByteArray();
+ dc.uusInfo.setUserData(userData);
+ Log
+ .v(LOG_TAG, String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
+ dc.uusInfo.getType(), dc.uusInfo.getDcs(),
+ dc.uusInfo.getUserData().length));
+ Log.v(LOG_TAG, "Incoming UUS : data (string)="
+ + new String(dc.uusInfo.getUserData()));
+ Log.v(LOG_TAG, "Incoming UUS : data (hex): "
+ + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
+ } else {
+ Log.v(LOG_TAG, "Incoming UUS : NOT present!");
+ }
+
+ // Make sure there's a leading + on addresses with a TOA of 145
+ dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
+
+ response.add(dc);
+
+ if (dc.isVoicePrivacy) {
+ mVoicePrivacyOnRegistrants.notifyRegistrants();
+ Log.d(LOG_TAG, "InCall VoicePrivacy is enabled");
+ } else {
+ mVoicePrivacyOffRegistrants.notifyRegistrants();
+ Log.d(LOG_TAG, "InCall VoicePrivacy is disabled");
+ }
+ }
+
+ Collections.sort(response);
+
+ return response;
+ }
+
+ @Override
+ protected Object responseGetPreferredNetworkType(Parcel p) {
+ int [] response = (int[]) responseInts(p);
+
+ if (response.length >= 1) {
+ // Since this is the response for getPreferredNetworkType
+ // we'll assume that it should be the value we want the
+ // vendor ril to take if we reestablish a connection to it.
+ mPreferredNetworkType = response[0];
+ }
+
+ // When the modem responds Phone.NT_MODE_GLOBAL, it means Phone.NT_MODE_WCDMA_PREF
+ if (response[0] == Phone.NT_MODE_GLOBAL) {
+ Log.d(LOG_TAG, "Overriding network type response from GLOBAL to WCDMA preferred");
+ response[0] = Phone.NT_MODE_WCDMA_PREF;
+ }
+
+ return response;
+ }
+
+ @Override
+ protected Object
+ responseOperatorInfos(Parcel p) {
+ String strings[] = (String [])responseStrings(p);
+ ArrayList<OperatorInfo> ret;
+
+ if (strings.length % 5 != 0) {
+ throw new RuntimeException(
+ "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
+ + strings.length + " strings, expected multible of 5");
+ }
+
+ ret = new ArrayList<OperatorInfo>(strings.length / 5);
+
+ for (int i = 0 ; i < strings.length ; i += 5) {
+ ret.add (
+ new OperatorInfo(
+ strings[i+0],
+ strings[i+1],
+ strings[i+2],
+ strings[i+3]));
+ }
+
+ return ret;
+ }
+
+ @Override
+ protected Object
+ responseSignalStrength(Parcel p) {
+ int numInts = 12;
+ int response[];
+
+ /* TODO: Add SignalStrength class to match RIL_SignalStrength */
+ response = new int[numInts];
+ for (int i = 0 ; i < numInts ; i++) {
+ response[i] = p.readInt();
+ }
+
+ // SamsungRIL is a v3 RIL, fill the rest with -1
+ for (int i = 7; i < numInts; i++) {
+ response[i] = -1;
+ }
+
+ /* Matching Samsung signal strength to asu.
+ Method taken from Samsungs cdma/gsmSignalStateTracker */
+ response[0] = ((response[0] & 0xFF00) >> 8) * 3; //gsmDbm
+ response[1] = -1; //gsmEcio
+ response[2] = (response[2] < 0)?-120:-response[2]; //cdmaDbm
+ response[3] = (response[3] < 0)?-160:-response[3]; //cdmaEcio
+ response[4] = (response[4] < 0)?-120:-response[4]; //evdoRssi
+ response[5] = (response[5] < 0)?-1:-response[5]; //evdoEcio
+ if (response[6] < 0 || response[6] > 8) {
+ response[6] = -1;
+ }
+
+ return response;
+ }
+
+}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java index c1ad7b3..1941362 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java @@ -26,6 +26,7 @@ import android.os.SystemClock; import android.util.Log; import android.telephony.PhoneNumberUtils; import android.telephony.ServiceState; +import android.text.TextUtils; import com.android.internal.telephony.*; @@ -46,6 +47,7 @@ public class GsmConnection extends Connection { boolean isIncoming; boolean disconnected; + String cnapName; int index; // index in GsmCallTracker.connections[], -1 if unassigned // The GSM index is 1 + this @@ -72,6 +74,7 @@ public class GsmConnection extends Connection { DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED; PostDialState postDialState = PostDialState.NOT_STARTED; int numberPresentation = Connection.PRESENTATION_ALLOWED; + int cnapNamePresentation = Connection.PRESENTATION_ALLOWED; UUSInfo uusInfo; Handler h; @@ -125,6 +128,8 @@ public class GsmConnection extends Connection { isIncoming = dc.isMT; createTime = System.currentTimeMillis(); + cnapName = dc.name; + cnapNamePresentation = dc.namePresentation; numberPresentation = dc.numberPresentation; uusInfo = dc.uusInfo; @@ -151,6 +156,9 @@ public class GsmConnection extends Connection { index = -1; isIncoming = false; + cnapName = null; + cnapNamePresentation = Connection.PRESENTATION_ALLOWED; + numberPresentation = Connection.PRESENTATION_ALLOWED; createTime = System.currentTimeMillis(); this.parent = parent; @@ -189,6 +197,14 @@ public class GsmConnection extends Connection { return parent; } + public String getCnapName() { + return cnapName; + } + + public int getCnapNamePresentation() { + return cnapNamePresentation; + } + public long getCreateTime() { return createTime; } @@ -437,6 +453,21 @@ public class GsmConnection extends Connection { changed = true; } + // A null cnapName should be the same as "" + if (TextUtils.isEmpty(dc.name)) { + if (!TextUtils.isEmpty(cnapName)) { + changed = true; + cnapName = ""; + } + } else if (!dc.name.equals(cnapName)) { + changed = true; + cnapName = dc.name; + } + + if (Phone.DEBUG_PHONE) log("--dssds----"+cnapName); + cnapNamePresentation = dc.namePresentation; + numberPresentation = dc.numberPresentation; + if (newParent != parent) { if (parent != null) { parent.detach(this); diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index 84127cf..9e8a830 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -1220,7 +1220,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } catch (Exception e){ } - return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss)); + boolean mvnoRoaming = Settings.System.getInt(phone.getContext().getContentResolver(), + Settings.System.MVNO_ROAMING, 0) == 1; + return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss || mvnoRoaming)); } private static int twoDigitsAt(String s, int offset) { diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 67181c9..d9e9b25 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -1180,14 +1180,14 @@ public class WifiStateMachine extends StateMachine { ip settings */ InterfaceConfiguration ifcg = null; try { - ifcg = mNwService.getInterfaceConfig(mInterfaceName); + ifcg = mNwService.getInterfaceConfig(mTetherInterfaceName); if (ifcg != null) { ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress( "0.0.0.0"), 0); - mNwService.setInterfaceConfig(mInterfaceName, ifcg); + mNwService.setInterfaceConfig(mTetherInterfaceName, ifcg); } } catch (Exception e) { - loge("Error resetting interface " + mInterfaceName + ", :" + e); + loge("Error resetting interface " + mTetherInterfaceName + ", :" + e); } if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) { |