Merge "Fix NPE when restarting ChooseTypeAndAccountActiivty." into jb-mr2-dev
diff --git a/api/current.txt b/api/current.txt
index 2ec1533..2a68997 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13931,8 +13931,11 @@
ctor public WifiEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
method public int describeContents();
method public java.lang.String getAnonymousIdentity();
+ method public java.security.cert.X509Certificate getCaCertificate();
+ method public java.security.cert.X509Certificate getClientCertificate();
method public int getEapMethod();
method public java.lang.String getIdentity();
+ method public java.lang.String getPassword();
method public int getPhase2Method();
method public java.lang.String getSubjectMatch();
method public void setAnonymousIdentity(java.lang.String);
@@ -13948,7 +13951,6 @@
}
public static final class WifiEnterpriseConfig.Eap {
- ctor public WifiEnterpriseConfig.Eap();
field public static final int NONE = -1; // 0xffffffff
field public static final int PEAP = 0; // 0x0
field public static final int PWD = 3; // 0x3
@@ -13957,7 +13959,6 @@
}
public static final class WifiEnterpriseConfig.Phase2 {
- ctor public WifiEnterpriseConfig.Phase2();
field public static final int GTC = 4; // 0x4
field public static final int MSCHAP = 2; // 0x2
field public static final int MSCHAPV2 = 3; // 0x3
@@ -13996,7 +13997,7 @@
method public deprecated android.net.DhcpInfo getDhcpInfo();
method public java.util.List<android.net.wifi.ScanResult> getScanResults();
method public int getWifiState();
- method public boolean isScanningAlwaysAvailable();
+ method public boolean isScanAlwaysAvailable();
method public boolean isWifiEnabled();
method public boolean pingSupplicant();
method public boolean reassociate();
@@ -17523,16 +17524,17 @@
public class StatFs {
ctor public StatFs(java.lang.String);
- method public int getAvailableBlocks();
+ method public deprecated int getAvailableBlocks();
method public long getAvailableBlocksLong();
method public long getAvailableBytes();
- method public int getBlockCount();
+ method public deprecated int getBlockCount();
method public long getBlockCountLong();
- method public int getBlockSize();
+ method public deprecated int getBlockSize();
method public long getBlockSizeLong();
- method public int getFreeBlocks();
+ method public deprecated int getFreeBlocks();
method public long getFreeBlocksLong();
method public long getFreeBytes();
+ method public long getTotalBytes();
method public void restat(java.lang.String);
}
@@ -21127,37 +21129,6 @@
package android.security {
- public final class AndroidKeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
- method public android.content.Context getContext();
- method public java.util.Date getEndDate();
- method public java.lang.String getKeystoreAlias();
- method public java.math.BigInteger getSerialNumber();
- method public java.util.Date getStartDate();
- method public javax.security.auth.x500.X500Principal getSubjectDN();
- method public boolean isEncryptionRequired();
- }
-
- public static final class AndroidKeyPairGeneratorSpec.Builder {
- ctor public AndroidKeyPairGeneratorSpec.Builder(android.content.Context);
- method public android.security.AndroidKeyPairGeneratorSpec build();
- method public android.security.AndroidKeyPairGeneratorSpec.Builder setAlias(java.lang.String);
- method public android.security.AndroidKeyPairGeneratorSpec.Builder setEncryptionRequired();
- method public android.security.AndroidKeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
- method public android.security.AndroidKeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
- method public android.security.AndroidKeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
- method public android.security.AndroidKeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
- }
-
- public final class AndroidKeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
- method public boolean isEncryptionRequired();
- }
-
- public static final class AndroidKeyStoreParameter.Builder {
- ctor public AndroidKeyStoreParameter.Builder(android.content.Context);
- method public android.security.AndroidKeyStoreParameter build();
- method public android.security.AndroidKeyStoreParameter.Builder setEncryptionRequired();
- }
-
public final class KeyChain {
ctor public KeyChain();
method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
@@ -21183,6 +21154,37 @@
ctor public KeyChainException(java.lang.Throwable);
}
+ public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public android.content.Context getContext();
+ method public java.util.Date getEndDate();
+ method public java.lang.String getKeystoreAlias();
+ method public java.math.BigInteger getSerialNumber();
+ method public java.util.Date getStartDate();
+ method public javax.security.auth.x500.X500Principal getSubjectDN();
+ method public boolean isEncryptionRequired();
+ }
+
+ public static final class KeyPairGeneratorSpec.Builder {
+ ctor public KeyPairGeneratorSpec.Builder(android.content.Context);
+ method public android.security.KeyPairGeneratorSpec build();
+ method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
+ method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
+ method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
+ method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
+ }
+
+ public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
+ method public boolean isEncryptionRequired();
+ }
+
+ public static final class KeyStoreParameter.Builder {
+ ctor public KeyStoreParameter.Builder(android.content.Context);
+ method public android.security.KeyStoreParameter build();
+ method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
+ }
+
}
package android.service.dreams {
@@ -24447,17 +24449,6 @@
method public void set(T, V);
}
- public class PropertyValueModel extends android.util.ValueModel {
- method public T get();
- method public H getHost();
- method public android.util.Property<H, T> getProperty();
- method public java.lang.Class<T> getType();
- method public static android.util.PropertyValueModel<H, T> of(H, android.util.Property<H, T>);
- method public static android.util.PropertyValueModel<H, T> of(H, java.lang.Class<T>, java.lang.String);
- method public static android.util.PropertyValueModel of(java.lang.Object, java.lang.String);
- method public void set(T);
- }
-
public class SparseArray implements java.lang.Cloneable {
ctor public SparseArray();
ctor public SparseArray(int);
@@ -24624,14 +24615,6 @@
field public int type;
}
- public abstract class ValueModel {
- ctor protected ValueModel();
- method public abstract T get();
- method public abstract java.lang.Class<T> getType();
- method public abstract void set(T);
- field public static final android.util.ValueModel EMPTY;
- }
-
public class Xml {
method public static android.util.AttributeSet asAttributeSet(org.xmlpull.v1.XmlPullParser);
method public static android.util.Xml.Encoding findEncodingByName(java.lang.String) throws java.io.UnsupportedEncodingException;
@@ -29097,12 +29080,10 @@
method public abstract void onSelectedDayChange(android.widget.CalendarView, int, int, int);
}
- public class CheckBox extends android.widget.CompoundButton implements android.widget.ValueEditor {
+ public class CheckBox extends android.widget.CompoundButton {
ctor public CheckBox(android.content.Context);
ctor public CheckBox(android.content.Context, android.util.AttributeSet);
ctor public CheckBox(android.content.Context, android.util.AttributeSet, int);
- method public android.util.ValueModel<java.lang.Boolean> getValueModel();
- method public void setValueModel(android.util.ValueModel<java.lang.Boolean>);
}
public abstract interface Checkable {
@@ -29275,16 +29256,14 @@
method public void setSize(int, int);
}
- public class EditText extends android.widget.TextView implements android.widget.ValueEditor {
+ public class EditText extends android.widget.TextView {
ctor public EditText(android.content.Context);
ctor public EditText(android.content.Context, android.util.AttributeSet);
ctor public EditText(android.content.Context, android.util.AttributeSet, int);
method public void extendSelection(int);
- method public android.util.ValueModel<java.lang.CharSequence> getValueModel();
method public void selectAll();
method public void setSelection(int, int);
method public void setSelection(int);
- method public void setValueModel(android.util.ValueModel<java.lang.CharSequence>);
}
public abstract interface ExpandableListAdapter {
@@ -30313,13 +30292,11 @@
method public abstract java.lang.Object[] getSections();
}
- public class SeekBar extends android.widget.AbsSeekBar implements android.widget.ValueEditor {
+ public class SeekBar extends android.widget.AbsSeekBar {
ctor public SeekBar(android.content.Context);
ctor public SeekBar(android.content.Context, android.util.AttributeSet);
ctor public SeekBar(android.content.Context, android.util.AttributeSet, int);
- method public android.util.ValueModel<java.lang.Integer> getValueModel();
method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
- method public void setValueModel(android.util.ValueModel<java.lang.Integer>);
}
public static abstract interface SeekBar.OnSeekBarChangeListener {
@@ -30907,11 +30884,6 @@
method public android.widget.TextView getText2();
}
- public abstract interface ValueEditor {
- method public abstract android.util.ValueModel<T> getValueModel();
- method public abstract void setValueModel(android.util.ValueModel<T>);
- }
-
public class VideoView extends android.view.SurfaceView implements android.widget.MediaController.MediaPlayerControl {
ctor public VideoView(android.content.Context);
ctor public VideoView(android.content.Context, android.util.AttributeSet);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index d64bff9..d8d5f2b 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -17,6 +17,7 @@
package android.content.res;
import android.os.Trace;
+import android.view.View;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -80,16 +81,16 @@
private static final Object sSync = new Object();
/*package*/ static Resources mSystem = null;
-
+
// Information about preloaded resources. Note that they are not
// protected by a lock, because while preloading in zygote we are all
// single-threaded, and after that these are immutable.
- private static final LongSparseArray<Drawable.ConstantState> sPreloadedDrawables
+ private static final LongSparseArray<Drawable.ConstantState>[] sPreloadedDrawables;
+ private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
= new LongSparseArray<Drawable.ConstantState>();
private static final LongSparseArray<ColorStateList> sPreloadedColorStateLists
= new LongSparseArray<ColorStateList>();
- private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
- = new LongSparseArray<Drawable.ConstantState>();
+
private static boolean sPreloaded;
private static int sPreloadedDensity;
@@ -120,6 +121,12 @@
private CompatibilityInfo mCompatibilityInfo;
+ static {
+ sPreloadedDrawables = new LongSparseArray[2];
+ sPreloadedDrawables[0] = new LongSparseArray<Drawable.ConstantState>();
+ sPreloadedDrawables[1] = new LongSparseArray<Drawable.ConstantState>();
+ }
+
/** @hide */
public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
return selectSystemTheme(curTheme, targetSdkVersion,
@@ -1982,6 +1989,7 @@
ActivityInfo.CONFIG_LAYOUT_DIRECTION);
private boolean verifyPreloadConfig(int changingConfigurations, int resourceId, String name) {
+ // We dont want to preloadd a Drawable when there is both a LTR and RTL version of it
if (((changingConfigurations&~(ActivityInfo.CONFIG_FONT_SCALE |
ActivityInfo.CONFIG_DENSITY)) & VARYING_CONFIGS) != 0) {
String resName;
@@ -1995,6 +2003,17 @@
+ " (" + resName + ") that varies with configuration!!");
return false;
}
+ if (TRACE_FOR_PRELOAD) {
+ String resName;
+ try {
+ resName = getResourceName(resourceId);
+ } catch (NotFoundException e) {
+ resName = "?";
+ }
+ Log.w(TAG, "Preloading " + name + " resource #0x"
+ + Integer.toHexString(resourceId)
+ + " (" + resName + ")");
+ }
return true;
}
@@ -2022,11 +2041,11 @@
if (dr != null) {
return dr;
}
-
+ final int layoutDirection = mConfiguration.getLayoutDirection();
Drawable.ConstantState cs = isColorDrawable
? sPreloadedColorDrawables.get(key)
: (sPreloadedDensity == mConfiguration.densityDpi
- ? sPreloadedDrawables.get(key) : null);
+ ? sPreloadedDrawables[layoutDirection].get(key) : null);
if (cs != null) {
dr = cs.newDrawable(this);
} else {
@@ -2100,11 +2119,12 @@
cs = dr.getConstantState();
if (cs != null) {
if (mPreloading) {
- if (verifyPreloadConfig(cs.getChangingConfigurations(), value.resourceId, "drawable")) {
+ if (verifyPreloadConfig(cs.getChangingConfigurations(), value.resourceId,
+ "drawable")) {
if (isColorDrawable) {
sPreloadedColorDrawables.put(key, cs);
} else {
- sPreloadedDrawables.put(key, cs);
+ sPreloadedDrawables[layoutDirection].put(key, cs);
}
}
} else {
diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java
index 2b359eb..ab4cd9b 100644
--- a/core/java/android/net/DhcpInfo.java
+++ b/core/java/android/net/DhcpInfo.java
@@ -22,8 +22,7 @@
/**
* A simple object for retrieving the results of a DHCP request.
- * @deprecated - use LinkProperties - To be removed 11/2013
- * STOPSHIP - make sure we expose LinkProperties through ConnectivityManager
+ * @deprecated - use LinkProperties - To be removed 11/2014
*/
public class DhcpInfo implements Parcelable {
public int ipAddress;
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 60ec0d7..2314057 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -57,9 +57,9 @@
}
/**
- * The size, in bytes, of a block on the file system. This corresponds to
- * the Unix {@code statfs.f_bsize} field.
+ * @deprecated Use {@link #getBlockSizeLong()} instead.
*/
+ @Deprecated
public int getBlockSize() {
return (int) mStat.f_bsize;
}
@@ -73,27 +73,25 @@
}
/**
- * The total number of blocks on the file system. This corresponds to the
- * Unix {@code statfs.f_blocks} field.
+ * @deprecated Use {@link #getBlockCountLong()} instead.
*/
+ @Deprecated
public int getBlockCount() {
return (int) mStat.f_blocks;
}
/**
- * The size, in bytes, of a block on the file system. This corresponds to
- * the Unix {@code statfs.f_bsize} field.
+ * The total number of blocks on the file system. This corresponds to the
+ * Unix {@code statfs.f_blocks} field.
*/
public long getBlockCountLong() {
return mStat.f_blocks;
}
/**
- * The total number of blocks that are free on the file system, including
- * reserved blocks (that are not available to normal applications). This
- * corresponds to the Unix {@code statfs.f_bfree} field. Most applications
- * will want to use {@link #getAvailableBlocks()} instead.
+ * @deprecated Use {@link #getFreeBlocksLong()} instead.
*/
+ @Deprecated
public int getFreeBlocks() {
return (int) mStat.f_bfree;
}
@@ -109,17 +107,18 @@
}
/**
- * The number of bytes that are free on the file system, including
- * reserved blocks (that are not available to normal applications).
+ * The number of bytes that are free on the file system, including reserved
+ * blocks (that are not available to normal applications). Most applications
+ * will want to use {@link #getAvailableBytes()} instead.
*/
public long getFreeBytes() {
return mStat.f_bfree * mStat.f_bsize;
}
/**
- * The number of blocks that are free on the file system and available to
- * applications. This corresponds to the Unix {@code statfs.f_bavail} field.
+ * @deprecated Use {@link #getAvailableBlocksLong()} instead.
*/
+ @Deprecated
public int getAvailableBlocks() {
return (int) mStat.f_bavail;
}
@@ -139,4 +138,11 @@
public long getAvailableBytes() {
return mStat.f_bavail * mStat.f_bsize;
}
+
+ /**
+ * The total number of bytes supported by the file system.
+ */
+ public long getTotalBytes() {
+ return mStat.f_blocks * mStat.f_bsize;
+ }
}
diff --git a/core/java/android/util/PropertyValueModel.java b/core/java/android/util/PropertyValueModel.java
deleted file mode 100755
index eb9c47d..0000000
--- a/core/java/android/util/PropertyValueModel.java
+++ /dev/null
@@ -1,143 +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.util;
-
-/**
- * A value model for a {@link Property property} of a host object. This class can be used for
- * both reflective and non-reflective property implementations.
- *
- * @param <H> the host type, where the host is the object that holds this property
- * @param <T> the value type
- *
- * @see Property
- * @see ValueModel
- */
-public class PropertyValueModel<H, T> extends ValueModel<T> {
- private final H mHost;
- private final Property<H, T> mProperty;
-
- private PropertyValueModel(H host, Property<H, T> property) {
- mProperty = property;
- mHost = host;
- }
-
- /**
- * Returns the host.
- *
- * @return the host
- */
- public H getHost() {
- return mHost;
- }
-
- /**
- * Returns the property.
- *
- * @return the property
- */
- public Property<H, T> getProperty() {
- return mProperty;
- }
-
- @Override
- public Class<T> getType() {
- return mProperty.getType();
- }
-
- @Override
- public T get() {
- return mProperty.get(mHost);
- }
-
- @Override
- public void set(T value) {
- mProperty.set(mHost, value);
- }
-
- /**
- * Return an appropriate PropertyValueModel for this host and property.
- *
- * @param host the host
- * @param property the property
- * @return the value model
- */
- public static <H, T> PropertyValueModel<H, T> of(H host, Property<H, T> property) {
- return new PropertyValueModel<H, T>(host, property);
- }
-
- /**
- * Return a PropertyValueModel for this {@code host} and a
- * reflective property, constructed from this {@code propertyType} and {@code propertyName}.
- *
- * @param host
- * @param propertyType the property type
- * @param propertyName the property name
- * @return a value model with this host and a reflective property with this type and name
- *
- * @see Property#of
- */
- public static <H, T> PropertyValueModel<H, T> of(H host, Class<T> propertyType,
- String propertyName) {
- return of(host, Property.of((Class<H>) host.getClass(), propertyType, propertyName));
- }
-
- private static Class getNullaryMethodReturnType(Class c, String name) {
- try {
- return c.getMethod(name).getReturnType();
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
-
- private static Class getFieldType(Class c, String name) {
- try {
- return c.getField(name).getType();
- } catch (NoSuchFieldException e) {
- return null;
- }
- }
-
- private static String capitalize(String name) {
- if (name.isEmpty()) {
- return name;
- }
- return Character.toUpperCase(name.charAt(0)) + name.substring(1);
- }
-
- /**
- * Return a PropertyValueModel for this {@code host} and and {@code propertyName}.
- *
- * @param host the host
- * @param propertyName the property name
- * @return a value model with this host and a reflective property with this name
- */
- public static PropertyValueModel of(Object host, String propertyName) {
- Class clazz = host.getClass();
- String suffix = capitalize(propertyName);
- Class propertyType = getNullaryMethodReturnType(clazz, "get" + suffix);
- if (propertyType == null) {
- propertyType = getNullaryMethodReturnType(clazz, "is" + suffix);
- }
- if (propertyType == null) {
- propertyType = getFieldType(clazz, propertyName);
- }
- if (propertyType == null) {
- throw new NoSuchPropertyException(propertyName);
- }
- return of(host, propertyType, propertyName);
- }
-}
diff --git a/core/java/android/util/ValueModel.java b/core/java/android/util/ValueModel.java
deleted file mode 100755
index 4789682..0000000
--- a/core/java/android/util/ValueModel.java
+++ /dev/null
@@ -1,74 +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.util;
-
-/**
- * A ValueModel is an abstraction for a 'slot' or place in memory in which a value
- * may be stored and retrieved. A common implementation of ValueModel is a regular property of
- * an object, whose value may be retrieved by calling the appropriate <em>getter</em>
- * method and set by calling the corresponding <em>setter</em> method.
- *
- * @param <T> the value type
- *
- * @see PropertyValueModel
- */
-public abstract class ValueModel<T> {
- /**
- * The empty model should be used in place of {@code null} to indicate that a
- * model has not been set. The empty model has no value and does nothing when it is set.
- */
- public static final ValueModel EMPTY = new ValueModel() {
- @Override
- public Class getType() {
- return Object.class;
- }
-
- @Override
- public Object get() {
- return null;
- }
-
- @Override
- public void set(Object value) {
-
- }
- };
-
- protected ValueModel() {
- }
-
- /**
- * Returns the type of this property.
- *
- * @return the property type
- */
- public abstract Class<T> getType();
-
- /**
- * Returns the value of this property.
- *
- * @return the property value
- */
- public abstract T get();
-
- /**
- * Sets the value of this property.
- *
- * @param value the new value for this property
- */
- public abstract void set(T value);
-}
\ No newline at end of file
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index be26d20..a0a63a6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2915,14 +2915,14 @@
*
* @hide
*/
- int mUserPaddingLeftInitial = 0;
+ int mUserPaddingLeftInitial;
/**
* Cache initial right padding.
*
* @hide
*/
- int mUserPaddingRightInitial = 0;
+ int mUserPaddingRightInitial;
/**
* Default undefined padding
@@ -3388,11 +3388,11 @@
break;
case com.android.internal.R.styleable.View_paddingStart:
startPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
- startPaddingDefined = true;
+ startPaddingDefined = (startPadding != UNDEFINED_PADDING);
break;
case com.android.internal.R.styleable.View_paddingEnd:
endPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
- endPaddingDefined = true;
+ endPaddingDefined = (endPadding != UNDEFINED_PADDING);
break;
case com.android.internal.R.styleable.View_scrollX:
x = a.getDimensionPixelOffset(attr, 0);
@@ -3712,10 +3712,12 @@
// Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
// and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
// defined.
- if (leftPaddingDefined) {
+ final boolean hasRelativePadding = startPaddingDefined || endPaddingDefined;
+
+ if (leftPaddingDefined && !hasRelativePadding) {
mUserPaddingLeftInitial = leftPadding;
}
- if (rightPaddingDefined) {
+ if (rightPaddingDefined && !hasRelativePadding) {
mUserPaddingRightInitial = rightPadding;
}
}
@@ -11952,26 +11954,30 @@
// left / right or right / left depending on the resolved layout direction.
// If start / end padding are not defined, use the left / right ones.
int resolvedLayoutDirection = getLayoutDirection();
- // Set user padding to initial values ...
- mUserPaddingLeft = mUserPaddingLeftInitial;
- mUserPaddingRight = mUserPaddingRightInitial;
- // ... then resolve it.
switch (resolvedLayoutDirection) {
case LAYOUT_DIRECTION_RTL:
if (mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingStart;
+ } else {
+ mUserPaddingRight = mUserPaddingRightInitial;
}
if (mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingEnd;
+ } else {
+ mUserPaddingLeft = mUserPaddingLeftInitial;
}
break;
case LAYOUT_DIRECTION_LTR:
default:
if (mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingStart;
+ } else {
+ mUserPaddingLeft = mUserPaddingLeftInitial;
}
if (mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingEnd;
+ } else {
+ mUserPaddingRight = mUserPaddingRightInitial;
}
}
diff --git a/core/java/android/widget/CheckBox.java b/core/java/android/widget/CheckBox.java
index 41ab5f2..f1804f8 100644
--- a/core/java/android/widget/CheckBox.java
+++ b/core/java/android/widget/CheckBox.java
@@ -20,7 +20,6 @@
import android.util.AttributeSet;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.util.ValueModel;
/**
@@ -56,9 +55,7 @@
* {@link android.R.styleable#View View Attributes}
* </p>
*/
-public class CheckBox extends CompoundButton implements ValueEditor<Boolean> {
- private ValueModel<Boolean> mValueModel = ValueModel.EMPTY;
-
+public class CheckBox extends CompoundButton {
public CheckBox(Context context) {
this(context, null);
}
@@ -82,22 +79,4 @@
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(CheckBox.class.getName());
}
-
- @Override
- public ValueModel<Boolean> getValueModel() {
- return mValueModel;
- }
-
- @Override
- public void setValueModel(ValueModel<Boolean> valueModel) {
- mValueModel = valueModel;
- setChecked(mValueModel.get());
- }
-
- @Override
- public boolean performClick() {
- boolean handled = super.performClick();
- mValueModel.set(isChecked());
- return handled;
- }
}
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index ec81214..57e51c2 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -17,7 +17,6 @@
package android.widget;
import android.content.Context;
-import android.graphics.Rect;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
@@ -25,7 +24,6 @@
import android.text.method.ArrowKeyMovementMethod;
import android.text.method.MovementMethod;
import android.util.AttributeSet;
-import android.util.ValueModel;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -49,9 +47,7 @@
* {@link android.R.styleable#TextView TextView Attributes},
* {@link android.R.styleable#View View Attributes}
*/
-public class EditText extends TextView implements ValueEditor<CharSequence> {
- private ValueModel<CharSequence> mValueModel = ValueModel.EMPTY;
-
+public class EditText extends TextView {
public EditText(Context context) {
this(context, null);
}
@@ -132,21 +128,4 @@
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(EditText.class.getName());
}
-
- @Override
- public ValueModel<CharSequence> getValueModel() {
- return mValueModel;
- }
-
- @Override
- public void setValueModel(ValueModel<CharSequence> valueModel) {
- mValueModel = valueModel;
- setText(mValueModel.get());
- }
-
- @Override
- void sendAfterTextChanged(Editable text) {
- super.sendAfterTextChanged(text);
- mValueModel.set(text);
- }
}
diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java
index a6486a8..2737f94 100644
--- a/core/java/android/widget/SeekBar.java
+++ b/core/java/android/widget/SeekBar.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.util.AttributeSet;
-import android.util.ValueModel;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -34,7 +33,7 @@
*
* @attr ref android.R.styleable#SeekBar_thumb
*/
-public class SeekBar extends AbsSeekBar implements ValueEditor<Integer> {
+public class SeekBar extends AbsSeekBar {
/**
* A callback that notifies clients when the progress level has been
@@ -70,9 +69,8 @@
void onStopTrackingTouch(SeekBar seekBar);
}
- private ValueModel<Integer> mValueModel = ValueModel.EMPTY;
private OnSeekBarChangeListener mOnSeekBarChangeListener;
-
+
public SeekBar(Context context) {
this(context, null);
}
@@ -91,23 +89,9 @@
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);
- if (fromUser) {
- mValueModel.set(getProgress());
- }
}
}
- @Override
- public ValueModel<Integer> getValueModel() {
- return mValueModel;
- }
-
- @Override
- public void setValueModel(ValueModel<Integer> valueModel) {
- mValueModel = valueModel;
- setProgress(mValueModel.get());
- }
-
/**
* Sets a listener to receive notifications of changes to the SeekBar's progress level. Also
* provides notifications of when the user starts and stops a touch gesture within the SeekBar.
diff --git a/core/java/android/widget/ValueEditor.java b/core/java/android/widget/ValueEditor.java
deleted file mode 100755
index 2b91abf..0000000
--- a/core/java/android/widget/ValueEditor.java
+++ /dev/null
@@ -1,53 +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.widget;
-
-import android.util.ValueModel;
-
-/**
- * An interface for editors of simple values. Classes implementing this interface are normally
- * UI controls (subclasses of {@link android.view.View View}) that can provide a suitable
- * user interface to display and edit values of the specified type. This interface is
- * intended to describe editors for simple types, like {@code boolean}, {@code int} or
- * {@code String}, where the values themselves are immutable.
- * <p>
- * For example, {@link android.widget.CheckBox CheckBox} implements
- * this interface for the Boolean type as it is capable of providing an appropriate
- * mechanism for displaying and changing the value of a Boolean property.
- *
- * @param <T> the value type that this editor supports
- */
-public interface ValueEditor<T> {
- /**
- * Return the last value model that was set. If no value model has been set, the editor
- * should return the value {@link android.util.ValueModel#EMPTY}.
- *
- * @return the value model
- */
- public ValueModel<T> getValueModel();
-
- /**
- * Sets the value model for this editor. When the value model is set, the editor should
- * retrieve the value from the value model, using {@link android.util.ValueModel#get()},
- * and set its internal state accordingly. Likewise, when the editor's internal state changes
- * it should update the value model by calling {@link android.util.ValueModel#set(T)}
- * with the appropriate value.
- *
- * @param valueModel the new value model for this editor.
- */
- public void setValueModel(ValueModel<T> valueModel);
-}
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index 6975583..43d1eb6 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -52,12 +52,12 @@
public class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
private android.security.KeyStore mKeyStore;
- private AndroidKeyPairGeneratorSpec mSpec;
+ private KeyPairGeneratorSpec mSpec;
/**
* Generate a KeyPair which is backed by the Android keystore service. You
* must call {@link KeyPairGenerator#initialize(AlgorithmParameterSpec)}
- * with an {@link AndroidKeyPairGeneratorSpec} as the {@code params}
+ * with an {@link KeyPairGeneratorSpec} as the {@code params}
* argument before calling this otherwise an {@code IllegalStateException}
* will be thrown.
* <p>
@@ -73,7 +73,7 @@
public KeyPair generateKeyPair() {
if (mKeyStore == null || mSpec == null) {
throw new IllegalStateException(
- "Must call initialize with an AndroidKeyPairGeneratorSpec first");
+ "Must call initialize with an android.security.KeyPairGeneratorSpec first");
}
if (((mSpec.getFlags() & KeyStore.FLAG_ENCRYPTED) != 0)
@@ -156,13 +156,13 @@
throws InvalidAlgorithmParameterException {
if (params == null) {
throw new InvalidAlgorithmParameterException(
- "must supply params of type AndroidKeyPairGenericSpec");
- } else if (!(params instanceof AndroidKeyPairGeneratorSpec)) {
+ "must supply params of type android.security.KeyPairGeneratorSpec");
+ } else if (!(params instanceof KeyPairGeneratorSpec)) {
throw new InvalidAlgorithmParameterException(
- "params must be of type AndroidKeyPairGeneratorSpec");
+ "params must be of type android.security.KeyPairGeneratorSpec");
}
- AndroidKeyPairGeneratorSpec spec = (AndroidKeyPairGeneratorSpec) params;
+ KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) params;
mSpec = spec;
mKeyStore = android.security.KeyStore.getInstance();
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index dcc9516..04ee8c4 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -209,7 +209,7 @@
}
private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain,
- AndroidKeyStoreParameter params) throws KeyStoreException {
+ KeyStoreParameter params) throws KeyStoreException {
byte[] keyBytes = null;
final String pkeyAlias;
@@ -544,15 +544,16 @@
return;
}
- if (param != null && !(param instanceof AndroidKeyStoreParameter)) {
- throw new KeyStoreException("protParam should be AndroidKeyStoreParameter; was: "
+ if (param != null && !(param instanceof KeyStoreParameter)) {
+ throw new KeyStoreException(
+ "protParam should be android.security.KeyStoreParameter; was: "
+ param.getClass().getName());
}
if (entry instanceof PrivateKeyEntry) {
PrivateKeyEntry prE = (PrivateKeyEntry) entry;
setPrivateKeyEntry(alias, prE.getPrivateKey(), prE.getCertificateChain(),
- (AndroidKeyStoreParameter) param);
+ (KeyStoreParameter) param);
return;
}
diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/AndroidKeyStoreProvider.java
index 8ca301e..b17e450 100644
--- a/keystore/java/android/security/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/AndroidKeyStoreProvider.java
@@ -24,7 +24,7 @@
* @hide
*/
public class AndroidKeyStoreProvider extends Provider {
- public static final String PROVIDER_NAME = "AndroidKeyStoreProvider";
+ public static final String PROVIDER_NAME = "AndroidKeyStore";
public AndroidKeyStoreProvider() {
super(PROVIDER_NAME, 1.0, "Android KeyStore security provider");
@@ -33,6 +33,6 @@
put("KeyStore." + AndroidKeyStore.NAME, AndroidKeyStore.class.getName());
// java.security.KeyPairGenerator
- put("KeyPairGenerator." + AndroidKeyStore.NAME, AndroidKeyPairGenerator.class.getName());
+ put("KeyPairGenerator.RSA", AndroidKeyPairGenerator.class.getName());
}
}
diff --git a/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
similarity index 89%
rename from keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
rename to keystore/java/android/security/KeyPairGeneratorSpec.java
index b126f03..59f89bc 100644
--- a/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -29,9 +29,9 @@
/**
* This provides the required parameters needed for initializing the
- * {@code KeyPairGenerator} that works with <a href="{@docRoot}
- * guide/topics/security/keystore.html">Android KeyStore facility</a>. The
- * Android KeyStore facility is accessed through a
+ * {@code KeyPairGenerator} that works with
+ * <a href="{@docRoot}guide/topics/security/keystore.html">Android KeyStore
+ * facility</a>. The Android KeyStore facility is accessed through a
* {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore}
* provider. The {@code context} passed in may be used to pop up some UI to ask
* the user to unlock or initialize the Android KeyStore facility.
@@ -49,7 +49,7 @@
* The self-signed X.509 certificate may be replaced at a later time by a
* certificate signed by a real Certificate Authority.
*/
-public final class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
+public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
private final String mKeystoreAlias;
private final Context mContext;
@@ -91,9 +91,9 @@
* period
* @throws IllegalArgumentException when any argument is {@code null} or
* {@code endDate} is before {@code startDate}.
- * @hide should be built with AndroidKeyPairGeneratorSpecBuilder
+ * @hide should be built with KeyPairGeneratorSpecBuilder
*/
- public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias,
+ public KeyPairGeneratorSpec(Context context, String keyStoreAlias,
X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate,
int flags) {
if (context == null) {
@@ -184,7 +184,7 @@
}
/**
- * Builder class for {@link AndroidKeyPairGeneratorSpec} objects.
+ * Builder class for {@link KeyPairGeneratorSpec} objects.
* <p>
* This will build a parameter spec for use with the <a href="{@docRoot}
* guide/topics/security/keystore.html">Android KeyStore facility</a>.
@@ -198,14 +198,10 @@
* Calendar end = new Calendar();
* end.add(1, Calendar.YEAR);
*
- * AndroidKeyPairGeneratorSpec spec =
- * new AndroidKeyPairGeneratorSpec.Builder(mContext)
- * .setAlias("myKey")
- * .setSubject(new X500Principal("CN=myKey"))
- * .setSerial(BigInteger.valueOf(1337))
- * .setStartDate(start.getTime())
- * .setEndDate(end.getTime())
- * .build();
+ * KeyPairGeneratorSpec spec =
+ * new KeyPairGeneratorSpec.Builder(mContext).setAlias("myKey")
+ * .setSubject(new X500Principal("CN=myKey")).setSerial(BigInteger.valueOf(1337))
+ * .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
* </pre>
*/
public final static class Builder {
@@ -309,13 +305,13 @@
}
/**
- * Builds the instance of the {@code AndroidKeyPairGeneratorSpec}.
+ * Builds the instance of the {@code KeyPairGeneratorSpec}.
*
* @throws IllegalArgumentException if a required field is missing
- * @return built instance of {@code AndroidKeyPairGeneratorSpec}
+ * @return built instance of {@code KeyPairGeneratorSpec}
*/
- public AndroidKeyPairGeneratorSpec build() {
- return new AndroidKeyPairGeneratorSpec(mContext, mKeystoreAlias, mSubjectDN,
+ public KeyPairGeneratorSpec build() {
+ return new KeyPairGeneratorSpec(mContext, mKeystoreAlias, mSubjectDN,
mSerialNumber, mStartDate, mEndDate, mFlags);
}
}
diff --git a/keystore/java/android/security/AndroidKeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
similarity index 72%
rename from keystore/java/android/security/AndroidKeyStoreParameter.java
rename to keystore/java/android/security/KeyStoreParameter.java
index 44f57c4..621a605 100644
--- a/keystore/java/android/security/AndroidKeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -17,7 +17,7 @@
package android.security;
import android.content.Context;
-import android.security.AndroidKeyPairGeneratorSpec.Builder;
+import android.security.KeyPairGeneratorSpec.Builder;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
@@ -26,9 +26,9 @@
/**
* This provides the optional parameters that can be specified for
- * {@code KeyStore} entries that work with <a href="{@docRoot}
- * guide/topics/security/keystore.html">Android KeyStore facility</a>. The
- * Android KeyStore facility is accessed through a
+ * {@code KeyStore} entries that work with
+ * <a href="{@docRoot}guide/topics/security/keystore.html">Android KeyStore
+ * facility</a>. The Android KeyStore facility is accessed through a
* {@link java.security.KeyStore} API using the {@code AndroidKeyStore}
* provider. The {@code context} passed in may be used to pop up some UI to ask
* the user to unlock or initialize the Android KeyStore facility.
@@ -39,15 +39,15 @@
* {@code KeyStore}.
* <p>
* Keys may be generated using the {@link KeyPairGenerator} facility with a
- * {@link AndroidKeyPairGeneratorSpec} to specify the entry's {@code alias}. A
+ * {@link KeyPairGeneratorSpec} to specify the entry's {@code alias}. A
* self-signed X.509 certificate will be attached to generated entries, but that
* may be replaced at a later time by a certificate signed by a real Certificate
* Authority.
*/
-public final class AndroidKeyStoreParameter implements ProtectionParameter {
+public final class KeyStoreParameter implements ProtectionParameter {
private int mFlags;
- private AndroidKeyStoreParameter(int flags) {
+ private KeyStoreParameter(int flags) {
mFlags = flags;
}
@@ -67,10 +67,10 @@
}
/**
- * Builder class for {@link AndroidKeyStoreParameter} objects.
+ * Builder class for {@link KeyStoreParameter} objects.
* <p>
- * This will build protection parameters for use with the <a
- * href="{@docRoot} guide/topics/security/keystore.html">Android KeyStore
+ * This will build protection parameters for use with the
+ * <a href="{@docRoot}guide/topics/security/keystore.html">Android KeyStore
* facility</a>.
* <p>
* This can be used to require that KeyStore entries be stored encrypted.
@@ -78,8 +78,9 @@
* Example:
*
* <pre class="prettyprint">
- * AndroidKeyStoreParameter params =
- * new AndroidKeyStoreParameter.Builder(mContext).setEncryptionRequired().build();
+ * KeyStoreParameter params = new KeyStoreParameter.Builder(mContext)
+ * .setEncryptionRequired()
+ * .build();
* </pre>
*/
public final static class Builder {
@@ -105,19 +106,23 @@
* screen (e.g., PIN, password) before creating or using the generated
* key is successful.
*/
- public Builder setEncryptionRequired() {
- mFlags |= KeyStore.FLAG_ENCRYPTED;
+ public Builder setEncryptionRequired(boolean required) {
+ if (required) {
+ mFlags |= KeyStore.FLAG_ENCRYPTED;
+ } else {
+ mFlags &= ~KeyStore.FLAG_ENCRYPTED;
+ }
return this;
}
/**
- * Builds the instance of the {@code AndroidKeyPairGeneratorSpec}.
+ * Builds the instance of the {@code KeyPairGeneratorSpec}.
*
* @throws IllegalArgumentException if a required field is missing
- * @return built instance of {@code AndroidKeyPairGeneratorSpec}
+ * @return built instance of {@code KeyPairGeneratorSpec}
*/
- public AndroidKeyStoreParameter build() {
- return new AndroidKeyStoreParameter(mFlags);
+ public KeyStoreParameter build() {
+ return new KeyStoreParameter(mFlags);
}
}
}
diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
index c5cf514..1582f74 100644
--- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
@@ -65,7 +65,7 @@
assertFalse(mAndroidKeyStore.isUnlocked());
- mGenerator = java.security.KeyPairGenerator.getInstance("AndroidKeyStore");
+ mGenerator = java.security.KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
}
private void setupPassword() {
@@ -80,7 +80,7 @@
public void testKeyPairGenerator_Initialize_Params_Encrypted_Success() throws Exception {
setupPassword();
- mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_1)
.setSubject(TEST_DN_1)
.setSerialNumber(TEST_SERIAL_1)
@@ -116,7 +116,7 @@
setupPassword();
mGenerator.initialize(
- new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_1)
.setSubject(TEST_DN_1)
.setSerialNumber(TEST_SERIAL_1)
@@ -130,7 +130,7 @@
public void testKeyPairGenerator_GenerateKeyPair_Encrypted_Success() throws Exception {
setupPassword();
- mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_1)
.setSubject(TEST_DN_1)
.setSerialNumber(TEST_SERIAL_1)
@@ -146,7 +146,7 @@
}
public void testKeyPairGenerator_GenerateKeyPair_Unencrypted_Success() throws Exception {
- mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_1)
.setSubject(TEST_DN_1)
.setSerialNumber(TEST_SERIAL_1)
@@ -163,7 +163,7 @@
public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception {
// Generate the first key
{
- mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_1)
.setSubject(TEST_DN_1)
.setSerialNumber(TEST_SERIAL_1)
@@ -178,7 +178,7 @@
// Replace the original key
{
- mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_2)
.setSubject(TEST_DN_2)
.setSerialNumber(TEST_SERIAL_2)
@@ -196,7 +196,7 @@
throws Exception {
// Generate the first key
{
- mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_1)
.setSubject(TEST_DN_1)
.setSerialNumber(TEST_SERIAL_1)
@@ -211,7 +211,7 @@
// Attempt to replace previous key
{
- mGenerator.initialize(new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_1)
.setSubject(TEST_DN_2)
.setSerialNumber(TEST_SERIAL_2)
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
index 507d41c..8798fb5 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -1232,8 +1232,8 @@
try {
mKeyStore.setEntry(TEST_ALIAS_1, entry,
- new AndroidKeyStoreParameter.Builder(getContext())
- .setEncryptionRequired()
+ new KeyStoreParameter.Builder(getContext())
+ .setEncryptionRequired(true)
.build());
fail("Shouldn't be able to insert encrypted entry when KeyStore uninitialized");
} catch (KeyStoreException expected) {
@@ -1752,8 +1752,10 @@
Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
try {
- mKeyStore.setEntry(TEST_ALIAS_1, entry, new AndroidKeyStoreParameter.Builder(
- getContext()).setEncryptionRequired().build());
+ mKeyStore.setEntry(TEST_ALIAS_1, entry,
+ new KeyStoreParameter.Builder(getContext())
+ .setEncryptionRequired(true)
+ .build());
fail("Should not allow setting of Entry without unlocked keystore");
} catch (KeyStoreException success) {
}
@@ -1762,8 +1764,8 @@
assertTrue(mAndroidKeyStore.isUnlocked());
mKeyStore.setEntry(TEST_ALIAS_1, entry,
- new AndroidKeyStoreParameter.Builder(getContext())
- .setEncryptionRequired()
+ new KeyStoreParameter.Builder(getContext())
+ .setEncryptionRequired(true)
.build());
}
}
diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
similarity index 83%
rename from keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java
rename to keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
index 5d4ab9c..113d730 100644
--- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java
+++ b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
@@ -23,7 +23,7 @@
import javax.security.auth.x500.X500Principal;
-public class AndroidKeyPairGeneratorSpecTest extends AndroidTestCase {
+public class KeyPairGeneratorSpecTest extends AndroidTestCase {
private static final String TEST_ALIAS_1 = "test1";
private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
@@ -39,8 +39,8 @@
private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
public void testConstructor_Success() throws Exception {
- AndroidKeyPairGeneratorSpec spec =
- new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
+ KeyPairGeneratorSpec spec =
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
NOW, NOW_PLUS_10_YEARS, 0);
assertEquals("Context should be the one specified", getContext(), spec.getContext());
@@ -55,7 +55,7 @@
}
public void testBuilder_Success() throws Exception {
- AndroidKeyPairGeneratorSpec spec = new AndroidKeyPairGeneratorSpec.Builder(getContext())
+ KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getContext())
.setAlias(TEST_ALIAS_1)
.setSubject(TEST_DN_1)
.setSerialNumber(SERIAL_1)
@@ -79,7 +79,7 @@
public void testConstructor_NullContext_Failure() throws Exception {
try {
- new AndroidKeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
+ new KeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
NOW_PLUS_10_YEARS, 0);
fail("Should throw IllegalArgumentException when context is null");
} catch (IllegalArgumentException success) {
@@ -88,7 +88,7 @@
public void testConstructor_NullKeystoreAlias_Failure() throws Exception {
try {
- new AndroidKeyPairGeneratorSpec(getContext(), null, TEST_DN_1, SERIAL_1, NOW,
+ new KeyPairGeneratorSpec(getContext(), null, TEST_DN_1, SERIAL_1, NOW,
NOW_PLUS_10_YEARS, 0);
fail("Should throw IllegalArgumentException when keystoreAlias is null");
} catch (IllegalArgumentException success) {
@@ -97,7 +97,7 @@
public void testConstructor_NullSubjectDN_Failure() throws Exception {
try {
- new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, null, SERIAL_1, NOW,
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, null, SERIAL_1, NOW,
NOW_PLUS_10_YEARS, 0);
fail("Should throw IllegalArgumentException when subjectDN is null");
} catch (IllegalArgumentException success) {
@@ -106,7 +106,7 @@
public void testConstructor_NullSerial_Failure() throws Exception {
try {
- new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, null, NOW,
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, null, NOW,
NOW_PLUS_10_YEARS, 0);
fail("Should throw IllegalArgumentException when startDate is null");
} catch (IllegalArgumentException success) {
@@ -115,7 +115,7 @@
public void testConstructor_NullStartDate_Failure() throws Exception {
try {
- new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, null,
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, null,
NOW_PLUS_10_YEARS, 0);
fail("Should throw IllegalArgumentException when startDate is null");
} catch (IllegalArgumentException success) {
@@ -124,7 +124,7 @@
public void testConstructor_NullEndDate_Failure() throws Exception {
try {
- new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
null, 0);
fail("Should throw IllegalArgumentException when keystoreAlias is null");
} catch (IllegalArgumentException success) {
@@ -133,7 +133,7 @@
public void testConstructor_EndBeforeStart_Failure() throws Exception {
try {
- new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
NOW_PLUS_10_YEARS, NOW, 0);
fail("Should throw IllegalArgumentException when end is before start");
} catch (IllegalArgumentException success) {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 917a47d..56e98e4 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -1205,6 +1206,11 @@
* call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection.
* <p>Even if a SCO connection is established, the following restrictions apply on audio
* output streams so that they can be routed to SCO headset:
+ * <p>NOTE: up to and including API version
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual
+ * voice call to the bluetooth headset.
+ * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio
+ * connection is established.
* <ul>
* <li> the stream type must be {@link #STREAM_VOICE_CALL} </li>
* <li> the format must be mono </li>
@@ -1226,7 +1232,7 @@
public void startBluetoothSco(){
IAudioService service = getService();
try {
- service.startBluetoothSco(mICallBack);
+ service.startBluetoothSco(mICallBack, mContext.getApplicationInfo().targetSdkVersion);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in startBluetoothSco", e);
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 637ac85..0df4f82 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -48,6 +48,7 @@
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -369,6 +370,14 @@
// waiting for headset service to connect
private static final int SCO_STATE_DEACTIVATE_EXT_REQ = 4;
+ // Indicates the mode used for SCO audio connection. The mode is virtual call if the request
+ // originated from an app targeting an API version before JB MR2 and raw audio after that.
+ private int mScoAudioMode;
+ // SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall())
+ private static final int SCO_MODE_VIRTUAL_CALL = 0;
+ // SCO audio mode is raw audio (BluetoothHeadset.connectAudio())
+ private static final int SCO_MODE_RAW = 1;
+
// Current connection state indicated by bluetooth headset
private int mScoConnectionState;
@@ -1910,7 +1919,7 @@
}
/** @see AudioManager#startBluetoothSco() */
- public void startBluetoothSco(IBinder cb){
+ public void startBluetoothSco(IBinder cb, int targetSdkVersion){
if (!checkAudioSettingsPermission("startBluetoothSco()") ||
!mBootCompleted) {
return;
@@ -1922,7 +1931,7 @@
// The caller identity must be cleared after getScoClient() because it is needed if a new
// client is created.
final long ident = Binder.clearCallingIdentity();
- client.incCount();
+ client.incCount(targetSdkVersion);
Binder.restoreCallingIdentity(ident);
}
@@ -1968,9 +1977,9 @@
}
}
- public void incCount() {
+ public void incCount(int targetSdkVersion) {
synchronized(mScoClients) {
- requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED);
+ requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, targetSdkVersion);
if (mStartcount == 0) {
try {
mCb.linkToDeath(this, 0);
@@ -1996,7 +2005,7 @@
Log.w(TAG, "decCount() going to 0 but not registered to binder");
}
}
- requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+ requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
}
}
}
@@ -2012,7 +2021,7 @@
}
mStartcount = 0;
if (stopSco) {
- requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+ requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
}
}
}
@@ -2040,7 +2049,7 @@
}
}
- private void requestScoState(int state) {
+ private void requestScoState(int state, int targetSdkVersion) {
checkScoAudioState();
if (totalCount() == 0) {
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
@@ -2055,8 +2064,18 @@
(mScoAudioState == SCO_STATE_INACTIVE ||
mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) {
if (mScoAudioState == SCO_STATE_INACTIVE) {
+ mScoAudioMode =
+ (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
+ SCO_MODE_VIRTUAL_CALL : SCO_MODE_RAW;
if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
- if (mBluetoothHeadset.connectAudio()) {
+ boolean status;
+ if (mScoAudioMode == SCO_MODE_RAW) {
+ status = mBluetoothHeadset.connectAudio();
+ } else {
+ status = mBluetoothHeadset.startScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice);
+ }
+ if (status) {
mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
} else {
broadcastScoConnectionState(
@@ -2078,7 +2097,14 @@
mScoAudioState == SCO_STATE_ACTIVATE_REQ)) {
if (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL) {
if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
- if (!mBluetoothHeadset.disconnectAudio()) {
+ boolean status;
+ if (mScoAudioMode == SCO_MODE_RAW) {
+ status = mBluetoothHeadset.disconnectAudio();
+ } else {
+ status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice);
+ }
+ if (!status) {
mScoAudioState = SCO_STATE_INACTIVE;
broadcastScoConnectionState(
AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
@@ -2251,10 +2277,20 @@
switch (mScoAudioState) {
case SCO_STATE_ACTIVATE_REQ:
mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- status = mBluetoothHeadset.connectAudio();
+ if (mScoAudioMode == SCO_MODE_RAW) {
+ status = mBluetoothHeadset.connectAudio();
+ } else {
+ status = mBluetoothHeadset.startScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice);
+ }
break;
case SCO_STATE_DEACTIVATE_REQ:
- status = mBluetoothHeadset.disconnectAudio();
+ if (mScoAudioMode == SCO_MODE_RAW) {
+ status = mBluetoothHeadset.disconnectAudio();
+ } else {
+ status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice);
+ }
break;
case SCO_STATE_DEACTIVATE_EXT_REQ:
status = mBluetoothHeadset.stopVoiceRecognition(
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 13f6c02..0d285fc 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -179,7 +179,7 @@
int getRemoteStreamVolume();
oneway void registerRemoteVolumeObserverForRcc(int rccId, in IRemoteVolumeObserver rvo);
- void startBluetoothSco(IBinder cb);
+ void startBluetoothSco(IBinder cb, int targetSdkVersion);
void stopBluetoothSco(IBinder cb);
void forceVolumeControlStream(int streamType, IBinder cb);
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 1501c79..df87db3 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -44,7 +44,16 @@
return MediaCodecList.getSupportedTypes(mIndex);
}
+ /**
+ * Encapsulates the capabilities of a given codec component,
+ * i.e. what profile/level combinations it supports and what colorspaces
+ * it is capable of providing the decoded data in.
+ */
public static final class CodecCapabilities {
+ // Enumerates supported profile/level combinations as defined
+ // by the type of encoded data. These combinations impose restrictions
+ // on video resolution, bitrate... and limit the available encoder tools
+ // such as B-frame support, arithmetic coding...
public CodecProfileLevel[] profileLevels;
// from OMX_COLOR_FORMATTYPE
@@ -219,6 +228,11 @@
public int level;
};
+ /**
+ * Enumerates the capabilities of the codec component. Since a single
+ * component can support data of a variety of types, the type has to be
+ * specified to yield a meaningful result.
+ */
public final CodecCapabilities getCapabilitiesForType(
String type) {
return MediaCodecList.getCodecCapabilities(mIndex, type);
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 61a0134..f77ddc4 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -65,6 +65,7 @@
public class RemoteControlClient
{
private final static String TAG = "RemoteControlClient";
+ private final static boolean DEBUG = false;
/**
* Playback state of a RemoteControlClient which is stopped.
@@ -219,7 +220,7 @@
public final static int PLAYBACKINFO_USES_STREAM = 5;
//==========================================
- // Public flags for the supported transport control capabililities
+ // Public flags for the supported transport control capabilities
/**
* Flag indicating a RemoteControlClient makes use of the "previous" media key.
*
@@ -642,6 +643,57 @@
sendPlaybackState_syncCacheLock();
// update AudioService
sendAudioServiceNewPlaybackState_syncCacheLock();
+
+ // handle automatic playback position refreshes
+ if (mEventHandler == null) {
+ return;
+ }
+ mEventHandler.removeMessages(MSG_POSITION_DRIFT_CHECK);
+ if (timeInMs == PLAYBACK_POSITION_INVALID) {
+ // this playback state refresh has no known playback position, it's no use
+ // trying to see if there is any drift at this point
+ // (this also bypasses this mechanism for older apps that use the old
+ // setPlaybackState(int) API)
+ return;
+ }
+ if (playbackPositionShouldMove(mPlaybackState)) {
+ // playback position moving, schedule next position drift check
+ mEventHandler.sendMessageDelayed(
+ mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK),
+ getCheckPeriodFromSpeed(playbackSpeed));
+ }
+ }
+ }
+ }
+
+ private void onPositionDriftCheck() {
+ if (DEBUG) { Log.d(TAG, "onPositionDriftCheck()"); }
+ synchronized(mCacheLock) {
+ if ((mEventHandler == null) || (mPositionProvider == null)) {
+ return;
+ }
+ if ((mPlaybackPositionMs == PLAYBACK_POSITION_INVALID) || (mPlaybackSpeed == 0.0f)) {
+ if (DEBUG) { Log.d(TAG, " no position or 0 speed, no check needed"); }
+ return;
+ }
+ long estPos = mPlaybackPositionMs + (long)
+ ((SystemClock.elapsedRealtime() - mPlaybackStateChangeTimeMs) / mPlaybackSpeed);
+ long actPos = mPositionProvider.onGetPlaybackPosition();
+ if (actPos >= 0) {
+ if (Math.abs(estPos - actPos) > POSITION_DRIFT_MAX_MS) {
+ // drift happened, report the new position
+ if (DEBUG) { Log.w(TAG, " drift detected: actual=" +actPos +" est=" +estPos); }
+ setPlaybackState(mPlaybackState, actPos, mPlaybackSpeed);
+ } else {
+ if (DEBUG) { Log.d(TAG, " no drift: actual=" + actPos +" est=" + estPos); }
+ // no drift, schedule the next drift check
+ mEventHandler.sendMessageDelayed(
+ mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK),
+ getCheckPeriodFromSpeed(mPlaybackSpeed));
+ }
+ } else {
+ // invalid position (negative value), can't check for drift
+ mEventHandler.removeMessages(MSG_POSITION_DRIFT_CHECK);
}
}
}
@@ -746,6 +798,14 @@
// tell RCDs that this RCC's playback position capabilities have changed
sendTransportControlInfo_syncCacheLock();
}
+ if ((mPositionProvider != null) && (mEventHandler != null)
+ && playbackPositionShouldMove(mPlaybackState)) {
+ // playback position is already moving, but now we have a position provider,
+ // so schedule a drift check right now
+ mEventHandler.sendMessageDelayed(
+ mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK),
+ 0 /*check now*/);
+ }
}
}
@@ -1099,6 +1159,7 @@
private final static int MSG_UNPLUG_DISPLAY = 8;
private final static int MSG_UPDATE_DISPLAY_ARTWORK_SIZE = 9;
private final static int MSG_SEEK_TO = 10;
+ private final static int MSG_POSITION_DRIFT_CHECK = 11;
private class EventHandler extends Handler {
public EventHandler(RemoteControlClient rcc, Looper looper) {
@@ -1146,6 +1207,9 @@
case MSG_SEEK_TO:
onSeekTo(msg.arg1, ((Long)msg.obj).longValue());
break;
+ case MSG_POSITION_DRIFT_CHECK:
+ onPositionDriftCheck();
+ break;
default:
Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler");
}
@@ -1440,4 +1504,57 @@
return false;
}
}
+
+ /**
+ * Returns whether, for the given playback state, the playback position is expected to
+ * be changing.
+ * @param playstate the playback state to evaluate
+ * @return true during any form of playback, false if it's not playing anything while in this
+ * playback state
+ */
+ private static boolean playbackPositionShouldMove(int playstate) {
+ switch(playstate) {
+ case PLAYSTATE_STOPPED:
+ case PLAYSTATE_PAUSED:
+ case PLAYSTATE_BUFFERING:
+ case PLAYSTATE_ERROR:
+ case PLAYSTATE_SKIPPING_FORWARDS:
+ case PLAYSTATE_SKIPPING_BACKWARDS:
+ return false;
+ case PLAYSTATE_PLAYING:
+ case PLAYSTATE_FAST_FORWARDING:
+ case PLAYSTATE_REWINDING:
+ default:
+ return true;
+ }
+ }
+
+ /**
+ * Period for playback position drift checks, 15s when playing at 1x or slower.
+ */
+ private final static long POSITION_REFRESH_PERIOD_PLAYING_MS = 15000;
+ /**
+ * Minimum period for playback position drift checks, never more often when every 2s, when
+ * fast forwarding or rewinding.
+ */
+ private final static long POSITION_REFRESH_PERIOD_MIN_MS = 2000;
+ /**
+ * The value above which the difference between client-reported playback position and
+ * estimated position is considered a drift.
+ */
+ private final static long POSITION_DRIFT_MAX_MS = 500;
+ /**
+ * Compute the period at which the estimated playback position should be compared against the
+ * actual playback position. Is a funciton of playback speed.
+ * @param speed 1.0f is normal playback speed
+ * @return the period in ms
+ */
+ private static long getCheckPeriodFromSpeed(float speed) {
+ if (Math.abs(speed) <= 1.0f) {
+ return POSITION_REFRESH_PERIOD_PLAYING_MS;
+ } else {
+ return Math.max((long)(POSITION_REFRESH_PERIOD_PLAYING_MS / Math.abs(speed)),
+ POSITION_REFRESH_PERIOD_MIN_MS);
+ }
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 7f3fc43..0fb3244 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -18,6 +18,7 @@
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
+import android.app.IUiModeManager;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.app.UiModeManager;
@@ -31,6 +32,7 @@
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -125,6 +127,11 @@
static final boolean SHOW_STARTING_ANIMATIONS = true;
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
+ // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
+ // No longer recommended for desk docks; still useful in car docks.
+ static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
+ static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
+
static final int LONG_PRESS_POWER_NOTHING = 0;
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
static final int LONG_PRESS_POWER_SHUT_OFF = 2;
@@ -247,6 +254,7 @@
boolean mSystemReady;
boolean mSystemBooted;
boolean mHdmiPlugged;
+ int mUiMode;
int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
int mLidOpenRotation;
int mCarDockRotation;
@@ -832,6 +840,8 @@
mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context, mHandler);
mShortcutManager.observe();
+ mUiMode = context.getResources().getInteger(
+ com.android.internal.R.integer.config_defaultUiModeType);
mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
mHomeIntent.addCategory(Intent.CATEGORY_HOME);
mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -3951,6 +3961,13 @@
if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ } else {
+ try {
+ IUiModeManager uiModeService = IUiModeManager.Stub.asInterface(
+ ServiceManager.getService(Context.UI_MODE_SERVICE));
+ mUiMode = uiModeService.getCurrentModeType();
+ } catch (RemoteException e) {
+ }
}
updateRotation(true);
synchronized (mLock) {
@@ -4587,9 +4604,70 @@
}
}
+ /**
+ * Return an Intent to launch the currently active dock app as home. Returns
+ * null if the standard home should be launched, which is the case if any of the following is
+ * true:
+ * <ul>
+ * <li>The device is not in either car mode or desk mode
+ * <li>The device is in car mode but ENABLE_CAR_DOCK_HOME_CAPTURE is false
+ * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
+ * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
+ * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
+ * </ul>
+ * @return
+ */
+ Intent createHomeDockIntent() {
+ Intent intent = null;
+
+ // What home does is based on the mode, not the dock state. That
+ // is, when in car mode you should be taken to car home regardless
+ // of whether we are actually in a car dock.
+ if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
+ if (ENABLE_CAR_DOCK_HOME_CAPTURE) {
+ intent = mCarDockIntent;
+ }
+ } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
+ if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
+ intent = mDeskDockIntent;
+ }
+ }
+
+ if (intent == null) {
+ return null;
+ }
+
+ ActivityInfo ai = null;
+ ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser(
+ intent,
+ PackageManager.MATCH_DEFAULT_ONLY,
+ UserHandle.USER_CURRENT);
+ if (info != null) {
+ ai = info.activityInfo;
+ }
+ if (ai != null
+ && ai.metaData != null
+ && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) {
+ intent = new Intent(intent);
+ intent.setClassName(ai.packageName, ai.name);
+ return intent;
+ }
+
+ return null;
+ }
+
void startDockOrHome() {
awakenDreams();
- // We don't have dock home anymore. Home is home. If you lived here, you'd be home by now.
+
+ Intent dock = createHomeDockIntent();
+ if (dock != null) {
+ try {
+ mContext.startActivityAsUser(dock, UserHandle.CURRENT);
+ return;
+ } catch (ActivityNotFoundException e) {
+ }
+ }
+
mContext.startActivityAsUser(mHomeIntent, UserHandle.CURRENT);
}
@@ -4616,6 +4694,18 @@
} else {
ActivityManagerNative.getDefault().stopAppSwitches();
sendCloseSystemWindows();
+ Intent dock = createHomeDockIntent();
+ if (dock != null) {
+ int result = ActivityManagerNative.getDefault()
+ .startActivityAsUser(null, null, dock,
+ dock.resolveTypeIfNeeded(mContext.getContentResolver()),
+ null, null, 0,
+ ActivityManager.START_FLAG_ONLY_IF_NEEDED,
+ null, null, null, UserHandle.USER_CURRENT);
+ if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
+ return false;
+ }
+ }
}
int result = ActivityManagerNative.getDefault()
.startActivityAsUser(null, null, mHomeIntent,
@@ -4844,7 +4934,8 @@
pw.print(prefix); pw.print("mLastFocusNeedsMenu=");
pw.println(mLastFocusNeedsMenu);
}
- pw.print(prefix); pw.print("mDockMode="); pw.print(mDockMode);
+ pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
+ pw.print(" mDockMode="); pw.print(mDockMode);
pw.print(" mCarDockRotation="); pw.print(mCarDockRotation);
pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation);
pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index 4d23e5c..9560199 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -404,7 +404,7 @@
try {
/* Turning off Wi-Fi when scans are still available */
- if (!enable && isScanningAlwaysAvailable()) {
+ if (!enable && isScanAlwaysAvailable()) {
/* Notify if device is provisioned and user has not opted out of the notification */
if (mNotifyScanMode.get() && mDeviceProvisioned.get()) {
Intent intent = new Intent(WifiManager.ACTION_NOTIFY_SCAN_ALWAYS_AVAILABLE);
@@ -497,7 +497,7 @@
* @return {@code true} if the enable/disable operation was
* started or is already in the queue.
*/
- public boolean isScanningAlwaysAvailable() {
+ public boolean isScanAlwaysAvailable() {
enforceAccessPermission();
return mSettingsStore.isScanAlwaysAvailable();
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index f093b52..547ae95 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -71,7 +71,7 @@
DhcpInfo getDhcpInfo();
- boolean isScanningAlwaysAvailable();
+ boolean isScanAlwaysAvailable();
boolean acquireWifiLock(IBinder lock, int lockType, String tag, in WorkSource ws);
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 4e7497c..e2512a4 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -223,6 +223,9 @@
public static final int PWD = 3;
/** @hide */
public static final String[] strings = { "PEAP", "TLS", "TTLS", "PWD" };
+
+ /** Prevent initialization */
+ private Eap() {}
}
/** The inner authentication method used */
@@ -239,6 +242,9 @@
private static final String PREFIX = "auth=";
/** @hide */
public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP", "MSCHAPV2", "GTC" };
+
+ /** Prevent initialization */
+ private Phase2() {}
}
/** Internal use only */
@@ -363,6 +369,16 @@
}
/**
+ * Get the password.
+ *
+ * Returns locally set password value. For networks fetched from
+ * framework, returns "*".
+ */
+ public String getPassword() {
+ return getFieldValue(PASSWORD_KEY, "");
+ }
+
+ /**
* Set CA certificate alias.
*
* <p> See the {@link android.security.KeyChain} for details on installing or choosing
@@ -404,6 +420,15 @@
}
/**
+ * Get CA certificate
+ *
+ * @return X.509 CA certificate
+ */
+ public X509Certificate getCaCertificate() {
+ return mCaCert;
+ }
+
+ /**
* Set Client certificate alias.
*
* <p> See the {@link android.security.KeyChain} for details on installing or choosing
@@ -463,6 +488,15 @@
mClientCertificate = clientCertificate;
}
+ /**
+ * Get client certificate
+ *
+ * @return X.509 client certificate
+ */
+ public X509Certificate getClientCertificate() {
+ return mClientCertificate;
+ }
+
boolean needsKeyStore() {
// Has no keys to be installed
if (mClientCertificate == null && mCaCert == null) return false;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 0c0a144..a7a5924 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -794,9 +794,9 @@
*
* To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}.
*/
- public boolean isScanningAlwaysAvailable() {
+ public boolean isScanAlwaysAvailable() {
try {
- return mService.isScanningAlwaysAvailable();
+ return mService.isScanAlwaysAvailable();
} catch (RemoteException e) {
return false;
}