Merge "Unhide BLAS intrinsics."
diff --git a/Android.mk b/Android.mk
index 1223475..bd8b16a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -209,6 +209,7 @@
core/java/android/os/IUserManager.aidl \
core/java/android/os/IVibratorService.aidl \
core/java/android/security/IKeystoreService.aidl \
+ core/java/android/service/carrier/ICarrierConfigService.aidl \
core/java/android/service/carrier/ICarrierMessagingCallback.aidl \
core/java/android/service/carrier/ICarrierMessagingService.aidl \
core/java/android/service/gatekeeper/IGateKeeperService.aidl \
@@ -390,15 +391,16 @@
telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl \
telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl \
telephony/java/com/android/ims/ImsConfigListener.aidl \
+ telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl \
+ telephony/java/com/android/internal/telephony/IMms.aidl \
+ telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl \
telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
+ telephony/java/com/android/internal/telephony/ISms.aidl \
+ telephony/java/com/android/internal/telephony/ISub.aidl \
telephony/java/com/android/internal/telephony/ITelephony.aidl \
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
- telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl \
- telephony/java/com/android/internal/telephony/ISms.aidl \
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
- telephony/java/com/android/internal/telephony/ISub.aidl \
- telephony/java/com/android/internal/telephony/IMms.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl \
wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
@@ -549,6 +551,7 @@
frameworks/base/core/java/android/view/textservice/SpellCheckerInfo.aidl \
frameworks/base/core/java/android/view/textservice/SentenceSuggestionsInfo.aidl \
frameworks/base/core/java/android/view/textservice/SuggestionsInfo.aidl \
+ frameworks/base/core/java/android/service/carrier/CarrierIdentifier.aidl \
frameworks/base/core/java/android/service/carrier/MessagePdu.aidl \
frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
frameworks/base/core/java/android/service/chooser/ChooserTarget.aidl \
diff --git a/api/current.txt b/api/current.txt
index 506730e..ee0ec9b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20,6 +20,7 @@
field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+ field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
@@ -1978,6 +1979,7 @@
field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974355; // 0x1030213
field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974356; // 0x1030214
field public static final int TextAppearance_Material_Widget_Button = 16974357; // 0x1030215
+ field public static final int TextAppearance_Material_Widget_Button_Inverse = 16974565; // 0x10302e5
field public static final int TextAppearance_Material_Widget_DropDownHint = 16974358; // 0x1030216
field public static final int TextAppearance_Material_Widget_DropDownItem = 16974359; // 0x1030217
field public static final int TextAppearance_Material_Widget_EditText = 16974360; // 0x1030218
@@ -7740,6 +7742,7 @@
field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
field public static final java.lang.String CAMERA_SERVICE = "camera";
field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
+ field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
@@ -15564,6 +15567,11 @@
ctor public MediaCryptoException(java.lang.String);
}
+ public abstract interface MediaDataSource implements java.io.Closeable {
+ method public abstract long getSize();
+ method public abstract int readAt(long, byte[], int);
+ }
+
public class MediaDescription implements android.os.Parcelable {
method public int describeContents();
method public java.lang.CharSequence getDescription();
@@ -15699,6 +15707,7 @@
method public final void release();
method public void seekTo(long, int);
method public void selectTrack(int);
+ method public final void setDataSource(android.media.MediaDataSource) throws java.io.IOException, java.lang.IllegalArgumentException;
method public final void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
method public final void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
method public final void setDataSource(java.lang.String) throws java.io.IOException;
@@ -15878,6 +15887,7 @@
method public void setDataSource(java.io.FileDescriptor, long, long) throws java.lang.IllegalArgumentException;
method public void setDataSource(java.io.FileDescriptor) throws java.lang.IllegalArgumentException;
method public void setDataSource(android.content.Context, android.net.Uri) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
+ method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException;
field public static final int METADATA_KEY_ALBUM = 1; // 0x1
field public static final int METADATA_KEY_ALBUMARTIST = 13; // 0xd
field public static final int METADATA_KEY_ARTIST = 2; // 0x2
@@ -15962,6 +15972,7 @@
method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+ method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDisplay(android.view.SurfaceHolder);
method public void setLooping(boolean);
method public void setNextMediaPlayer(android.media.MediaPlayer);
@@ -22833,6 +22844,8 @@
method public static long getNativeHeapFreeSize();
method public static long getNativeHeapSize();
method public static long getPss();
+ method public static java.lang.String getRuntimeStat(java.lang.String);
+ method public static java.util.Map<java.lang.String, java.lang.String> getRuntimeStats();
method public static deprecated int getThreadAllocCount();
method public static deprecated int getThreadAllocSize();
method public static deprecated int getThreadExternalAllocCount();
@@ -28554,6 +28567,26 @@
package android.service.carrier {
+ public abstract class CarrierConfigService extends android.app.Service {
+ ctor public CarrierConfigService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.os.Bundle onLoadConfig(android.service.carrier.CarrierIdentifier);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
+ }
+
+ public class CarrierIdentifier implements android.os.Parcelable {
+ ctor public CarrierIdentifier(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+ method public int describeContents();
+ method public java.lang.String getGid1();
+ method public java.lang.String getGid2();
+ method public java.lang.String getImsi();
+ method public java.lang.String getMcc();
+ method public java.lang.String getMnc();
+ method public java.lang.String getSpn();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.carrier.CarrierIdentifier> CREATOR;
+ }
+
public abstract class CarrierMessagingService extends android.app.Service {
ctor public CarrierMessagingService();
method public android.os.IBinder onBind(android.content.Intent);
@@ -30245,10 +30278,17 @@
public abstract class InCallService extends android.app.Service {
ctor public InCallService();
- method public final android.telecom.Phone getPhone();
+ method public final boolean canAddCall();
+ method public final android.telecom.AudioState getAudioState();
+ method public final java.util.List<android.telecom.Call> getCalls();
+ method public void onAudioStateChanged(android.telecom.AudioState);
method public android.os.IBinder onBind(android.content.Intent);
- method public void onPhoneCreated(android.telecom.Phone);
- method public void onPhoneDestroyed(android.telecom.Phone);
+ method public void onBringToForeground(boolean);
+ method public void onCallAdded(android.telecom.Call);
+ method public void onCallRemoved(android.telecom.Call);
+ method public void onCanAddCallChanged(boolean);
+ method public final void setAudioRoute(int);
+ method public final void setMuted(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
}
@@ -30455,9 +30495,9 @@
method public java.lang.String getLine1Number(android.telecom.PhoneAccountHandle);
method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
method public android.telecom.PhoneAccountHandle getSimCallManager();
+ method public java.lang.String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
method public boolean handleMmi(java.lang.String);
method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
- method public boolean hasVoiceMailNumber(android.telecom.PhoneAccountHandle);
method public boolean isInCall();
method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
method public void registerPhoneAccount(android.telecom.PhoneAccount);
@@ -30519,6 +30559,18 @@
package android.telephony {
+ public class CarrierConfigManager {
+ method public android.os.Bundle getConfig();
+ method public android.os.Bundle getConfigForSubId(int);
+ method public void reloadCarrierConfigForSubId(int);
+ field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+ field public static final java.lang.String BOOL_CARRIER_VOLTE_AVAILABLE = "bool_carrier_volte_available";
+ field public static final java.lang.String BOOL_CARRIER_VOLTE_PROVISIONED = "bool_carrier_volte_provisioned";
+ field public static final java.lang.String BOOL_CARRIER_VOLTE_TTY_SUPPORTED = "bool_carrier_volte_tty_supported";
+ field public static final java.lang.String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
+ field public static final java.lang.String INT_VOLTE_REPLACEMENT_RAT = "int_volte_replacement_rat";
+ }
+
public final class CellIdentityCdma implements android.os.Parcelable {
method public int describeContents();
method public int getBasestationId();
@@ -34524,6 +34576,7 @@
method public boolean onTouchEvent(android.view.MotionEvent);
method public void setIsLongpressEnabled(boolean);
method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener);
+ method public void setOnStylusButtonPressListener(android.view.GestureDetector.OnStylusButtonPressListener);
}
public static abstract interface GestureDetector.OnDoubleTapListener {
@@ -34541,7 +34594,11 @@
method public abstract boolean onSingleTapUp(android.view.MotionEvent);
}
- public static class GestureDetector.SimpleOnGestureListener implements android.view.GestureDetector.OnDoubleTapListener android.view.GestureDetector.OnGestureListener {
+ public static abstract interface GestureDetector.OnStylusButtonPressListener {
+ method public abstract boolean onStylusButtonPress(android.view.MotionEvent);
+ }
+
+ public static class GestureDetector.SimpleOnGestureListener implements android.view.GestureDetector.OnDoubleTapListener android.view.GestureDetector.OnGestureListener android.view.GestureDetector.OnStylusButtonPressListener {
ctor public GestureDetector.SimpleOnGestureListener();
method public boolean onDoubleTap(android.view.MotionEvent);
method public boolean onDoubleTapEvent(android.view.MotionEvent);
@@ -34552,6 +34609,7 @@
method public void onShowPress(android.view.MotionEvent);
method public boolean onSingleTapConfirmed(android.view.MotionEvent);
method public boolean onSingleTapUp(android.view.MotionEvent);
+ method public boolean onStylusButtonPress(android.view.MotionEvent);
}
public class Gravity {
diff --git a/api/system-current.txt b/api/system-current.txt
index 9720cda..f476203 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -28,6 +28,7 @@
field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+ field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
field public static final java.lang.String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE";
@@ -2057,6 +2058,7 @@
field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974355; // 0x1030213
field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974356; // 0x1030214
field public static final int TextAppearance_Material_Widget_Button = 16974357; // 0x1030215
+ field public static final int TextAppearance_Material_Widget_Button_Inverse = 16974565; // 0x10302e5
field public static final int TextAppearance_Material_Widget_DropDownHint = 16974358; // 0x1030216
field public static final int TextAppearance_Material_Widget_DropDownItem = 16974359; // 0x1030217
field public static final int TextAppearance_Material_Widget_EditText = 16974360; // 0x1030218
@@ -7956,6 +7958,7 @@
field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
field public static final java.lang.String CAMERA_SERVICE = "camera";
field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
+ field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
@@ -16776,6 +16779,11 @@
ctor public MediaCryptoException(java.lang.String);
}
+ public abstract interface MediaDataSource implements java.io.Closeable {
+ method public abstract long getSize();
+ method public abstract int readAt(long, byte[], int);
+ }
+
public class MediaDescription implements android.os.Parcelable {
method public int describeContents();
method public java.lang.CharSequence getDescription();
@@ -16912,6 +16920,7 @@
method public final void release();
method public void seekTo(long, int);
method public void selectTrack(int);
+ method public final void setDataSource(android.media.MediaDataSource) throws java.io.IOException, java.lang.IllegalArgumentException;
method public final void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
method public final void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
method public final void setDataSource(java.lang.String) throws java.io.IOException;
@@ -17091,6 +17100,7 @@
method public void setDataSource(java.io.FileDescriptor, long, long) throws java.lang.IllegalArgumentException;
method public void setDataSource(java.io.FileDescriptor) throws java.lang.IllegalArgumentException;
method public void setDataSource(android.content.Context, android.net.Uri) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
+ method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException;
field public static final int METADATA_KEY_ALBUM = 1; // 0x1
field public static final int METADATA_KEY_ALBUMARTIST = 13; // 0xd
field public static final int METADATA_KEY_ARTIST = 2; // 0x2
@@ -17175,6 +17185,7 @@
method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+ method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDisplay(android.view.SurfaceHolder);
method public void setLooping(boolean);
method public void setNextMediaPlayer(android.media.MediaPlayer);
@@ -24721,6 +24732,8 @@
method public static long getNativeHeapFreeSize();
method public static long getNativeHeapSize();
method public static long getPss();
+ method public static java.lang.String getRuntimeStat(java.lang.String);
+ method public static java.util.Map<java.lang.String, java.lang.String> getRuntimeStats();
method public static deprecated int getThreadAllocCount();
method public static deprecated int getThreadAllocSize();
method public static deprecated int getThreadExternalAllocCount();
@@ -30557,6 +30570,26 @@
package android.service.carrier {
+ public abstract class CarrierConfigService extends android.app.Service {
+ ctor public CarrierConfigService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.os.Bundle onLoadConfig(android.service.carrier.CarrierIdentifier);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
+ }
+
+ public class CarrierIdentifier implements android.os.Parcelable {
+ ctor public CarrierIdentifier(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+ method public int describeContents();
+ method public java.lang.String getGid1();
+ method public java.lang.String getGid2();
+ method public java.lang.String getImsi();
+ method public java.lang.String getMcc();
+ method public java.lang.String getMnc();
+ method public java.lang.String getSpn();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.carrier.CarrierIdentifier> CREATOR;
+ }
+
public abstract class CarrierMessagingService extends android.app.Service {
ctor public CarrierMessagingService();
method public android.os.IBinder onBind(android.content.Intent);
@@ -32345,10 +32378,20 @@
public abstract class InCallService extends android.app.Service {
ctor public InCallService();
+ method public final boolean canAddCall();
+ method public final android.telecom.AudioState getAudioState();
+ method public final java.util.List<android.telecom.Call> getCalls();
method public final android.telecom.Phone getPhone();
+ method public void onAudioStateChanged(android.telecom.AudioState);
method public android.os.IBinder onBind(android.content.Intent);
+ method public void onBringToForeground(boolean);
+ method public void onCallAdded(android.telecom.Call);
+ method public void onCallRemoved(android.telecom.Call);
+ method public void onCanAddCallChanged(boolean);
method public void onPhoneCreated(android.telecom.Phone);
method public void onPhoneDestroyed(android.telecom.Phone);
+ method public final void setAudioRoute(int);
+ method public final void setMuted(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
}
@@ -32570,9 +32613,9 @@
method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String);
method public java.util.List<android.telecom.PhoneAccountHandle> getRegisteredConnectionManagers();
method public android.telecom.PhoneAccountHandle getSimCallManager();
+ method public java.lang.String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
method public boolean handleMmi(java.lang.String);
method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
- method public boolean hasVoiceMailNumber(android.telecom.PhoneAccountHandle);
method public boolean isInCall();
method public boolean isRinging();
method public boolean isTtySupported();
@@ -32639,6 +32682,20 @@
package android.telephony {
+ public class CarrierConfigManager {
+ method public android.os.Bundle getConfig();
+ method public android.os.Bundle getConfigForSubId(int);
+ method public static android.os.Bundle getDefaultConfig();
+ method public void reloadCarrierConfigForSubId(int);
+ method public void updateConfigForPhoneId(int, java.lang.String);
+ field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+ field public static final java.lang.String BOOL_CARRIER_VOLTE_AVAILABLE = "bool_carrier_volte_available";
+ field public static final java.lang.String BOOL_CARRIER_VOLTE_PROVISIONED = "bool_carrier_volte_provisioned";
+ field public static final java.lang.String BOOL_CARRIER_VOLTE_TTY_SUPPORTED = "bool_carrier_volte_tty_supported";
+ field public static final java.lang.String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
+ field public static final java.lang.String INT_VOLTE_REPLACEMENT_RAT = "int_volte_replacement_rat";
+ }
+
public final class CellIdentityCdma implements android.os.Parcelable {
method public int describeContents();
method public int getBasestationId();
@@ -36689,6 +36746,7 @@
method public boolean onTouchEvent(android.view.MotionEvent);
method public void setIsLongpressEnabled(boolean);
method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener);
+ method public void setOnStylusButtonPressListener(android.view.GestureDetector.OnStylusButtonPressListener);
}
public static abstract interface GestureDetector.OnDoubleTapListener {
@@ -36706,7 +36764,11 @@
method public abstract boolean onSingleTapUp(android.view.MotionEvent);
}
- public static class GestureDetector.SimpleOnGestureListener implements android.view.GestureDetector.OnDoubleTapListener android.view.GestureDetector.OnGestureListener {
+ public static abstract interface GestureDetector.OnStylusButtonPressListener {
+ method public abstract boolean onStylusButtonPress(android.view.MotionEvent);
+ }
+
+ public static class GestureDetector.SimpleOnGestureListener implements android.view.GestureDetector.OnDoubleTapListener android.view.GestureDetector.OnGestureListener android.view.GestureDetector.OnStylusButtonPressListener {
ctor public GestureDetector.SimpleOnGestureListener();
method public boolean onDoubleTap(android.view.MotionEvent);
method public boolean onDoubleTapEvent(android.view.MotionEvent);
@@ -36717,6 +36779,7 @@
method public void onShowPress(android.view.MotionEvent);
method public boolean onSingleTapConfirmed(android.view.MotionEvent);
method public boolean onSingleTapUp(android.view.MotionEvent);
+ method public boolean onStylusButtonPress(android.view.MotionEvent);
}
public class Gravity {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 4ede5b1..e446700 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -105,6 +105,7 @@
import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager;
import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -420,6 +421,13 @@
return new SubscriptionManager(ctx.getOuterContext());
}});
+ registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
+ new CachedServiceFetcher<CarrierConfigManager>() {
+ @Override
+ public CarrierConfigManager createService(ContextImpl ctx) {
+ return new CarrierConfigManager();
+ }});
+
registerService(Context.TELECOM_SERVICE, TelecomManager.class,
new CachedServiceFetcher<TelecomManager>() {
@Override
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 0cbf960..370f61c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2193,6 +2193,7 @@
MEDIA_ROUTER_SERVICE,
TELEPHONY_SERVICE,
TELEPHONY_SUBSCRIPTION_SERVICE,
+ CARRIER_CONFIG_SERVICE,
TELECOM_SERVICE,
CLIPBOARD_SERVICE,
INPUT_METHOD_SERVICE,
@@ -2338,6 +2339,8 @@
* @see android.telephony.TelephonyManager
* @see #TELEPHONY_SUBSCRIPTION_SERVICE
* @see android.telephony.SubscriptionManager
+ * @see #CARRIER_CONFIG_SERVICE
+ * @see android.telephony.CarrierConfigManager
* @see #INPUT_METHOD_SERVICE
* @see android.view.inputmethod.InputMethodManager
* @see #UI_MODE_SERVICE
@@ -2755,6 +2758,16 @@
/**
* Use with {@link #getSystemService} to retrieve a
+ * {@link android.telephony.CarrierConfigManager} for reading carrier configuration values.
+ *
+ * @see #getSystemService
+ * @see android.telephony.CarrierConfigManager
+ */
+ public static final String CARRIER_CONFIG_SERVICE = "carrier_config";
+
+ /**
+ * Use with {@link #getSystemService} to retrieve a
+ * {@link android.text.ClipboardManager} for accessing and modifying
* {@link android.content.ClipboardManager} for accessing and modifying
* the contents of the global clipboard.
*
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 75b1101..4aff7a1 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1173,7 +1173,6 @@
* the name of the runtime statistic to look up.
* @return the value of the specified runtime statistic or {@code null} if the
* runtime statistic doesn't exist.
- * @hide
*/
public static String getRuntimeStat(String statName) {
return VMDebug.getRuntimeStat(statName);
@@ -1184,7 +1183,6 @@
* that {@link #getRuntimeStat(String)} supports.
*
* @return a map of the names/values of the supported runtime statistics.
- * @hide
*/
public static Map<String, String> getRuntimeStats() {
return VMDebug.getRuntimeStats();
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index ea53c0d..ab8a8b6 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -192,6 +192,8 @@
public static final int KM_ERROR_SECURE_HW_BUSY = -48;
public static final int KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = -49;
public static final int KM_ERROR_UNSUPPORTED_EC_FIELD = -50;
+ public static final int KM_ERROR_MISSING_NONCE = -51;
+ public static final int KM_ERROR_INVALID_NONCE = -52;
public static final int KM_ERROR_UNIMPLEMENTED = -100;
public static final int KM_ERROR_VERSION_MISMATCH = -101;
public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -231,6 +233,8 @@
sErrorCodeToString.put(KM_ERROR_INVALID_TAG, "Invalid tag");
sErrorCodeToString.put(KM_ERROR_MEMORY_ALLOCATION_FAILED, "Memory allocation failed");
sErrorCodeToString.put(KM_ERROR_UNSUPPORTED_EC_FIELD, "Unsupported EC field");
+ sErrorCodeToString.put(KM_ERROR_MISSING_NONCE, "Required IV missing");
+ sErrorCodeToString.put(KM_ERROR_INVALID_NONCE, "Invalid IV");
sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
}
diff --git a/core/java/android/service/carrier/CarrierConfigService.java b/core/java/android/service/carrier/CarrierConfigService.java
new file mode 100644
index 0000000..1880d16
--- /dev/null
+++ b/core/java/android/service/carrier/CarrierConfigService.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 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.service.carrier;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+
+/**
+ * A service that sets carrier configuration for telephony services.
+ * <p>
+ * To extend this class, you must declare the service in your manifest file to require the
+ * {@link android.Manifest.permission#BIND_CARRIER_CONFIG_SERVICE} permission and include an intent
+ * filter with the {@link #SERVICE_INTERFACE} action. For example:
+ * </p>
+ *
+ * <pre>{@code
+ * <service android:name=".MyCarrierConfigService"
+ * android:label="@string/service_name"
+ * android:permission="android.permission.BIND_CARRIER_CONFIG_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.service.carrier.CarrierConfigService" />
+ * </intent-filter>
+ * </service>
+ * }</pre>
+ */
+public abstract class CarrierConfigService extends Service {
+
+ public static final String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
+
+ private final ICarrierConfigService.Stub mStubWrapper;
+
+ public CarrierConfigService() {
+ mStubWrapper = new ICarrierConfigServiceWrapper();
+ }
+
+ /**
+ * Override this method to set carrier configuration.
+ * <p>
+ * This method will be called by telephony services to get carrier-specific configuration
+ * values. The returned config will be saved by the system until,
+ * <ol>
+ * <li>The carrier app package is updated, or</li>
+ * <li>The carrier app requests a reload with
+ * {@link android.telephony.CarrierConfigManager#reloadCarrierConfigForSubId
+ * reloadCarrierConfigForSubId}.</li>
+ * </ol>
+ * This method can be called after a SIM card loads, which may be before or after boot.
+ * </p>
+ * <p>
+ * This method should not block for a long time. If expensive operations (e.g. network access)
+ * are required, this method can schedule the work and return null. Then, use
+ * {@link android.telephony.CarrierConfigManager#reloadCarrierConfigForSubId
+ * reloadCarrierConfigForSubId} to trigger a reload when the config is ready.
+ * </p>
+ * <p>
+ * Implementations should use the keys defined in {@link android.telephony.CarrierConfigManager
+ * CarrierConfigManager}. Any configuration values not set in the returned {@link Bundle} may be
+ * overridden by the system's default configuration service.
+ * </p>
+ *
+ * @param id contains details about the current carrier that can be used do decide what
+ * configuration values to return.
+ * @return a {@link Bundle} object containing the configuration or null if default values should
+ * be used.
+ */
+ public abstract Bundle onLoadConfig(CarrierIdentifier id);
+
+ /** @hide */
+ @Override
+ public final IBinder onBind(Intent intent) {
+ if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+ return null;
+ }
+ return mStubWrapper;
+ }
+
+ /**
+ * A wrapper around ICarrierConfigService that forwards calls to implementations of
+ * {@link CarrierConfigService}.
+ *
+ * @hide
+ */
+ private class ICarrierConfigServiceWrapper extends ICarrierConfigService.Stub {
+
+ @Override
+ public Bundle getCarrierConfig(CarrierIdentifier id) {
+ return CarrierConfigService.this.onLoadConfig(id);
+ }
+ }
+}
diff --git a/packages/SystemUI/res/drawable/ic_audio_phone.xml b/core/java/android/service/carrier/CarrierIdentifier.aidl
similarity index 65%
rename from packages/SystemUI/res/drawable/ic_audio_phone.xml
rename to core/java/android/service/carrier/CarrierIdentifier.aidl
index 64147f2b..48b1398 100644
--- a/packages/SystemUI/res/drawable/ic_audio_phone.xml
+++ b/core/java/android/service/carrier/CarrierIdentifier.aidl
@@ -1,7 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright 2014, The Android Open Source Project
+/**
+ * Copyright (c) 2015, 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.
@@ -15,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
--->
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@*android:drawable/ic_audio_phone_am_alpha"
- android:autoMirrored="true"
- android:tint="#ffffffff" />
\ No newline at end of file
+package android.service.carrier;
+
+parcelable CarrierIdentifier;
diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java
new file mode 100644
index 0000000..495fea6
--- /dev/null
+++ b/core/java/android/service/carrier/CarrierIdentifier.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2015, 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.service.carrier;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Used to pass info to CarrierConfigService implementations so they can decide what values to
+ * return.
+ */
+public class CarrierIdentifier implements Parcelable {
+
+ /** Used to create a {@link CarrierIdentifier} from a {@link Parcel}. */
+ public static final Creator<CarrierIdentifier> CREATOR = new Creator<CarrierIdentifier>() {
+ @Override
+ public CarrierIdentifier createFromParcel(Parcel parcel) {
+ return new CarrierIdentifier(parcel);
+ }
+
+ @Override
+ public CarrierIdentifier[] newArray(int i) {
+ return new CarrierIdentifier[i];
+ }
+ };
+
+ private String mMcc;
+ private String mMnc;
+ private String mSpn;
+ private String mImsi;
+ private String mGid1;
+ private String mGid2;
+
+ public CarrierIdentifier(String mcc, String mnc, String spn, String imsi, String gid1,
+ String gid2) {
+ mMcc = mcc;
+ mMnc = mnc;
+ mSpn = spn;
+ mImsi = imsi;
+ mGid1 = gid1;
+ mGid2 = gid2;
+ }
+
+ /** @hide */
+ public CarrierIdentifier(Parcel parcel) {
+ readFromParcel(parcel);
+ }
+
+ /** Get the mobile country code. */
+ public String getMcc() {
+ return mMcc;
+ }
+
+ /** Get the mobile network code. */
+ public String getMnc() {
+ return mMnc;
+ }
+
+ /** Get the service provider name. */
+ public String getSpn() {
+ return mSpn;
+ }
+
+ /** Get the international mobile subscriber identity. */
+ public String getImsi() {
+ return mImsi;
+ }
+
+ /** Get the group identifier level 1. */
+ public String getGid1() {
+ return mGid1;
+ }
+
+ /** Get the group identifier level 2. */
+ public String getGid2() {
+ return mGid2;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(mMcc);
+ out.writeString(mMnc);
+ out.writeString(mSpn);
+ out.writeString(mImsi);
+ out.writeString(mGid1);
+ out.writeString(mGid2);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mMcc = in.readString();
+ mMnc = in.readString();
+ mSpn = in.readString();
+ mImsi = in.readString();
+ mGid1 = in.readString();
+ mGid2 = in.readString();
+ }
+}
diff --git a/core/java/android/service/carrier/ICarrierConfigService.aidl b/core/java/android/service/carrier/ICarrierConfigService.aidl
new file mode 100644
index 0000000..d8390b6
--- /dev/null
+++ b/core/java/android/service/carrier/ICarrierConfigService.aidl
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2015, 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.service.carrier;
+
+import android.os.Bundle;
+import android.service.carrier.CarrierIdentifier;
+
+/**
+ * Service used to get carrier config from carrier apps.
+ *
+ * @see android.service.carrier.CarrierConfigService
+ * @hide
+ */
+interface ICarrierConfigService {
+
+ /** @see android.service.carrier.CarrierConfigService#onLoadConfig */
+ Bundle getCarrierConfig(in CarrierIdentifier id);
+}
\ No newline at end of file
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 2351548..b8544c6 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -149,12 +149,30 @@
}
/**
+ * The listener that is used to notify when a stylus button press occurs.
+ */
+ public interface OnStylusButtonPressListener {
+ /**
+ * Notified when a stylus button press occurs. This is when the stylus
+ * is touching the screen and the {@value MotionEvent#BUTTON_SECONDARY}
+ * is pressed.
+ *
+ * @param e The motion event that occurred during the stylus button
+ * press.
+ * @return true if the event is consumed, else false
+ */
+ boolean onStylusButtonPress(MotionEvent e);
+ }
+
+ /**
* A convenience class to extend when you only want to listen for a subset
* of all the gestures. This implements all methods in the
- * {@link OnGestureListener} and {@link OnDoubleTapListener} but does
- * nothing and return {@code false} for all applicable methods.
+ * {@link OnGestureListener}, {@link OnDoubleTapListener}, and {@link OnStylusButtonPressListener}
+ * but does nothing and return {@code false} for all applicable methods.
*/
- public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener {
+ public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
+ OnStylusButtonPressListener {
+
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@@ -190,6 +208,10 @@
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
+
+ public boolean onStylusButtonPress(MotionEvent e) {
+ return false;
+ }
}
private int mTouchSlopSquare;
@@ -211,10 +233,12 @@
private final Handler mHandler;
private final OnGestureListener mListener;
private OnDoubleTapListener mDoubleTapListener;
+ private OnStylusButtonPressListener mStylusButtonListener;
private boolean mStillDown;
private boolean mDeferConfirmSingleTap;
private boolean mInLongPress;
+ private boolean mInStylusButtonPress;
private boolean mAlwaysInTapRegion;
private boolean mAlwaysInBiggerTapRegion;
@@ -358,6 +382,9 @@
if (listener instanceof OnDoubleTapListener) {
setOnDoubleTapListener((OnDoubleTapListener) listener);
}
+ if (listener instanceof OnStylusButtonPressListener) {
+ setOnStylusButtonPressListener((OnStylusButtonPressListener) listener);
+ }
init(context);
}
@@ -420,6 +447,19 @@
}
/**
+ * Sets the listener which will be called for stylus button related
+ * gestures.
+ *
+ * @param onStylusButtonPressListener the listener invoked for all the
+ * callbacks, or null to stop listening for stylus button
+ * gestures.
+ */
+ public void setOnStylusButtonPressListener(
+ OnStylusButtonPressListener onStylusButtonPressListener) {
+ mStylusButtonListener = onStylusButtonPressListener;
+ }
+
+ /**
* Set whether longpress is enabled, if this is enabled when a user
* presses and holds down you get a longpress event and nothing further.
* If it's disabled the user can press and hold down and then later
@@ -512,7 +552,18 @@
break;
case MotionEvent.ACTION_DOWN:
- if (mDoubleTapListener != null) {
+ if (mStylusButtonListener != null
+ && ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
+ && (ev.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
+ if (mStylusButtonListener.onStylusButtonPress(ev)) {
+ mInStylusButtonPress = true;
+ handled = true;
+ mHandler.removeMessages(LONG_PRESS);
+ mHandler.removeMessages(TAP);
+ }
+ }
+
+ if (mDoubleTapListener != null && !mInStylusButtonPress) {
boolean hadTapMessage = mHandler.hasMessages(TAP);
if (hadTapMessage) mHandler.removeMessages(TAP);
if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
@@ -540,8 +591,8 @@
mStillDown = true;
mInLongPress = false;
mDeferConfirmSingleTap = false;
-
- if (mIsLongpressEnabled) {
+
+ if (mIsLongpressEnabled && !mInStylusButtonPress) {
mHandler.removeMessages(LONG_PRESS);
mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
+ TAP_TIMEOUT + LONGPRESS_TIMEOUT);
@@ -551,7 +602,17 @@
break;
case MotionEvent.ACTION_MOVE:
- if (mInLongPress) {
+ if (mStylusButtonListener != null && !mInStylusButtonPress && !mInLongPress
+ && ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
+ && (ev.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
+ if (mStylusButtonListener.onStylusButtonPress(ev)) {
+ mInStylusButtonPress = true;
+ handled = true;
+ mHandler.removeMessages(LONG_PRESS);
+ mHandler.removeMessages(TAP);
+ }
+ }
+ if (mInLongPress || mInStylusButtonPress) {
break;
}
final float scrollX = mLastFocusX - focusX;
@@ -591,6 +652,9 @@
} else if (mInLongPress) {
mHandler.removeMessages(TAP);
mInLongPress = false;
+ } else if (mInStylusButtonPress) {
+ mHandler.removeMessages(TAP);
+ mInStylusButtonPress = false;
} else if (mAlwaysInTapRegion) {
handled = mListener.onSingleTapUp(ev);
if (mDeferConfirmSingleTap && mDoubleTapListener != null) {
@@ -649,9 +713,8 @@
mAlwaysInTapRegion = false;
mAlwaysInBiggerTapRegion = false;
mDeferConfirmSingleTap = false;
- if (mInLongPress) {
- mInLongPress = false;
- }
+ mInLongPress = false;
+ mInStylusButtonPress = false;
}
private void cancelTaps() {
@@ -662,9 +725,8 @@
mAlwaysInTapRegion = false;
mAlwaysInBiggerTapRegion = false;
mDeferConfirmSingleTap = false;
- if (mInLongPress) {
- mInLongPress = false;
- }
+ mInLongPress = false;
+ mInStylusButtonPress = false;
}
private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp,
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index e7b6238..c9d9a8c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3116,6 +3116,25 @@
}
}
+ private boolean performStylusButtonPressAction(MotionEvent ev) {
+ if (ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
+ && ev.isButtonPressed(MotionEvent.BUTTON_SECONDARY)
+ && mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) {
+ final View child = getChildAt(mMotionPosition - mFirstPosition);
+ if (child != null) {
+ final int longPressPosition = mMotionPosition;
+ final long longPressId = mAdapter.getItemId(mMotionPosition);
+ if (performLongPress(child, longPressPosition, longPressId)) {
+ mTouchMode = TOUCH_MODE_REST;
+ setPressed(false);
+ child.setPressed(false);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
boolean performLongPress(final View child,
final int longPressPosition, final long longPressId) {
// CHOICE_MODE_MULTIPLE_MODAL takes over long press.
@@ -3757,8 +3776,8 @@
}
if (mTouchMode == TOUCH_MODE_DOWN && mMotionPosition != INVALID_POSITION
- && performButtonActionOnTouchDown(ev)) {
- removeCallbacks(mPendingCheckForTap);
+ && (performButtonActionOnTouchDown(ev) || performStylusButtonPressAction(ev))) {
+ removeCallbacks(mPendingCheckForTap);
}
}
@@ -3800,6 +3819,11 @@
mTouchMode = TOUCH_MODE_DONE_WAITING;
updateSelectorState();
} else if (motionView != null) {
+ if (performStylusButtonPressAction(ev)) {
+ removeCallbacks(mPendingCheckForTap);
+ removeCallbacks(mPendingCheckForLongPress);
+ }
+
// Still within bounds, update the hotspot.
final float[] point = mTmpPoint;
point[0] = x;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 13877fb..5465212 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2408,6 +2408,15 @@
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature" />
+ <!-- The system process that pulls carrier configuration from carrier apps will
+ have this permission. Carrier apps that provide
+ {@link android.service.carrier.CarrierConfigService} should require this
+ permission for clients binding to their service. -->
+ <permission android:name="android.permission.BIND_CARRIER_CONFIG_SERVICE"
+ android:label="@string/permlab_bindCarrierConfigService"
+ android:description="@string/permdesc_bindCarrierConfigService"
+ android:protectionLevel="signature|system" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/drawable-hdpi/ic_audio_bt_alpha.png b/core/res/res/drawable-hdpi/ic_audio_bt_alpha.png
deleted file mode 100644
index 597c384..0000000
--- a/core/res/res/drawable-hdpi/ic_audio_bt_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_bt_mute_alpha.png b/core/res/res/drawable-hdpi/ic_audio_bt_mute_alpha.png
deleted file mode 100644
index 298db92..0000000
--- a/core/res/res/drawable-hdpi/ic_audio_bt_mute_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_phone_am_alpha.png b/core/res/res/drawable-hdpi/ic_audio_phone_am_alpha.png
deleted file mode 100644
index 8a7d67a..0000000
--- a/core/res/res/drawable-hdpi/ic_audio_phone_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_bt_alpha.png b/core/res/res/drawable-mdpi/ic_audio_bt_alpha.png
deleted file mode 100644
index 282c643..0000000
--- a/core/res/res/drawable-mdpi/ic_audio_bt_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_bt_mute_alpha.png b/core/res/res/drawable-mdpi/ic_audio_bt_mute_alpha.png
deleted file mode 100644
index f734c1c..0000000
--- a/core/res/res/drawable-mdpi/ic_audio_bt_mute_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_phone_am_alpha.png b/core/res/res/drawable-mdpi/ic_audio_phone_am_alpha.png
deleted file mode 100644
index beda721..0000000
--- a/core/res/res/drawable-mdpi/ic_audio_phone_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_bt_alpha.png b/core/res/res/drawable-xhdpi/ic_audio_bt_alpha.png
deleted file mode 100644
index b8aa083..0000000
--- a/core/res/res/drawable-xhdpi/ic_audio_bt_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_bt_mute_alpha.png b/core/res/res/drawable-xhdpi/ic_audio_bt_mute_alpha.png
deleted file mode 100644
index 93a2481..0000000
--- a/core/res/res/drawable-xhdpi/ic_audio_bt_mute_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_phone_am_alpha.png b/core/res/res/drawable-xhdpi/ic_audio_phone_am_alpha.png
deleted file mode 100644
index 2a04619..0000000
--- a/core/res/res/drawable-xhdpi/ic_audio_phone_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_bt_alpha.png b/core/res/res/drawable-xxhdpi/ic_audio_bt_alpha.png
deleted file mode 100755
index 140edac..0000000
--- a/core/res/res/drawable-xxhdpi/ic_audio_bt_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_bt_mute_alpha.png b/core/res/res/drawable-xxhdpi/ic_audio_bt_mute_alpha.png
deleted file mode 100644
index 97829b4..0000000
--- a/core/res/res/drawable-xxhdpi/ic_audio_bt_mute_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_phone_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_audio_phone_am_alpha.png
deleted file mode 100644
index 1fd54a1..0000000
--- a/core/res/res/drawable-xxhdpi/ic_audio_phone_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/btn_colored_material.xml b/core/res/res/drawable/btn_colored_material.xml
new file mode 100644
index 0000000..81cbe39
--- /dev/null
+++ b/core/res/res/drawable/btn_colored_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetLeft="@dimen/button_inset_horizontal_material"
+ android:insetTop="@dimen/button_inset_vertical_material"
+ android:insetRight="@dimen/button_inset_horizontal_material"
+ android:insetBottom="@dimen/button_inset_vertical_material">
+ <ripple android:color="?attr/colorControlHighlight">
+ <item>
+ <shape android:shape="rectangle"
+ android:tint="@color/btn_colored_material">
+ <corners android:radius="@dimen/control_corner_material" />
+ <solid android:color="@color/white" />
+ <padding android:left="@dimen/button_padding_horizontal_material"
+ android:top="@dimen/button_padding_vertical_material"
+ android:right="@dimen/button_padding_horizontal_material"
+ android:bottom="@dimen/button_padding_vertical_material" />
+ </shape>
+ </item>
+ </ripple>
+</inset>
diff --git a/core/res/res/drawable/ic_audio_bt.xml b/core/res/res/drawable/ic_audio_bt.xml
deleted file mode 100644
index 4f5af3d..0000000
--- a/core/res/res/drawable/ic_audio_bt.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_audio_bt_alpha"
- android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_audio_bt_mute.xml b/core/res/res/drawable/ic_audio_bt_mute.xml
deleted file mode 100644
index d2004c0..0000000
--- a/core/res/res/drawable/ic_audio_bt_mute.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_audio_bt_mute_alpha"
- android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_audio_phone.xml b/core/res/res/drawable/ic_audio_phone.xml
deleted file mode 100644
index 1bab863..0000000
--- a/core/res/res/drawable/ic_audio_phone.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright 2013, 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.
- */
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_audio_phone_am_alpha"
- android:autoMirrored="true"
- android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8336058..07f8c60 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -423,6 +423,9 @@
point on the move. A value of 0 means no periodic scans will be used in the framework. -->
<integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer>
+ <!-- Integer indicating disconnect mode scan interval in milliseconds -->
+ <integer translatable="false" name="config_wifi_disconnected_scan_interval">15000</integer>
+
<!-- Integer indicating associated partial scan interval in milliseconds -->
<integer translatable="false" name="config_wifi_framework_associated_scan_interval">20000</integer>
@@ -472,6 +475,9 @@
<!-- Wifi driver supports batched scan -->
<bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
+ <!-- Wifi HAL supported PNO -->
+ <bool translatable="false" name="config_wifi_hal_pno_enable">false</bool>
+
<!-- Idle Receive current for wifi radio. 0 by default-->
<integer translatable="false" name="config_wifi_idle_receive_cur_ma">1</integer>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 282c80b..77b56ea 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2641,6 +2641,7 @@
<public type="style" name="Theme.Material.DayNight.Panel" />
<public type="style" name="Theme.Material.Light.LightStatusBar" />
<public type="style" name="ThemeOverlay.Material.Dialog" />
+ <public type="style" name="TextAppearance.Material.Widget.Button.Inverse" />
<public type="id" name="pasteAsPlainText" />
<public type="id" name="undo" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3d1fd7c..59366cc 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1323,6 +1323,108 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_use_sip">Allows the app to make and receive SIP calls.</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_register_sim_subscription">register new telecom SIM connections</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_register_sim_subscription">Allows the app to register new telecom SIM connections.</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_register_call_provider">register new telecom connections</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_register_call_provider">Allows the app to register new telecom connections.</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_connection_manager">manage telecom connections</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_connection_manager">Allows the app to manage telecom connections.</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_bind_incall_service">interact with in-call screen</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_bind_incall_service">Allows the app to control when and how the user sees the in-call screen.</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_bind_connection_service">interact with telephony services</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_bind_connection_service">Allows the app to interact with telephony services to make/receive calls.</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_control_incall_experience">provide an in-call user experience</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_control_incall_experience">Allows the app to provide an in-call user experience.</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_readNetworkUsageHistory">read historical network usage</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_readNetworkUsageHistory">Allows the app to read historical network usage for specific networks and apps.</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_manageNetworkPolicy">manage network policy</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_manageNetworkPolicy">Allows the app to manage network policies and define app-specific rules.</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_modifyNetworkAccounting">modify network usage accounting</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_modifyNetworkAccounting">Allows the app to modify how network usage is accounted against apps. Not for use by normal apps.</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_accessNotifications">access notifications</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_accessNotifications">Allows the app to retrieve, examine, and clear notifications, including those posted by other apps.</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_bindNotificationListenerService">bind to a notification listener service</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_bindNotificationListenerService">Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps.</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_bindConditionProviderService">bind to a condition provider service</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_bindConditionProviderService">Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps.</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_bindDreamService">bind to a dream service</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_bindDreamService">Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps.</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_invokeCarrierSetup">invoke the carrier-provided configuration app</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_invokeCarrierSetup">Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps.</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_accessNetworkConditions">listen for observations on network conditions</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_accessNetworkConditions">Allows an application to listen for observations on network conditions. Should never be needed for normal apps.</string>
+
+ <string name="permlab_setInputCalibration">change input device calibration</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_setInputCalibration">Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps.</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_accessDrmCertificates">access DRM certificates</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_accessDrmCertificates">Allows an application to provision and use DRM certficates. Should never be needed for normal apps.</string>
+
+ <string name="permlab_handoverStatus">Receive Android Beam transfer status</string>
+ <string name="permdesc_handoverStatus">Allows this application to receive information about current Android Beam transfers</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_removeDrmCertificates">remove DRM certificates</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_removeDrmCertificates">Allows an application to remove DRM certficates. Should never be needed for normal apps.</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_bindCarrierMessagingService">bind to a carrier messaging service</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_bindCarrierMessagingService">Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps.</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_bindCarrierConfigService">bind to a carrier config service</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_bindCarrierConfigService">Allows the holder to bind to a carrier config service. Should never be needed for normal apps.</string>
+
<!-- Policy administration -->
<!-- Title of policy access to limiting the user's password choices -->
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 88cac72..b874f63 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -289,6 +289,10 @@
<style name="TextAppearance.Material.Widget"/>
<style name="TextAppearance.Material.Widget.Button" parent="TextAppearance.Material.Button" />
+ <style name="TextAppearance.Material.Widget.Button.Inverse">
+ <item name="textColor">?attr/textColorPrimaryInverse</item>
+ </style>
+
<style name="TextAppearance.Material.Widget.EditText">
<item name="textColor">?attr/textColorPrimaryInverse</item>
<item name="textColorHint">?attr/textColorHintInverse</item>
@@ -461,7 +465,8 @@
<!-- Colored bordered ink button -->
<style name="Widget.Material.Button.Colored">
- <item name="backgroundTint">@color/btn_colored_material</item>
+ <item name="background">@drawable/btn_colored_material</item>
+ <item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Inverse</item>
</style>
<!-- Small bordered ink button -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ac8216e..180b415 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -378,7 +378,9 @@
<java-symbol type="integer" name="config_shortPressOnSleepBehavior" />
<java-symbol type="integer" name="config_wifi_framework_scan_interval" />
<java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
+ <java-symbol type="integer" name="config_wifi_disconnected_scan_interval" />
<java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
+ <java-symbol type="bool" name="config_wifi_hal_pno_enable" />
<java-symbol type="integer" name="db_connection_pool_size" />
<java-symbol type="integer" name="db_journal_size_limit" />
<java-symbol type="integer" name="db_wal_autocheckpoint" />
@@ -1163,13 +1165,10 @@
<java-symbol type="drawable" name="expander_open_holo_dark" />
<java-symbol type="drawable" name="ic_audio_alarm" />
<java-symbol type="drawable" name="ic_audio_alarm_mute" />
- <java-symbol type="drawable" name="ic_audio_bt" />
- <java-symbol type="drawable" name="ic_audio_bt_mute" />
<java-symbol type="drawable" name="ic_audio_media" />
<java-symbol type="drawable" name="ic_audio_media_mute" />
<java-symbol type="drawable" name="ic_audio_notification" />
<java-symbol type="drawable" name="ic_audio_notification_mute" />
- <java-symbol type="drawable" name="ic_audio_phone" />
<java-symbol type="drawable" name="ic_audio_ring_notif" />
<java-symbol type="drawable" name="ic_audio_ring_notif_mute" />
<java-symbol type="drawable" name="ic_audio_ring_notif_vibrate" />
diff --git a/docs/html/tools/help/hprof-conv.jd b/docs/html/tools/help/hprof-conv.jd
index f96def2..982f337 100644
--- a/docs/html/tools/help/hprof-conv.jd
+++ b/docs/html/tools/help/hprof-conv.jd
@@ -8,9 +8,13 @@
generated by the Android SDK tools to a standard format so you
can view the file in a profiling tool of your choice. </p>
-<pre> hprof-conv <infile> <outfile></pre>
+<pre> hprof-conv [-z] <infile> <outfile></pre>
<p>
You can use "-" for <code><infile></code> or <code><outfile></code>
to specify stdin or stdout.
</p>
+
+<p>
+You can use "-z" to filter out zygote allocations shared by all applications.
+</p>
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 7bc6378..37e00b2 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -547,18 +547,12 @@
if (mIvRequired) {
// IV is needed
if ((mIv == null) && (mEncrypting)) {
- // TODO: Switch to keymaster-generated IV code below once keymaster supports
- // that.
- // IV is needed but was not provided by the caller -- generate an IV.
- mIv = new byte[mBlockSizeBytes];
- SecureRandom rng = (mRng != null) ? mRng : new SecureRandom();
- rng.nextBytes(mIv);
-// // IV was not provided by the caller and thus will be generated by keymaster.
-// // Mix in some additional entropy from the provided SecureRandom.
-// if (mRng != null) {
-// mAdditionalEntropyForBegin = new byte[mBlockSizeBytes];
-// mRng.nextBytes(mAdditionalEntropyForBegin);
-// }
+ // IV was not provided by the caller and thus will be generated by keymaster.
+ // Mix in some additional entropy from the provided SecureRandom.
+ if (mRng != null) {
+ mAdditionalEntropyForBegin = new byte[mBlockSizeBytes];
+ mRng.nextBytes(mAdditionalEntropyForBegin);
+ }
}
}
}
diff --git a/media/java/android/media/DataSource.java b/media/java/android/media/DataSource.java
deleted file mode 100644
index 347bd5f..0000000
--- a/media/java/android/media/DataSource.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 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.media;
-
-import java.io.Closeable;
-
-/**
- * An abstraction for a media data source, e.g. a file or an http stream
- * {@hide}
- */
-public interface DataSource extends Closeable {
- /**
- * Reads data from the data source at the requested position
- *
- * @param offset where in the source to read
- * @param buffer the buffer to read the data into
- * @param size how many bytes to read
- * @return the number of bytes read, or -1 if there was an error
- */
- public int readAt(long offset, byte[] buffer, int size);
-
- /**
- * Gets the size of the data source.
- *
- * @return size of data source, or -1 if the length is unknown
- */
- public long getSize();
-}
diff --git a/media/java/android/media/MediaDataSource.java b/media/java/android/media/MediaDataSource.java
new file mode 100644
index 0000000..246c0ef
--- /dev/null
+++ b/media/java/android/media/MediaDataSource.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012 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.media;
+
+import java.io.Closeable;
+
+/**
+ * For supplying media data to the framework. Implement this if your app has
+ * special requirements for the way media data is obtained.
+ *
+ * <p class="note">Methods of this interface may be called on multiple different
+ * threads. There will be a thread synchronization point between each call to ensure that
+ * modifications to the state of your MediaDataSource are visible to future calls. This means
+ * you don't need to do your own synchronization unless you're modifying the
+ * MediaDataSource from another thread while it's being used by the framework.</p>
+ */
+public interface MediaDataSource extends Closeable {
+ /**
+ * Called to request data from the given position.
+ *
+ * Implementations should should write up to {@code size} bytes into
+ * {@code buffer}, and return the number of bytes written.
+ *
+ * Return {@code 0} to indicate that {@code position} is at, or beyond, the
+ * end of the source.
+ *
+ * Return {@code -1} to indicate that a fatal error occurred. The failed
+ * read will not be retried, so transient errors should be handled
+ * internally.
+ *
+ * Throwing an exception from this method will have the same effect as
+ * returning {@code -1}.
+ *
+ * @param position the position in the data source to read from.
+ * @param buffer the buffer to read the data into.
+ * @param size the number of bytes to read.
+ * @return the number of bytes read, or -1 if there was an error.
+ */
+ public int readAt(long position, byte[] buffer, int size);
+
+ /**
+ * Called to get the size of the data source.
+ *
+ * @return the size of data source in bytes, or -1 if the size is unknown.
+ */
+ public long getSize();
+}
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index b23b540..b4acbc0 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -66,10 +66,11 @@
}
/**
- * Sets the DataSource object to be used as the data source for this extractor
- * {@hide}
+ * Sets the data source (MediaDataSource) to use.
+ *
+ * @param dataSource the MediaDataSource for the media you want to extract from
*/
- public native final void setDataSource(DataSource source) throws IOException;
+ public native final void setDataSource(MediaDataSource dataSource) throws IllegalArgumentException, IOException;
/**
* Sets the data source as a content Uri.
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 9aa8003..a3ff080 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -203,7 +203,20 @@
}
/**
- * Call this method after setDataSource(). This method retrieves the
+ * Sets the data source (MediaDataSource) to use.
+ *
+ * @param dataSource the MediaDataSource for the media you want to play
+ */
+ public void setDataSource(MediaDataSource dataSource)
+ throws IllegalArgumentException {
+ _setDataSource(dataSource);
+ }
+
+ private native void _setDataSource(MediaDataSource dataSource)
+ throws IllegalArgumentException;
+
+ /**
+ * Call this method after setDataSource(). This method retrieves the
* meta data value associated with the keyCode.
*
* The keyCode currently supported is listed below as METADATA_XXX
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 83954ae..cb80bc4 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -181,7 +181,8 @@
* {@link #setDataSource(FileDescriptor)}, or
* {@link #setDataSource(String)}, or
* {@link #setDataSource(Context, Uri)}, or
- * {@link #setDataSource(FileDescriptor, long, long)} transfers a
+ * {@link #setDataSource(FileDescriptor, long, long)}, or
+ * {@link #setDataSource(MediaDataSource)} transfers a
* MediaPlayer object in the <em>Idle</em> state to the
* <em>Initialized</em> state.
* <ul>
@@ -1127,6 +1128,20 @@
throws IOException, IllegalArgumentException, IllegalStateException;
/**
+ * Sets the data source (MediaDataSource) to use.
+ *
+ * @param dataSource the MediaDataSource for the media you want to play
+ * @throws IllegalStateException if it is called in an invalid state
+ */
+ public void setDataSource(MediaDataSource dataSource)
+ throws IllegalArgumentException, IllegalStateException {
+ _setDataSource(dataSource);
+ }
+
+ private native void _setDataSource(MediaDataSource dataSource)
+ throws IllegalArgumentException, IllegalStateException;
+
+ /**
* Prepares the player for playback, synchronously.
*
* After setting the datasource and the display surface, you need to either
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 66d055a..c8464c7 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -7,6 +7,7 @@
android_media_MediaCrypto.cpp \
android_media_MediaCodec.cpp \
android_media_MediaCodecList.cpp \
+ android_media_MediaDataSource.cpp \
android_media_MediaDrm.cpp \
android_media_MediaExtractor.cpp \
android_media_MediaHTTPConnection.cpp \
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
new file mode 100644
index 0000000..1e6d2af
--- /dev/null
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2015, 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "JMediaDataSource-JNI"
+#include <utils/Log.h>
+
+#include "android_media_MediaDataSource.h"
+
+#include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include <binder/MemoryDealer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+namespace android {
+
+JMediaDataSource::JMediaDataSource(JNIEnv* env, jobject source)
+ : mJavaObjStatus(OK), mSizeIsCached(false), mCachedSize(0), mMemory(NULL) {
+ mMediaDataSourceObj = env->NewGlobalRef(source);
+ CHECK(mMediaDataSourceObj != NULL);
+
+ ScopedLocalRef<jclass> mediaDataSourceClass(env, env->GetObjectClass(mMediaDataSourceObj));
+ CHECK(mediaDataSourceClass.get() != NULL);
+
+ mReadMethod = env->GetMethodID(mediaDataSourceClass.get(), "readAt", "(J[BI)I");
+ CHECK(mReadMethod != NULL);
+ mGetSizeMethod = env->GetMethodID(mediaDataSourceClass.get(), "getSize", "()J");
+ CHECK(mGetSizeMethod != NULL);
+ mCloseMethod = env->GetMethodID(mediaDataSourceClass.get(), "close", "()V");
+ CHECK(mCloseMethod != NULL);
+
+ ScopedLocalRef<jbyteArray> tmp(env, env->NewByteArray(kBufferSize));
+ mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
+ CHECK(mByteArrayObj != NULL);
+
+ sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "JMediaDataSource");
+ mMemory = memoryDealer->allocate(kBufferSize);
+ if (mMemory == NULL) {
+ ALOGE("Failed to allocate memory!");
+ }
+}
+
+JMediaDataSource::~JMediaDataSource() {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->DeleteGlobalRef(mMediaDataSourceObj);
+ env->DeleteGlobalRef(mByteArrayObj);
+}
+
+sp<IMemory> JMediaDataSource::getIMemory() {
+ Mutex::Autolock lock(mLock);
+ return mMemory;
+}
+
+ssize_t JMediaDataSource::readAt(off64_t offset, size_t size) {
+ Mutex::Autolock lock(mLock);
+
+ if (mJavaObjStatus != OK || mMemory == NULL) {
+ return -1;
+ }
+ if (size > kBufferSize) {
+ size = kBufferSize;
+ }
+
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ jint numread = env->CallIntMethod(mMediaDataSourceObj, mReadMethod,
+ (jlong)offset, mByteArrayObj, (jint)size);
+ if (env->ExceptionCheck()) {
+ ALOGW("An exception occurred in readAt()");
+ LOGW_EX(env);
+ env->ExceptionClear();
+ mJavaObjStatus = UNKNOWN_ERROR;
+ return -1;
+ }
+ if (numread < 0) {
+ ALOGW("An error occurred in readAt()");
+ mJavaObjStatus = UNKNOWN_ERROR;
+ return -1;
+ }
+ if ((size_t)numread > size) {
+ ALOGE("readAt read too many bytes.");
+ mJavaObjStatus = UNKNOWN_ERROR;
+ return -1;
+ }
+
+ ALOGV("readAt %lld / %zu => %d.", (long long)offset, size, numread);
+ env->GetByteArrayRegion(mByteArrayObj, 0, numread, (jbyte*)mMemory->pointer());
+ return numread;
+}
+
+status_t JMediaDataSource::getSize(off64_t* size) {
+ Mutex::Autolock lock(mLock);
+
+ if (mJavaObjStatus != OK) {
+ return UNKNOWN_ERROR;
+ }
+ if (mSizeIsCached) {
+ return mCachedSize;
+ }
+
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ *size = env->CallLongMethod(mMediaDataSourceObj, mGetSizeMethod);
+ if (env->ExceptionCheck()) {
+ ALOGW("An exception occurred in getSize()");
+ LOGW_EX(env);
+ env->ExceptionClear();
+ // After returning an error, size shouldn't be used by callers.
+ *size = UNKNOWN_ERROR;
+ mJavaObjStatus = UNKNOWN_ERROR;
+ return UNKNOWN_ERROR;
+ }
+
+ // The minimum size should be -1, which indicates unknown size.
+ if (*size < 0) {
+ *size = -1;
+ }
+
+ mCachedSize = *size;
+ mSizeIsCached = true;
+ return OK;
+}
+
+void JMediaDataSource::close() {
+ Mutex::Autolock lock(mLock);
+
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mMediaDataSourceObj, mCloseMethod);
+ // The closed state is effectively the same as an error state.
+ mJavaObjStatus = UNKNOWN_ERROR;
+}
+
+} // namespace android
diff --git a/media/jni/android_media_MediaDataSource.h b/media/jni/android_media_MediaDataSource.h
new file mode 100644
index 0000000..2bc237e
--- /dev/null
+++ b/media/jni/android_media_MediaDataSource.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2015, 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.
+ */
+
+#ifndef _ANDROID_MEDIA_MEDIADATASOURCE_H_
+#define _ANDROID_MEDIA_MEDIADATASOURCE_H_
+
+#include "jni.h"
+
+#include <media/IDataSource.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+// The native counterpart to a Java android.media.MediaDataSource. It inherits from
+// IDataSource so that it can be accessed remotely.
+//
+// If the java DataSource returns an error or throws an exception it
+// will be considered to be in a broken state, and the only further call this
+// will make is to close().
+class JMediaDataSource : public BnDataSource {
+public:
+ enum {
+ kBufferSize = 64 * 1024,
+ };
+
+ JMediaDataSource(JNIEnv *env, jobject source);
+ virtual ~JMediaDataSource();
+
+ virtual sp<IMemory> getIMemory();
+ virtual ssize_t readAt(off64_t offset, size_t size);
+ virtual status_t getSize(off64_t* size);
+ virtual void close();
+
+private:
+ // Protect all member variables with mLock because this object will be
+ // accessed on different binder worker threads.
+ Mutex mLock;
+
+ // The status of the java DataSource. Set to OK unless an error occurred or
+ // close() was called.
+ status_t mJavaObjStatus;
+ // Only call the java getSize() once so the app can't change the size on us.
+ bool mSizeIsCached;
+ off64_t mCachedSize;
+ sp<IMemory> mMemory;
+
+ jobject mMediaDataSourceObj;
+ jmethodID mReadMethod;
+ jmethodID mGetSizeMethod;
+ jmethodID mCloseMethod;
+ jbyteArray mByteArrayObj;
+
+ DISALLOW_EVIL_CONSTRUCTORS(JMediaDataSource);
+};
+
+} // namespace android
+
+#endif // _ANDROID_MEDIA_MEDIADATASOURCE_H_
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index c0795b6..b6b7a80 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -25,6 +25,7 @@
#include "android_runtime/Log.h"
#include "jni.h"
#include "JNIHelp.h"
+#include "android_media_MediaDataSource.h"
#include <media/IMediaHTTPService.h>
#include <media/hardware/CryptoAPI.h>
@@ -50,74 +51,6 @@
static fields_t gFields;
-class JavaDataSourceBridge : public DataSource {
- jmethodID mReadMethod;
- jmethodID mGetSizeMethod;
- jmethodID mCloseMethod;
- jobject mDataSource;
- public:
- JavaDataSourceBridge(JNIEnv *env, jobject source) {
- mDataSource = env->NewGlobalRef(source);
-
- jclass datasourceclass = env->GetObjectClass(mDataSource);
- CHECK(datasourceclass != NULL);
-
- mReadMethod = env->GetMethodID(datasourceclass, "readAt", "(J[BI)I");
- CHECK(mReadMethod != NULL);
-
- mGetSizeMethod = env->GetMethodID(datasourceclass, "getSize", "()J");
- CHECK(mGetSizeMethod != NULL);
-
- mCloseMethod = env->GetMethodID(datasourceclass, "close", "()V");
- CHECK(mCloseMethod != NULL);
- }
-
- ~JavaDataSourceBridge() {
- JNIEnv *env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mDataSource, mCloseMethod);
- env->DeleteGlobalRef(mDataSource);
- }
-
- virtual status_t initCheck() const {
- return OK;
- }
-
- virtual ssize_t readAt(off64_t offset, void* buffer, size_t size) {
- JNIEnv *env = AndroidRuntime::getJNIEnv();
-
- // XXX could optimize this by reusing the same array
- jbyteArray byteArrayObj = env->NewByteArray(size);
- env->DeleteLocalRef(env->GetObjectClass(mDataSource));
- env->DeleteLocalRef(env->GetObjectClass(byteArrayObj));
- ssize_t numread = env->CallIntMethod(mDataSource, mReadMethod, offset, byteArrayObj, (jint)size);
- env->GetByteArrayRegion(byteArrayObj, 0, size, (jbyte*) buffer);
- env->DeleteLocalRef(byteArrayObj);
- if (env->ExceptionCheck()) {
- ALOGW("Exception occurred while reading %zu at %lld", size, (long long)offset);
- LOGW_EX(env);
- env->ExceptionClear();
- return -1;
- }
- return numread;
- }
-
- virtual status_t getSize(off64_t *size) {
- JNIEnv *env = AndroidRuntime::getJNIEnv();
-
- CHECK(size != NULL);
-
- int64_t len = env->CallLongMethod(mDataSource, mGetSizeMethod);
- if (len < 0) {
- *size = ERROR_UNSUPPORTED;
- } else {
- *size = len;
- }
- return OK;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
JMediaExtractor::JMediaExtractor(JNIEnv *env, jobject thiz)
: mClass(NULL),
mObject(NULL) {
@@ -777,7 +710,8 @@
return;
}
- sp<JavaDataSourceBridge> bridge = new JavaDataSourceBridge(env, callbackObj);
+ sp<DataSource> bridge =
+ DataSource::CreateFromIDataSource(new JMediaDataSource(env, callbackObj));
status_t err = extractor->setDataSource(bridge);
if (err != OK) {
@@ -881,7 +815,7 @@
{ "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
(void *)android_media_MediaExtractor_setDataSourceFd },
- { "setDataSource", "(Landroid/media/DataSource;)V",
+ { "setDataSource", "(Landroid/media/MediaDataSource;)V",
(void *)android_media_MediaExtractor_setDataSourceCallback },
{ "getCachedDuration", "()J",
diff --git a/media/jni/android_media_MediaHTTPConnection.cpp b/media/jni/android_media_MediaHTTPConnection.cpp
index 7226ef5..393003d 100644
--- a/media/jni/android_media_MediaHTTPConnection.cpp
+++ b/media/jni/android_media_MediaHTTPConnection.cpp
@@ -134,7 +134,6 @@
static jint android_media_MediaHTTPConnection_native_readAt(
JNIEnv *env, jobject thiz, jlong offset, jint size) {
sp<JMediaHTTPConnection> conn = getObject(env, thiz);
-
if (size > JMediaHTTPConnection::kBufferSize) {
size = JMediaHTTPConnection::kBufferSize;
}
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index c6fa379..59fb6d6 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -30,6 +30,7 @@
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
+#include "android_media_MediaDataSource.h"
#include "android_media_Utils.h"
#include "android_util_Binder.h"
@@ -171,6 +172,23 @@
process_media_retriever_call(env, retriever->setDataSource(fd, offset, length), "java/lang/RuntimeException", "setDataSource failed");
}
+static void android_media_MediaMetadataRetriever_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
+{
+ ALOGV("setDataSourceCallback");
+ MediaMetadataRetriever* retriever = getRetriever(env, thiz);
+ if (retriever == 0) {
+ jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
+ return;
+ }
+ if (dataSource == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+
+ sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
+ process_media_retriever_call(env, retriever->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed");
+}
+
template<typename T>
static void rotate0(T* dst, const T* src, size_t width, size_t height)
{
@@ -457,6 +475,7 @@
},
{"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD},
+ {"_setDataSource", "(Landroid/media/MediaDataSource;)V", (void *)android_media_MediaMetadataRetriever_setDataSourceCallback},
{"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime},
{"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata},
{"getEmbeddedPicture", "(I)[B", (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture},
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 3e41716..c247220 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -36,6 +36,7 @@
#include "utils/Errors.h" // for status_t
#include "utils/KeyedVector.h"
#include "utils/String8.h"
+#include "android_media_MediaDataSource.h"
#include "android_media_Utils.h"
#include "android_os_Parcel.h"
@@ -251,6 +252,23 @@
process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
}
+static void
+android_media_MediaPlayer_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
+{
+ sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+ if (mp == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ if (dataSource == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+ sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
+ process_media_player_call(env, thiz, mp->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed." );
+}
+
static sp<IGraphicBufferProducer>
getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetLongField(thiz, fields.surface_texture);
@@ -871,7 +889,8 @@
(void *)android_media_MediaPlayer_setDataSourceAndHeaders
},
- {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
+ {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
+ {"_setDataSource", "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
{"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
{"_prepare", "()V", (void *)android_media_MediaPlayer_prepare},
{"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
index d2ef3d7..a9f03b6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
@@ -191,7 +191,8 @@
cancelIntent.putExtra(EXTRA_CANCEL, mJobId);
mProgressBuilder.addAction(R.drawable.ic_cab_cancel,
getString(android.R.string.cancel), PendingIntent.getService(this, 0,
- cancelIntent, PendingIntent.FLAG_ONE_SHOT));
+ cancelIntent,
+ PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT));
// Send an initial progress notification.
mProgressBuilder.setProgress(0, 0, true); // Indeterminate progress while setting up.
diff --git a/packages/SystemUI/res/drawable/ic_audio_alarm.xml b/packages/SystemUI/res/drawable/ic_audio_alarm.xml
deleted file mode 100644
index 91010a3..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_alarm.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28.0dp"
- android:height="28.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#ffffffff"
- android:pathData="M44.0,11.44l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-28.24,-4.66l-2.57,-3.06 -9.19,7.71 2.57,3.06 9.19,-7.71zm9.24,9.22l-3.0,0.0l0.0,12.0l9.49,5.71 1.51,-2.47 -8.0,-4.74l0.0,-10.5zm-1.01,-8.0c-9.95,0.0 -17.99,8.06 -17.99,18.0s8.04,18.0 17.99,18.0 18.01,-8.06 18.01,-18.0 -8.06,-18.0 -18.01,-18.0zm0.01,32.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.26,14.0 -14.0,14.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_alarm_mute.xml b/packages/SystemUI/res/drawable/ic_audio_alarm_mute.xml
deleted file mode 100644
index dd124d7..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_alarm_mute.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28.0dp"
- android:height="28.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#ffffffff"
- android:pathData="M24.0,12.0c7.73,0.0 14.0,6.27 14.0,14.0 0.0,1.69 -0.31,3.3 -0.86,4.8l3.04,3.04c1.16,-2.37 1.82,-5.03 1.82,-7.84 0.0,-9.94 -8.06,-18.0 -18.01,-18.0 -2.81,0.0 -5.46,0.66 -7.84,1.81l3.05,3.05c1.5,-0.55 3.11,-0.86 4.8,-0.86zm20.0,-0.56l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-38.16,-6.85l-2.55,2.54 2.66,2.66 -2.22,1.86 2.84,2.84 2.22,-1.86 1.6,1.6c-2.73,3.16 -4.39,7.27 -4.39,11.77 0.0,9.94 8.04,18.0 17.99,18.0 4.51,0.0 8.62,-1.67 11.77,-4.4l4.4,4.4 2.54,-2.55 -34.91,-34.91 -1.95,-1.95zm27.1,32.19c-2.43,2.01 -5.54,3.22 -8.94,3.22 -7.73,0.0 -14.0,-6.27 -14.0,-14.0 0.0,-3.4 1.21,-6.51 3.22,-8.94l19.72,19.72zm-16.91,-30.23l-2.84,-2.84 -1.7,1.43 2.84,2.84 1.7,-1.43z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_bt.xml b/packages/SystemUI/res/drawable/ic_audio_bt.xml
deleted file mode 100644
index c0da519..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_bt.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_bt_mute.xml b/packages/SystemUI/res/drawable/ic_audio_bt_mute.xml
deleted file mode 100644
index 718eee5..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_bt_mute.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M26.0,11.8l3.8,3.8l-3.2,3.2l2.8,2.8l6.0,-6.0L24.0,4.2l-2.0,0.0l0.0,10.1l4.0,4.0L26.0,11.8zM10.8,8.2L8.0,11.0l13.2,13.2L10.0,35.3l2.8,2.8L22.0,29.0l0.0,15.2l2.0,0.0l8.6,-8.6l4.6,4.6l2.8,-2.8L10.8,8.2zM26.0,36.5L26.0,29.0l3.8,3.8L26.0,36.5z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_remote.xml b/packages/SystemUI/res/drawable/ic_audio_remote.xml
deleted file mode 100644
index 762878b..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_remote.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_vol.xml b/packages/SystemUI/res/drawable/ic_audio_vol.xml
deleted file mode 100644
index 587ea89..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_vol.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28.0dp"
- android:height="28.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#ffffffff"
- android:pathData="M6.0,18.0l0.0,12.0l8.0,0.0l10.0,10.0L24.0,8.0L14.0,18.0L6.0,18.0zm27.0,6.0c0.0,-3.53 -2.04,-6.58 -5.0,-8.05l0.0,16.11c2.96,-1.48 5.0,-4.53 5.0,-8.06zM28.0,6.46l0.0,4.13c5.78,1.72 10.0,7.07 10.0,13.41s-4.22,11.69 -10.0,13.41l0.0,4.13c8.01,-1.82 14.0,-8.97 14.0,-17.54S36.01,8.28 28.0,6.46z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_vol_mute.xml b/packages/SystemUI/res/drawable/ic_audio_vol_mute.xml
deleted file mode 100644
index 8a7c7ec..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_vol_mute.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28.0dp"
- android:height="28.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#ffffffff"
- android:pathData="M33.0,24.0c0.0,-3.53 -2.04,-6.58 -5.0,-8.05l0.0,4.42l4.91,4.91c0.06,-0.42 0.09,-0.85 0.09,-1.28zm5.0,0.0c0.0,1.88 -0.41,3.65 -1.08,5.28l3.03,3.03C41.25,29.82 42.0,27.0 42.0,24.0c0.0,-8.56 -5.99,-15.72 -14.0,-17.54l0.0,4.13c5.78,1.72 10.0,7.07 10.0,13.41zM8.55,6.0L6.0,8.55 15.45,18.0L6.0,18.0l0.0,12.0l8.0,0.0l10.0,10.0L24.0,26.55l8.51,8.51c-1.34,1.03 -2.85,1.86 -4.51,2.36l0.0,4.13c2.75,-0.63 5.26,-1.89 7.37,-3.62L39.45,42.0 42.0,39.45l-18.0,-18.0L8.55,6.0zM24.0,8.0l-4.18,4.18L24.0,16.36L24.0,8.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_ringer_audible.xml
deleted file mode 100644
index fd50617..0000000
--- a/packages/SystemUI/res/drawable/ic_ringer_audible.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_mute.xml b/packages/SystemUI/res/drawable/ic_ringer_mute.xml
deleted file mode 100644
index b29a139..0000000
--- a/packages/SystemUI/res/drawable/ic_ringer_mute.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M23.000000,44.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000l-8.000000,0.000000C19.000000,42.200001 20.799999,44.000000 23.000000,44.000000zM36.000000,21.000000c0.000000,-6.100000 -4.300000,-11.300000 -10.000000,-12.600000L26.000000,7.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,1.400000c-1.000000,0.200000 -2.000000,0.600000 -2.900000,1.100000L36.000000,28.400000L36.000000,21.000000zM35.500000,38.000000l4.000000,4.000000l2.500000,-2.500000L8.500000,6.000000L6.000000,8.500000l5.800000,5.800000C10.700000,16.299999 10.000000,18.600000 10.000000,21.000000l0.000000,11.000000l-4.000000,4.000000l0.000000,2.000000L35.500000,38.000000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml
deleted file mode 100644
index 4bff96d..0000000
--- a/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/layout/volume_panel.xml b/packages/SystemUI/res/layout/volume_panel.xml
deleted file mode 100644
index 4d8aaa7..0000000
--- a/packages/SystemUI/res/layout/volume_panel.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/visible_panel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
-
- <FrameLayout
- android:id="@+id/slider_panel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/system_secondary_color"
- android:paddingTop="8dp"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:clipChildren="false" />
-
- <include
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- layout="@layout/zen_mode_panel" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_panel_dialog.xml b/packages/SystemUI/res/layout/volume_panel_dialog.xml
deleted file mode 100644
index 700102f..0000000
--- a/packages/SystemUI/res/layout/volume_panel_dialog.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
- Copyright (C) 2015 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.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/volume_panel_z"
- android:layout_marginLeft="@dimen/notification_side_padding"
- android:layout_marginRight="@dimen/notification_side_padding"
- android:background="@drawable/qs_background_primary"
- android:translationZ="@dimen/volume_panel_z" >
-
- <include layout="@layout/volume_panel" />
-
-</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_panel_item.xml b/packages/SystemUI/res/layout/volume_panel_item.xml
deleted file mode 100644
index dad68c3..0000000
--- a/packages/SystemUI/res/layout/volume_panel_item.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:clipChildren="false"
- android:gravity="start|center_vertical"
- android:orientation="horizontal" >
-
- <ImageView
- android:id="@+id/stream_icon"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:scaleType="center"
- android:background="@drawable/btn_borderless_rect"
- android:contentDescription="@null" />
-
- <FrameLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/suppressor"
- android:visibility="gone"
- android:textAppearance="@style/TextAppearance.QS.VolumeSuppressor"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <SeekBar
- android:id="@+id/seekbar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="0dp"
- android:paddingEnd="16dp"
- android:paddingStart="8dp"
- android:paddingTop="0dp" />
-
- </FrameLayout>
-
- <View
- android:id="@+id/divider"
- android:layout_width="1dp"
- android:layout_height="32dp"
- android:layout_marginLeft="8dp"
- android:layout_marginRight="8dp"
- android:background="@color/volume_panel_divider" />
-
- <ImageView
- android:id="@+id/secondary_icon"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:scaleType="center"
- android:background="@drawable/btn_borderless_rect"
- android:contentDescription="@null" />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index d829f0e..b676bce 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -126,7 +126,7 @@
android:lineSpacingMultiplier="1.20029"
android:layout_toStartOf="@id/zen_introduction_confirm"
android:text="@string/zen_priority_introduction"
- android:textAppearance="@style/TextAppearance.QS.VolumeSuppressor" />
+ android:textAppearance="@style/TextAppearance.QS.Introduction" />
<TextView
android:id="@+id/zen_introduction_customize"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 88d1769..1f1455a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -129,7 +129,6 @@
<color name="segmented_button_selected">#FFFFFFFF</color>
<color name="segmented_button_unselected">#B3B0BEC5</color><!-- 70% blue grey 200 -->
- <color name="volume_panel_divider">#1FFFFFFF</color><!-- 12% white -->
<color name="dark_mode_icon_color_single_tone">#99000000</color>
<color name="dark_mode_icon_color_dual_tone_background">#3d000000</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 88bf58a..2e44547 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -276,9 +276,6 @@
<!-- Doze: alpha to apply to small icons when dozing -->
<integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff -->
- <!-- Volume: time to delay dismissing the volume panel after a click is performed -->
- <integer name="volume_panel_dismiss_delay">200</integer>
-
<!-- Hotspot tile: number of days to show after feature is used. -->
<integer name="days_to_show_hotspot_tile">30</integer>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 9e084a0..7e50454 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -344,15 +344,6 @@
<!-- The chevron padding to the circle when hinting -->
<dimen name="hint_chevron_circle_padding">16dp</dimen>
- <!-- Volume panel dialog y offset -->
- <dimen name="volume_panel_top">0dp</dimen>
-
- <!-- Volume panel dialog width -->
- <dimen name="volume_panel_width">344dp</dimen>
-
- <!-- Volume panel z depth -->
- <dimen name="volume_panel_z">3dp</dimen>
-
<!-- Distance between notifications and header when they are considered to be colliding. -->
<dimen name="header_notifications_collide_distance">48dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 87f9ca2..ef2e6f3 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -138,9 +138,8 @@
<item name="android:textColor">@color/system_accent_color</item>
</style>
- <style name="TextAppearance.QS.VolumeSuppressor">
+ <style name="TextAppearance.QS.Introduction">
<item name="android:textSize">14sp</item>
- <item name="android:textColor">@color/qs_tile_text</item>
</style>
<style name="TextAppearance.QS.DetailButton">
@@ -228,12 +227,6 @@
<item name="android:gravity">center</item>
</style>
- <!-- Window animations used for volume panel. -->
- <style name="VolumePanelAnimation">
- <item name="android:windowEnterAnimation">@*android:anim/popup_enter_material</item>
- <item name="android:windowExitAnimation">@*android:anim/popup_exit_material</item>
- </style>
-
<style name="TextAppearance.Material.Notification.Parenthetical"
parent="@*android:style/TextAppearance.Material.Notification">
<item name="android:textStyle">italic</item>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 33a07d9..cb8217e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -62,7 +62,7 @@
private boolean mShowingPublic;
private boolean mSensitive;
private boolean mShowingPublicInitialized;
- private boolean mShowingPublicForIntrinsicHeight;
+ private boolean mHideSensitiveForIntrinsicHeight;
/**
* Is this notification expanded by the system. The expansion state can be overridden by the
@@ -570,13 +570,15 @@
}
boolean inExpansionState = isExpanded();
int maxContentHeight;
- if (mIsHeadsUp) {
+ if (mSensitive && mHideSensitiveForIntrinsicHeight) {
+ return mRowMinHeight;
+ } else if (mIsHeadsUp) {
if (inExpansionState) {
maxContentHeight = Math.max(mMaxExpandHeight, mHeadsUpHeight);
} else {
maxContentHeight = Math.max(mRowMinHeight, mHeadsUpHeight);
}
- } else if ((!inExpansionState && !mChildrenExpanded) || mShowingPublicForIntrinsicHeight) {
+ } else if ((!inExpansionState && !mChildrenExpanded)) {
maxContentHeight = mRowMinHeight;
} else if (mChildrenExpanded) {
maxContentHeight = mChildrenContainer.getIntrinsicHeight();
@@ -661,7 +663,7 @@
}
public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
- mShowingPublicForIntrinsicHeight = mSensitive && hideSensitive;
+ mHideSensitiveForIntrinsicHeight = hideSensitive;
}
public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
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 61e679a..a5dad92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1116,11 +1116,12 @@
if (shadeEntry == null) {
return;
}
- if (mUseHeadsUp && shouldInterrupt(notification)) {
+ boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(notification);
+ if (isHeadsUped) {
mHeadsUpManager.showNotification(shadeEntry);
}
- if (notification.getNotification().fullScreenIntent != null) {
+ if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
// Stop screensaver if the notification has a full-screen intent.
// (like an incoming phone call)
awakenDreams();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 920a0a1..dccf2e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -464,15 +464,21 @@
public void updateEntry() {
long currentTime = mClock.currentTimeMillis();
- postTime = Math.max(postTime, currentTime);
- long finishTime = postTime + mHeadsUpNotificationDecay;
- long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
earliestRemovaltime = currentTime + mMinimumDisplayTime;
+ postTime = Math.max(postTime, currentTime);
removeAutoCancelCallbacks();
- mHandler.postDelayed(mRemoveHeadsUpRunnable, removeDelay);
+ if (canEntryDecay()) {
+ long finishTime = postTime + mHeadsUpNotificationDecay;
+ long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
+ mHandler.postDelayed(mRemoveHeadsUpRunnable, removeDelay);
+ }
updateSortOrder(HeadsUpEntry.this);
}
+ private boolean canEntryDecay() {
+ return entry.notification.getNotification().fullScreenIntent == null;
+ }
+
@Override
public int compareTo(HeadsUpEntry o) {
return postTime < o.postTime ? 1
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index f247488..88fc602 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -220,7 +220,6 @@
private PhoneStatusBar mPhoneStatusBar;
private int[] mTempInt2 = new int[2];
private boolean mGenerateChildOrderChangedEvent;
- private boolean mRemoveAnimationEnabled;
private HashSet<Runnable> mAnimationFinishedRunnables = new HashSet<>();
private HashSet<Pair<ExpandableNotificationRow, Boolean>> mHeadsUpChangeAnimations
= new HashSet<>();
@@ -1630,16 +1629,11 @@
((ExpandableView) child).setOnHeightChangedListener(null);
mCurrentStackScrollState.removeViewStateForView(child);
updateScrollStateForRemovedChild(child);
- if (mRemoveAnimationEnabled) {
- boolean animationGenerated = generateRemoveAnimation(child);
- if (animationGenerated && !mSwipedOutViews.contains(child)) {
- // Add this view to an overlay in order to ensure that it will still be temporary
- // drawn when removed
- getOverlay().add(child);
- }
- } else {
- // TODO: handle this more cleanly when HEADS-up and the shade are merged
- requestAnimateEverything();
+ boolean animationGenerated = generateRemoveAnimation(child);
+ if (animationGenerated && !mSwipedOutViews.contains(child)) {
+ // Add this view to an overlay in order to ensure that it will still be temporary
+ // drawn when removed
+ getOverlay().add(child);
}
updateAnimationState(false, child);
@@ -2631,10 +2625,6 @@
return touchY > mIntrinsicPadding;
}
- public void setRemoveAnimationEnabled(boolean enabled) {
- mRemoveAnimationEnabled = enabled;
- }
-
private void updateExpandButtons() {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
deleted file mode 100644
index 45cb4a1..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*
- * 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 com.android.systemui.volume;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.ColorDrawable;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.media.AudioSystem;
-import android.media.RingtoneManager;
-import android.media.ToneGenerator;
-import android.media.VolumeProvider;
-import android.media.session.MediaController;
-import android.media.session.MediaController.PlaybackInfo;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Vibrator;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.systemui.DemoMode;
-import com.android.systemui.statusbar.policy.ZenModeController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Handles the user interface for the volume keys.
- *
- * @hide
- */
-public class VolumePanel extends Handler implements DemoMode {
- private static final String TAG = "VolumePanel";
- private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
-
- private static final int PLAY_SOUND_DELAY = AudioSystem.PLAY_SOUND_DELAY;
-
- /**
- * The delay before vibrating. This small period exists so if the user is
- * moving to silent mode, it will not emit a short vibrate (it normally
- * would since vibrate is between normal mode and silent mode using hardware
- * keys).
- */
- public static final int VIBRATE_DELAY = 300;
-
- private static final int VIBRATE_DURATION = 300;
- private static final int BEEP_DURATION = 150;
- private static final int MAX_VOLUME = 100;
- private static final int FREE_DELAY = 10000;
- private static final int TIMEOUT_DELAY = 3000;
- private static final int TIMEOUT_DELAY_SHORT = 1500;
- private static final int TIMEOUT_DELAY_COLLAPSED = 4500;
- private static final int TIMEOUT_DELAY_SAFETY_WARNING = 5000;
- private static final int TIMEOUT_DELAY_EXPANDED = 10000;
-
- private static final int MSG_VOLUME_CHANGED = 0;
- private static final int MSG_FREE_RESOURCES = 1;
- private static final int MSG_PLAY_SOUND = 2;
- private static final int MSG_STOP_SOUNDS = 3;
- private static final int MSG_VIBRATE = 4;
- private static final int MSG_TIMEOUT = 5;
- private static final int MSG_RINGER_MODE_CHANGED = 6;
- private static final int MSG_MUTE_CHANGED = 7;
- private static final int MSG_REMOTE_VOLUME_CHANGED = 8;
- private static final int MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN = 9;
- private static final int MSG_SLIDER_VISIBILITY_CHANGED = 10;
- private static final int MSG_DISPLAY_SAFE_VOLUME_WARNING = 11;
- private static final int MSG_LAYOUT_DIRECTION = 12;
- private static final int MSG_ZEN_MODE_AVAILABLE_CHANGED = 13;
- private static final int MSG_USER_ACTIVITY = 14;
- private static final int MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED = 15;
- private static final int MSG_INTERNAL_RINGER_MODE_CHANGED = 16;
-
- // Pseudo stream type for remote volume
- private static final int STREAM_REMOTE_MUSIC = -200;
-
- private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
- .build();
-
- private static final int IC_AUDIO_VOL = com.android.systemui.R.drawable.ic_audio_vol;
- private static final int IC_AUDIO_VOL_MUTE = com.android.systemui.R.drawable.ic_audio_vol_mute;
- private static final int IC_AUDIO_BT = com.android.systemui.R.drawable.ic_audio_bt;
- private static final int IC_AUDIO_BT_MUTE = com.android.systemui.R.drawable.ic_audio_bt_mute;
-
- private final String mTag;
- protected final Context mContext;
- private final AudioManager mAudioManager;
- private final ZenModeController mZenController;
- private boolean mRingIsSilent;
- private boolean mVoiceCapable;
- private boolean mZenModeAvailable;
- private boolean mZenPanelExpanded;
- private int mTimeoutDelay = TIMEOUT_DELAY;
- private float mDisabledAlpha;
- private int mLastRingerMode = AudioManager.RINGER_MODE_NORMAL;
- private int mLastRingerProgress = 0;
- private int mDemoIcon;
-
- /** Volume panel content view */
- private final View mView;
- /** Dialog hosting the panel */
- private final Dialog mDialog;
-
- /** The visible portion of the volume overlay */
- private final ViewGroup mPanel;
- /** Contains the slider and its touchable icons */
- private final ViewGroup mSliderPanel;
- /** The zen mode configuration panel view */
- private ZenModePanel mZenPanel;
- /** The component currently suppressing notification stream effects */
- private ComponentName mNotificationEffectsSuppressor;
-
- private Callback mCallback;
-
- /** Currently active stream that shows up at the top of the list of sliders */
- private int mActiveStreamType = -1;
- /** All the slider controls mapped by stream type */
- private SparseArray<StreamControl> mStreamControls;
- private final AccessibilityManager mAccessibilityManager;
- private final SecondaryIconTransition mSecondaryIconTransition;
- private final IconPulser mIconPulser;
-
- private enum StreamResources {
- BluetoothSCOStream(AudioManager.STREAM_BLUETOOTH_SCO,
- R.string.volume_icon_description_bluetooth,
- IC_AUDIO_BT,
- IC_AUDIO_BT_MUTE,
- false),
- RingerStream(AudioManager.STREAM_RING,
- R.string.volume_icon_description_ringer,
- com.android.systemui.R.drawable.ic_ringer_audible,
- com.android.systemui.R.drawable.ic_ringer_mute,
- false),
- VoiceStream(AudioManager.STREAM_VOICE_CALL,
- R.string.volume_icon_description_incall,
- com.android.systemui.R.drawable.ic_audio_phone,
- com.android.systemui.R.drawable.ic_audio_phone,
- false),
- AlarmStream(AudioManager.STREAM_ALARM,
- R.string.volume_alarm,
- com.android.systemui.R.drawable.ic_audio_alarm,
- com.android.systemui.R.drawable.ic_audio_alarm_mute,
- false),
- MediaStream(AudioManager.STREAM_MUSIC,
- R.string.volume_icon_description_media,
- IC_AUDIO_VOL,
- IC_AUDIO_VOL_MUTE,
- true),
- NotificationStream(AudioManager.STREAM_NOTIFICATION,
- R.string.volume_icon_description_notification,
- com.android.systemui.R.drawable.ic_ringer_audible,
- com.android.systemui.R.drawable.ic_ringer_mute,
- true),
- RemoteStream(STREAM_REMOTE_MUSIC,
- R.string.volume_icon_description_media, //FIXME should have its own description
- com.android.systemui.R.drawable.ic_audio_remote,
- com.android.systemui.R.drawable.ic_audio_remote,
- false);// will be dynamically updated
-
- int streamType;
- int descRes;
- int iconRes;
- int iconMuteRes;
- // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly requested
- boolean show;
-
- StreamResources(int streamType, int descRes, int iconRes, int iconMuteRes, boolean show) {
- this.streamType = streamType;
- this.descRes = descRes;
- this.iconRes = iconRes;
- this.iconMuteRes = iconMuteRes;
- this.show = show;
- }
- }
-
- // List of stream types and their order
- private static final StreamResources[] STREAMS = {
- StreamResources.BluetoothSCOStream,
- StreamResources.RingerStream,
- StreamResources.VoiceStream,
- StreamResources.MediaStream,
- StreamResources.NotificationStream,
- StreamResources.AlarmStream,
- StreamResources.RemoteStream
- };
-
- /** Object that contains data for each slider */
- private class StreamControl {
- int streamType;
- MediaController controller;
- ViewGroup group;
- ImageView icon;
- SeekBar seekbarView;
- TextView suppressorView;
- View divider;
- ImageView secondaryIcon;
- int iconRes;
- int iconMuteRes;
- int iconSuppressedRes;
- int minVolume;
- }
-
- // Synchronize when accessing this
- private ToneGenerator mToneGenerators[];
- private Vibrator mVibrator;
- private boolean mHasVibrator;
-
- private static AlertDialog sSafetyWarning;
- private static Object sSafetyWarningLock = new Object();
-
- protected LayoutParams getDialogLayoutParams(Window window, Resources res) {
- final LayoutParams lp = window.getAttributes();
- lp.token = null;
- lp.y = res.getDimensionPixelOffset(com.android.systemui.R.dimen.volume_panel_top);
- lp.type = LayoutParams.TYPE_STATUS_BAR_PANEL;
- lp.format = PixelFormat.TRANSLUCENT;
- lp.windowAnimations = com.android.systemui.R.style.VolumePanelAnimation;
- lp.setTitle(TAG);
- return lp;
- }
-
- public VolumePanel(Context context, ZenModeController zenController) {
- mTag = String.format("%s.%08x", TAG, hashCode());
- mContext = context;
- mZenController = zenController;
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- mAccessibilityManager = (AccessibilityManager) context.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
- mSecondaryIconTransition = new SecondaryIconTransition();
- mIconPulser = new IconPulser(context);
-
- if (LOGD) Log.d(mTag, "new VolumePanel");
-
- mDisabledAlpha = 0.5f;
- if (mContext.getTheme() != null) {
- final TypedArray arr = mContext.getTheme().obtainStyledAttributes(
- new int[] { android.R.attr.disabledAlpha });
- mDisabledAlpha = arr.getFloat(0, mDisabledAlpha);
- arr.recycle();
- }
-
- mDialog = new Dialog(context) {
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE &&
- sSafetyWarning == null) {
- forceTimeout(0);
- return true;
- }
- return false;
- }
- };
-
- final Window window = mDialog.getWindow();
- window.requestFeature(Window.FEATURE_NO_TITLE);
- mDialog.setCanceledOnTouchOutside(true);
- mDialog.setContentView(com.android.systemui.R.layout.volume_panel_dialog);
- mDialog.setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- mActiveStreamType = -1;
- mAudioManager.forceVolumeControlStream(mActiveStreamType);
- setZenPanelVisible(false);
- mDemoIcon = 0;
- mSecondaryIconTransition.cancel();
- }
- });
-
- mDialog.create();
-
- final Resources res = context.getResources();
- window.setAttributes(getDialogLayoutParams(window, res));
-
- updateWidth();
-
- window.setBackgroundDrawable(new ColorDrawable(0x00000000));
- window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
- window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE
- | LayoutParams.FLAG_NOT_TOUCH_MODAL
- | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | LayoutParams.FLAG_HARDWARE_ACCELERATED);
- mView = window.findViewById(R.id.content);
- Interaction.register(mView, new Interaction.Callback() {
- @Override
- public void onInteraction() {
- resetTimeout();
- }
- });
-
- mPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.visible_panel);
- mSliderPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.slider_panel);
- mZenPanel = (ZenModePanel) mView.findViewById(com.android.systemui.R.id.zen_mode_panel);
- initZenModePanel();
-
- mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
- mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
- mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
- mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
-
- if (mZenController != null) {
- mZenModeAvailable = mZenController.isZenAvailable();
- mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
- mZenController.addCallback(mZenCallback);
- }
-
- registerReceiver();
- }
-
- public void onConfigurationChanged(Configuration newConfig) {
- updateWidth();
- if (mZenPanel != null) {
- mZenPanel.updateLocale();
- }
- }
-
- private void updateWidth() {
- final Resources res = mContext.getResources();
- final LayoutParams lp = mDialog.getWindow().getAttributes();
- lp.width = res.getDimensionPixelSize(com.android.systemui.R.dimen.notification_panel_width);
- lp.gravity =
- res.getInteger(com.android.systemui.R.integer.notification_panel_layout_gravity);
- mDialog.getWindow().setAttributes(lp);
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("VolumePanel state:");
- pw.print(" mTag="); pw.println(mTag);
- pw.print(" mRingIsSilent="); pw.println(mRingIsSilent);
- pw.print(" mVoiceCapable="); pw.println(mVoiceCapable);
- pw.print(" mHasVibrator="); pw.println(mHasVibrator);
- pw.print(" mZenModeAvailable="); pw.println(mZenModeAvailable);
- pw.print(" mZenPanelExpanded="); pw.println(mZenPanelExpanded);
- pw.print(" mNotificationEffectsSuppressor="); pw.println(mNotificationEffectsSuppressor);
- pw.print(" mTimeoutDelay="); pw.println(mTimeoutDelay);
- pw.print(" mDisabledAlpha="); pw.println(mDisabledAlpha);
- pw.print(" mLastRingerMode="); pw.println(mLastRingerMode);
- pw.print(" mLastRingerProgress="); pw.println(mLastRingerProgress);
- pw.print(" isShowing()="); pw.println(isShowing());
- pw.print(" mCallback="); pw.println(mCallback);
- pw.print(" sConfirmSafeVolumeDialog=");
- pw.println(sSafetyWarning != null ? "<not null>" : null);
- pw.print(" mActiveStreamType="); pw.println(mActiveStreamType);
- pw.print(" mStreamControls=");
- if (mStreamControls == null) {
- pw.println("null");
- } else {
- final int N = mStreamControls.size();
- pw.print("<size "); pw.print(N); pw.println('>');
- for (int i = 0; i < N; i++) {
- final StreamControl sc = mStreamControls.valueAt(i);
- pw.print(" stream "); pw.print(sc.streamType); pw.print(":");
- if (sc.seekbarView != null) {
- pw.print(" progress="); pw.print(sc.seekbarView.getProgress());
- pw.print(" of "); pw.print(sc.seekbarView.getMax());
- if (!sc.seekbarView.isEnabled()) pw.print(" (disabled)");
- }
- if (sc.icon != null && sc.icon.isClickable()) pw.print(" (clickable)");
- pw.println();
- }
- }
- if (mZenPanel != null) {
- mZenPanel.dump(fd, pw, args);
- }
- }
-
- private void initZenModePanel() {
- mZenPanel.init(mZenController);
- mZenPanel.setCallback(new ZenModePanel.Callback() {
- @Override
- public void onMoreSettings() {
- if (mCallback != null) {
- mCallback.onZenSettings();
- }
- }
-
- @Override
- public void onPrioritySettings() {
- if (mCallback != null) {
- mCallback.onZenPrioritySettings();
- }
- }
-
- @Override
- public void onInteraction() {
- resetTimeout();
- }
-
- @Override
- public void onExpanded(boolean expanded) {
- if (mZenPanelExpanded == expanded) return;
- mZenPanelExpanded = expanded;
- updateTimeoutDelay();
- resetTimeout();
- }
- });
- }
-
- private void setLayoutDirection(int layoutDirection) {
- mPanel.setLayoutDirection(layoutDirection);
- updateStates();
- }
-
- private void registerReceiver() {
- final IntentFilter filter = new IntentFilter();
- filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
- filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- mContext.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
-
- if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
- removeMessages(MSG_RINGER_MODE_CHANGED);
- sendEmptyMessage(MSG_RINGER_MODE_CHANGED);
- }
-
- if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
- removeMessages(MSG_INTERNAL_RINGER_MODE_CHANGED);
- sendEmptyMessage(MSG_INTERNAL_RINGER_MODE_CHANGED);
- }
-
- if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- postDismiss(0);
- }
- }
- }, filter);
- }
-
- private boolean isMuted(int streamType) {
- if (streamType == STREAM_REMOTE_MUSIC) {
- // TODO do we need to support a distinct mute property for remote?
- return false;
- } else {
- return mAudioManager.isStreamMute(streamType);
- }
- }
-
- private int getStreamMinVolume(int streamType) {
- if (streamType == STREAM_REMOTE_MUSIC) {
- return 0;
- } else {
- return mAudioManager.getStreamMinVolume(streamType);
- }
- }
-
- private int getStreamMaxVolume(int streamType) {
- if (streamType == STREAM_REMOTE_MUSIC) {
- if (mStreamControls != null) {
- StreamControl sc = mStreamControls.get(streamType);
- if (sc != null && sc.controller != null) {
- PlaybackInfo ai = sc.controller.getPlaybackInfo();
- return ai.getMaxVolume();
- }
- }
- return -1;
- } else {
- return mAudioManager.getStreamMaxVolume(streamType);
- }
- }
-
- private int getStreamVolume(int streamType) {
- if (streamType == STREAM_REMOTE_MUSIC) {
- if (mStreamControls != null) {
- StreamControl sc = mStreamControls.get(streamType);
- if (sc != null && sc.controller != null) {
- PlaybackInfo ai = sc.controller.getPlaybackInfo();
- return ai.getCurrentVolume();
- }
- }
- return -1;
- } else {
- return mAudioManager.getLastAudibleStreamVolume(streamType);
- }
- }
-
- private void setStreamVolume(StreamControl sc, int index, int flags) {
- if (sc.streamType == STREAM_REMOTE_MUSIC) {
- if (sc.controller != null) {
- sc.controller.setVolumeTo(index, flags);
- } else {
- Log.w(mTag, "Adjusting remote volume without a controller!");
- }
- } else if (getStreamVolume(sc.streamType) != index) {
- mAudioManager.setStreamVolume(sc.streamType, index, flags);
- }
- }
-
- private void createSliders() {
- final Resources res = mContext.getResources();
- final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
-
- mStreamControls = new SparseArray<StreamControl>(STREAMS.length);
-
- final StreamResources notificationStream = StreamResources.NotificationStream;
- for (int i = 0; i < STREAMS.length; i++) {
- StreamResources streamRes = STREAMS[i];
-
- final int streamType = streamRes.streamType;
- final boolean isNotification = isNotificationOrRing(streamType);
-
- final StreamControl sc = new StreamControl();
- sc.streamType = streamType;
- sc.group = (ViewGroup) inflater.inflate(
- com.android.systemui.R.layout.volume_panel_item, null);
- sc.group.setTag(sc);
- sc.icon = (ImageView) sc.group.findViewById(com.android.systemui.R.id.stream_icon);
- sc.icon.setTag(sc);
- sc.icon.setContentDescription(res.getString(streamRes.descRes));
- sc.iconRes = streamRes.iconRes;
- sc.iconMuteRes = streamRes.iconMuteRes;
- sc.icon.setImageResource(sc.iconRes);
- sc.icon.setClickable(isNotification && mHasVibrator);
- if (isNotification) {
- if (mHasVibrator) {
- sc.icon.setSoundEffectsEnabled(false);
- sc.iconMuteRes = com.android.systemui.R.drawable.ic_ringer_vibrate;
- sc.icon.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- resetTimeout();
- toggleRinger(sc);
- }
- });
- }
- sc.iconSuppressedRes = com.android.systemui.R.drawable.ic_ringer_mute;
- }
- sc.seekbarView = (SeekBar) sc.group.findViewById(com.android.systemui.R.id.seekbar);
- sc.suppressorView =
- (TextView) sc.group.findViewById(com.android.systemui.R.id.suppressor);
- sc.suppressorView.setVisibility(View.GONE);
- final boolean showSecondary = !isNotification && notificationStream.show;
- sc.divider = sc.group.findViewById(com.android.systemui.R.id.divider);
- sc.secondaryIcon = (ImageView) sc.group
- .findViewById(com.android.systemui.R.id.secondary_icon);
- sc.secondaryIcon.setImageResource(com.android.systemui.R.drawable.ic_ringer_audible);
- sc.secondaryIcon.setContentDescription(res.getString(notificationStream.descRes));
- sc.secondaryIcon.setClickable(showSecondary);
- sc.divider.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
- sc.secondaryIcon.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
- if (showSecondary) {
- sc.secondaryIcon.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mSecondaryIconTransition.start(sc);
- }
- });
- }
- sc.minVolume = getStreamMinVolume(streamType);
- sc.seekbarView.setMax(getStreamMaxVolume(streamType) - sc.minVolume);
- sc.seekbarView.setOnSeekBarChangeListener(mSeekListener);
- sc.seekbarView.setTag(sc);
- mStreamControls.put(streamType, sc);
- }
- }
-
- private void toggleRinger(StreamControl sc) {
- if (!mHasVibrator) return;
- if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL) {
- mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_VIBRATE);
- postVolumeChanged(sc.streamType, AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
- } else {
- mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL);
- postVolumeChanged(sc.streamType, AudioManager.FLAG_PLAY_SOUND);
- }
- }
-
- private void reorderSliders(int activeStreamType) {
- mSliderPanel.removeAllViews();
-
- final StreamControl active = mStreamControls.get(activeStreamType);
- if (active == null) {
- Log.e(TAG, "Missing stream type! - " + activeStreamType);
- mActiveStreamType = -1;
- } else {
- mSliderPanel.addView(active.group);
- mActiveStreamType = activeStreamType;
- active.group.setVisibility(View.VISIBLE);
- updateSlider(active, true /*forceReloadIcon*/);
- updateTimeoutDelay();
- updateZenPanelVisible();
- }
- }
-
- private void updateSliderProgress(StreamControl sc, int progress) {
- final boolean isRinger = isNotificationOrRing(sc.streamType);
- if (isRinger && mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
- progress = mLastRingerProgress;
- }
- if (progress < 0) {
- progress = getStreamVolume(sc.streamType);
- }
- sc.seekbarView.setProgress(progress - sc.minVolume);
- if (isRinger) {
- mLastRingerProgress = progress;
- }
- }
-
- private void updateSliderIcon(StreamControl sc, boolean muted) {
- ComponentName suppressor = null;
- if (isNotificationOrRing(sc.streamType)) {
- suppressor = mNotificationEffectsSuppressor;
- int ringerMode = mAudioManager.getRingerModeInternal();
- if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
- ringerMode = mLastRingerMode;
- } else {
- mLastRingerMode = ringerMode;
- }
- if (mHasVibrator) {
- muted = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
- } else {
- muted = false;
- }
- }
- sc.icon.setImageResource(mDemoIcon != 0 ? mDemoIcon
- : suppressor != null ? sc.iconSuppressedRes
- : muted ? sc.iconMuteRes
- : sc.iconRes);
- }
-
- private void updateSliderSuppressor(StreamControl sc) {
- final ComponentName suppressor = isNotificationOrRing(sc.streamType)
- ? mNotificationEffectsSuppressor : null;
- if (suppressor == null) {
- sc.seekbarView.setVisibility(View.VISIBLE);
- sc.suppressorView.setVisibility(View.GONE);
- } else {
- sc.seekbarView.setVisibility(View.GONE);
- sc.suppressorView.setVisibility(View.VISIBLE);
- sc.suppressorView.setText(mContext.getString(R.string.muted_by,
- getSuppressorCaption(suppressor)));
- }
- }
-
- private String getSuppressorCaption(ComponentName suppressor) {
- final PackageManager pm = mContext.getPackageManager();
- try {
- final ServiceInfo info = pm.getServiceInfo(suppressor, 0);
- if (info != null) {
- final CharSequence seq = info.loadLabel(pm);
- if (seq != null) {
- final String str = seq.toString().trim();
- if (str.length() > 0) {
- return str;
- }
- }
- }
- } catch (Throwable e) {
- Log.w(TAG, "Error loading suppressor caption", e);
- }
- return suppressor.getPackageName();
- }
-
- /** Update the mute and progress state of a slider */
- private void updateSlider(StreamControl sc, boolean forceReloadIcon) {
- updateSliderProgress(sc, -1);
- final boolean muted = isMuted(sc.streamType);
- if (forceReloadIcon) {
- sc.icon.setImageDrawable(null);
- }
- updateSliderIcon(sc, muted);
- updateSliderEnabled(sc, muted, false);
- updateSliderSuppressor(sc);
- }
-
- private void updateSliderEnabled(final StreamControl sc, boolean muted, boolean fixedVolume) {
- final boolean wasEnabled = sc.seekbarView.isEnabled();
- final boolean isRinger = isNotificationOrRing(sc.streamType);
- if (sc.streamType == STREAM_REMOTE_MUSIC) {
- // never disable touch interactions for remote playback, the muting is not tied to
- // the state of the phone.
- sc.seekbarView.setEnabled(!fixedVolume);
- } else if (isRinger && mNotificationEffectsSuppressor != null) {
- sc.icon.setEnabled(true);
- sc.icon.setAlpha(1f);
- sc.icon.setClickable(false);
- } else if (isRinger
- && mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
- sc.seekbarView.setEnabled(false);
- sc.icon.setEnabled(false);
- sc.icon.setAlpha(mDisabledAlpha);
- sc.icon.setClickable(false);
- } else if (fixedVolume ||
- (sc.streamType != mAudioManager.getUiSoundsStreamType() && !isRinger && muted) ||
- (sSafetyWarning != null)) {
- sc.seekbarView.setEnabled(false);
- } else {
- sc.seekbarView.setEnabled(true);
- sc.icon.setEnabled(true);
- sc.icon.setAlpha(1f);
- }
- // show the silent hint when the disabled slider is touched in silent mode
- if (isRinger && wasEnabled != sc.seekbarView.isEnabled()) {
- if (sc.seekbarView.isEnabled()) {
- sc.group.setOnTouchListener(null);
- sc.icon.setClickable(mHasVibrator);
- } else {
- final View.OnTouchListener showHintOnTouch = new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- resetTimeout();
- showSilentHint();
- return false;
- }
- };
- sc.group.setOnTouchListener(showHintOnTouch);
- }
- }
- }
-
- private void showSilentHint() {
- if (mZenPanel != null) {
- mZenPanel.showSilentHint();
- }
- }
-
- private void showVibrateHint() {
- final StreamControl active = mStreamControls.get(mActiveStreamType);
- if (active != null) {
- mIconPulser.start(active.icon);
- if (!hasMessages(MSG_VIBRATE)) {
- sendEmptyMessageDelayed(MSG_VIBRATE, VIBRATE_DELAY);
- }
- }
- }
-
- private static boolean isNotificationOrRing(int streamType) {
- return streamType == AudioManager.STREAM_RING
- || streamType == AudioManager.STREAM_NOTIFICATION;
- }
-
- public void setCallback(Callback callback) {
- mCallback = callback;
- }
-
- private void updateTimeoutDelay() {
- mTimeoutDelay = mDemoIcon != 0 ? TIMEOUT_DELAY_EXPANDED
- : sSafetyWarning != null ? TIMEOUT_DELAY_SAFETY_WARNING
- : mActiveStreamType == AudioManager.STREAM_MUSIC ? TIMEOUT_DELAY_SHORT
- : mZenPanelExpanded ? TIMEOUT_DELAY_EXPANDED
- : isZenPanelVisible() ? TIMEOUT_DELAY_COLLAPSED
- : TIMEOUT_DELAY;
- }
-
- private boolean isZenPanelVisible() {
- return mZenPanel != null && mZenPanel.getVisibility() == View.VISIBLE;
- }
-
- private void setZenPanelVisible(boolean visible) {
- if (LOGD) Log.d(mTag, "setZenPanelVisible " + visible + " mZenPanel=" + mZenPanel);
- final boolean changing = visible != isZenPanelVisible();
- if (visible) {
- mZenPanel.setHidden(false);
- resetTimeout();
- } else {
- mZenPanel.setHidden(true);
- }
- if (changing) {
- updateTimeoutDelay();
- resetTimeout();
- }
- }
-
- private void updateStates() {
- final int count = mSliderPanel.getChildCount();
- for (int i = 0; i < count; i++) {
- StreamControl sc = (StreamControl) mSliderPanel.getChildAt(i).getTag();
- updateSlider(sc, true /*forceReloadIcon*/);
- }
- }
-
- private void updateActiveSlider() {
- final StreamControl active = mStreamControls.get(mActiveStreamType);
- if (active != null) {
- updateSlider(active, false /*forceReloadIcon*/);
- }
- }
-
- private void updateZenPanelVisible() {
- setZenPanelVisible(mZenModeAvailable && isNotificationOrRing(mActiveStreamType));
- }
-
- public void postVolumeChanged(int streamType, int flags) {
- if (hasMessages(MSG_VOLUME_CHANGED)) return;
- synchronized (this) {
- if (mStreamControls == null) {
- createSliders();
- }
- }
- removeMessages(MSG_FREE_RESOURCES);
- obtainMessage(MSG_VOLUME_CHANGED, streamType, flags).sendToTarget();
- }
-
- public void postRemoteVolumeChanged(MediaController controller, int flags) {
- if (hasMessages(MSG_REMOTE_VOLUME_CHANGED)) return;
- synchronized (this) {
- if (mStreamControls == null) {
- createSliders();
- }
- }
- removeMessages(MSG_FREE_RESOURCES);
- obtainMessage(MSG_REMOTE_VOLUME_CHANGED, flags, 0, controller).sendToTarget();
- }
-
- public void postRemoteSliderVisibility(boolean visible) {
- obtainMessage(MSG_SLIDER_VISIBILITY_CHANGED,
- STREAM_REMOTE_MUSIC, visible ? 1 : 0).sendToTarget();
- }
-
- /**
- * Called by AudioService when it has received new remote playback information that
- * would affect the VolumePanel display (mainly volumes). The difference with
- * {@link #postRemoteVolumeChanged(int, int)} is that the handling of the posted message
- * (MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN) will only update the volume slider if it is being
- * displayed.
- * This special code path is due to the fact that remote volume updates arrive to AudioService
- * asynchronously. So after AudioService has sent the volume update (which should be treated
- * as a request to update the volume), the application will likely set a new volume. If the UI
- * is still up, we need to refresh the display to show this new value.
- */
- public void postHasNewRemotePlaybackInfo() {
- if (hasMessages(MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN)) return;
- // don't create or prevent resources to be freed, if they disappear, this update came too
- // late and shouldn't warrant the panel to be displayed longer
- obtainMessage(MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN).sendToTarget();
- }
-
- public void postMuteChanged(int streamType, int flags) {
- if (hasMessages(MSG_VOLUME_CHANGED)) return;
- synchronized (this) {
- if (mStreamControls == null) {
- createSliders();
- }
- }
- removeMessages(MSG_FREE_RESOURCES);
- obtainMessage(MSG_MUTE_CHANGED, streamType, flags).sendToTarget();
- }
-
- public void postDisplaySafeVolumeWarning(int flags) {
- if (hasMessages(MSG_DISPLAY_SAFE_VOLUME_WARNING)) return;
- obtainMessage(MSG_DISPLAY_SAFE_VOLUME_WARNING, flags, 0).sendToTarget();
- }
-
- public void postDismiss(long delay) {
- forceTimeout(delay);
- }
-
- public void postLayoutDirection(int layoutDirection) {
- removeMessages(MSG_LAYOUT_DIRECTION);
- obtainMessage(MSG_LAYOUT_DIRECTION, layoutDirection, 0).sendToTarget();
- }
-
- private static String flagsToString(int flags) {
- return flags == 0 ? "0" : (flags + "=" + AudioManager.flagsToString(flags));
- }
-
- private static String streamToString(int stream) {
- return AudioSystem.streamToString(stream);
- }
-
- /**
- * Override this if you have other work to do when the volume changes (for
- * example, vibrating, playing a sound, etc.). Make sure to call through to
- * the superclass implementation.
- */
- protected void onVolumeChanged(int streamType, int flags) {
-
- if (LOGD) Log.d(mTag, "onVolumeChanged(streamType: " + streamToString(streamType)
- + ", flags: " + flagsToString(flags) + ")");
-
- if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
- synchronized (this) {
- if (mActiveStreamType != streamType) {
- reorderSliders(streamType);
- }
- onShowVolumeChanged(streamType, flags, null);
- }
- }
-
- if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && ! mRingIsSilent) {
- removeMessages(MSG_PLAY_SOUND);
- sendMessageDelayed(obtainMessage(MSG_PLAY_SOUND, streamType, flags), PLAY_SOUND_DELAY);
- }
-
- if ((flags & AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE) != 0) {
- removeMessages(MSG_PLAY_SOUND);
- removeMessages(MSG_VIBRATE);
- onStopSounds();
- }
-
- removeMessages(MSG_FREE_RESOURCES);
- sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
- resetTimeout();
- }
-
- protected void onMuteChanged(int streamType, int flags) {
-
- if (LOGD) Log.d(mTag, "onMuteChanged(streamType: " + streamToString(streamType)
- + ", flags: " + flagsToString(flags) + ")");
-
- StreamControl sc = mStreamControls.get(streamType);
- if (sc != null) {
- updateSliderIcon(sc, isMuted(sc.streamType));
- }
-
- onVolumeChanged(streamType, flags);
- }
-
- protected void onShowVolumeChanged(int streamType, int flags, MediaController controller) {
- int index = getStreamVolume(streamType);
-
- mRingIsSilent = false;
-
- if (LOGD) {
- Log.d(mTag, "onShowVolumeChanged(streamType: " + streamToString(streamType)
- + ", flags: " + flagsToString(flags) + "), index: " + index);
- }
-
- // get max volume for progress bar
-
- int max = getStreamMaxVolume(streamType) - getStreamMinVolume(streamType);
- StreamControl sc = mStreamControls.get(streamType);
-
- switch (streamType) {
-
- case AudioManager.STREAM_RING: {
- Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
- mContext, RingtoneManager.TYPE_RINGTONE);
- if (ringuri == null) {
- mRingIsSilent = true;
- }
- break;
- }
-
- case AudioManager.STREAM_MUSIC: {
- // Special case for when Bluetooth is active for music
- if ((mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC) &
- (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
- AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
- setMusicIcon(IC_AUDIO_BT, IC_AUDIO_BT_MUTE);
- } else {
- setMusicIcon(IC_AUDIO_VOL, IC_AUDIO_VOL_MUTE);
- }
- break;
- }
-
- case AudioManager.STREAM_ALARM: {
- break;
- }
-
- case AudioManager.STREAM_NOTIFICATION: {
- Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
- mContext, RingtoneManager.TYPE_NOTIFICATION);
- if (ringuri == null) {
- mRingIsSilent = true;
- }
- break;
- }
-
- case STREAM_REMOTE_MUSIC: {
- if (controller == null && sc != null) {
- // If we weren't passed one try using the last one set.
- controller = sc.controller;
- }
- if (controller == null) {
- // We still don't have one, ignore the command.
- Log.w(mTag, "sent remote volume change without a controller!");
- } else {
- PlaybackInfo vi = controller.getPlaybackInfo();
- index = vi.getCurrentVolume();
- max = vi.getMaxVolume();
- if ((vi.getVolumeControl() & VolumeProvider.VOLUME_CONTROL_FIXED) != 0) {
- // if the remote volume is fixed add the flag for the UI
- flags |= AudioManager.FLAG_FIXED_VOLUME;
- }
- }
- if (LOGD) { Log.d(mTag, "showing remote volume "+index+" over "+ max); }
- break;
- }
- }
-
- if (sc != null) {
- if (streamType == STREAM_REMOTE_MUSIC && controller != sc.controller) {
- if (sc.controller != null) {
- sc.controller.unregisterCallback(mMediaControllerCb);
- }
- sc.controller = controller;
- if (controller != null) {
- sc.controller.registerCallback(mMediaControllerCb);
- }
- }
- if (sc.seekbarView.getMax() != max) {
- sc.seekbarView.setMax(max);
- }
- updateSliderProgress(sc, index);
- final boolean muted = isMuted(streamType);
- updateSliderEnabled(sc, muted, (flags & AudioManager.FLAG_FIXED_VOLUME) != 0);
- if (isNotificationOrRing(streamType)) {
- // check for secondary-icon transition completion
- if (mSecondaryIconTransition.isRunning()) {
- mSecondaryIconTransition.cancel(); // safe to reset
- sc.seekbarView.setAlpha(0); sc.seekbarView.animate().alpha(1);
- mZenPanel.setAlpha(0); mZenPanel.animate().alpha(1);
- }
- updateSliderIcon(sc, muted);
- }
- }
-
- if (!isShowing()) {
- int stream = (streamType == STREAM_REMOTE_MUSIC) ? -1 : streamType;
- // when the stream is for remote playback, use -1 to reset the stream type evaluation
- mAudioManager.forceVolumeControlStream(stream);
- mDialog.show();
- if (mCallback != null) {
- mCallback.onVisible(true);
- }
- announceDialogShown();
- }
-
- // Do a little vibrate if applicable (only when going into vibrate mode)
- if ((streamType != STREAM_REMOTE_MUSIC) &&
- ((flags & AudioManager.FLAG_VIBRATE) != 0) &&
- isNotificationOrRing(streamType) &&
- mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
- sendMessageDelayed(obtainMessage(MSG_VIBRATE), VIBRATE_DELAY);
- }
-
- // Pulse the zen icon if an adjustment was suppressed due to silent mode.
- if ((flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
- showSilentHint();
- }
-
- // Pulse the slider icon & vibrate if an adjustment down was suppressed due to vibrate mode.
- if ((flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
- showVibrateHint();
- }
- }
-
- private void announceDialogShown() {
- mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- }
-
- private boolean isShowing() {
- return mDialog.isShowing();
- }
-
- protected void onPlaySound(int streamType, int flags) {
-
- if (hasMessages(MSG_STOP_SOUNDS)) {
- removeMessages(MSG_STOP_SOUNDS);
- // Force stop right now
- onStopSounds();
- }
-
- synchronized (this) {
- ToneGenerator toneGen = getOrCreateToneGenerator(streamType);
- if (toneGen != null) {
- toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
- sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
- }
- }
- }
-
- protected void onStopSounds() {
-
- synchronized (this) {
- int numStreamTypes = AudioSystem.getNumStreamTypes();
- for (int i = numStreamTypes - 1; i >= 0; i--) {
- ToneGenerator toneGen = mToneGenerators[i];
- if (toneGen != null) {
- toneGen.stopTone();
- }
- }
- }
- }
-
- protected void onVibrate() {
-
- // Make sure we ended up in vibrate ringer mode
- if (mAudioManager.getRingerModeInternal() != AudioManager.RINGER_MODE_VIBRATE) {
- return;
- }
- if (mVibrator != null) {
- mVibrator.vibrate(VIBRATE_DURATION, VIBRATION_ATTRIBUTES);
- }
- }
-
- protected void onRemoteVolumeChanged(MediaController controller, int flags) {
- if (LOGD) Log.d(mTag, "onRemoteVolumeChanged(controller:" + controller + ", flags: "
- + flagsToString(flags) + ")");
-
- if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || isShowing()) {
- synchronized (this) {
- if (mActiveStreamType != STREAM_REMOTE_MUSIC) {
- reorderSliders(STREAM_REMOTE_MUSIC);
- }
- onShowVolumeChanged(STREAM_REMOTE_MUSIC, flags, controller);
- }
- } else {
- if (LOGD) Log.d(mTag, "not calling onShowVolumeChanged(), no FLAG_SHOW_UI or no UI");
- }
-
- removeMessages(MSG_FREE_RESOURCES);
- sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
- resetTimeout();
- }
-
- protected void onRemoteVolumeUpdateIfShown() {
- if (LOGD) Log.d(mTag, "onRemoteVolumeUpdateIfShown()");
- if (isShowing()
- && (mActiveStreamType == STREAM_REMOTE_MUSIC)
- && (mStreamControls != null)) {
- onShowVolumeChanged(STREAM_REMOTE_MUSIC, 0, null);
- }
- }
-
- /**
- * Clear the current remote stream controller.
- */
- private void clearRemoteStreamController() {
- if (mStreamControls != null) {
- StreamControl sc = mStreamControls.get(STREAM_REMOTE_MUSIC);
- if (sc != null) {
- if (sc.controller != null) {
- sc.controller.unregisterCallback(mMediaControllerCb);
- sc.controller = null;
- }
- }
- }
- }
-
- /**
- * Handler for MSG_SLIDER_VISIBILITY_CHANGED Hide or show a slider
- *
- * @param streamType can be a valid stream type value, or
- * VolumePanel.STREAM_MASTER, or VolumePanel.STREAM_REMOTE_MUSIC
- * @param visible
- */
- synchronized protected void onSliderVisibilityChanged(int streamType, int visible) {
- if (LOGD) Log.d(mTag, "onSliderVisibilityChanged(stream="+streamType+", visi="+visible+")");
- boolean isVisible = (visible == 1);
- for (int i = STREAMS.length - 1 ; i >= 0 ; i--) {
- StreamResources streamRes = STREAMS[i];
- if (streamRes.streamType == streamType) {
- streamRes.show = isVisible;
- if (!isVisible && (mActiveStreamType == streamType)) {
- mActiveStreamType = -1;
- }
- break;
- }
- }
- }
-
- protected void onDisplaySafeVolumeWarning(int flags) {
- if ((flags & (AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_SHOW_UI_WARNINGS)) != 0
- || isShowing()) {
- synchronized (sSafetyWarningLock) {
- if (sSafetyWarning != null) {
- return;
- }
- sSafetyWarning = new SafetyWarningDialog(mContext, mAudioManager) {
- @Override
- protected void cleanUp() {
- synchronized (sSafetyWarningLock) {
- sSafetyWarning = null;
- }
- forceTimeout(0);
- updateStates();
- }
- };
- sSafetyWarning.show();
- }
- updateStates();
- }
- if (mAccessibilityManager.isTouchExplorationEnabled()) {
- removeMessages(MSG_TIMEOUT);
- } else {
- updateTimeoutDelay();
- resetTimeout();
- }
- }
-
- /**
- * Lock on this VolumePanel instance as long as you use the returned ToneGenerator.
- */
- private ToneGenerator getOrCreateToneGenerator(int streamType) {
- synchronized (this) {
- if (mToneGenerators[streamType] == null) {
- try {
- mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
- } catch (RuntimeException e) {
- if (LOGD) {
- Log.d(mTag, "ToneGenerator constructor failed with "
- + "RuntimeException: " + e);
- }
- }
- }
- return mToneGenerators[streamType];
- }
- }
-
-
- /**
- * Switch between icons because Bluetooth music is same as music volume, but with
- * different icons.
- */
- private void setMusicIcon(int resId, int resMuteId) {
- StreamControl sc = mStreamControls.get(AudioManager.STREAM_MUSIC);
- if (sc != null) {
- sc.iconRes = resId;
- sc.iconMuteRes = resMuteId;
- updateSliderIcon(sc, isMuted(sc.streamType));
- }
- }
-
- protected void onFreeResources() {
- synchronized (this) {
- for (int i = mToneGenerators.length - 1; i >= 0; i--) {
- if (mToneGenerators[i] != null) {
- mToneGenerators[i].release();
- }
- mToneGenerators[i] = null;
- }
- }
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
-
- case MSG_VOLUME_CHANGED: {
- onVolumeChanged(msg.arg1, msg.arg2);
- break;
- }
-
- case MSG_MUTE_CHANGED: {
- onMuteChanged(msg.arg1, msg.arg2);
- break;
- }
-
- case MSG_FREE_RESOURCES: {
- onFreeResources();
- break;
- }
-
- case MSG_STOP_SOUNDS: {
- onStopSounds();
- break;
- }
-
- case MSG_PLAY_SOUND: {
- onPlaySound(msg.arg1, msg.arg2);
- break;
- }
-
- case MSG_VIBRATE: {
- onVibrate();
- break;
- }
-
- case MSG_TIMEOUT: {
- if (isShowing()) {
- mDialog.dismiss();
- clearRemoteStreamController();
- mActiveStreamType = -1;
- if (mCallback != null) {
- mCallback.onVisible(false);
- }
- }
- synchronized (sSafetyWarningLock) {
- if (sSafetyWarning != null) {
- if (LOGD) Log.d(mTag, "SafetyWarning timeout");
- sSafetyWarning.dismiss();
- }
- }
- break;
- }
-
- case MSG_RINGER_MODE_CHANGED:
- case MSG_INTERNAL_RINGER_MODE_CHANGED:
- case MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED: {
- if (isShowing()) {
- updateActiveSlider();
- }
- break;
- }
-
- case MSG_REMOTE_VOLUME_CHANGED: {
- onRemoteVolumeChanged((MediaController) msg.obj, msg.arg1);
- break;
- }
-
- case MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN:
- onRemoteVolumeUpdateIfShown();
- break;
-
- case MSG_SLIDER_VISIBILITY_CHANGED:
- onSliderVisibilityChanged(msg.arg1, msg.arg2);
- break;
-
- case MSG_DISPLAY_SAFE_VOLUME_WARNING:
- onDisplaySafeVolumeWarning(msg.arg1);
- break;
-
- case MSG_LAYOUT_DIRECTION:
- setLayoutDirection(msg.arg1);
- break;
-
- case MSG_ZEN_MODE_AVAILABLE_CHANGED:
- mZenModeAvailable = msg.arg1 != 0;
- updateZenPanelVisible();
- break;
-
- case MSG_USER_ACTIVITY:
- if (mCallback != null) {
- mCallback.onInteraction();
- }
- break;
- }
- }
-
- private void resetTimeout() {
- final boolean touchExploration = mAccessibilityManager.isTouchExplorationEnabled();
- if (LOGD) Log.d(mTag, "resetTimeout at " + System.currentTimeMillis()
- + " delay=" + mTimeoutDelay + " touchExploration=" + touchExploration);
- if (sSafetyWarning == null || !touchExploration) {
- removeMessages(MSG_TIMEOUT);
- sendEmptyMessageDelayed(MSG_TIMEOUT, mTimeoutDelay);
- removeMessages(MSG_USER_ACTIVITY);
- sendEmptyMessage(MSG_USER_ACTIVITY);
- }
- }
-
- private void forceTimeout(long delay) {
- if (LOGD) Log.d(mTag, "forceTimeout delay=" + delay + " callers=" + Debug.getCallers(3));
- removeMessages(MSG_TIMEOUT);
- sendEmptyMessageDelayed(MSG_TIMEOUT, delay);
- }
-
- public ZenModeController getZenController() {
- return mZenController;
- }
-
- @Override
- public void dispatchDemoCommand(String command, Bundle args) {
- if (!COMMAND_VOLUME.equals(command)) return;
- String icon = args.getString("icon");
- final String iconMute = args.getString("iconmute");
- final boolean mute = iconMute != null;
- icon = mute ? iconMute : icon;
- icon = icon.endsWith("Stream") ? icon : (icon + "Stream");
- final StreamResources sr = StreamResources.valueOf(icon);
- mDemoIcon = mute ? sr.iconMuteRes : sr.iconRes;
- final int forcedStreamType = StreamResources.MediaStream.streamType;
- mAudioManager.forceVolumeControlStream(forcedStreamType);
- mAudioManager.adjustStreamVolume(forcedStreamType, AudioManager.ADJUST_SAME,
- AudioManager.FLAG_SHOW_UI);
- }
-
- private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- final Object tag = seekBar.getTag();
- if (fromUser && tag instanceof StreamControl) {
- StreamControl sc = (StreamControl) tag;
- setStreamVolume(sc, progress + sc.minVolume,
- AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
- }
- resetTimeout();
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
- };
-
- private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
- @Override
- public void onZenAvailableChanged(boolean available) {
- obtainMessage(MSG_ZEN_MODE_AVAILABLE_CHANGED, available ? 1 : 0, 0).sendToTarget();
- }
-
- @Override
- public void onEffectsSupressorChanged() {
- mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
- sendEmptyMessage(MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED);
- }
- };
-
- private final MediaController.Callback mMediaControllerCb = new MediaController.Callback() {
- public void onAudioInfoChanged(PlaybackInfo info) {
- onRemoteVolumeUpdateIfShown();
- }
- };
-
- private final class SecondaryIconTransition extends AnimatorListenerAdapter
- implements Runnable {
- private static final int ANIMATION_TIME = 400;
- private static final int WAIT_FOR_SWITCH_TIME = 1000;
-
- private final int mAnimationTime = (int)(ANIMATION_TIME * ValueAnimator.getDurationScale());
- private final int mFadeOutTime = mAnimationTime / 2;
- private final int mDelayTime = mAnimationTime / 3;
-
- private final Interpolator mIconInterpolator =
- AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in);
-
- private StreamControl mTarget;
-
- public void start(StreamControl sc) {
- if (sc == null) throw new IllegalArgumentException();
- if (LOGD) Log.d(mTag, "Secondary icon animation start");
- if (mTarget != null) {
- cancel();
- }
- mTarget = sc;
- mTimeoutDelay = mAnimationTime + WAIT_FOR_SWITCH_TIME;
- resetTimeout();
- mTarget.secondaryIcon.setClickable(false);
- final int N = mTarget.group.getChildCount();
- for (int i = 0; i < N; i++) {
- final View child = mTarget.group.getChildAt(i);
- if (child != mTarget.secondaryIcon) {
- child.animate().alpha(0).setDuration(mFadeOutTime).start();
- }
- }
- mTarget.secondaryIcon.animate()
- .translationXBy(mTarget.icon.getX() - mTarget.secondaryIcon.getX())
- .setInterpolator(mIconInterpolator)
- .setStartDelay(mDelayTime)
- .setDuration(mAnimationTime - mDelayTime)
- .setListener(this)
- .start();
- }
-
- public boolean isRunning() {
- return mTarget != null;
- }
-
- public void cancel() {
- if (mTarget == null) return;
- mTarget.secondaryIcon.setClickable(true);
- final int N = mTarget.group.getChildCount();
- for (int i = 0; i < N; i++) {
- final View child = mTarget.group.getChildAt(i);
- if (child != mTarget.secondaryIcon) {
- child.animate().cancel();
- child.setAlpha(1);
- }
- }
- mTarget.secondaryIcon.animate().cancel();
- mTarget.secondaryIcon.setTranslationX(0);
- mTarget = null;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mTarget == null) return;
- AsyncTask.execute(this);
- }
-
- @Override
- public void run() {
- if (mTarget == null) return;
- if (LOGD) Log.d(mTag, "Secondary icon animation complete, show notification slider");
- mAudioManager.forceVolumeControlStream(StreamResources.NotificationStream.streamType);
- mAudioManager.adjustStreamVolume(StreamResources.NotificationStream.streamType,
- AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
- }
- }
-
- public interface Callback {
- void onZenSettings();
- void onZenPrioritySettings();
- void onInteraction();
- void onVisible(boolean visible);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelComponent.java
deleted file mode 100644
index b072cab..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelComponent.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2015 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.volume;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.media.AudioManager;
-import android.media.IRemoteVolumeController;
-import android.media.IVolumeController;
-import android.media.VolumePolicy;
-import android.media.session.ISessionController;
-import android.media.session.MediaController;
-import android.media.session.MediaSessionManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.RemoteException;
-
-import com.android.systemui.R;
-import com.android.systemui.SystemUI;
-import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.qs.tiles.DndTile;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
-import com.android.systemui.statusbar.policy.ZenModeController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Implementation of VolumeComponent backed by the old volume panel.
- */
-public class VolumePanelComponent implements VolumeComponent {
-
- private final SystemUI mSysui;
- private final Context mContext;
- private final Handler mHandler;
- private final VolumeController mVolumeController;
- private final RemoteVolumeController mRemoteVolumeController;
- private final AudioManager mAudioManager;
- private final MediaSessionManager mMediaSessionManager;
-
- private VolumePanel mPanel;
- private int mDismissDelay;
-
- public VolumePanelComponent(SystemUI sysui, Context context, Handler handler,
- ZenModeController controller) {
- mSysui = sysui;
- mContext = context;
- mHandler = handler;
- mAudioManager = context.getSystemService(AudioManager.class);
- mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
- mVolumeController = new VolumeController();
- mRemoteVolumeController = new RemoteVolumeController();
- mDismissDelay = mContext.getResources().getInteger(R.integer.volume_panel_dismiss_delay);
- mPanel = new VolumePanel(mContext, controller);
- mPanel.setCallback(new VolumePanel.Callback() {
- @Override
- public void onZenSettings() {
- mHandler.removeCallbacks(mStartZenSettings);
- mHandler.post(mStartZenSettings);
- }
-
- @Override
- public void onZenPrioritySettings() {
- mHandler.removeCallbacks(mStartZenPrioritySettings);
- mHandler.post(mStartZenPrioritySettings);
- }
-
- @Override
- public void onInteraction() {
- final KeyguardViewMediator kvm = mSysui.getComponent(KeyguardViewMediator.class);
- if (kvm != null) {
- kvm.userActivity();
- }
- }
-
- @Override
- public void onVisible(boolean visible) {
- if (mAudioManager != null && mVolumeController != null) {
- mAudioManager.notifyVolumeControllerVisible(mVolumeController, visible);
- }
- }
- });
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mPanel != null) {
- mPanel.dump(fd, pw, args);
- }
- }
-
- public void register() {
- mAudioManager.setVolumeController(mVolumeController);
- mAudioManager.setVolumePolicy(VolumePolicy.DEFAULT);
- mMediaSessionManager.setRemoteVolumeController(mRemoteVolumeController);
- DndTile.setVisible(mContext, false);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- if (mPanel != null) {
- mPanel.onConfigurationChanged(newConfig);
- }
- }
-
- @Override
- public ZenModeController getZenController() {
- return mPanel.getZenController();
- }
-
- @Override
- public void dispatchDemoCommand(String command, Bundle args) {
- mPanel.dispatchDemoCommand(command, args);
- }
-
- @Override
- public void dismissNow() {
- mPanel.postDismiss(0);
- }
-
- private void startSettings(Intent intent) {
- mSysui.getComponent(PhoneStatusBar.class).startActivityDismissingKeyguard(intent,
- true /* onlyProvisioned */, true /* dismissShade */);
- mPanel.postDismiss(mDismissDelay);
- }
-
- private final Runnable mStartZenSettings = new Runnable() {
- @Override
- public void run() {
- startSettings(ZenModePanel.ZEN_SETTINGS);
- }
- };
-
- private final Runnable mStartZenPrioritySettings = new Runnable() {
- @Override
- public void run() {
- startSettings(ZenModePanel.ZEN_PRIORITY_SETTINGS);
- }
- };
-
- private final class RemoteVolumeController extends IRemoteVolumeController.Stub {
- @Override
- public void remoteVolumeChanged(ISessionController binder, int flags)
- throws RemoteException {
- MediaController controller = new MediaController(mContext, binder);
- mPanel.postRemoteVolumeChanged(controller, flags);
- }
-
- @Override
- public void updateRemoteController(ISessionController session) throws RemoteException {
- mPanel.postRemoteSliderVisibility(session != null);
- // TODO stash default session in case the slider can be opened other
- // than by remoteVolumeChanged.
- }
- }
-
- /** For now, simply host an unmodified base volume panel in this process. */
- private final class VolumeController extends IVolumeController.Stub {
-
- @Override
- public void displaySafeVolumeWarning(int flags) throws RemoteException {
- mPanel.postDisplaySafeVolumeWarning(flags);
- }
-
- @Override
- public void volumeChanged(int streamType, int flags)
- throws RemoteException {
- mPanel.postVolumeChanged(streamType, flags);
- }
-
- @Override
- public void masterMuteChanged(int flags) throws RemoteException {
- // no-op
- }
-
- @Override
- public void setLayoutDirection(int layoutDirection)
- throws RemoteException {
- mPanel.postLayoutDirection(layoutDirection);
- }
-
- @Override
- public void dismiss() throws RemoteException {
- dismissNow();
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index e979786..5f04aaf 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -31,7 +31,6 @@
import android.media.AudioManager;
import android.media.session.MediaSessionManager;
import android.os.Handler;
-import android.os.SystemProperties;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
@@ -52,8 +51,6 @@
private static final String TAG = "VolumeUI";
private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
- private static final boolean USE_OLD_VOLUME = SystemProperties.getBoolean("volume.old", false);
-
private final Handler mHandler = new Handler();
private final Receiver mReceiver = new Receiver();
private final RestorationNotification mRestorationNotification = new RestorationNotification();
@@ -64,8 +61,7 @@
private MediaSessionManager mMediaSessionManager;
private ServiceMonitor mVolumeControllerService;
- private VolumePanelComponent mOldVolume;
- private VolumeDialogComponent mNewVolume;
+ private VolumeDialogComponent mVolumeComponent;
@Override
public void start() {
@@ -77,8 +73,7 @@
mMediaSessionManager = (MediaSessionManager) mContext
.getSystemService(Context.MEDIA_SESSION_SERVICE);
final ZenModeController zenController = new ZenModeControllerImpl(mContext, mHandler);
- mOldVolume = new VolumePanelComponent(this, mContext, mHandler, zenController);
- mNewVolume = new VolumeDialogComponent(this, mContext, null, zenController);
+ mVolumeComponent = new VolumeDialogComponent(this, mContext, null, zenController);
putComponent(VolumeComponent.class, getVolumeComponent());
mReceiver.start();
mVolumeControllerService = new ServiceMonitor(TAG, LOGD,
@@ -88,7 +83,7 @@
}
private VolumeComponent getVolumeComponent() {
- return USE_OLD_VOLUME ? mOldVolume : mNewVolume;
+ return mVolumeComponent;
}
@Override
@@ -235,7 +230,7 @@
.putExtra(Receiver.EXTRA_COMPONENT, component);
mNotificationManager.notify(R.id.notification_volumeui,
new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_ringer_audible)
+ .setSmallIcon(R.drawable.ic_volume_media)
.setWhen(0)
.setShowWhen(false)
.setOngoing(true)
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 23d5c05..98fb11b 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -107,7 +107,16 @@
@Override
public void dumpControllerState(PrintWriter pw) {
- // TODO:
+ pw.println("AppIdle");
+ pw.println("Plugged In: " + mPluggedIn);
+ synchronized (mTrackedTasks) {
+ for (JobStatus task : mTrackedTasks) {
+ pw.print(task.job.getService().getPackageName());
+ pw.print(":idle=" + !task.appNotIdleConstraintSatisfied.get());
+ pw.print(", ");
+ }
+ pw.println();
+ }
}
@Override
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 66072da..a17474a 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -17,6 +17,7 @@
package android.telecom;
import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
@@ -30,6 +31,8 @@
import com.android.internal.telecom.IInCallService;
import java.lang.String;
+import java.util.Collections;
+import java.util.List;
/**
* This service is implemented by any app that wishes to provide the user-interface for managing
@@ -63,6 +66,7 @@
switch (msg.what) {
case MSG_SET_IN_CALL_ADAPTER:
mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj));
+ mPhone.addListener(mPhoneListener);
onPhoneCreated(mPhone);
break;
case MSG_ADD_CALL:
@@ -144,6 +148,39 @@
}
}
+ private Phone.Listener mPhoneListener = new Phone.Listener() {
+ /** ${inheritDoc} */
+ @Override
+ public void onAudioStateChanged(Phone phone, AudioState audioState) {
+ InCallService.this.onAudioStateChanged(audioState);
+ }
+
+ /** ${inheritDoc} */
+ @Override
+ public void onBringToForeground(Phone phone, boolean showDialpad) {
+ InCallService.this.onBringToForeground(showDialpad);
+ }
+
+ /** ${inheritDoc} */
+ @Override
+ public void onCallAdded(Phone phone, Call call) {
+ InCallService.this.onCallAdded(call);
+ }
+
+ /** ${inheritDoc} */
+ @Override
+ public void onCallRemoved(Phone phone, Call call) {
+ InCallService.this.onCallRemoved(call);
+ }
+
+ /** ${inheritDoc} */
+ @Override
+ public void onCanAddCallChanged(Phone phone, boolean canAddCall) {
+ InCallService.this.onCanAddCallChanged(canAddCall);
+ }
+
+ };
+
private Phone mPhone;
public InCallService() {
@@ -161,8 +198,14 @@
mPhone = null;
oldPhone.destroy();
+ // destroy sets all the calls to disconnected if any live ones still exist. Therefore,
+ // it is important to remove the Listener *after* the call to destroy so that
+ // InCallService.on* callbacks are appropriately called.
+ oldPhone.removeListener(mPhoneListener);
+
onPhoneDestroyed(oldPhone);
}
+
return false;
}
@@ -172,19 +215,75 @@
* @return The {@code Phone} object associated with this {@code InCallService}, or {@code null}
* if the {@code InCallService} is not in a state where it has an associated
* {@code Phone}.
+ * @hide
*/
+ @SystemApi
public final Phone getPhone() {
return mPhone;
}
/**
+ * Obtains the current list of {@code Call}s to be displayed by this in-call experience.
+ *
+ * @return A list of the relevant {@code Call}s.
+ */
+ public final List<Call> getCalls() {
+ return mPhone == null ? Collections.<Call>emptyList() : mPhone.getCalls();
+ }
+
+ /**
+ * Returns if the device can support additional calls.
+ *
+ * @return Whether the phone supports adding more calls.
+ */
+ public final boolean canAddCall() {
+ return mPhone == null ? false : mPhone.canAddCall();
+ }
+
+ /**
+ * Obtains the current phone call audio state.
+ *
+ * @return An object encapsulating the audio state. Returns null if the service is not
+ * fully initialized.
+ */
+ public final AudioState getAudioState() {
+ return mPhone == null ? null : mPhone.getAudioState();
+ }
+
+ /**
+ * Sets the microphone mute state. When this request is honored, there will be change to
+ * the {@link #getAudioState()}.
+ *
+ * @param state {@code true} if the microphone should be muted; {@code false} otherwise.
+ */
+ public final void setMuted(boolean state) {
+ if (mPhone != null) {
+ mPhone.setMuted(state);
+ }
+ }
+
+ /**
+ * Sets the audio route (speaker, bluetooth, etc...). When this request is honored, there will
+ * be change to the {@link #getAudioState()}.
+ *
+ * @param route The audio route to use.
+ */
+ public final void setAudioRoute(int route) {
+ if (mPhone != null) {
+ mPhone.setAudioRoute(route);
+ }
+ }
+
+ /**
* Invoked when the {@code Phone} has been created. This is a signal to the in-call experience
* to start displaying in-call information to the user. Each instance of {@code InCallService}
* will have only one {@code Phone}, and this method will be called exactly once in the lifetime
* of the {@code InCallService}.
*
* @param phone The {@code Phone} object associated with this {@code InCallService}.
+ * @hide
*/
+ @SystemApi
public void onPhoneCreated(Phone phone) {
}
@@ -195,11 +294,64 @@
* call to {@link #onPhoneCreated(Phone)}.
*
* @param phone The {@code Phone} object associated with this {@code InCallService}.
+ * @hide
*/
+ @SystemApi
public void onPhoneDestroyed(Phone phone) {
}
/**
+ * Called when the audio state changes.
+ *
+ * @param audioState The new {@link AudioState}.
+ */
+ public void onAudioStateChanged(AudioState audioState) {
+ }
+
+ /**
+ * Called to bring the in-call screen to the foreground. The in-call experience should
+ * respond immediately by coming to the foreground to inform the user of the state of
+ * ongoing {@code Call}s.
+ *
+ * @param showDialpad If true, put up the dialpad when the screen is shown.
+ */
+ public void onBringToForeground(boolean showDialpad) {
+ }
+
+ /**
+ * Called when a {@code Call} has been added to this in-call session. The in-call user
+ * experience should add necessary state listeners to the specified {@code Call} and
+ * immediately start to show the user information about the existence
+ * and nature of this {@code Call}. Subsequent invocations of {@link #getCalls()} will
+ * include this {@code Call}.
+ *
+ * @param call A newly added {@code Call}.
+ */
+ public void onCallAdded(Call call) {
+ }
+
+ /**
+ * Called when a {@code Call} has been removed from this in-call session. The in-call user
+ * experience should remove any state listeners from the specified {@code Call} and
+ * immediately stop displaying any information about this {@code Call}.
+ * Subsequent invocations of {@link #getCalls()} will no longer include this {@code Call}.
+ *
+ * @param call A newly removed {@code Call}.
+ */
+ public void onCallRemoved(Call call) {
+ }
+
+ /**
+ * Called when the ability to add more calls changes. If the phone cannot
+ * support more calls then {@code canAddCall} is set to {@code false}. If it can, then it
+ * is set to {@code true}. This can be used to control the visibility of UI to add more calls.
+ *
+ * @param canAddCall Indicates whether an additional call can be added.
+ */
+ public void onCanAddCallChanged(boolean canAddCall) {
+ }
+
+ /**
* Class to invoke functionality related to video calls.
*/
public static abstract class VideoCall {
@@ -373,8 +525,7 @@
*
* @param cameraCapabilities The changed camera capabilities.
*/
- public abstract void onCameraCapabilitiesChanged(
- CameraCapabilities cameraCapabilities);
+ public abstract void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities);
}
}
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 60b9cb9..5abbb50 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -720,20 +720,21 @@
}
/**
- * Return whether a given phone account has a voicemail number configured.
+ * Return the voicemail number for a given phone account.
*
- * @param accountHandle The handle for the account to check for a voicemail number.
- * @return {@code true} If the given phone account has a voicemail number.
+ * @param accountHandle The handle for the phone account.
+ * @return The voicemail number for the phone account, and {@code null} if one has not been
+ * configured.
*/
- public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) {
+ public String getVoiceMailNumber(PhoneAccountHandle accountHandle) {
try {
if (isServiceConnected()) {
- return getTelecomService().hasVoiceMailNumber(accountHandle);
+ return getTelecomService().getVoiceMailNumber(accountHandle);
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling ITelecomService#hasVoiceMailNumber.", e);
}
- return false;
+ return null;
}
/**
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index d2030f2..35db97f 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -121,9 +121,9 @@
boolean isVoiceMailNumber(in PhoneAccountHandle accountHandle, String number);
/**
- * @see TelecomServiceImpl#hasVoiceMailNumber
+ * @see TelecomServiceImpl#getVoiceMailNumber
*/
- boolean hasVoiceMailNumber(in PhoneAccountHandle accountHandle);
+ String getVoiceMailNumber(in PhoneAccountHandle accountHandle);
/**
* @see TelecomServiceImpl#getLine1Number
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
new file mode 100644
index 0000000..cdf77b4
--- /dev/null
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2015 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.telephony;
+
+import com.android.internal.telephony.ICarrierConfigLoader;
+
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+/**
+ * Provides access to telephony configuration values that are carrier-specific.
+ * <p>
+ * Users should obtain an instance of this class by calling
+ * {@code mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);}
+ * </p>
+ *
+ * @see Context#getSystemService
+ * @see Context#CARRIER_CONFIG_SERVICE
+ */
+public class CarrierConfigManager {
+ /**
+ * @hide
+ */
+ public CarrierConfigManager() {
+ }
+
+ /**
+ * This intent is broadcast by the system when carrier config changes.
+ */
+ public static final String
+ ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+
+ /**
+ * Flag specifying whether VoLTE should be available for carrier, independent of carrier
+ * provisioning. If false: hard disabled. If true: then depends on carrier provisioning,
+ * availability, etc.
+ */
+ public static final String BOOL_CARRIER_VOLTE_AVAILABLE = "bool_carrier_volte_available";
+
+ /**
+ * Flag specifying whether VoLTE availability is based on provisioning.
+ */
+ public static final String BOOL_CARRIER_VOLTE_PROVISIONED = "bool_carrier_volte_provisioned";
+
+ /**
+ * Flag specifying whether VoLTE TTY is supported.
+ */
+ public static final String BOOL_CARRIER_VOLTE_TTY_SUPPORTED
+ = "bool_carrier_volte_tty_supported";
+
+ /**
+ * Show APN Settings for some CDMA carriers.
+ */
+ public static final String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
+
+ /**
+ * If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 or RIL_RADIO_TECHNOLOGY_UNKNOWN:0
+ * this is the value that should be used instead. A configuration value of
+ * RIL_RADIO_TECHNOLOGY_UNKNOWN:0 means there is no replacement value and that the default
+ * assumption for phone type (GSM) should be used.
+ */
+ public static final String INT_VOLTE_REPLACEMENT_RAT = "int_volte_replacement_rat";
+
+ private final static String TAG = "CarrierConfigManager";
+
+ /** The default value for every variable. */
+ private final static Bundle sDefaults;
+
+ static {
+ sDefaults = new Bundle();
+ sDefaults.putBoolean(BOOL_CARRIER_VOLTE_AVAILABLE, false);
+ sDefaults.putBoolean(BOOL_CARRIER_VOLTE_PROVISIONED, false);
+ sDefaults.putBoolean(BOOL_CARRIER_VOLTE_TTY_SUPPORTED, true);
+ sDefaults.putBoolean(BOOL_SHOW_APN_SETTING_CDMA, false);
+
+ sDefaults.putInt(INT_VOLTE_REPLACEMENT_RAT, 0);
+ }
+
+ /**
+ * Gets the configuration values for a particular subscription, which is associated with a
+ * specific SIM card. If an invalid subId is used, the returned config will contain default
+ * values.
+ *
+ * @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
+ * @return A {@link Bundle} containing the config for the given subId, or default values for an
+ * invalid subId.
+ */
+ public Bundle getConfigForSubId(int subId) {
+ try {
+ return getICarrierConfigLoader().getConfigForSubId(subId);
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "Error getting config for subId " + Integer.toString(subId) + ": "
+ + ex.toString());
+ } catch (NullPointerException ex) {
+ Rlog.e(TAG, "Error getting config for subId " + Integer.toString(subId) + ": "
+ + ex.toString());
+ }
+ return null;
+ }
+
+ /**
+ * Gets the configuration values for the default subscription.
+ *
+ * @see #getConfigForSubId
+ */
+ public Bundle getConfig() {
+ return getConfigForSubId(SubscriptionManager.getDefaultSubId());
+ }
+
+ /**
+ * Calling this method triggers telephony services to fetch the current carrier configuration.
+ * <p>
+ * Normally this does not need to be called because the platform reloads config on its own. Call
+ * this method if your app wants to update config at an arbitrary moment.
+ * </p>
+ * <p>
+ * This method returns before the reload has completed, and
+ * {@link android.service.carrier.CarrierConfigService#onLoadConfig} will be called from an
+ * arbitrary thread.
+ * </p>
+ */
+ public void reloadCarrierConfigForSubId(int subId) {
+ try {
+ getICarrierConfigLoader().reloadCarrierConfigForSubId(subId);
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
+ } catch (NullPointerException ex) {
+ Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
+ }
+ }
+
+ /**
+ * Request the carrier config loader to update the cofig for phoneId.
+ *
+ * Depending on simState, the config may be cleared or loaded from config app.
+ * This is only used by SubscriptionInfoUpdater.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void updateConfigForPhoneId(int phoneId, String simState) {
+ try {
+ getICarrierConfigLoader().updateConfigForPhoneId(phoneId, simState);
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
+ } catch (NullPointerException ex) {
+ Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
+ }
+ }
+
+ /**
+ * Returns a bundle with the default value for every supported configuration variable.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static Bundle getDefaultConfig() {
+ return sDefaults;
+ }
+
+ /** @hide */
+ private ICarrierConfigLoader getICarrierConfigLoader() {
+ return ICarrierConfigLoader.Stub
+ .asInterface(ServiceManager.getService(Context.CARRIER_CONFIG_SERVICE));
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
new file mode 100644
index 0000000..b5cdd9a2
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 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.internal.telephony;
+
+import android.os.Bundle;
+
+/**
+ * Interface used to interact with the CarrierConfigLoader
+ */
+interface ICarrierConfigLoader {
+
+ Bundle getConfigForSubId(int subId);
+
+ void reloadCarrierConfigForSubId(int subId);
+
+ void updateConfigForPhoneId(int phoneId, String simState);
+}
diff --git a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
index aabd3f1..f7654ce 100644
--- a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
@@ -16,7 +16,7 @@
package android.app;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.content.Context;
@@ -30,19 +30,19 @@
*
* The methods being re-implemented are the ones responsible for instantiating Fragment objects.
* Because the classes of these objects are found in the project, these methods need access to
- * {@link IProjectCallback} object. They are however static methods, so the callback is set
- * before the inflation through {@link #setProjectCallback(IProjectCallback)}.
+ * {@link LayoutlibCallback} object. They are however static methods, so the callback is set
+ * before the inflation through {@link #setLayoutlibCallback(LayoutlibCallback)}.
*/
public class Fragment_Delegate {
- private static IProjectCallback sProjectCallback;
+ private static LayoutlibCallback sLayoutlibCallback;
/**
- * Sets the current {@link IProjectCallback} to be used to instantiate classes coming
+ * Sets the current {@link LayoutlibCallback} to be used to instantiate classes coming
* from the project being rendered.
*/
- public static void setProjectCallback(IProjectCallback projectCallback) {
- sProjectCallback = projectCallback;
+ public static void setLayoutlibCallback(LayoutlibCallback layoutlibCallback) {
+ sLayoutlibCallback = layoutlibCallback;
}
/**
@@ -62,17 +62,17 @@
* This is currently just used to get its ClassLoader.
* @param fname The class name of the fragment to instantiate.
* @param args Bundle of arguments to supply to the fragment, which it
- * can retrieve with {@link #getArguments()}. May be null.
+ * can retrieve with {@link Fragment#getArguments()}. May be null.
* @return Returns a new fragment instance.
- * @throws InstantiationException If there is a failure in instantiating
+ * @throws Fragment.InstantiationException If there is a failure in instantiating
* the given fragment class. This is a runtime exception; it is not
* normally expected to happen.
*/
@LayoutlibDelegate
/*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
try {
- if (sProjectCallback != null) {
- Fragment f = (Fragment) sProjectCallback.loadView(fname,
+ if (sLayoutlibCallback != null) {
+ Fragment f = (Fragment) sLayoutlibCallback.loadView(fname,
new Class[0], new Object[0]);
if (args != null) {
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
index 96ca250..2c2c672 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
@@ -16,8 +16,8 @@
package android.content.res;
-import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
@@ -49,7 +49,7 @@
public final class BridgeResources extends Resources {
private BridgeContext mContext;
- private IProjectCallback mProjectCallback;
+ private LayoutlibCallback mLayoutlibCallback;
private boolean[] mPlatformResourceFlag = new boolean[1];
private TypedValue mTmpValue = new TypedValue();
@@ -94,12 +94,12 @@
AssetManager assets,
DisplayMetrics metrics,
Configuration config,
- IProjectCallback projectCallback) {
+ LayoutlibCallback layoutlibCallback) {
return Resources.mSystem = new BridgeResources(context,
assets,
metrics,
config,
- projectCallback);
+ layoutlibCallback);
}
/**
@@ -109,16 +109,16 @@
public static void disposeSystem() {
if (Resources.mSystem instanceof BridgeResources) {
((BridgeResources)(Resources.mSystem)).mContext = null;
- ((BridgeResources)(Resources.mSystem)).mProjectCallback = null;
+ ((BridgeResources)(Resources.mSystem)).mLayoutlibCallback = null;
}
Resources.mSystem = null;
}
private BridgeResources(BridgeContext context, AssetManager assets, DisplayMetrics metrics,
- Configuration config, IProjectCallback projectCallback) {
+ Configuration config, LayoutlibCallback layoutlibCallback) {
super(assets, metrics, config);
mContext = context;
- mProjectCallback = projectCallback;
+ mLayoutlibCallback = layoutlibCallback;
}
public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) {
@@ -138,8 +138,8 @@
}
// didn't find a match in the framework? look in the project.
- if (mProjectCallback != null) {
- resourceInfo = mProjectCallback.resolveResourceId(id);
+ if (mLayoutlibCallback != null) {
+ resourceInfo = mLayoutlibCallback.resolveResourceId(id);
if (resourceInfo != null) {
platformResFlag_out[0] = false;
@@ -154,11 +154,6 @@
}
@Override
- public Drawable getDrawable(int id) throws NotFoundException {
- return getDrawable(id, null);
- }
-
- @Override
public Drawable getDrawable(int id, Theme theme) {
Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
@@ -257,7 +252,7 @@
try {
// check if the current parser can provide us with a custom parser.
if (mPlatformResourceFlag[0] == false) {
- parser = mProjectCallback.getParser(value);
+ parser = mLayoutlibCallback.getParser(value);
}
// create a new one manually if needed.
@@ -692,8 +687,8 @@
Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
// if the name is unknown in the framework, get it from the custom view loader.
- if (resourceInfo == null && mProjectCallback != null) {
- resourceInfo = mProjectCallback.resolveResourceId(id);
+ if (resourceInfo == null && mLayoutlibCallback != null) {
+ resourceInfo = mLayoutlibCallback.resolveResourceId(id);
}
String message = null;
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 18036927..7d4271b 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -16,6 +16,7 @@
package android.content.res;
+import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.AttrResourceValue;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderResources;
@@ -40,9 +41,12 @@
import android.view.ViewGroup.LayoutParams;
import java.io.File;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
+import static com.android.ide.common.rendering.api.RenderResources.*;
+
/**
* Custom implementation of TypedArray to handle non compiled resources.
*/
@@ -56,6 +60,11 @@
private final String[] mNames;
private final boolean[] mIsFramework;
+ // Contains ids that are @empty. We still store null in mResourceData for that index, since we
+ // want to save on the check against empty, each time a resource value is requested.
+ @Nullable
+ private int[] mEmptyIds;
+
public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
boolean platformFile) {
super(resources, null, null, 0);
@@ -90,19 +99,32 @@
// fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
// first count the array size
int count = 0;
+ ArrayList<Integer> emptyIds = null;
for (int i = 0; i < mResourceData.length; i++) {
ResourceValue data = mResourceData[i];
if (data != null) {
- if (RenderResources.REFERENCE_NULL.equals(data.getValue())) {
- // No need to store this resource value. This saves needless checking for
- // "@null" every time an attribute is requested.
+ String dataValue = data.getValue();
+ if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) {
mResourceData[i] = null;
+ } else if (REFERENCE_EMPTY.equals(dataValue)) {
+ mResourceData[i] = null;
+ if (emptyIds == null) {
+ emptyIds = new ArrayList<Integer>(4);
+ }
+ emptyIds.add(i);
} else {
count++;
}
}
}
+ if (emptyIds != null) {
+ mEmptyIds = new int[emptyIds.size()];
+ for (int i = 0; i < emptyIds.size(); i++) {
+ mEmptyIds[i] = emptyIds.get(i);
+ }
+ }
+
// allocate the table with an extra to store the size
mIndices = new int[count+1];
mIndices[0] = count;
@@ -624,7 +646,7 @@
if (isFrameworkId) {
idValue = Bridge.getResourceId(ResourceType.ID, idName);
} else {
- idValue = mContext.getProjectCallback().getResourceId(ResourceType.ID, idName);
+ idValue = mContext.getLayoutlibCallback().getResourceId(ResourceType.ID, idName);
}
return idValue == null ? defValue : idValue;
}
@@ -644,7 +666,7 @@
idValue = Bridge.getResourceId(resValue.getResourceType(),
resValue.getName());
} else {
- idValue = mContext.getProjectCallback().getResourceId(
+ idValue = mContext.getLayoutlibCallback().getResourceId(
resValue.getResourceType(), resValue.getName());
}
@@ -748,6 +770,12 @@
return index >= 0 && index < mResourceData.length && mResourceData[index] != null;
}
+ @Override
+ public boolean hasValueOrEmpty(int index) {
+ return hasValue(index) || index >= 0 && index < mResourceData.length &&
+ mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0;
+ }
+
/**
* Retrieve the raw TypedValue for the attribute at <var>index</var>
* and return a temporary object holding its data. This object is only
diff --git a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
index 691339e..138b2d5 100644
--- a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
+++ b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
@@ -69,8 +69,8 @@
// this is not an attribute in the android namespace, we query the customviewloader, if
// the namespaces match.
- if (mContext.getProjectCallback().getNamespace().equals(ns)) {
- Integer v = mContext.getProjectCallback().getResourceId(ResourceType.ATTR, name);
+ if (mContext.getLayoutlibCallback().getNamespace().equals(ns)) {
+ Integer v = mContext.getLayoutlibCallback().getResourceId(ResourceType.ATTR, name);
if (v != null) {
return v.intValue();
}
@@ -273,7 +273,7 @@
if (mPlatformFile || resource.isFramework()) {
id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
} else {
- id = mContext.getProjectCallback().getResourceId(
+ id = mContext.getLayoutlibCallback().getResourceId(
resource.getResourceType(), resource.getName());
}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index 80036e5..9eea663 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -16,7 +16,7 @@
package android.view;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.MergeCookie;
import com.android.ide.common.rendering.api.ResourceReference;
@@ -46,7 +46,7 @@
*/
public final class BridgeInflater extends LayoutInflater {
- private final IProjectCallback mProjectCallback;
+ private final LayoutlibCallback mLayoutlibCallback;
private boolean mIsInMerge = false;
private ResourceReference mResourceReference;
@@ -64,21 +64,21 @@
super(original, newContext);
newContext = getBaseContext(newContext);
if (newContext instanceof BridgeContext) {
- mProjectCallback = ((BridgeContext) newContext).getProjectCallback();
+ mLayoutlibCallback = ((BridgeContext) newContext).getLayoutlibCallback();
} else {
- mProjectCallback = null;
+ mLayoutlibCallback = null;
}
}
/**
- * Instantiate a new BridgeInflater with an {@link IProjectCallback} object.
+ * Instantiate a new BridgeInflater with an {@link LayoutlibCallback} object.
*
* @param context The Android application context.
- * @param projectCallback the {@link IProjectCallback} object.
+ * @param layoutlibCallback the {@link LayoutlibCallback} object.
*/
- public BridgeInflater(Context context, IProjectCallback projectCallback) {
+ public BridgeInflater(Context context, LayoutlibCallback layoutlibCallback) {
super(context);
- mProjectCallback = projectCallback;
+ mLayoutlibCallback = layoutlibCallback;
mConstructorArgs[0] = context;
}
@@ -167,12 +167,13 @@
ResourceValue value = null;
+ @SuppressWarnings("deprecation")
Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource);
if (layoutInfo != null) {
value = bridgeContext.getRenderResources().getFrameworkResource(
ResourceType.LAYOUT, layoutInfo.getSecond());
} else {
- layoutInfo = mProjectCallback.resolveResourceId(resource);
+ layoutInfo = mLayoutlibCallback.resolveResourceId(resource);
if (layoutInfo != null) {
value = bridgeContext.getRenderResources().getProjectResource(
@@ -203,7 +204,7 @@
}
private View loadCustomView(String name, AttributeSet attrs) throws Exception {
- if (mProjectCallback != null) {
+ if (mLayoutlibCallback != null) {
// first get the classname in case it's not the node name
if (name.equals("view")) {
name = attrs.getAttributeValue(null, "class");
@@ -211,7 +212,7 @@
mConstructorArgs[1] = attrs;
- Object customView = mProjectCallback.loadView(name, mConstructorSignature,
+ Object customView = mLayoutlibCallback.loadView(name, mConstructorSignature,
mConstructorArgs);
if (customView instanceof View) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 8e74ce1..1da8bb4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -19,8 +19,8 @@
import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.AssetRepository;
import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
@@ -114,7 +114,7 @@
private final RenderResources mRenderResources;
private final Configuration mConfig;
private final ApplicationInfo mApplicationInfo;
- private final IProjectCallback mProjectCallback;
+ private final LayoutlibCallback mLayoutlibCallback;
private final WindowManager mWindowManager;
private final DisplayManager mDisplayManager;
@@ -148,13 +148,13 @@
public BridgeContext(Object projectKey, DisplayMetrics metrics,
RenderResources renderResources,
AssetRepository assets,
- IProjectCallback projectCallback,
+ LayoutlibCallback layoutlibCallback,
Configuration config,
int targetSdkVersion,
boolean hasRtlSupport) {
mProjectKey = projectKey;
mMetrics = metrics;
- mProjectCallback = projectCallback;
+ mLayoutlibCallback = layoutlibCallback;
mRenderResources = renderResources;
mConfig = config;
@@ -173,7 +173,7 @@
/**
* Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
- * {@link DisplayMetrics}, {@link Configuration}, and {@link IProjectCallback}.
+ * {@link DisplayMetrics}, {@link Configuration}, and {@link LayoutlibCallback}.
*
* @see #disposeResources()
*/
@@ -185,7 +185,7 @@
assetManager,
mMetrics,
mConfig,
- mProjectCallback);
+ mLayoutlibCallback);
mTheme = mSystemResources.newTheme();
}
@@ -224,8 +224,8 @@
return mMetrics;
}
- public IProjectCallback getProjectCallback() {
- return mProjectCallback;
+ public LayoutlibCallback getLayoutlibCallback() {
+ return mLayoutlibCallback;
}
public RenderResources getRenderResources() {
@@ -284,7 +284,7 @@
Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid);
boolean isFrameworkRes = true;
if (resourceInfo == null) {
- resourceInfo = mProjectCallback.resolveResourceId(resid);
+ resourceInfo = mLayoutlibCallback.resolveResourceId(resid);
isFrameworkRes = false;
}
@@ -340,8 +340,8 @@
}
// didn't find a match in the framework? look in the project.
- if (mProjectCallback != null) {
- resourceInfo = mProjectCallback.resolveResourceId(id);
+ if (mLayoutlibCallback != null) {
+ resourceInfo = mLayoutlibCallback.resolveResourceId(id);
if (resourceInfo != null) {
return new ResourceReference(resourceInfo.getSecond(), false);
@@ -439,9 +439,9 @@
private ILayoutPullParser getParser(ResourceReference resource) {
ILayoutPullParser parser;
if (resource instanceof ResourceValue) {
- parser = mProjectCallback.getParser((ResourceValue) resource);
+ parser = mLayoutlibCallback.getParser((ResourceValue) resource);
} else {
- parser = mProjectCallback.getParser(resource.getName());
+ parser = mLayoutlibCallback.getParser(resource.getName());
}
return parser;
}
@@ -694,7 +694,7 @@
boolean isFrameworkRes = true;
Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
if (value == null) {
- value = mProjectCallback.resolveResourceId(defStyleRes);
+ value = mLayoutlibCallback.resolveResourceId(defStyleRes);
isFrameworkRes = false;
}
@@ -732,7 +732,7 @@
}
}
- String appNamespace = mProjectCallback.getNamespace();
+ String appNamespace = mLayoutlibCallback.getNamespace();
if (attributeList != null) {
for (int index = 0 ; index < attributeList.size() ; index++) {
@@ -875,7 +875,7 @@
if (resolvedResource != null) {
isFramework = true;
} else {
- resolvedResource = mProjectCallback.resolveResourceId(attr);
+ resolvedResource = mLayoutlibCallback.resolveResourceId(attr);
}
if (resolvedResource != null) {
@@ -901,7 +901,7 @@
return Pair.of(info.getSecond(), Boolean.TRUE);
}
- info = mProjectCallback.resolveResourceId(attr);
+ info = mLayoutlibCallback.resolveResourceId(attr);
if (info != null) {
return Pair.of(info.getSecond(), Boolean.FALSE);
}
@@ -953,8 +953,8 @@
// getResourceId creates a new resource id if an existing resource id isn't found. So, we
// check for the existence of the resource before calling it.
if (getRenderResources().getProjectResource(resType, resName) != null) {
- if (mProjectCallback != null) {
- Integer value = mProjectCallback.getResourceId(resType, resName);
+ if (mLayoutlibCallback != null) {
+ Integer value = mLayoutlibCallback.getResourceId(resType, resName);
if (value != null) {
return value;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
index b72329a..9273ac2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
@@ -18,8 +18,8 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
@@ -30,7 +30,6 @@
import android.widget.LinearLayout;
import java.lang.reflect.Method;
-import java.util.HashMap;
import static com.android.layoutlib.bridge.util.ReflectionUtils.*;
@@ -61,7 +60,7 @@
public static void setAdapter(@NonNull View recyclerView, @NonNull BridgeContext context,
@NonNull SessionParams params) {
try {
- setLayoutManager(recyclerView, context, params.getProjectCallback());
+ setLayoutManager(recyclerView, context, params.getLayoutlibCallback());
Object adapter = createAdapter(params);
setProperty(recyclerView, CN_ADAPTER, adapter, "setAdapter");
} catch (ReflectionException e) {
@@ -71,7 +70,7 @@
}
private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
- @NonNull IProjectCallback callback) throws ReflectionException {
+ @NonNull LayoutlibCallback callback) throws ReflectionException {
Object cookie = context.getCookie(recyclerView);
assert cookie == null || cookie instanceof LayoutManagerType || cookie instanceof String;
if (!(cookie instanceof LayoutManagerType)) {
@@ -90,7 +89,7 @@
@Nullable
private static Object createLayoutManager(@Nullable LayoutManagerType type,
- @NonNull Context context, @NonNull IProjectCallback callback)
+ @NonNull Context context, @NonNull LayoutlibCallback callback)
throws ReflectionException {
if (type == null) {
type = LayoutManagerType.getDefault();
@@ -109,7 +108,7 @@
return null;
}
try {
- return params.getProjectCallback().loadView(CN_ADAPTER, new Class[0], new Object[0]);
+ return params.getLayoutlibCallback().loadView(CN_ADAPTER, new Class[0], new Object[0]);
} catch (Exception e) {
throw new ReflectionException(e);
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
index ee57067..dd1f661 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -70,7 +70,7 @@
try {
Class[] constructorParams = {View.class};
Object[] constructorArgs = {getDecorContent()};
- mWindowDecorActionBar = params.getProjectCallback().loadView(WINDOW_ACTION_BAR_CLASS,
+ mWindowDecorActionBar = params.getLayoutlibCallback().loadView(WINDOW_ACTION_BAR_CLASS,
constructorParams, constructorArgs);
mWindowActionBarClass = mWindowDecorActionBar == null ? null :
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
index 2a83ea1..3d1a9b9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
@@ -51,7 +51,7 @@
@NonNull ViewGroup parentView) {
mBridgeContext = context;
mParams = params;
- mCallback = params.getProjectCallback().getActionBarCallback();
+ mCallback = params.getLayoutlibCallback().getActionBarCallback();
ResourceValue layoutName = getLayoutResource(context);
if (layoutName == null) {
throw new RuntimeException("Unable to find the layout for Action Bar.");
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index 127cb72..c708316 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -16,10 +16,6 @@
package com.android.layoutlib.bridge.impl;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderParams;
@@ -43,6 +39,10 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
/**
* Base class for rendering action.
*
@@ -120,7 +120,7 @@
// build the context
mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
- mParams.getAssets(), mParams.getProjectCallback(), getConfiguration(),
+ mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(),
mParams.getTargetSdkVersion(), mParams.isRtlSupported());
setUp();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 7c11284d..d9572591 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -16,20 +16,13 @@
package com.android.layoutlib.bridge.impl;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.IAnimationListener;
import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.ResourceReference;
@@ -54,13 +47,13 @@
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
-import com.android.layoutlib.bridge.bars.BridgeActionBar;
import com.android.layoutlib.bridge.bars.AppCompatActionBar;
+import com.android.layoutlib.bridge.bars.BridgeActionBar;
import com.android.layoutlib.bridge.bars.Config;
+import com.android.layoutlib.bridge.bars.FrameworkActionBar;
import com.android.layoutlib.bridge.bars.NavigationBar;
import com.android.layoutlib.bridge.bars.StatusBar;
import com.android.layoutlib.bridge.bars.TitleBar;
-import com.android.layoutlib.bridge.bars.FrameworkActionBar;
import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
import com.android.resources.Density;
@@ -116,6 +109,13 @@
import java.util.List;
import java.util.Map;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
/**
* Class implementing the render session.
* <p/>
@@ -219,7 +219,7 @@
WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
// build the inflater and parser.
- mInflater = new BridgeInflater(context, params.getProjectCallback());
+ mInflater = new BridgeInflater(context, params.getLayoutlibCallback());
context.setBridgeInflater(mInflater);
mBlockParser = new BridgeXmlBlockParser(
@@ -401,7 +401,7 @@
// Sets the project callback (custom view loader) to the fragment delegate so that
// it can instantiate the custom Fragment.
- Fragment_Delegate.setProjectCallback(params.getProjectCallback());
+ Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback());
String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG);
boolean isPreference = "PreferenceScreen".equals(rootTag);
@@ -416,13 +416,13 @@
// done with the parser, pop it.
context.popParser();
- Fragment_Delegate.setProjectCallback(null);
+ Fragment_Delegate.setLayoutlibCallback(null);
// set the AttachInfo on the root view.
AttachInfo_Accessor.setAttachInfo(mViewRoot);
// post-inflate process. For now this supports TabHost/TabWidget
- postInflateProcess(view, params.getProjectCallback(), isPreference ? view : null);
+ postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
// get the background drawable
if (mWindowBackground != null) {
@@ -686,7 +686,7 @@
animationResource = context.getRenderResources().getProjectResource(
ResourceType.ANIMATOR, animationName);
if (animationResource != null) {
- animationId = context.getProjectCallback().getResourceId(
+ animationId = context.getLayoutlibCallback().getResourceId(
ResourceType.ANIMATOR, animationName);
}
}
@@ -1257,17 +1257,17 @@
* {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
* based on the content of the {@link FrameLayout}.
* @param view the root view to process.
- * @param projectCallback callback to the project.
+ * @param layoutlibCallback callback to the project.
* @param skip the view and it's children are not processed.
*/
@SuppressWarnings("deprecation") // For the use of Pair
- private void postInflateProcess(View view, IProjectCallback projectCallback, View skip)
+ private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip)
throws PostInflateException {
if (view == skip) {
return;
}
if (view instanceof TabHost) {
- setupTabHost((TabHost) view, projectCallback);
+ setupTabHost((TabHost) view, layoutlibCallback);
} else if (view instanceof QuickContactBadge) {
QuickContactBadge badge = (QuickContactBadge) view;
badge.setImageToDefault();
@@ -1286,8 +1286,8 @@
// if there was no adapter binding, trying to get it from the call back.
if (binding == null) {
- binding = params.getProjectCallback().getAdapterBinding(listRef,
- context.getViewKey(view), view);
+ binding = layoutlibCallback.getAdapterBinding(
+ listRef, context.getViewKey(view), view);
}
if (binding != null) {
@@ -1303,7 +1303,7 @@
for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView(
binding.getHeaderAt(i),
- list, false /*attachToRoot*/, skipCallbackParser);
+ list, false, skipCallbackParser);
if (pair.getFirst() != null) {
list.addHeaderView(pair.getFirst());
}
@@ -1315,7 +1315,7 @@
for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView(
binding.getFooterAt(i),
- list, false /*attachToRoot*/, skipCallbackParser);
+ list, false, skipCallbackParser);
if (pair.getFirst() != null) {
list.addFooterView(pair.getFirst());
}
@@ -1326,17 +1326,14 @@
if (view instanceof ExpandableListView) {
((ExpandableListView) view).setAdapter(
- new FakeExpandableAdapter(
- listRef, binding, params.getProjectCallback()));
+ new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
} else {
((AbsListView) view).setAdapter(
- new FakeAdapter(
- listRef, binding, params.getProjectCallback()));
+ new FakeAdapter(listRef, binding, layoutlibCallback));
}
} else if (view instanceof AbsSpinner) {
((AbsSpinner) view).setAdapter(
- new FakeAdapter(
- listRef, binding, params.getProjectCallback()));
+ new FakeAdapter(listRef, binding, layoutlibCallback));
}
}
}
@@ -1347,7 +1344,7 @@
final int count = group.getChildCount();
for (int c = 0; c < count; c++) {
View child = group.getChildAt(c);
- postInflateProcess(child, projectCallback, skip);
+ postInflateProcess(child, layoutlibCallback, skip);
}
}
}
@@ -1371,10 +1368,10 @@
/**
* Sets up a {@link TabHost} object.
* @param tabHost the TabHost to setup.
- * @param projectCallback The project callback object to access the project R class.
+ * @param layoutlibCallback The project callback object to access the project R class.
* @throws PostInflateException
*/
- private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
+ private void setupTabHost(TabHost tabHost, LayoutlibCallback layoutlibCallback)
throws PostInflateException {
// look for the TabWidget, and the FrameLayout. They have their own specific names
View v = tabHost.findViewById(android.R.id.tabs);
@@ -1417,8 +1414,9 @@
if (count == 0) {
// Create a dummy child to get a single tab
- TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label",
- tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details))
+ TabSpec spec = tabHost.newTabSpec("tag")
+ .setIndicator("Tab Label", tabHost.getResources()
+ .getDrawable(android.R.drawable.ic_menu_info_details, null))
.setContent(new TabHost.TabContentFactory() {
@Override
public View createTabContent(String tag) {
@@ -1434,7 +1432,7 @@
@SuppressWarnings("ConstantConditions") // child cannot be null.
int id = child.getId();
@SuppressWarnings("deprecation")
- Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id);
+ Pair<ResourceType, String> resource = layoutlibCallback.resolveResourceId(id);
String name;
if (resource != null) {
name = resource.getSecond();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
index 6c998af..9aab340 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
@@ -17,7 +17,7 @@
package com.android.layoutlib.bridge.impl.binding;
import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute;
@@ -40,7 +40,7 @@
public class AdapterHelper {
static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
- IProjectCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
+ LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
// we don't care about recycling here because we never scroll.
DataBindingItem dataBindingItem = item.getDataBindingItem();
@@ -65,7 +65,7 @@
}
private static void fillView(BridgeContext context, View view, AdapterItem item,
- AdapterItem parentItem, IProjectCallback callback, ResourceReference adapterRef) {
+ AdapterItem parentItem, LayoutlibCallback callback, ResourceReference adapterRef) {
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
final int count = group.getChildCount();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
index 9a13f5a..142eac1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
@@ -18,7 +18,7 @@
import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.util.Pair;
@@ -37,18 +37,17 @@
* and {@link SpinnerAdapter}.
*
*/
-@SuppressWarnings("deprecation")
public class FakeAdapter extends BaseAdapter {
// don't use a set because the order is important.
private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
- private final IProjectCallback mCallback;
+ private final LayoutlibCallback mCallback;
private final ResourceReference mAdapterRef;
private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
private boolean mSkipCallbackParser = false;
public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
- IProjectCallback callback) {
+ LayoutlibCallback callback) {
mAdapterRef = adapterRef;
mCallback = callback;
@@ -111,11 +110,11 @@
public View getView(int position, View convertView, ViewGroup parent) {
// we don't care about recycling here because we never scroll.
AdapterItem item = mItems.get(position);
- Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentGroup*/, parent,
- mCallback, mAdapterRef, mSkipCallbackParser);
+ @SuppressWarnings("deprecation")
+ Pair<View, Boolean> pair = AdapterHelper.getView(item, null, parent, mCallback,
+ mAdapterRef, mSkipCallbackParser);
mSkipCallbackParser = pair.getSecond();
return pair.getFirst();
-
}
@Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
index e539579..344b17e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
@@ -18,7 +18,7 @@
import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.util.Pair;
@@ -34,7 +34,7 @@
@SuppressWarnings("deprecation")
public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
- private final IProjectCallback mCallback;
+ private final LayoutlibCallback mCallback;
private final ResourceReference mAdapterRef;
private boolean mSkipCallbackParser = false;
@@ -45,7 +45,7 @@
private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>();
public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
- IProjectCallback callback) {
+ LayoutlibCallback callback) {
mAdapterRef = adapterRef;
mCallback = callback;
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
index e38f437..9bf302a 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index 565e881..0a5e798 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -20,7 +20,7 @@
import com.android.ide.common.rendering.api.ActionBarCallback;
import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.resources.ResourceType;
@@ -28,10 +28,7 @@
import com.android.util.Pair;
import com.android.utils.ILogger;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -40,7 +37,7 @@
import com.google.android.collect.Maps;
@SuppressWarnings("deprecation") // For Pair
-public class LayoutLibTestCallback extends ClassLoader implements IProjectCallback {
+public class LayoutLibTestCallback extends LayoutlibCallback {
private static final String PROJECT_CLASSES_LOCATION = "/testApp/MyApplication/build/intermediates/classes/debug/";
private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
@@ -48,16 +45,16 @@
private final Map<Integer, Pair<ResourceType, String>> mProjectResources = Maps.newHashMap();
private final Map<IntArrayWrapper, String> mStyleableValueToNameMap = Maps.newHashMap();
private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
- private final Map<String, Class<?>> mClasses = Maps.newHashMap();
private final ILogger mLog;
private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
+ private final ClassLoader mModuleClassLoader = new ModuleClassLoader(PROJECT_CLASSES_LOCATION);
public LayoutLibTestCallback(ILogger logger) {
mLog = logger;
}
public void initResources() throws ClassNotFoundException {
- Class<?> rClass = loadClass(PACKAGE_NAME + ".R");
+ Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R");
Class<?>[] nestedClasses = rClass.getDeclaredClasses();
for (Class<?> resClass : nestedClasses) {
final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName());
@@ -91,40 +88,11 @@
}
}
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- Class<?> aClass = mClasses.get(name);
- if (aClass != null) {
- return aClass;
- }
- String pathName = PROJECT_CLASSES_LOCATION.concat(name.replace('.', '/')).concat(".class");
- InputStream classInputStream = getClass().getResourceAsStream(pathName);
- if (classInputStream == null) {
- throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
- }
- byte[] data;
- try {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- int nRead;
- data = new byte[16384];
- while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
- buffer.write(data, 0, nRead);
- }
- buffer.flush();
- data = buffer.toByteArray();
- } catch (IOException e) {
- // Wrap the exception with ClassNotFoundException so that caller can deal with it.
- throw new ClassNotFoundException("Unable to load class " + name, e);
- }
- aClass = defineClass(name, data, 0, data.length);
- mClasses.put(name, aClass);
- return aClass;
- }
@Override
public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
throws Exception {
- Class<?> viewClass = findClass(name);
+ Class<?> viewClass = mModuleClassLoader.loadClass(name);
Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature);
viewConstructor.setAccessible(true);
return viewConstructor.newInstance(constructorArgs);
@@ -180,4 +148,9 @@
public ActionBarCallback getActionBarCallback() {
return mActionBarCallback;
}
+
+ @Override
+ public boolean supports(int ideFeature) {
+ return false;
+ }
}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java
new file mode 100644
index 0000000..110f4c8
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 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.layoutlib.bridge.intensive.setup;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+import com.google.android.collect.Maps;
+
+/**
+ * The ClassLoader to load the project's classes.
+ */
+public class ModuleClassLoader extends ClassLoader {
+
+ private final Map<String, Class<?>> mClasses = Maps.newHashMap();
+ private final String mClassLocation;
+
+ public ModuleClassLoader(String classLocation) {
+ mClassLocation = classLocation;
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ Class<?> aClass = mClasses.get(name);
+ if (aClass != null) {
+ return aClass;
+ }
+ String pathName = mClassLocation.concat(name.replace('.', '/')).concat(".class");
+ InputStream classInputStream = getClass().getResourceAsStream(pathName);
+ if (classInputStream == null) {
+ throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
+ }
+ byte[] data;
+ try {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ int nRead;
+ data = new byte[16384]; // 16k
+ while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
+ buffer.write(data, 0, nRead);
+ }
+ buffer.flush();
+ data = buffer.toByteArray();
+ } catch (IOException e) {
+ // Wrap the exception with ClassNotFoundException so that caller can deal with it.
+ throw new ClassNotFoundException("Unable to load class " + name, e);
+ }
+ aClass = defineClass(name, data, 0, data.length);
+ mClasses.put(name, aClass);
+ return aClass;
+ }
+}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index e8a51e3..5dc70bd 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -261,6 +261,12 @@
return freq > 4900 && freq < 5900;
}
+ /**
+ * @hide
+ * storing the raw bytes of full result IEs
+ **/
+ public byte[] bytes;
+
/** information element from beacon
* @hide
*/