summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/animation/ObjectAnimator.java95
-rw-r--r--core/java/android/app/ActivityThread.java5
-rw-r--r--core/java/android/app/ActivityTransitionCoordinator.java30
-rw-r--r--core/java/android/app/ContextImpl.java8
-rw-r--r--core/java/android/app/Notification.java11
-rw-r--r--core/java/android/app/SearchManager.java106
-rw-r--r--core/java/android/app/TaskManagerImpl.java24
-rw-r--r--core/java/android/app/admin/DeviceAdminReceiver.java41
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java82
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl4
-rw-r--r--core/java/android/app/task/Task.java11
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java20
-rw-r--r--core/java/android/bluetooth/IBluetooth.aidl1
-rw-r--r--core/java/android/content/Context.java16
-rw-r--r--core/java/android/content/Intent.java70
-rw-r--r--core/java/android/content/SyncRequest.java31
-rw-r--r--core/java/android/content/pm/ActivityInfo.java11
-rw-r--r--core/java/android/content/pm/PackageParser.java3
-rw-r--r--core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java54
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java4
-rw-r--r--core/java/android/hardware/camera2/utils/TaskDrainer.java2
-rw-r--r--core/java/android/hardware/hdmi/HdmiCec.java5
-rw-r--r--core/java/android/hardware/hdmi/HdmiCecClient.java119
-rw-r--r--core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java4
-rw-r--r--core/java/android/hardware/hdmi/HdmiCecManager.java68
-rw-r--r--core/java/android/hardware/hdmi/HdmiCecMessage.java4
-rw-r--r--core/java/android/hardware/hdmi/HdmiControlManager.java4
-rw-r--r--core/java/android/hardware/hdmi/HdmiHotplugEvent.java4
-rw-r--r--core/java/android/hardware/hdmi/HdmiPlaybackClient.java4
-rw-r--r--core/java/android/hardware/hdmi/HdmiTvClient.java5
-rw-r--r--core/java/android/hardware/hdmi/IHdmiCecListener.aidl29
-rw-r--r--core/java/android/hardware/hdmi/IHdmiCecService.aidl40
-rw-r--r--core/java/android/net/ConnectivityManager.java70
-rw-r--r--core/java/android/net/DhcpResults.java8
-rw-r--r--core/java/android/net/DnsPinger.java2
-rw-r--r--core/java/android/net/LinkProperties.java86
-rw-r--r--core/java/android/net/Network.java55
-rw-r--r--core/java/android/net/NetworkAgent.java5
-rw-r--r--core/java/android/net/NetworkUtils.java2
-rw-r--r--core/java/android/net/ProxyDataTracker.java4
-rw-r--r--core/java/android/os/BatteryManager.java90
-rw-r--r--core/java/android/os/BatteryProperty.java61
-rw-r--r--core/java/android/os/UserManager.java5
-rw-r--r--core/java/android/provider/Browser.java29
-rw-r--r--core/java/android/provider/DocumentsContract.java120
-rw-r--r--core/java/android/provider/DocumentsProvider.java81
-rw-r--r--core/java/android/util/Range.java30
-rw-r--r--core/java/android/util/Rational.java457
-rw-r--r--core/java/android/view/View.java7
-rw-r--r--core/java/android/view/ViewGroup.java15
-rw-r--r--core/java/android/view/WindowInsets.java7
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java6
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java59
-rw-r--r--core/java/com/android/internal/view/IInputMethodClient.aidl1
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl2
-rw-r--r--core/java/com/android/internal/view/InputBindResult.java16
-rw-r--r--core/java/com/android/server/SystemService.java54
57 files changed, 1343 insertions, 844 deletions
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 130754e..8947550 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -16,11 +16,14 @@
package android.animation;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.Log;
import android.util.Property;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
@@ -41,10 +44,15 @@ import java.util.ArrayList;
*
*/
public final class ObjectAnimator extends ValueAnimator {
+ private static final String LOG_TAG = "ObjectAnimator";
+
private static final boolean DBG = false;
- // The target object on which the property exists, set in the constructor
- private Object mTarget;
+ /**
+ * A weak reference to the target object on which the property exists, set
+ * in the constructor. We'll cancel the animation if this goes away.
+ */
+ private WeakReference<Object> mTarget;
private String mPropertyName;
@@ -78,7 +86,7 @@ public final class ObjectAnimator extends ValueAnimator {
*
* @param propertyName The name of the property being animated. Should not be null.
*/
- public void setPropertyName(String propertyName) {
+ public void setPropertyName(@NonNull String propertyName) {
// mValues could be null if this is being constructed piecemeal. Just record the
// propertyName to be used later when setValues() is called if so.
if (mValues != null) {
@@ -100,7 +108,7 @@ public final class ObjectAnimator extends ValueAnimator {
*
* @param property The property being animated. Should not be null.
*/
- public void setProperty(Property property) {
+ public void setProperty(@NonNull Property property) {
// mValues could be null if this is being constructed piecemeal. Just record the
// propertyName to be used later when setValues() is called if so.
if (mValues != null) {
@@ -134,6 +142,7 @@ public final class ObjectAnimator extends ValueAnimator {
* object (if there was just one) or a comma-separated list of all of the
* names (if there are more than one).</p>
*/
+ @Nullable
public String getPropertyName() {
String propertyName = null;
if (mPropertyName != null) {
@@ -176,7 +185,7 @@ public final class ObjectAnimator extends ValueAnimator {
* @param propertyName The name of the property being animated.
*/
private ObjectAnimator(Object target, String propertyName) {
- mTarget = target;
+ setTarget(target);
setPropertyName(propertyName);
}
@@ -187,7 +196,7 @@ public final class ObjectAnimator extends ValueAnimator {
* @param property The property being animated.
*/
private <T> ObjectAnimator(T target, Property<T, ?> property) {
- mTarget = target;
+ setTarget(target);
setProperty(property);
}
@@ -574,8 +583,9 @@ public final class ObjectAnimator extends ValueAnimator {
* @param path The <code>Path</code> to animate values along.
* @return An ObjectAnimator object that is set up to animate along <code>path</code>.
*/
+ @NonNull
public static ObjectAnimator ofObject(Object target, String propertyName,
- TypeConverter<PointF, ?> converter, Path path) {
+ @Nullable TypeConverter<PointF, ?> converter, Path path) {
PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(propertyName, converter, path);
return ofPropertyValuesHolder(target, pvh);
}
@@ -595,6 +605,7 @@ public final class ObjectAnimator extends ValueAnimator {
* @param values A set of values that the animation will animate between over time.
* @return An ObjectAnimator object that is set up to animate between the given values.
*/
+ @NonNull
public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property,
TypeEvaluator<V> evaluator, V... values) {
ObjectAnimator anim = new ObjectAnimator(target, property);
@@ -622,6 +633,7 @@ public final class ObjectAnimator extends ValueAnimator {
* @param values A set of values that the animation will animate between over time.
* @return An ObjectAnimator object that is set up to animate between the given values.
*/
+ @NonNull
public static <T, V, P> ObjectAnimator ofObject(T target, Property<T, P> property,
TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values) {
PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, evaluator,
@@ -644,8 +656,9 @@ public final class ObjectAnimator extends ValueAnimator {
* @param path The <code>Path</code> to animate values along.
* @return An ObjectAnimator object that is set up to animate along <code>path</code>.
*/
- public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property,
- TypeConverter<PointF, V> converter, Path path) {
+ @NonNull
+ public static <T, V> ObjectAnimator ofObject(T target, @NonNull Property<T, V> property,
+ @Nullable TypeConverter<PointF, V> converter, Path path) {
PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, path);
return ofPropertyValuesHolder(target, pvh);
}
@@ -667,10 +680,11 @@ public final class ObjectAnimator extends ValueAnimator {
* over time.
* @return An ObjectAnimator object that is set up to animate between the given values.
*/
+ @NonNull
public static ObjectAnimator ofPropertyValuesHolder(Object target,
PropertyValuesHolder... values) {
ObjectAnimator anim = new ObjectAnimator();
- anim.mTarget = target;
+ anim.setTarget(target);
anim.setValues(values);
return anim;
}
@@ -736,10 +750,10 @@ public final class ObjectAnimator extends ValueAnimator {
mAutoCancel = cancel;
}
- private boolean hasSameTargetAndProperties(Animator anim) {
+ private boolean hasSameTargetAndProperties(@Nullable Animator anim) {
if (anim instanceof ObjectAnimator) {
PropertyValuesHolder[] theirValues = ((ObjectAnimator) anim).getValues();
- if (((ObjectAnimator) anim).getTarget() == mTarget &&
+ if (((ObjectAnimator) anim).getTarget() == getTarget() &&
mValues.length == theirValues.length) {
for (int i = 0; i < mValues.length; ++i) {
PropertyValuesHolder pvhMine = mValues[i];
@@ -789,11 +803,11 @@ public final class ObjectAnimator extends ValueAnimator {
}
}
if (DBG) {
- Log.d("ObjectAnimator", "Anim target, duration: " + mTarget + ", " + getDuration());
+ Log.d(LOG_TAG, "Anim target, duration: " + getTarget() + ", " + getDuration());
for (int i = 0; i < mValues.length; ++i) {
PropertyValuesHolder pvh = mValues[i];
ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes;
- Log.d("ObjectAnimator", " Values[" + i + "]: " +
+ Log.d(LOG_TAG, " Values[" + i + "]: " +
pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " +
keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue());
}
@@ -818,9 +832,12 @@ public final class ObjectAnimator extends ValueAnimator {
if (!mInitialized) {
// mValueType may change due to setter/getter setup; do this before calling super.init(),
// which uses mValueType to set up the default type evaluator.
- int numValues = mValues.length;
- for (int i = 0; i < numValues; ++i) {
- mValues[i].setupSetterAndGetter(mTarget);
+ final Object target = getTarget();
+ if (target != null) {
+ final int numValues = mValues.length;
+ for (int i = 0; i < numValues; ++i) {
+ mValues[i].setupSetterAndGetter(target);
+ }
}
super.initAnimation();
}
@@ -836,6 +853,7 @@ public final class ObjectAnimator extends ValueAnimator {
* <code>ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start()</code>.
*/
@Override
+ @NonNull
public ObjectAnimator setDuration(long duration) {
super.setDuration(duration);
return this;
@@ -847,8 +865,9 @@ public final class ObjectAnimator extends ValueAnimator {
*
* @return The object being animated
*/
+ @Nullable
public Object getTarget() {
- return mTarget;
+ return mTarget == null ? null : mTarget.get();
}
/**
@@ -857,10 +876,10 @@ public final class ObjectAnimator extends ValueAnimator {
* @param target The object being animated
*/
@Override
- public void setTarget(Object target) {
- if (mTarget != target) {
- final Object oldTarget = mTarget;
- mTarget = target;
+ public void setTarget(@Nullable Object target) {
+ final Object oldTarget = getTarget();
+ if (oldTarget != target) {
+ mTarget = target == null ? null : new WeakReference<Object>(target);
if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) {
return;
}
@@ -872,18 +891,26 @@ public final class ObjectAnimator extends ValueAnimator {
@Override
public void setupStartValues() {
initAnimation();
- int numValues = mValues.length;
- for (int i = 0; i < numValues; ++i) {
- mValues[i].setupStartValue(mTarget);
+
+ final Object target = getTarget();
+ if (target != null) {
+ final int numValues = mValues.length;
+ for (int i = 0; i < numValues; ++i) {
+ mValues[i].setupStartValue(target);
+ }
}
}
@Override
public void setupEndValues() {
initAnimation();
- int numValues = mValues.length;
- for (int i = 0; i < numValues; ++i) {
- mValues[i].setupEndValue(mTarget);
+
+ final Object target = getTarget();
+ if (target != null) {
+ final int numValues = mValues.length;
+ for (int i = 0; i < numValues; ++i) {
+ mValues[i].setupEndValue(target);
+ }
}
}
@@ -901,10 +928,17 @@ public final class ObjectAnimator extends ValueAnimator {
*/
@Override
void animateValue(float fraction) {
+ final Object target = getTarget();
+ if (mTarget != null && target == null) {
+ // We lost the target reference, cancel and clean up.
+ cancel();
+ return;
+ }
+
super.animateValue(fraction);
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
- mValues[i].setAnimatedValue(mTarget);
+ mValues[i].setAnimatedValue(target);
}
}
@@ -915,9 +949,10 @@ public final class ObjectAnimator extends ValueAnimator {
}
@Override
+ @NonNull
public String toString() {
String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " +
- mTarget;
+ getTarget();
if (mValues != null) {
for (int i = 0; i < mValues.length; ++i) {
returnVal += "\n " + mValues[i].toString();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d9adba3..ea46044 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -98,6 +98,7 @@ import com.android.internal.os.RuntimeInit;
import com.android.internal.os.SamplingProfilerIntegration;
import com.android.internal.util.FastPrintWriter;
import com.android.org.conscrypt.OpenSSLSocketImpl;
+import com.android.org.conscrypt.TrustedCertificateStore;
import com.google.android.collect.Lists;
import dalvik.system.VMRuntime;
@@ -5049,6 +5050,10 @@ public final class ActivityThread {
Security.addProvider(new AndroidKeyStoreProvider());
+ // Make sure TrustedCertificateStore looks in the right place for CA certificates
+ final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
+ TrustedCertificateStore.setDefaultUserDirectory(configDir);
+
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index b658597..a4384f8 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -251,13 +251,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
if (view == null) {
mEpicenterCallback.setEpicenter(null);
} else {
- int[] loc = new int[2];
- view.getLocationOnScreen(loc);
- int left = loc[0] + Math.round(view.getTranslationX());
- int top = loc[1] + Math.round(view.getTranslationY());
- int right = left + view.getWidth();
- int bottom = top + view.getHeight();
- Rect epicenter = new Rect(left, top, right, bottom);
+ Rect epicenter = new Rect();
+ view.getBoundsOnScreen(epicenter);
mEpicenterCallback.setEpicenter(epicenter);
}
}
@@ -492,11 +487,11 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
protected Bundle captureSharedElementState() {
Bundle bundle = new Bundle();
- int[] tempLoc = new int[2];
+ Rect tempBounds = new Rect();
for (int i = 0; i < mSharedElementNames.size(); i++) {
View sharedElement = mSharedElements.get(i);
String name = mSharedElementNames.get(i);
- captureSharedElementState(sharedElement, name, bundle, tempLoc);
+ captureSharedElementState(sharedElement, name, bundle, tempBounds);
}
return bundle;
}
@@ -509,20 +504,19 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
* @param name The shared element name in the target Activity to apply the placement
* information for.
* @param transitionArgs Bundle to store shared element placement information.
- * @param tempLoc A temporary int[2] for capturing the current location of views.
+ * @param tempBounds A temporary Rect for capturing the current location of views.
*/
private static void captureSharedElementState(View view, String name, Bundle transitionArgs,
- int[] tempLoc) {
+ Rect tempBounds) {
Bundle sharedElementBundle = new Bundle();
- view.getLocationOnScreen(tempLoc);
- float scaleX = view.getScaleX();
- sharedElementBundle.putInt(KEY_SCREEN_X, tempLoc[0]);
- int width = Math.round(view.getWidth() * scaleX);
+ tempBounds.set(0, 0, view.getWidth(), view.getHeight());
+ view.getBoundsOnScreen(tempBounds);
+ sharedElementBundle.putInt(KEY_SCREEN_X, tempBounds.left);
+ int width = tempBounds.width();
sharedElementBundle.putInt(KEY_WIDTH, width);
- float scaleY = view.getScaleY();
- sharedElementBundle.putInt(KEY_SCREEN_Y, tempLoc[1]);
- int height = Math.round(view.getHeight() * scaleY);
+ sharedElementBundle.putInt(KEY_SCREEN_Y, tempBounds.top);
+ int height = tempBounds.height();
sharedElementBundle.putInt(KEY_HEIGHT, height);
sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ());
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index e03224c..ad506e4 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -59,9 +59,7 @@ import android.hardware.ConsumerIrManager;
import android.hardware.ISerialManager;
import android.hardware.SerialManager;
import android.hardware.SystemSensorManager;
-import android.hardware.hdmi.HdmiCecManager;
import android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.IHdmiCecService;
import android.hardware.hdmi.IHdmiControlService;
import android.hardware.camera2.CameraManager;
import android.hardware.display.DisplayManager;
@@ -386,12 +384,6 @@ class ContextImpl extends Context {
return new BluetoothManager(ctx);
}});
- registerService(HDMI_CEC_SERVICE, new StaticServiceFetcher() {
- public Object createStaticService() {
- IBinder b = ServiceManager.getService(HDMI_CEC_SERVICE);
- return new HdmiCecManager(IHdmiCecService.Stub.asInterface(b));
- }});
-
registerService(HDMI_CONTROL_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
IBinder b = ServiceManager.getService(HDMI_CONTROL_SERVICE);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 72b5cd9..a1cdf59 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -17,6 +17,8 @@
package android.app;
import android.annotation.IntDef;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -74,6 +76,15 @@ public class Notification implements Parcelable
private static final String TAG = "Notification";
/**
+ * An activity that provides a user interface for adjusting notification preferences for its
+ * containing application. Optional but recommended for apps that post
+ * {@link android.app.Notification Notifications}.
+ */
+ @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+ public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES
+ = "android.intent.category.NOTIFICATION_PREFERENCES";
+
+ /**
* Use all default values (where applicable).
*/
public static final int DEFAULT_ALL = ~0;
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 33c3409..261b15d 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -253,6 +253,7 @@ public class SearchManager
* for more information on these schemes.
*/
public final static String SUGGEST_COLUMN_ICON_1 = "suggest_icon_1";
+
/**
* Column name for suggestions cursor. <i>Optional.</i> If your cursor includes this column,
* then all suggestions will be provided in a format that includes space for two small icons,
@@ -269,6 +270,24 @@ public class SearchManager
* for more information on these schemes.
*/
public final static String SUGGEST_COLUMN_ICON_2 = "suggest_icon_2";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your cursor includes this column,
+ * then the image will be displayed when forming the suggestion. The suggested dimension for
+ * the image is 270x400 px for portrait mode and 400x225 px for landscape mode. The data in the
+ * column must be a resource ID of a drawable, or a URI in one of the following formats:
+ *
+ * <ul>
+ * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+ * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
+ * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+ * </ul>
+ *
+ * See {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)}
+ * for more information on these schemes.
+ */
+ public final static String SUGGEST_COLUMN_RESULT_CARD_IMAGE = "suggest_result_card_image";
+
/**
* Column name for suggestions cursor. <i>Optional.</i> If this column exists <i>and</i>
* this element exists at the given row, this is the action that will be used when
@@ -279,6 +298,7 @@ public class SearchManager
* it from the cursor.
*/
public final static String SUGGEST_COLUMN_INTENT_ACTION = "suggest_intent_action";
+
/**
* Column name for suggestions cursor. <i>Optional.</i> If this column exists <i>and</i>
* this element exists at the given row, this is the data that will be used when
@@ -289,6 +309,7 @@ public class SearchManager
* it is more efficient to specify it using XML metadata and omit it from the cursor.
*/
public final static String SUGGEST_COLUMN_INTENT_DATA = "suggest_intent_data";
+
/**
* Column name for suggestions cursor. <i>Optional.</i> If this column exists <i>and</i>
* this element exists at the given row, this is the data that will be used when
@@ -297,6 +318,7 @@ public class SearchManager
* an extra under the key {@link #EXTRA_DATA_KEY}.
*/
public final static String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
+
/**
* Column name for suggestions cursor. <i>Optional.</i> If this column exists <i>and</i>
* this element exists at the given row, then "/" and this value will be appended to the data
@@ -304,6 +326,7 @@ public class SearchManager
* appropriate base string.
*/
public final static String SUGGEST_COLUMN_INTENT_DATA_ID = "suggest_intent_data_id";
+
/**
* Column name for suggestions cursor. <i>Required if action is
* {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}, optional otherwise.</i> If this
@@ -331,6 +354,89 @@ public class SearchManager
"suggest_spinner_while_refreshing";
/**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content is media type, you
+ * should provide this column so search app could understand more about your content. The data
+ * in the column must specify the MIME type of the content.
+ */
+ public final static String SUGGEST_COLUMN_CONTENT_TYPE = "suggest_content_type";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content is media type, you
+ * should provide this column to specify whether your content is live media such as live video
+ * or live audio. The value in the column is of integer type with value of either 0 indicating
+ * non-live content or 1 indicating live content.
+ */
+ public final static String SUGGEST_COLUMN_IS_LIVE = "suggest_is_live";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content is video, you should
+ * provide this column to specify the number of vertical lines. The data in the column is of
+ * integer type.
+ */
+ public final static String SUGGEST_COLUMN_VIDEO_WIDTH = "suggest_video_width";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content is video, you should
+ * provide this column to specify the number of horizontal lines. The data in the column is of
+ * integer type.
+ */
+ public final static String SUGGEST_COLUMN_VIDEO_HEIGHT = "suggest_video_height";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content contains audio, you
+ * should provide this column to specify the audio channel configuration. The data in the
+ * column is string with format like "channels.subchannels" such as "1.0" or "5.1".
+ */
+ public final static String SUGGEST_COLUMN_AUDIO_CHANNEL_CONFIG = "suggest_audio_channel_config";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content is purchasable, you
+ * should provide this column to specify the displayable string representation of the purchase
+ * price of your content including the currency and the amount. If it's free, you should
+ * provide localized string to specify that it's free. This column can be omitted if the content
+ * is not applicable to purchase.
+ */
+ public final static String SUGGEST_COLUMN_PURCHASE_PRICE = "suggest_purchase_price";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content is rentable, you
+ * should provide this column to specify the displayable string representation of the rental
+ * price of your content including the currency and the amount. If it's free, you should
+ * provide localized string to specify that it's free. This column can be ommitted if the
+ * content is not applicable to rent.
+ */
+ public final static String SUGGEST_COLUMN_RENTAL_PRICE = "suggest_rental_price";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content has a rating, you
+ * should provide this column to specify the rating style of your content. The data in the
+ * column must be one of the constant values specified in {@link android.media.Rating}
+ */
+ public final static String SUGGEST_COLUMN_RATING_STYLE = "suggest_rating_style";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content has a rating, you
+ * should provide this column to specify the rating score of your content. The data in the
+ * column is of float type. See {@link android.media.Rating} about valid rating scores for each
+ * rating style.
+ */
+ public final static String SUGGEST_COLUMN_RATING_SCORE = "suggest_rating_score";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content is video or audio and
+ * has a known production year, you should provide this column to specify the production year
+ * of your content. The data in the column is of integer type.
+ */
+ public final static String SUGGEST_COLUMN_PRODUCTION_YEAR = "suggest_production_year";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your content is video or audio, you
+ * should provide this column to specify the duration of your content in milliseconds. The data
+ * in the column is of long type.
+ */
+ public final static String SUGGEST_COLUMN_DURATION = "suggest_duration";
+
+ /**
* Column name for suggestions cursor. <i>Optional.</i> This column is used to specify
* additional flags per item. Multiple flags can be specified.
* <p>
diff --git a/core/java/android/app/TaskManagerImpl.java b/core/java/android/app/TaskManagerImpl.java
index f42839e..fe29fb7 100644
--- a/core/java/android/app/TaskManagerImpl.java
+++ b/core/java/android/app/TaskManagerImpl.java
@@ -20,6 +20,7 @@ package android.app;
import android.app.task.ITaskManager;
import android.app.task.Task;
import android.app.task.TaskManager;
+import android.os.RemoteException;
import java.util.List;
@@ -37,26 +38,35 @@ public class TaskManagerImpl extends TaskManager {
@Override
public int schedule(Task task) {
- // TODO Auto-generated method stub
- return 0;
+ try {
+ return mBinder.schedule(task);
+ } catch (RemoteException e) {
+ return TaskManager.RESULT_FAILURE;
+ }
}
@Override
public void cancel(int taskId) {
- // TODO Auto-generated method stub
+ try {
+ mBinder.cancel(taskId);
+ } catch (RemoteException e) {}
}
@Override
public void cancelAll() {
- // TODO Auto-generated method stub
+ try {
+ mBinder.cancelAll();
+ } catch (RemoteException e) {}
}
@Override
public List<Task> getAllPendingTasks() {
- // TODO Auto-generated method stub
- return null;
+ try {
+ return mBinder.getAllPendingTasks();
+ } catch (RemoteException e) {
+ return null;
+ }
}
-
}
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 2cc15e2..1015514 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -16,6 +16,7 @@
package android.app.admin;
+import android.accounts.AccountManager;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Service;
@@ -165,15 +166,14 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
= "android.app.action.ACTION_PASSWORD_EXPIRING";
/**
- * Broadcast Action: This broadcast is sent to the newly created profile when
- * the provisioning of a managed profile has completed successfully. It is used in both the
- * Profile Owner and the Device Owner provisioning.
+ * Broadcast Action: This broadcast is sent to indicate that provisioning of a managed profile
+ * or managed device has completed successfully.
*
- * <p>The broadcast is limited to the DeviceAdminReceiver component specified in the message
- * that started the provisioning. It is also limited to the managed profile.
- *
- * <p> The intent may contain the extra
- * {@link DevicePolicyManager#EXTRA_PROVISIONING_EMAIL_ADDRESS}.
+ * <p>The broadcast is limited to the profile that will be managed by the application that
+ * requested provisioning. In the device owner case the profile is the primary user.
+ * The broadcast will also be limited to the {@link DeviceAdminReceiver} component
+ * specified in the original intent or NFC bump that started the provisioning process
+ * (@see DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE).
*
* <p>Input: Nothing.</p>
* <p>Output: Nothing</p>
@@ -310,18 +310,23 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
}
/**
- * Called on the new profile when managed profile provisioning has completed.
- * Managed profile provisioning is the process of setting up the device so that it has a
- * separate profile which is managed by the mobile device management(mdm) application that
- * triggered the provisioning.
+ * Called when provisioning of a managed profile or managed device has completed successfully.
+ *
+ * <p> As a prerequisit for the execution of this callback the (@link DeviceAdminReceiver} has
+ * to declare an intent filter for {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}.
+ * Its component must also be specified in the {@link DevicePolicyManager#EXTRA_DEVICE_ADMIN}
+ * of the {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} intent that started the
+ * managed provisioning.
*
- * <p>As part of provisioning a new profile is created, the mdm is moved to the new profile and
- * set as the owner of the profile so that it has full control over it.
- * This intent is only received by the mdm package that is set as profile owner during
- * provisioning.
+ * <p>When provisioning is complete, the managed profile is hidden until the profile owner
+ * calls {DevicePolicyManager#setProfileEnabled(ComponentName admin)}. Typically a profile
+ * owner will enable the profile when it has finished any additional setup such as adding an
+ * account by using the {@link AccountManager} and calling apis to bring the profile into the
+ * desired state.
*
- * <p>Provisioning can be triggered via an intent with the action
- * android.managedprovisioning.ACTION_PROVISION_MANAGED_PROFILE.
+ * <p> Note that provisioning completes without waiting for any server interactions, so the
+ * profile owner needs to wait for data to be available if required (e.g android device ids or
+ * other data that is set as a result of server interactions).
*
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 785987f..4aa4294 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -26,6 +26,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.RestrictionsManager;
+import android.media.AudioService;
import android.net.ProxyInfo;
import android.os.Bundle;
import android.os.Handler;
@@ -99,17 +100,25 @@ public class DevicePolicyManager {
/**
* Activity action: Starts the provisioning flow which sets up a managed profile.
- * This intent will typically be sent by a mobile device management application(mdm).
- * Managed profile provisioning creates a profile, moves the mdm to the profile,
- * sets the mdm as the profile owner and removes all non required applications from the profile.
- * As a profile owner the mdm than has full control over the managed profile.
*
- * <p>The intent must contain the extras {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} and
- * {@link #EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME}.
+ * <p>A managed profile allows data separation for example for the usage of a
+ * device as a personal and corporate device. The user which provisioning is started from and
+ * the managed profile share a launcher.
+ *
+ * <p>This intent will typically be sent by a mobile device management application (mdm).
+ * Provisioning adds a managed profile and sets the mdm as the profile owner who has full
+ * control over the profile
+ *
+ * <p>This intent must contain the extras {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}
+ * {@link #EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME} and {@link #EXTRA_DEVICE_ADMIN}.
*
* <p> When managed provisioning has completed, an intent of the type
* {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the
- * mdm app on the managed profile.
+ * managed profile. The intent is sent to the {@link DeviceAdminReceiver} specified in the
+ * {@link #EXTRA_DEVICE_ADMIN} exclusively.
+ *
+ * If provisioning fails, the managedProfile is removed so the device returns to its previous
+ * state.
*
* <p>Input: Nothing.</p>
* <p>Output: Nothing</p>
@@ -135,7 +144,7 @@ public class DevicePolicyManager {
* <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
- = "deviceAdminPackageName";
+ = "android.app.extra.deviceAdminPackageName";
/**
* An int extra used to identify that during the current setup process the user has already
@@ -155,7 +164,7 @@ public class DevicePolicyManager {
* <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}
*/
public static final String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME
- = "defaultManagedProfileName";
+ = "android.app.extra.defaultManagedProfileName";
/**
* A String extra holding the email address of the profile that is created during managed
@@ -889,6 +898,9 @@ public class DevicePolicyManager {
* {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to be able to call this
* method; if it has not, a security exception will be thrown.
*
+ * <p> Note that setting the password will automatically reset the expiration time for all
+ * active admins. Active admins do not need to explicitly call this method in that case.
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param timeout The limit (in ms) that a password can remain in effect. A value of 0
* means there is no restriction (unlimited).
@@ -1821,6 +1833,23 @@ public class DevicePolicyManager {
return isDeviceOwnerApp(packageName);
}
+ /**
+ * Clears the current device owner. The caller must be the device owner.
+ *
+ * This function should be used cautiously as once it is called it cannot
+ * be undone. The device owner can only be set as a part of device setup
+ * before setup completes.
+ */
+ public void clearDeviceOwnerApp() {
+ if (mService != null) {
+ try {
+ mService.clearDeviceOwner(mContext.getPackageName());
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed to clear device owner");
+ }
+ }
+ }
+
/** @hide */
public String getDeviceOwner() {
if (mService != null) {
@@ -2033,6 +2062,8 @@ public class DevicePolicyManager {
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param filter The {@link IntentFilter} the intent has to match to be also resolved in the
* other profile
+ * @param flags {@link DevicePolicyManager#FLAG_MANAGED_CAN_ACCESS_PARENT} and
+ * {@link DevicePolicyManager#FLAG_PARENT_CAN_ACCESS_MANAGED} are supported.
*/
public void addCrossProfileIntentFilter(ComponentName admin, IntentFilter filter, int flags) {
if (mService != null) {
@@ -2376,4 +2407,37 @@ public class DevicePolicyManager {
}
}
}
+
+ /**
+ * Called by profile or device owners to set the master volume mute on or off.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param on {@code true} to mute master volume, {@code false} to turn mute off.
+ */
+ public void setMasterVolumeMuted(ComponentName admin, boolean on) {
+ if (mService != null) {
+ try {
+ mService.setMasterVolumeMuted(admin, on);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed to setMasterMute on device policy service");
+ }
+ }
+ }
+
+ /**
+ * Called by profile or device owners to check whether the master volume mute is on or off.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @return {@code true} if master volume is muted, {@code false} if it's not.
+ */
+ public boolean isMasterVolumeMuted(ComponentName admin) {
+ if (mService != null) {
+ try {
+ return mService.isMasterVolumeMuted(admin);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed to get isMasterMute on device policy service");
+ }
+ }
+ return false;
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 3d80869..f8df780 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -108,6 +108,7 @@ interface IDevicePolicyManager {
boolean isDeviceOwner(String packageName);
String getDeviceOwner();
String getDeviceOwnerName();
+ void clearDeviceOwner(String packageName);
boolean setProfileOwner(String packageName, String ownerName, int userHandle);
String getProfileOwner(int userHandle);
@@ -146,4 +147,7 @@ interface IDevicePolicyManager {
void setGlobalSetting(in ComponentName who, in String setting, in String value);
void setSecureSetting(in ComponentName who, in String setting, in String value);
+
+ void setMasterVolumeMuted(in ComponentName admin, boolean on);
+ boolean isMasterVolumeMuted(in ComponentName admin);
}
diff --git a/core/java/android/app/task/Task.java b/core/java/android/app/task/Task.java
index 87d57fb..0e660b3 100644
--- a/core/java/android/app/task/Task.java
+++ b/core/java/android/app/task/Task.java
@@ -48,6 +48,11 @@ public class Task implements Parcelable {
* @hide
*/
public static final int DEFAULT_BACKOFF_POLICY = BackoffPolicy.EXPONENTIAL;
+ /**
+ * Maximum backoff we allow for a job, in milliseconds.
+ * @hide
+ */
+ public static final long MAX_BACKOFF_DELAY_MILLIS = 24 * 60 * 60 * 1000; // 24 hours.
/**
* Linear: retry_time(failure_time, t) = failure_time + initial_retry_delay * t, t >= 1
@@ -185,7 +190,7 @@ public class Task implements Parcelable {
private Task(Parcel in) {
taskId = in.readInt();
extras = in.readPersistableBundle();
- service = ComponentName.readFromParcel(in);
+ service = in.readParcelable(null);
requireCharging = in.readInt() == 1;
requireDeviceIdle = in.readInt() == 1;
networkCapabilities = in.readInt();
@@ -201,7 +206,7 @@ public class Task implements Parcelable {
private Task(Task.Builder b) {
taskId = b.mTaskId;
- extras = new PersistableBundle(b.mExtras);
+ extras = b.mExtras;
service = b.mTaskService;
requireCharging = b.mRequiresCharging;
requireDeviceIdle = b.mRequiresDeviceIdle;
@@ -225,7 +230,7 @@ public class Task implements Parcelable {
public void writeToParcel(Parcel out, int flags) {
out.writeInt(taskId);
out.writePersistableBundle(extras);
- ComponentName.writeToParcel(service, out);
+ out.writeParcelable(service, flags);
out.writeInt(requireCharging ? 1 : 0);
out.writeInt(requireDeviceIdle ? 1 : 0);
out.writeInt(networkCapabilities);
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 7f8d0ab..64d80a0 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -874,6 +874,26 @@ public final class BluetoothDevice implements Parcelable {
}
/**
+ * Returns whether there is an open connection to this device.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
+ *
+ * @return True if there is at least one open connection to this device.
+ * @hide
+ */
+ public boolean isConnected() {
+ if (sService == null) {
+ // BT is not enabled, we cannot be connected.
+ return false;
+ }
+ try {
+ return sService.isConnected(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ return false;
+ }
+ }
+
+ /**
* Get the Bluetooth class of the remote device.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
*
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 07db8cc..a45c6b8 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -58,6 +58,7 @@ interface IBluetooth
boolean cancelBondProcess(in BluetoothDevice device);
boolean removeBond(in BluetoothDevice device);
int getBondState(in BluetoothDevice device);
+ boolean isConnected(in BluetoothDevice device);
String getRemoteName(in BluetoothDevice device);
int getRemoteType(in BluetoothDevice device);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a040efb..2897887 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
+import android.annotation.SystemApi;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
@@ -2148,8 +2149,6 @@ public abstract class Context {
* @see android.app.SearchManager
* @see #SENSOR_SERVICE
* @see android.hardware.SensorManager
- * @see #HDMI_CEC_SERVICE
- * @see android.hardware.hdmi.HdmiCecManager
* @see #STORAGE_SERVICE
* @see android.os.storage.StorageManager
* @see #VIBRATOR_SERVICE
@@ -2637,23 +2636,14 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
- * {@link android.hardware.hdmi.HdmiCecManager} for controlling and managing
- * HDMI-CEC protocol.
- *
- * @see #getSystemService
- * @see android.hardware.hdmi.HdmiCecManager
- */
- // TODO: Remove this once HdmiControlService is ready.
- public static final String HDMI_CEC_SERVICE = "hdmi_cec";
-
- /**
- * Use with {@link #getSystemService} to retrieve a
* {@link android.hardware.hdmi.HdmiControlManager} for controlling and managing
* HDMI-CEC protocol.
*
* @see #getSystemService
* @see android.hardware.hdmi.HdmiControlManager
+ * @hide
*/
+ @SystemApi
public static final String HDMI_CONTROL_SERVICE = "hdmi_control";
/**
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index bd07470..6e53a6f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2656,7 +2656,9 @@ public class Intent implements Parcelable, Cloneable {
/**
* Broadcast sent to the primary user when an associated managed profile is added (the profile
* was created and is ready to be used). Carries an extra {@link #EXTRA_USER} that specifies
- * the UserHandle of the profile that was added. This is only sent to registered receivers,
+ * the UserHandle of the profile that was added. Only applications (for example Launchers)
+ * that need to display merged content across both primary and managed profiles need to
+ * worry about this broadcast. This is only sent to registered receivers,
* not manifest receivers.
*/
public static final String ACTION_MANAGED_PROFILE_ADDED =
@@ -2664,8 +2666,10 @@ public class Intent implements Parcelable, Cloneable {
/**
* Broadcast sent to the primary user when an associated managed profile is removed. Carries an
- * extra {@link #EXTRA_USER} that specifies the UserHandle of the profile that was removed. This
- * is only sent to registered receivers, not manifest receivers.
+ * extra {@link #EXTRA_USER} that specifies the UserHandle of the profile that was removed.
+ * Only applications (for example Launchers) that need to display merged content across both
+ * primary and managed profiles need to worry about this broadcast. This is only sent to
+ * registered receivers, not manifest receivers.
*/
public static final String ACTION_MANAGED_PROFILE_REMOVED =
"android.intent.action.MANAGED_PROFILE_REMOVED";
@@ -2731,6 +2735,7 @@ public class Intent implements Parcelable, Cloneable {
* returned in {@link #getClipData()}.
*
* @see DocumentsContract
+ * @see #ACTION_OPEN_DOCUMENT_TREE
* @see #ACTION_CREATE_DOCUMENT
* @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION
*/
@@ -2765,28 +2770,30 @@ public class Intent implements Parcelable, Cloneable {
*
* @see DocumentsContract
* @see #ACTION_OPEN_DOCUMENT
+ * @see #ACTION_OPEN_DOCUMENT_TREE
* @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT";
/**
- * Activity Action: Allow the user to pick a directory. When invoked, the
- * system will display the various {@link DocumentsProvider} instances
- * installed on the device, letting the user navigate through them. Apps can
- * fully manage documents within the returned directory.
+ * Activity Action: Allow the user to pick a directory subtree. When
+ * invoked, the system will display the various {@link DocumentsProvider}
+ * instances installed on the device, letting the user navigate through
+ * them. Apps can fully manage documents within the returned directory.
* <p>
* To gain access to descendant (child, grandchild, etc) documents, use
- * {@link DocumentsContract#buildDocumentViaUri(Uri, String)} and
- * {@link DocumentsContract#buildChildDocumentsViaUri(Uri, String)} using
- * the returned directory URI.
+ * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)} and
+ * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)}
+ * with the returned URI.
* <p>
- * Output: The URI representing the selected directory.
+ * Output: The URI representing the selected directory tree.
*
* @see DocumentsContract
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_PICK_DIRECTORY = "android.intent.action.PICK_DIRECTORY";
+ public static final String
+ ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
@@ -2976,14 +2983,6 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE";
- /**
- * An activity that provides a user interface for adjusting notification preferences for its
- * containing application. Optional but recommended for apps that post
- * {@link android.app.Notification Notifications}.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
-
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Application launch intent categories (see addCategory()).
@@ -3373,8 +3372,8 @@ public class Intent implements Parcelable, Cloneable {
*
* @see #ACTION_GET_CONTENT
* @see #ACTION_OPEN_DOCUMENT
+ * @see #ACTION_OPEN_DOCUMENT_TREE
* @see #ACTION_CREATE_DOCUMENT
- * @see #ACTION_PICK_DIRECTORY
*/
public static final String EXTRA_LOCAL_ONLY =
"android.intent.extra.LOCAL_ONLY";
@@ -3712,30 +3711,8 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 0x00100000;
/**
- * If set, this marks a point in the task's activity stack that should
- * be cleared when the task is reset. That is, the next time the task
- * is brought to the foreground with
- * {@link #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED} (typically as a result of
- * the user re-launching it from home), this activity and all on top of
- * it will be finished so that the user does not return to them, but
- * instead returns to whatever activity preceeded it.
- *
- * <p>When this flag is assigned to the root activity all activities up
- * to, but not including the root activity, will be cleared. This prevents
- * this flag from being used to finish all activities in a task and thereby
- * ending the task.
- *
- * <p>This is useful for cases where you have a logical break in your
- * application. For example, an e-mail application may have a command
- * to view an attachment, which launches an image view activity to
- * display it. This activity should be part of the e-mail application's
- * task, since it is a part of the task the user is involved in. However,
- * if the user leaves that task, and later selects the e-mail app from
- * home, we may like them to return to the conversation they were
- * viewing, not the picture attachment, since that is confusing. By
- * setting this flag when launching the image viewer, that viewer and
- * any activities it starts will be removed the next time the user returns
- * to mail.
+ * @deprecated As of API 21 this performs identically to
+ * {@link #FLAG_ACTIVITY_NEW_DOCUMENT} which should be used instead of this.
*/
public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
/**
@@ -3762,8 +3739,7 @@ public class Intent implements Parcelable, Cloneable {
* @see android.R.attr#documentLaunchMode
* @see #FLAG_ACTIVITY_MULTIPLE_TASK
*/
- public static final int FLAG_ACTIVITY_NEW_DOCUMENT =
- FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | FLAG_ACTIVITY_NEW_TASK;
+ public static final int FLAG_ACTIVITY_NEW_DOCUMENT = FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
/**
* If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaveHint}
* callback from occurring on the current frontmost activity before it is
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
index 869f85c..7619c6d 100644
--- a/core/java/android/content/SyncRequest.java
+++ b/core/java/android/content/SyncRequest.java
@@ -21,6 +21,11 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+/**
+ * Convenience class to construct sync requests. See {@link android.content.SyncRequest.Builder}
+ * for an explanation of the various functions. The resulting object is passed through to the
+ * framework via {@link android.content.ContentResolver#requestSync(SyncRequest)}.
+ */
public class SyncRequest implements Parcelable {
private static final String TAG = "SyncRequest";
/** Account to pass to the sync adapter. Can be null. */
@@ -57,6 +62,10 @@ public class SyncRequest implements Parcelable {
return mIsPeriodic;
}
+ /**
+ * {@hide}
+ * @return whether this sync is expedited.
+ */
public boolean isExpedited() {
return mIsExpedited;
}
@@ -199,14 +208,8 @@ public class SyncRequest implements Parcelable {
* discriminate between equivalent syncs.
*/
private Bundle mSyncConfigExtras;
- /** Expected upload transfer in bytes. */
- private long mTxBytes = -1L;
- /** Expected download transfer in bytes. */
- private long mRxBytes = -1L;
/** Whether or not this sync can occur on metered networks. Default false. */
private boolean mDisallowMetered;
- /** Priority of this sync relative to others from calling app [-2, 2]. Default 0. */
- private int mPriority = 0;
/**
* Whether this builder is building a periodic sync, or a one-time sync.
*/
@@ -314,7 +317,6 @@ public class SyncRequest implements Parcelable {
return this;
}
- /** {@hide} */
private void setupInterval(long at, long before) {
if (before > at) {
throw new IllegalArgumentException("Specified run time for the sync must be" +
@@ -477,18 +479,6 @@ public class SyncRequest implements Parcelable {
}
/**
- * @param priority the priority of this request among all requests from the calling app.
- * Range of [-2,2] similar to how this is done with notifications.
- */
- public Builder setPriority(int priority) {
- if (priority < -2 || priority > 2) {
- throw new IllegalArgumentException("Priority must be within range [-2, 2]");
- }
- mPriority = priority;
- return this;
- }
-
- /**
* Performs validation over the request and throws the runtime exception
* <code>IllegalArgumentException</code> if this validation fails.
*
@@ -522,9 +512,6 @@ public class SyncRequest implements Parcelable {
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
}
- mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD, mTxBytes);
- mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD, mRxBytes);
- mSyncConfigExtras.putInt(ContentResolver.SYNC_EXTRAS_PRIORITY, mPriority);
if (mSyncType == SYNC_TYPE_PERIODIC) {
// If this is a periodic sync ensure than invalid extras were not set.
if (ContentResolver.invalidPeriodicExtras(mCustomExtras) ||
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index c2fe3a2..791e5aa 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -84,6 +84,11 @@ public class ActivityInfo extends ComponentInfo
*/
public static final int DOCUMENT_LAUNCH_ALWAYS = 2;
/**
+ * Constant corresponding to <code>never</code> in
+ * the {@link android.R.attr#documentLaunchMode} attribute.
+ */
+ public static final int DOCUMENT_LAUNCH_NEVER = 3;
+ /**
* The document launch mode style requested by the activity. From the
* {@link android.R.attr#documentLaunchMode} attribute, one of
* {@link #DOCUMENT_LAUNCH_NONE}, {@link #DOCUMENT_LAUNCH_INTO_EXISTING},
@@ -99,6 +104,12 @@ public class ActivityInfo extends ComponentInfo
public int documentLaunchMode;
/**
+ * The maximum number of tasks rooted at this activity that can be in the recent task list.
+ * Refer to {@link android.R.attr#maxRecents}.
+ */
+ public int maxRecents;
+
+ /**
* Optional name of a permission required to be able to access this
* Activity. From the "permission" attribute.
*/
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ab8bf61..4cac7fd 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2511,6 +2511,9 @@ public class PackageParser {
a.info.documentLaunchMode = sa.getInt(
com.android.internal.R.styleable.AndroidManifestActivity_documentLaunchMode,
ActivityInfo.DOCUMENT_LAUNCH_NONE);
+ a.info.maxRecents = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestActivity_maxRecents,
+ 15);
a.info.screenOrientation = sa.getInt(
com.android.internal.R.styleable.AndroidManifestActivity_screenOrientation,
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index c3e042e..f829f5e 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -118,9 +118,11 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
if (configureSuccess) {
mStateListener.onConfigured(this);
+ if (VERBOSE) Log.v(TAG, "ctor - Created session successfully");
} else {
mStateListener.onConfigureFailed(this);
mClosed = true; // do not fire any other callbacks, do not allow any other work
+ Log.e(TAG, "Failed to create capture session; configuration failed");
}
}
@@ -132,6 +134,10 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
@Override
public synchronized int capture(CaptureRequest request, CaptureListener listener,
Handler handler) throws CameraAccessException {
+ if (request == null) {
+ throw new IllegalArgumentException("request must not be null");
+ }
+
checkNotClosed();
checkLegalToCapture();
@@ -139,7 +145,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
if (VERBOSE) {
Log.v(TAG, "capture - request " + request + ", listener " + listener + " handler" +
- "" + handler);
+ " " + handler);
}
return addPendingSequence(mDeviceImpl.capture(request,
@@ -149,6 +155,12 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
@Override
public synchronized int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
Handler handler) throws CameraAccessException {
+ if (requests == null) {
+ throw new IllegalArgumentException("requests must not be null");
+ } else if (requests.isEmpty()) {
+ throw new IllegalArgumentException("requests must have at least one element");
+ }
+
checkNotClosed();
checkLegalToCapture();
@@ -167,11 +179,20 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
@Override
public synchronized int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
Handler handler) throws CameraAccessException {
+ if (request == null) {
+ throw new IllegalArgumentException("request must not be null");
+ }
+
checkNotClosed();
checkLegalToCapture();
handler = checkHandler(handler);
+ if (VERBOSE) {
+ Log.v(TAG, "setRepeatingRequest - request " + request + ", listener " + listener +
+ " handler" + " " + handler);
+ }
+
return addPendingSequence(mDeviceImpl.setRepeatingRequest(request,
createCaptureListenerProxy(handler, listener), mDeviceHandler));
}
@@ -179,6 +200,12 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
@Override
public synchronized int setRepeatingBurst(List<CaptureRequest> requests,
CaptureListener listener, Handler handler) throws CameraAccessException {
+ if (requests == null) {
+ throw new IllegalArgumentException("requests must not be null");
+ } else if (requests.isEmpty()) {
+ throw new IllegalArgumentException("requests must have at least one element");
+ }
+
checkNotClosed();
checkLegalToCapture();
@@ -249,8 +276,11 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
* but this would introduce nondeterministic behavior.
*/
+ if (VERBOSE) Log.v(TAG, "replaceSessionClose");
+
// #close was already called explicitly, keep going the slow route
if (mClosed) {
+ if (VERBOSE) Log.v(TAG, "replaceSessionClose - close was already called");
return;
}
@@ -260,21 +290,39 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
@Override
public synchronized void close() {
+
if (mClosed) {
+ if (VERBOSE) Log.v(TAG, "close - reentering");
return;
}
+ if (VERBOSE) Log.v(TAG, "close - first time");
+
mClosed = true;
/*
* Flush out any repeating request. Since camera is closed, no new requests
* can be queued, and eventually the entire request queue will be drained.
*
- * Once this is done, wait for camera to idle, then unconfigure the camera.
- * Once that's done, fire #onClosed.
+ * If the camera device was already closed, short circuit and do nothing; since
+ * no more internal device callbacks will fire anyway.
+ *
+ * Otherwise, once stopRepeating is done, wait for camera to idle, then unconfigure the
+ * camera. Once that's done, fire #onClosed.
*/
try {
mDeviceImpl.stopRepeating();
+ } catch (IllegalStateException e) {
+ // OK: Camera device may already be closed, nothing else to do
+ Log.w(TAG, "The camera device was already closed: ", e);
+
+ // TODO: Fire onClosed anytime we get the device onClosed or the ISE?
+ // or just suppress the ISE only and rely onClosed.
+ // Also skip any of the draining work if this is already closed.
+
+ // Short-circuit; queue listener immediately and return
+ mStateListener.onClosed(this);
+ return;
} catch (CameraAccessException e) {
// OK: close does not throw checked exceptions.
Log.e(TAG, "Exception while stopping repeating: ", e);
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index d4adae1..d9f3af4 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -257,6 +257,7 @@ public class CameraDeviceImpl extends android.hardware.camera2.CameraDevice {
synchronized (mLock) {
mInError = true;
mDeviceHandler.post(new Runnable() {
+ @Override
public void run() {
if (isError) {
mDeviceListener.onError(CameraDeviceImpl.this, code);
@@ -360,6 +361,9 @@ public class CameraDeviceImpl extends android.hardware.camera2.CameraDevice {
} catch (CameraAccessException e) {
configureSuccess = false;
pendingException = e;
+ if (DEBUG) {
+ Log.v(TAG, "createCaptureSession - failed with exception ", e);
+ }
}
// Fire onConfigured if configureOutputs succeeded, fire onConfigureFailed otherwise.
diff --git a/core/java/android/hardware/camera2/utils/TaskDrainer.java b/core/java/android/hardware/camera2/utils/TaskDrainer.java
index 3cba9a1..dc09f62 100644
--- a/core/java/android/hardware/camera2/utils/TaskDrainer.java
+++ b/core/java/android/hardware/camera2/utils/TaskDrainer.java
@@ -52,7 +52,7 @@ public class TaskDrainer<T> {
}
private static final String TAG = "TaskDrainer";
- private static final boolean VERBOSE = false;
+ private final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
private final Handler mHandler;
private final DrainListener mListener;
diff --git a/core/java/android/hardware/hdmi/HdmiCec.java b/core/java/android/hardware/hdmi/HdmiCec.java
index 723eda1..8ad9463 100644
--- a/core/java/android/hardware/hdmi/HdmiCec.java
+++ b/core/java/android/hardware/hdmi/HdmiCec.java
@@ -16,9 +16,14 @@
package android.hardware.hdmi;
+import android.annotation.SystemApi;
+
/**
* Defines constants and utility methods related to HDMI-CEC protocol.
+ *
+ * @hide
*/
+@SystemApi
public final class HdmiCec {
/** TV device type. */
diff --git a/core/java/android/hardware/hdmi/HdmiCecClient.java b/core/java/android/hardware/hdmi/HdmiCecClient.java
deleted file mode 100644
index dcb3624..0000000
--- a/core/java/android/hardware/hdmi/HdmiCecClient.java
+++ /dev/null
@@ -1,119 +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.
- */
-
-package android.hardware.hdmi;
-
-import android.os.IBinder;
-import android.os.RemoteException;
-
-import android.util.Log;
-
-/**
- * HdmiCecClient is used to control HDMI-CEC logical device instance in the system.
- * It is connected to actual hardware part via HdmiCecService. It provides with methods
- * to send CEC messages to other device on the bus, and listener that allows to receive
- * incoming messages to the device.
- */
-public final class HdmiCecClient {
- private static final String TAG = "HdmiCecClient";
-
- private final IHdmiCecService mService;
- private final IBinder mBinder;
-
- /**
- * Listener used by the client to get the incoming messages.
- */
- public static abstract class Listener {
- /**
- * Called when CEC message arrives. Override this method to receive the incoming
- * CEC messages from other device on the bus.
- *
- * @param message {@link HdmiCecMessage} object
- */
- public void onMessageReceived(HdmiCecMessage message) { }
-
- /**
- * Called when hotplug event occurs. Override this method to receive the events.
- *
- * @param connected true if the cable is connected; otherwise false.
- */
- public void onCableStatusChanged(boolean connected) { }
- }
-
- // Private constructor.
- private HdmiCecClient(IHdmiCecService service, IBinder b) {
- mService = service;
- mBinder = b;
- }
-
- // Factory method for HdmiCecClient.
- // Declared package-private. Accessed by HdmiCecManager only.
- static HdmiCecClient create(IHdmiCecService service, IBinder b) {
- return new HdmiCecClient(service, b);
- }
-
- /**
- * Send &lt;Active Source&gt; message.
- */
- public void sendActiveSource() {
- Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
- }
-
- /**
- * Send &lt;Inactive Source&gt; message.
- */
- public void sendInactiveSource() {
- Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
- }
-
- /**
- * Send &lt;Text View On&gt; message.
- */
- public void sendTextViewOn() {
- Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
- }
-
- /**
- * Send &lt;Image View On&gt; message.
- */
- public void sendImageViewOn() {
- Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
- }
-
- /**
- * Send &lt;Give Device Power Status&gt; message.
- *
- * @param address logical address of the device to send the message to, such as
- * {@link HdmiCec#ADDR_TV}.
- */
- public void sendGiveDevicePowerStatus(int address) {
- Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
- }
-
- /**
- * Returns true if the TV or attached display is powered on.
- * <p>
- * The result of this method is only meaningful on playback devices (where the device
- * type is {@link HdmiCec#DEVICE_PLAYBACK}).
- * </p>
- *
- * @return true if TV is on; otherwise false.
- */
- public boolean isTvOn() {
- Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
- return true;
- }
-}
diff --git a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java
index 9698445..fbfcca0 100644
--- a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java
+++ b/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java
@@ -16,6 +16,7 @@
package android.hardware.hdmi;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -23,7 +24,10 @@ import android.os.Parcelable;
* A class to encapsulate device information for HDMI-CEC. This container
* include basic information such as logical address, physical address and
* device type, and additional information like vendor id and osd name.
+ *
+ * @hide
*/
+@SystemApi
public final class HdmiCecDeviceInfo implements Parcelable {
// Logical address, phsical address, device type, vendor id and display name
// are immutable value.
diff --git a/core/java/android/hardware/hdmi/HdmiCecManager.java b/core/java/android/hardware/hdmi/HdmiCecManager.java
deleted file mode 100644
index 03c46d8..0000000
--- a/core/java/android/hardware/hdmi/HdmiCecManager.java
+++ /dev/null
@@ -1,68 +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.
- */
-
-package android.hardware.hdmi;
-
-import android.os.IBinder;
-import android.os.RemoteException;
-
-/**
- * The HdmiCecManager class is used to provide an HdmiCecClient instance,
- * get various information on HDMI ports configuration. It is connected to actual hardware
- * via HdmiCecService.
- */
-public final class HdmiCecManager {
- private final IHdmiCecService mService;
-
- /**
- * @hide - hide this constructor because it has a parameter of type IHdmiCecService,
- * which is a system private class. The right way to create an instance of this class
- * is using the factory Context.getSystemService.
- */
- public HdmiCecManager(IHdmiCecService service) {
- mService = service;
- }
-
- /**
- * Provide the HdmiCecClient instance of the given type. It also registers the listener
- * for client to get the events coming to the device.
- *
- * @param type type of the HDMI-CEC logical device
- * @param listener listener to be called
- * @return {@link HdmiCecClient} instance. {@code null} on failure.
- */
- public HdmiCecClient getClient(int type, HdmiCecClient.Listener listener) {
- return HdmiCecClient.create(mService, null);
- }
-
- private IHdmiCecListener getListenerWrapper(final HdmiCecClient.Listener listener) {
- // TODO: The message/events are not yet forwarded to client since it is not clearly
- // defined as to how/who to handle them. Revisit it once the decision is
- // made on what messages will have to reach the clients, what will be
- // handled by service/manager.
- return new IHdmiCecListener.Stub() {
- @Override
- public void onMessageReceived(HdmiCecMessage message) {
- // Do nothing.
- }
-
- @Override
- public void onCableStatusChanged(boolean connected) {
- // Do nothing.
- }
- };
- }
-}
diff --git a/core/java/android/hardware/hdmi/HdmiCecMessage.java b/core/java/android/hardware/hdmi/HdmiCecMessage.java
index 62fa279..ac16ad8 100644
--- a/core/java/android/hardware/hdmi/HdmiCecMessage.java
+++ b/core/java/android/hardware/hdmi/HdmiCecMessage.java
@@ -16,6 +16,7 @@
package android.hardware.hdmi;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,7 +28,10 @@ import java.util.Arrays;
* A class to encapsulate HDMI-CEC message used for the devices connected via
* HDMI cable to communicate with one another. A message is defined by its
* source and destination address, command (or opcode), and optional parameters.
+ *
+ * @hide
*/
+@SystemApi
public final class HdmiCecMessage implements Parcelable {
public static final byte[] EMPTY_PARAM = EmptyArray.BYTE;
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 5b6e862..f15fa00 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -17,6 +17,7 @@
package android.hardware.hdmi;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.RemoteException;
/**
@@ -28,7 +29,10 @@ import android.os.RemoteException;
* {@link HdmiTvClient} object if the system is configured to host one. Android system
* can host more than one logical CEC devices. If multiple types are configured they
* all work as if they were independent logical devices running in the system.
+ *
+ * @hide
*/
+@SystemApi
public final class HdmiControlManager {
@Nullable private final IHdmiControlService mService;
diff --git a/core/java/android/hardware/hdmi/HdmiHotplugEvent.java b/core/java/android/hardware/hdmi/HdmiHotplugEvent.java
index 1462f83..7be4bc5 100644
--- a/core/java/android/hardware/hdmi/HdmiHotplugEvent.java
+++ b/core/java/android/hardware/hdmi/HdmiHotplugEvent.java
@@ -16,12 +16,16 @@
package android.hardware.hdmi;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
/**
* A class that describes the HDMI port hotplug event.
+ *
+ * @hide
*/
+@SystemApi
public final class HdmiHotplugEvent implements Parcelable {
private final int mPort;
diff --git a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
index f0bd237..2e49a38 100644
--- a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
+++ b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
@@ -16,6 +16,7 @@
package android.hardware.hdmi;
+import android.annotation.SystemApi;
import android.os.RemoteException;
import android.util.Log;
@@ -25,7 +26,10 @@ import android.util.Log;
* in the Android system which acts as a playback device such as set-top box.
* It provides with methods that control, get information from TV/Display device
* connected through HDMI bus.
+ *
+ * @hide
*/
+@SystemApi
public final class HdmiPlaybackClient {
private static final String TAG = "HdmiPlaybackClient";
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java
index 73c7247..6dc4a4f 100644
--- a/core/java/android/hardware/hdmi/HdmiTvClient.java
+++ b/core/java/android/hardware/hdmi/HdmiTvClient.java
@@ -15,11 +15,16 @@
*/
package android.hardware.hdmi;
+import android.annotation.SystemApi;
+
/**
* HdmiTvClient represents HDMI-CEC logical device of type TV in the Android system
* which acts as TV/Display. It provides with methods that manage, interact with other
* devices on the CEC bus.
+ *
+ * @hide
*/
+@SystemApi
public final class HdmiTvClient {
private static final String TAG = "HdmiTvClient";
diff --git a/core/java/android/hardware/hdmi/IHdmiCecListener.aidl b/core/java/android/hardware/hdmi/IHdmiCecListener.aidl
deleted file mode 100644
index d281ce6..0000000
--- a/core/java/android/hardware/hdmi/IHdmiCecListener.aidl
+++ /dev/null
@@ -1,29 +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.
- */
-
-package android.hardware.hdmi;
-
-import android.hardware.hdmi.HdmiCecMessage;
-
-/**
- * Interface definition for HdmiCecService to do interprocess communcation.
- *
- * @hide
- */
-oneway interface IHdmiCecListener {
- void onMessageReceived(in HdmiCecMessage message);
- void onCableStatusChanged(in boolean connected);
-}
diff --git a/core/java/android/hardware/hdmi/IHdmiCecService.aidl b/core/java/android/hardware/hdmi/IHdmiCecService.aidl
deleted file mode 100644
index ecdd345..0000000
--- a/core/java/android/hardware/hdmi/IHdmiCecService.aidl
+++ /dev/null
@@ -1,40 +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.
- */
-
-package android.hardware.hdmi;
-
-import android.hardware.hdmi.HdmiCecMessage;
-import android.hardware.hdmi.IHdmiCecListener;
-import android.os.IBinder;
-
-/**
- * Binder interface that components running in the appplication process
- * will use to enable HDMI-CEC protocol exchange with other devices.
- *
- * @hide
- */
-interface IHdmiCecService {
- IBinder allocateLogicalDevice(int type, IHdmiCecListener listener);
- void removeServiceListener(IBinder b, IHdmiCecListener listener);
- void sendActiveSource(IBinder b);
- void sendInactiveSource(IBinder b);
- void sendImageViewOn(IBinder b);
- void sendTextViewOn(IBinder b);
- void sendGiveDevicePowerStatus(IBinder b, int address);
- boolean isTvOn(IBinder b);
- void sendMessage(IBinder b, in HdmiCecMessage message);
-}
-
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index b96f166..27402668 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -22,6 +22,7 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.net.NetworkUtils;
import android.os.Binder;
import android.os.Build.VERSION_CODES;
import android.os.Handler;
@@ -892,6 +893,7 @@ public class ConnectivityManager {
case NetworkCapabilities.NET_CAPABILITY_IMS:
case NetworkCapabilities.NET_CAPABILITY_RCS:
case NetworkCapabilities.NET_CAPABILITY_XCAP:
+ case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
continue;
default:
// At least one capability usually provided by unrestricted
@@ -981,13 +983,13 @@ public class ConnectivityManager {
public void onAvailable(NetworkRequest request, Network network) {
currentNetwork = network;
Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
- network.bindProcessForHostResolution();
+ setProcessDefaultNetworkForHostResolution(network);
}
@Override
public void onLost(NetworkRequest request, Network network) {
if (network.equals(currentNetwork)) {
currentNetwork = null;
- network.unbindProcessForHostResolution();
+ setProcessDefaultNetworkForHostResolution(null);
}
Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
}
@@ -1071,7 +1073,7 @@ public class ConnectivityManager {
* @return {@code true} on success, {@code false} on failure
*
* @deprecated Deprecated in favor of the {@link #requestNetwork},
- * {@link Network#bindProcess} and {@link Network#socketFactory} api.
+ * {@link #setProcessDefaultNetwork} and {@link Network#getSocketFactory} api.
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
@@ -1095,7 +1097,7 @@ public class ConnectivityManager {
* @return {@code true} on success, {@code false} on failure
* @hide
* @deprecated Deprecated in favor of the {@link #requestNetwork} and
- * {@link Network#bindProcess} api.
+ * {@link #setProcessDefaultNetwork} api.
*/
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
byte[] address = hostAddress.getAddress();
@@ -2347,4 +2349,64 @@ public class ConnectivityManager {
mService.releaseNetworkRequest(networkRequest);
} catch (RemoteException e) {}
}
+
+ /**
+ * Binds the current process to {@code network}. All Sockets created in the future
+ * (and not explicitly bound via a bound SocketFactory from
+ * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
+ * {@code network}. All host name resolutions will be limited to {@code network} as well.
+ * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
+ * work and all host name resolutions will fail. This is by design so an application doesn't
+ * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
+ * To clear binding pass {@code null} for {@code network}. Using individually bound
+ * Sockets created by Network.getSocketFactory().createSocket() and
+ * performing network-specific host name resolutions via
+ * {@link Network#getAllByName Network.getAllByName} is preferred to calling
+ * {@code setProcessDefaultNetwork}.
+ *
+ * @param network The {@link Network} to bind the current process to, or {@code null} to clear
+ * the current binding.
+ * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
+ */
+ public static boolean setProcessDefaultNetwork(Network network) {
+ if (network == null) {
+ NetworkUtils.unbindProcessToNetwork();
+ } else {
+ NetworkUtils.bindProcessToNetwork(network.netId);
+ }
+ // TODO fix return value
+ return true;
+ }
+
+ /**
+ * Returns the {@link Network} currently bound to this process via
+ * {@link #setProcessDefaultNetwork}, or {@code null} if no {@link Network} is explicitly bound.
+ *
+ * @return {@code Network} to which this process is bound, or {@code null}.
+ */
+ public static Network getProcessDefaultNetwork() {
+ int netId = NetworkUtils.getNetworkBoundToProcess();
+ if (netId == 0) return null;
+ return new Network(netId);
+ }
+
+ /**
+ * Binds host resolutions performed by this process to {@code network}.
+ * {@link #setProcessDefaultNetwork} takes precedence over this setting.
+ *
+ * @param network The {@link Network} to bind host resolutions from the current process to, or
+ * {@code null} to clear the current binding.
+ * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
+ * @hide
+ * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
+ */
+ public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
+ if (network == null) {
+ NetworkUtils.unbindProcessToNetworkForHostResolution();
+ } else {
+ NetworkUtils.bindProcessToNetworkForHostResolution(network.netId);
+ }
+ // TODO hook up the return value.
+ return true;
+ }
}
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 22b26b1..49a307e 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -74,8 +74,10 @@ public class DhcpResults implements Parcelable {
if (linkProperties.getRoutes().size() == 0) {
for (RouteInfo r : orig.linkProperties.getRoutes()) linkProperties.addRoute(r);
}
- if (linkProperties.getDnses().size() == 0) {
- for (InetAddress d : orig.linkProperties.getDnses()) linkProperties.addDns(d);
+ if (linkProperties.getDnsServers().size() == 0) {
+ for (InetAddress d : orig.linkProperties.getDnsServers()) {
+ linkProperties.addDnsServer(d);
+ }
}
}
@@ -211,7 +213,7 @@ public class DhcpResults implements Parcelable {
public boolean addDns(String addrString) {
if (TextUtils.isEmpty(addrString) == false) {
try {
- linkProperties.addDns(NetworkUtils.numericToInetAddress(addrString));
+ linkProperties.addDnsServer(NetworkUtils.numericToInetAddress(addrString));
} catch (IllegalArgumentException e) {
Log.e(TAG, "addDns failed with addrString " + addrString);
return true;
diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java
index 66f0fd0..7acf3f5 100644
--- a/core/java/android/net/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -248,7 +248,7 @@ public final class DnsPinger extends Handler {
return mDefaultDns;
}
- Collection<InetAddress> dnses = curLinkProps.getDnses();
+ Collection<InetAddress> dnses = curLinkProps.getDnsServers();
if (dnses == null || dnses.size() == 0) {
loge("getDns::LinkProps has null dns - returning default");
return mDefaultDns;
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 3c36679..cff9025 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -30,6 +30,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
+import java.util.List;
/**
* Describes the properties of a network link.
@@ -58,10 +59,12 @@ public class LinkProperties implements Parcelable {
private Hashtable<String, LinkProperties> mStackedLinks =
new Hashtable<String, LinkProperties>();
- // @hide
+ /**
+ * @hide
+ */
public static class CompareResult<T> {
- public Collection<T> removed = new ArrayList<T>();
- public Collection<T> added = new ArrayList<T>();
+ public List<T> removed = new ArrayList<T>();
+ public List<T> added = new ArrayList<T>();
@Override
public String toString() {
@@ -81,7 +84,7 @@ public class LinkProperties implements Parcelable {
if (source != null) {
mIfaceName = source.getInterfaceName();
for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
- for (InetAddress i : source.getDnses()) mDnses.add(i);
+ for (InetAddress i : source.getDnsServers()) mDnses.add(i);
mDomains = source.getDomains();
for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
mHttpProxy = (source.getHttpProxy() == null) ?
@@ -98,6 +101,7 @@ public class LinkProperties implements Parcelable {
* will have their interface changed to match this new value.
*
* @param iface The name of the network interface used for this link.
+ * @hide
*/
public void setInterfaceName(String iface) {
mIfaceName = iface;
@@ -117,9 +121,11 @@ public class LinkProperties implements Parcelable {
return mIfaceName;
}
- // @hide
- public Collection<String> getAllInterfaceNames() {
- Collection interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
+ /**
+ * @hide
+ */
+ public List<String> getAllInterfaceNames() {
+ List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
for (LinkProperties stacked: mStackedLinks.values()) {
interfaceNames.addAll(stacked.getAllInterfaceNames());
@@ -134,23 +140,23 @@ public class LinkProperties implements Parcelable {
* prefix lengths for each address. This is a simplified utility alternative to
* {@link LinkProperties#getLinkAddresses}.
*
- * @return An umodifiable {@link Collection} of {@link InetAddress} for this link.
+ * @return An umodifiable {@link List} of {@link InetAddress} for this link.
* @hide
*/
- public Collection<InetAddress> getAddresses() {
- Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+ public List<InetAddress> getAddresses() {
+ List<InetAddress> addresses = new ArrayList<InetAddress>();
for (LinkAddress linkAddress : mLinkAddresses) {
addresses.add(linkAddress.getAddress());
}
- return Collections.unmodifiableCollection(addresses);
+ return Collections.unmodifiableList(addresses);
}
/**
* Returns all the addresses on this link and all the links stacked above it.
* @hide
*/
- public Collection<InetAddress> getAllAddresses() {
- Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+ public List<InetAddress> getAllAddresses() {
+ List<InetAddress> addresses = new ArrayList<InetAddress>();
for (LinkAddress linkAddress : mLinkAddresses) {
addresses.add(linkAddress.getAddress());
}
@@ -174,6 +180,7 @@ public class LinkProperties implements Parcelable {
* same address/prefix does not already exist. If it does exist it is replaced.
* @param address The {@code LinkAddress} to add.
* @return true if {@code address} was added or updated, false otherwise.
+ * @hide
*/
public boolean addLinkAddress(LinkAddress address) {
if (address == null) {
@@ -200,6 +207,7 @@ public class LinkProperties implements Parcelable {
*
* @param toRemove A {@link LinkAddress} specifying the address to remove.
* @return true if the address was removed, false if it did not exist.
+ * @hide
*/
public boolean removeLinkAddress(LinkAddress toRemove) {
int i = findLinkAddressIndex(toRemove);
@@ -214,18 +222,18 @@ public class LinkProperties implements Parcelable {
* Returns all the {@link LinkAddress} on this link. Typically a link will have
* one IPv4 address and one or more IPv6 addresses.
*
- * @return An unmodifiable {@link Collection} of {@link LinkAddress} for this link.
+ * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
*/
- public Collection<LinkAddress> getLinkAddresses() {
- return Collections.unmodifiableCollection(mLinkAddresses);
+ public List<LinkAddress> getLinkAddresses() {
+ return Collections.unmodifiableList(mLinkAddresses);
}
/**
* Returns all the addresses on this link and all the links stacked above it.
* @hide
*/
- public Collection<LinkAddress> getAllLinkAddresses() {
- Collection<LinkAddress> addresses = new ArrayList<LinkAddress>();
+ public List<LinkAddress> getAllLinkAddresses() {
+ List<LinkAddress> addresses = new ArrayList<LinkAddress>();
addresses.addAll(mLinkAddresses);
for (LinkProperties stacked: mStackedLinks.values()) {
addresses.addAll(stacked.getAllLinkAddresses());
@@ -239,6 +247,7 @@ public class LinkProperties implements Parcelable {
*
* @param addresses The {@link Collection} of {@link LinkAddress} to set in this
* object.
+ * @hide
*/
public void setLinkAddresses(Collection<LinkAddress> addresses) {
mLinkAddresses.clear();
@@ -250,20 +259,21 @@ public class LinkProperties implements Parcelable {
/**
* Adds the given {@link InetAddress} to the list of DNS servers.
*
- * @param dns The {@link InetAddress} to add to the list of DNS servers.
+ * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
+ * @hide
*/
- public void addDns(InetAddress dns) {
- if (dns != null) mDnses.add(dns);
+ public void addDnsServer(InetAddress dnsServer) {
+ if (dnsServer != null) mDnses.add(dnsServer);
}
/**
* Returns all the {@link LinkAddress} for DNS servers on this link.
*
- * @return An umodifiable {@link Collection} of {@link InetAddress} for DNS servers on
+ * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
* this link.
*/
- public Collection<InetAddress> getDnses() {
- return Collections.unmodifiableCollection(mDnses);
+ public List<InetAddress> getDnsServers() {
+ return Collections.unmodifiableList(mDnses);
}
/**
@@ -271,6 +281,7 @@ public class LinkProperties implements Parcelable {
*
* @param domains A {@link String} listing in priority order the comma separated
* domains to search when resolving host names on this link.
+ * @hide
*/
public void setDomains(String domains) {
mDomains = domains;
@@ -323,6 +334,7 @@ public class LinkProperties implements Parcelable {
* proper course is to add either un-named or properly named {@link RouteInfo}.
*
* @param route A {@link RouteInfo} to add to this object.
+ * @hide
*/
public void addRoute(RouteInfo route) {
if (route != null) {
@@ -339,18 +351,18 @@ public class LinkProperties implements Parcelable {
/**
* Returns all the {@link RouteInfo} set on this link.
*
- * @return An unmodifiable {@link Collection} of {@link RouteInfo} for this link.
+ * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
*/
- public Collection<RouteInfo> getRoutes() {
- return Collections.unmodifiableCollection(mRoutes);
+ public List<RouteInfo> getRoutes() {
+ return Collections.unmodifiableList(mRoutes);
}
/**
* Returns all the routes on this link and all the links stacked above it.
* @hide
*/
- public Collection<RouteInfo> getAllRoutes() {
- Collection<RouteInfo> routes = new ArrayList();
+ public List<RouteInfo> getAllRoutes() {
+ List<RouteInfo> routes = new ArrayList();
routes.addAll(mRoutes);
for (LinkProperties stacked: mStackedLinks.values()) {
routes.addAll(stacked.getAllRoutes());
@@ -364,6 +376,7 @@ public class LinkProperties implements Parcelable {
* not enforce it and applications may ignore them.
*
* @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+ * @hide
*/
public void setHttpProxy(ProxyInfo proxy) {
mHttpProxy = proxy;
@@ -419,16 +432,17 @@ public class LinkProperties implements Parcelable {
* Returns all the links stacked on top of this link.
* @hide
*/
- public Collection<LinkProperties> getStackedLinks() {
- Collection<LinkProperties> stacked = new ArrayList<LinkProperties>();
+ public List<LinkProperties> getStackedLinks() {
+ List<LinkProperties> stacked = new ArrayList<LinkProperties>();
for (LinkProperties link : mStackedLinks.values()) {
stacked.add(new LinkProperties(link));
}
- return Collections.unmodifiableCollection(stacked);
+ return Collections.unmodifiableList(stacked);
}
/**
* Clears this object to its initial state.
+ * @hide
*/
public void clear() {
mIfaceName = null;
@@ -486,6 +500,7 @@ public class LinkProperties implements Parcelable {
* Returns true if this link has an IPv4 address.
*
* @return {@code true} if there is an IPv4 address, {@code false} otherwise.
+ * @hide
*/
public boolean hasIPv4Address() {
for (LinkAddress address : mLinkAddresses) {
@@ -500,6 +515,7 @@ public class LinkProperties implements Parcelable {
* Returns true if this link has an IPv6 address.
*
* @return {@code true} if there is an IPv6 address, {@code false} otherwise.
+ * @hide
*/
public boolean hasIPv6Address() {
for (LinkAddress address : mLinkAddresses) {
@@ -543,7 +559,7 @@ public class LinkProperties implements Parcelable {
* @hide
*/
public boolean isIdenticalDnses(LinkProperties target) {
- Collection<InetAddress> targetDnses = target.getDnses();
+ Collection<InetAddress> targetDnses = target.getDnsServers();
String targetDomains = target.getDomains();
if (mDomains == null) {
if (targetDomains != null) return false;
@@ -696,7 +712,7 @@ public class LinkProperties implements Parcelable {
result.removed = new ArrayList<InetAddress>(mDnses);
result.added.clear();
if (target != null) {
- for (InetAddress newAddress : target.getDnses()) {
+ for (InetAddress newAddress : target.getDnsServers()) {
if (! result.removed.remove(newAddress)) {
result.added.add(newAddress);
}
@@ -831,7 +847,7 @@ public class LinkProperties implements Parcelable {
addressCount = in.readInt();
for (int i=0; i<addressCount; i++) {
try {
- netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
+ netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
} catch (UnknownHostException e) { }
}
netProp.setDomains(in.readString());
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 64516e6..d933f26 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -32,7 +32,8 @@ import javax.net.SocketFactory;
* {@link ConnectivityManager.NetworkCallbackListener} in response to
* {@link ConnectivityManager#requestNetwork} or {@link ConnectivityManager#listenForNetwork}.
* It is used to direct traffic to the given {@code Network}, either on a {@link Socket} basis
- * through a targeted {@link SocketFactory} or process-wide via {@link #bindProcess}.
+ * through a targeted {@link SocketFactory} or process-wide via
+ * {@link ConnectivityManager#setProcessDefaultNetwork}.
*/
public class Network implements Parcelable {
@@ -160,63 +161,13 @@ public class Network implements Parcelable {
* @return a {@link SocketFactory} which produces {@link Socket} instances bound to this
* {@code Network}.
*/
- public SocketFactory socketFactory() {
+ public SocketFactory getSocketFactory() {
if (mNetworkBoundSocketFactory == null) {
mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId);
}
return mNetworkBoundSocketFactory;
}
- /**
- * Binds the current process to this network. All sockets created in the future (and not
- * explicitly bound via a bound {@link SocketFactory} (see {@link Network#socketFactory})
- * will be bound to this network. Note that if this {@code Network} ever disconnects
- * all sockets created in this way will cease to work. This is by design so an application
- * doesn't accidentally use sockets it thinks are still bound to a particular {@code Network}.
- */
- public void bindProcess() {
- NetworkUtils.bindProcessToNetwork(netId);
- }
-
- /**
- * Binds host resolutions performed by this process to this network. {@link #bindProcess}
- * takes precedence over this setting.
- *
- * @hide
- * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
- */
- public void bindProcessForHostResolution() {
- NetworkUtils.bindProcessToNetworkForHostResolution(netId);
- }
-
- /**
- * Clears any process specific {@link Network} binding for host resolution. This does
- * not clear bindings enacted via {@link #bindProcess}.
- *
- * @hide
- * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
- */
- public void unbindProcessForHostResolution() {
- NetworkUtils.unbindProcessToNetworkForHostResolution();
- }
-
- /**
- * A static utility method to return any {@code Network} currently bound by this process.
- *
- * @return {@code Network} to which this process is bound.
- */
- public static Network getProcessBoundNetwork() {
- return new Network(NetworkUtils.getNetworkBoundToProcess());
- }
-
- /**
- * Clear any process specific {@code Network} binding. This reverts a call to
- * {@link Network#bindProcess}.
- */
- public static void unbindProcess() {
- NetworkUtils.unbindProcessToNetwork();
- }
-
// implement the Parcelable interface
public int describeContents() {
return 0;
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 7e8b1f1..3d0874b 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -80,6 +80,11 @@ public abstract class NetworkAgent extends Handler {
*/
public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
+ /* centralize place where base network score, and network score scaling, will be
+ * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE
+ */
+ public static final int WIFI_BASE_SCORE = 60;
+
/**
* Sent by the NetworkAgent to ConnectivityService to pass the current
* network score.
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index edb3286..b02f88e 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -111,7 +111,7 @@ public class NetworkUtils {
/**
* Binds the current process to the network designated by {@code netId}. All sockets created
* in the future (and not explicitly bound via a bound {@link SocketFactory} (see
- * {@link Network#socketFactory}) will be bound to this network. Note that if this
+ * {@link Network#getSocketFactory}) will be bound to this network. Note that if this
* {@code Network} ever disconnects all sockets created in this way will cease to work. This
* is by design so an application doesn't accidentally use sockets it thinks are still bound to
* a particular {@code Network}.
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index 0340e7e..a578383 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -108,8 +108,8 @@ public class ProxyDataTracker extends BaseNetworkStateTracker {
mNetworkCapabilities = new NetworkCapabilities();
mNetworkInfo.setIsAvailable(true);
try {
- mLinkProperties.addDns(InetAddress.getByName(DNS1));
- mLinkProperties.addDns(InetAddress.getByName(DNS2));
+ mLinkProperties.addDnsServer(InetAddress.getByName(DNS1));
+ mLinkProperties.addDnsServer(InetAddress.getByName(DNS2));
mLinkProperties.setInterfaceName(INTERFACE_NAME);
} catch (UnknownHostException e) {
Log.e(TAG, "Could not add DNS address", e);
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 32050dc..537e993 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -128,29 +128,97 @@ public class BatteryManager {
public static final int BATTERY_PLUGGED_ANY =
BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS;
+ /*
+ * Battery property identifiers. These must match the values in
+ * frameworks/native/include/batteryservice/BatteryService.h
+ */
+ /** Battery capacity in microampere-hours, as an integer. */
+ public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1;
+
+ /**
+ * Instantaneous battery current in microamperes, as an integer. Positive
+ * values indicate net current entering the battery from a charge source,
+ * negative values indicate net current discharging from the battery.
+ */
+ public static final int BATTERY_PROPERTY_CURRENT_NOW = 2;
+
+ /**
+ * Average battery current in microamperes, as an integer. Positive
+ * values indicate net current entering the battery from a charge source,
+ * negative values indicate net current discharging from the battery.
+ * The time period over which the average is computed may depend on the
+ * fuel gauge hardware and its configuration.
+ */
+ public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3;
+
+ /**
+ * Remaining battery capacity as an integer percentage of total capacity
+ * (with no fractional part).
+ */
+ public static final int BATTERY_PROPERTY_CAPACITY = 4;
+
+ /**
+ * Battery remaining energy in nanowatt-hours, as a long integer.
+ */
+ public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5;
+
private IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar;
/**
- * Return the requested battery property.
+ * Query a battery property from the batteryproperties service.
*
- * @param id identifier from {@link BatteryProperty} of the requested property
- * @return a {@link BatteryProperty} object that returns the property value, or null on error
+ * Returns the requested value, or Long.MIN_VALUE if property not
+ * supported on this system or on other error.
*/
- public BatteryProperty getProperty(int id) throws RemoteException {
+ private long queryProperty(int id) {
+ long ret;
+
if (mBatteryPropertiesRegistrar == null) {
IBinder b = ServiceManager.getService("batteryproperties");
mBatteryPropertiesRegistrar =
IBatteryPropertiesRegistrar.Stub.asInterface(b);
if (mBatteryPropertiesRegistrar == null)
- return null;
+ return Long.MIN_VALUE;
}
- BatteryProperty prop = new BatteryProperty();
- if ((mBatteryPropertiesRegistrar.getProperty(id, prop) == 0) &&
- (prop.getLong() != Long.MIN_VALUE))
- return prop;
- else
- return null;
+ try {
+ BatteryProperty prop = new BatteryProperty();
+
+ if (mBatteryPropertiesRegistrar.getProperty(id, prop) == 0)
+ ret = prop.getLong();
+ else
+ ret = Long.MIN_VALUE;
+ } catch (RemoteException e) {
+ ret = Long.MIN_VALUE;
+ }
+
+ return ret;
+ }
+
+ /**
+ * Return the value of a battery property of integer type. If the
+ * platform does not provide the property queried, this value will
+ * be Integer.MIN_VALUE.
+ *
+ * @param id identifier of the requested property
+ *
+ * @return the property value, or Integer.MIN_VALUE if not supported.
+ */
+ public int getIntProperty(int id) {
+ return (int)queryProperty(id);
+ }
+
+ /**
+ * Return the value of a battery property of long type If the
+ * platform does not provide the property queried, this value will
+ * be Long.MIN_VALUE.
+ *
+ * @param id identifier of the requested property
+ *
+ * @return the property value, or Long.MIN_VALUE if not supported.
+ */
+ public long getLongProperty(int id) {
+ return queryProperty(id);
}
}
diff --git a/core/java/android/os/BatteryProperty.java b/core/java/android/os/BatteryProperty.java
index 27dad4f..84119bd 100644
--- a/core/java/android/os/BatteryProperty.java
+++ b/core/java/android/os/BatteryProperty.java
@@ -20,44 +20,13 @@ import android.os.Parcelable;
/**
* Battery properties that may be queried using
- * {@link BatteryManager#getProperty
* BatteryManager.getProperty()}
*/
-public class BatteryProperty implements Parcelable {
- /*
- * Battery property identifiers. These must match the values in
- * frameworks/native/include/batteryservice/BatteryService.h
- */
- /** Battery capacity in microampere-hours, as an integer. */
- public static final int CHARGE_COUNTER = 1;
-
- /**
- * Instantaneous battery current in microamperes, as an integer. Positive
- * values indicate net current entering the battery from a charge source,
- * negative values indicate net current discharging from the battery.
- */
- public static final int CURRENT_NOW = 2;
-
- /**
- * Average battery current in microamperes, as an integer. Positive
- * values indicate net current entering the battery from a charge source,
- * negative values indicate net current discharging from the battery.
- * The time period over which the average is computed may depend on the
- * fuel gauge hardware and its configuration.
- */
- public static final int CURRENT_AVERAGE = 3;
-
- /**
- * Remaining battery capacity as an integer percentage of total capacity
- * (with no fractional part).
- */
- public static final int CAPACITY = 4;
-
- /**
- * Battery remaining energy in nanowatt-hours, as a long integer.
- */
- public static final int ENERGY_COUNTER = 5;
+/**
+ * @hide
+ */
+public class BatteryProperty implements Parcelable {
private long mValueLong;
/**
@@ -68,30 +37,12 @@ public class BatteryProperty implements Parcelable {
}
/**
- * Return the value of a property of integer type previously queried
- * via {@link BatteryManager#getProperty
- * BatteryManager.getProperty()}. If the platform does
- * not provide the property queried, this value will be
- * Integer.MIN_VALUE.
- *
- * @return The queried property value, or Integer.MIN_VALUE if not supported.
- */
- public int getInt() {
- return (int)mValueLong;
- }
-
- /**
- * Return the value of a property of long type previously queried
- * via {@link BatteryManager#getProperty
- * BatteryManager.getProperty()}. If the platform does
- * not provide the property queried, this value will be
- * Long.MIN_VALUE.
- *
- * @return The queried property value, or Long.MIN_VALUE if not supported.
+ * @hide
*/
public long getLong() {
return mValueLong;
}
+
/*
* Parcel read/write code must be kept in sync with
* frameworks/native/services/batteryservice/BatteryProperty.cpp
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index f7a89ba..91fbb9d 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -481,10 +481,11 @@ public class UserManager {
}
/**
- * @hide
* Returns whether the current user has been disallowed from performing certain actions
* or setting certain settings.
- * @param restrictionKey the string key representing the restriction
+ *
+ * @param restrictionKey The string key representing the restriction.
+ * @return {@code true} if the current user has the given restriction, {@code false} otherwise.
*/
public boolean hasUserRestriction(String restrictionKey) {
return hasUserRestriction(restrictionKey, Process.myUserHandle());
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index a34d9c3..fa85903 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -25,6 +25,7 @@ import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.BitmapFactory;
import android.net.Uri;
+import android.os.Build;
import android.provider.BrowserContract.Bookmarks;
import android.provider.BrowserContract.Combined;
import android.provider.BrowserContract.History;
@@ -404,12 +405,17 @@ public class Browser {
null, null, History.DATE_LAST_VISITED + " ASC");
if (cursor.moveToFirst() && cursor.getCount() >= MAX_HISTORY_COUNT) {
- final WebIconDatabase iconDb = WebIconDatabase.getInstance();
+ WebIconDatabase iconDb = null;
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
+ iconDb = WebIconDatabase.getInstance();
+ }
/* eliminate oldest history items */
for (int i = 0; i < TRUNCATE_N_OLDEST; i++) {
cr.delete(ContentUris.withAppendedId(History.CONTENT_URI, cursor.getLong(0)),
- null, null);
- iconDb.releaseIconForPageUrl(cursor.getString(1));
+ null, null);
+ if (iconDb != null) {
+ iconDb.releaseIconForPageUrl(cursor.getString(1));
+ }
if (!cursor.moveToNext()) break;
}
}
@@ -469,11 +475,16 @@ public class Browser {
cursor = cr.query(History.CONTENT_URI, new String[] { History.URL }, whereClause,
null, null);
if (cursor.moveToFirst()) {
- final WebIconDatabase iconDb = WebIconDatabase.getInstance();
+ WebIconDatabase iconDb = null;
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
+ iconDb = WebIconDatabase.getInstance();
+ }
do {
- // Delete favicons
- // TODO don't release if the URL is bookmarked
- iconDb.releaseIconForPageUrl(cursor.getString(0));
+ // Delete favicons
+ // TODO don't release if the URL is bookmarked
+ if (iconDb != null) {
+ iconDb.releaseIconForPageUrl(cursor.getString(0));
+ }
} while (cursor.moveToNext());
cr.delete(History.CONTENT_URI, whereClause, null);
@@ -568,7 +579,9 @@ public class Browser {
*/
public static final void requestAllIcons(ContentResolver cr, String where,
WebIconDatabase.IconListener listener) {
- WebIconDatabase.getInstance().bulkRequestIconForPageUrl(cr, where, listener);
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
+ WebIconDatabase.getInstance().bulkRequestIconForPageUrl(cr, where, listener);
+ }
}
/**
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 6b8e2de..327fe4a 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -60,7 +60,8 @@ import java.util.List;
* <p>
* All client apps must hold a valid URI permission grant to access documents,
* typically issued when a user makes a selection through
- * {@link Intent#ACTION_OPEN_DOCUMENT} or {@link Intent#ACTION_CREATE_DOCUMENT}.
+ * {@link Intent#ACTION_OPEN_DOCUMENT}, {@link Intent#ACTION_CREATE_DOCUMENT},
+ * or {@link Intent#ACTION_OPEN_DOCUMENT_TREE}.
*
* @see DocumentsProvider
*/
@@ -73,8 +74,8 @@ public final class DocumentsContract {
// content://com.example/root/sdcard/search/?query=pony
// content://com.example/document/12/
// content://com.example/document/12/children/
- // content://com.example/via/12/document/24/
- // content://com.example/via/12/document/24/children/
+ // content://com.example/tree/12/document/24/
+ // content://com.example/tree/12/document/24/children/
private DocumentsContract() {
}
@@ -441,12 +442,13 @@ public final class DocumentsContract {
public static final int FLAG_SUPPORTS_SEARCH = 1 << 3;
/**
- * Flag indicating that this root supports directory selection.
+ * Flag indicating that this root supports testing parent child
+ * relationships.
*
* @see #COLUMN_FLAGS
* @see DocumentsProvider#isChildDocument(String, String)
*/
- public static final int FLAG_SUPPORTS_DIR_SELECTION = 1 << 4;
+ public static final int FLAG_SUPPORTS_IS_CHILD = 1 << 4;
/**
* Flag indicating that this root is currently empty. This may be used
@@ -518,7 +520,7 @@ public final class DocumentsContract {
private static final String PATH_DOCUMENT = "document";
private static final String PATH_CHILDREN = "children";
private static final String PATH_SEARCH = "search";
- private static final String PATH_VIA = "via";
+ private static final String PATH_TREE = "tree";
private static final String PARAM_QUERY = "query";
private static final String PARAM_MANAGE = "manage";
@@ -564,17 +566,17 @@ public final class DocumentsContract {
* Build URI representing access to descendant documents of the given
* {@link Document#COLUMN_DOCUMENT_ID}.
*
- * @see #getViaDocumentId(Uri)
+ * @see #getTreeDocumentId(Uri)
*/
- public static Uri buildViaUri(String authority, String documentId) {
+ public static Uri buildTreeDocumentUri(String authority, String documentId) {
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
- .appendPath(PATH_VIA).appendPath(documentId).build();
+ .appendPath(PATH_TREE).appendPath(documentId).build();
}
/**
- * Build URI representing the given {@link Document#COLUMN_DOCUMENT_ID} in a
- * document provider. When queried, a provider will return a single row with
- * columns defined by {@link Document}.
+ * Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in
+ * a document provider. When queried, a provider will return a single row
+ * with columns defined by {@link Document}.
*
* @see DocumentsProvider#queryDocument(String, String[])
* @see #getDocumentId(Uri)
@@ -585,42 +587,46 @@ public final class DocumentsContract {
}
/**
- * Build URI representing the given {@link Document#COLUMN_DOCUMENT_ID} in a
- * document provider. Instead of directly accessing the target document,
- * gain access via another document. The target document must be a
- * descendant (child, grandchild, etc) of the via document.
+ * Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in
+ * a document provider. When queried, a provider will return a single row
+ * with columns defined by {@link Document}.
+ * <p>
+ * However, instead of directly accessing the target document, the returned
+ * URI will leverage access granted through a subtree URI, typically
+ * returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target document
+ * must be a descendant (child, grandchild, etc) of the subtree.
* <p>
* This is typically used to access documents under a user-selected
- * directory, since it doesn't require the user to separately confirm each
- * new document access.
+ * directory tree, since it doesn't require the user to separately confirm
+ * each new document access.
*
- * @param viaUri a related document (directory) that the caller is
- * leveraging to gain access to the target document. The target
- * document must be a descendant of this directory.
+ * @param treeUri the subtree to leverage to gain access to the target
+ * document. The target directory must be a descendant of this
+ * subtree.
* @param documentId the target document, which the caller may not have
* direct access to.
- * @see Intent#ACTION_PICK_DIRECTORY
+ * @see Intent#ACTION_OPEN_DOCUMENT_TREE
* @see DocumentsProvider#isChildDocument(String, String)
* @see #buildDocumentUri(String, String)
*/
- public static Uri buildDocumentViaUri(Uri viaUri, String documentId) {
+ public static Uri buildDocumentUriUsingTree(Uri treeUri, String documentId) {
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
- .authority(viaUri.getAuthority()).appendPath(PATH_VIA)
- .appendPath(getViaDocumentId(viaUri)).appendPath(PATH_DOCUMENT)
+ .authority(treeUri.getAuthority()).appendPath(PATH_TREE)
+ .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT)
.appendPath(documentId).build();
}
/** {@hide} */
- public static Uri buildDocumentMaybeViaUri(Uri baseUri, String documentId) {
- if (isViaUri(baseUri)) {
- return buildDocumentViaUri(baseUri, documentId);
+ public static Uri buildDocumentUriMaybeUsingTree(Uri baseUri, String documentId) {
+ if (isTreeUri(baseUri)) {
+ return buildDocumentUriUsingTree(baseUri, documentId);
} else {
return buildDocumentUri(baseUri.getAuthority(), documentId);
}
}
/**
- * Build URI representing the children of the given directory in a document
+ * Build URI representing the children of the target directory in a document
* provider. When queried, a provider will return zero or more rows with
* columns defined by {@link Document}.
*
@@ -637,28 +643,33 @@ public final class DocumentsContract {
}
/**
- * Build URI representing the children of the given directory in a document
- * provider. Instead of directly accessing the target document, gain access
- * via another document. The target document must be a descendant (child,
- * grandchild, etc) of the via document.
+ * Build URI representing the children of the target directory in a document
+ * provider. When queried, a provider will return zero or more rows with
+ * columns defined by {@link Document}.
+ * <p>
+ * However, instead of directly accessing the target directory, the returned
+ * URI will leverage access granted through a subtree URI, typically
+ * returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target
+ * directory must be a descendant (child, grandchild, etc) of the subtree.
* <p>
* This is typically used to access documents under a user-selected
- * directory, since it doesn't require the user to separately confirm each
- * new document access.
+ * directory tree, since it doesn't require the user to separately confirm
+ * each new document access.
*
- * @param viaUri a related document (directory) that the caller is
- * leveraging to gain access to the target document. The target
- * document must be a descendant of this directory.
- * @param parentDocumentId the target document, which the caller may not
- * have direct access to.
- * @see Intent#ACTION_PICK_DIRECTORY
+ * @param treeUri the subtree to leverage to gain access to the target
+ * document. The target directory must be a descendant of this
+ * subtree.
+ * @param parentDocumentId the document to return children for, which the
+ * caller may not have direct access to, and which must be a
+ * directory with MIME type of {@link Document#MIME_TYPE_DIR}.
+ * @see Intent#ACTION_OPEN_DOCUMENT_TREE
* @see DocumentsProvider#isChildDocument(String, String)
* @see #buildChildDocumentsUri(String, String)
*/
- public static Uri buildChildDocumentsViaUri(Uri viaUri, String parentDocumentId) {
+ public static Uri buildChildDocumentsUriUsingTree(Uri treeUri, String parentDocumentId) {
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
- .authority(viaUri.getAuthority()).appendPath(PATH_VIA)
- .appendPath(getViaDocumentId(viaUri)).appendPath(PATH_DOCUMENT)
+ .authority(treeUri.getAuthority()).appendPath(PATH_TREE)
+ .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT)
.appendPath(parentDocumentId).appendPath(PATH_CHILDREN).build();
}
@@ -683,21 +694,24 @@ public final class DocumentsContract {
* {@link DocumentsProvider}.
*
* @see #buildDocumentUri(String, String)
- * @see #buildDocumentViaUri(Uri, String)
+ * @see #buildDocumentUriUsingTree(Uri, String)
*/
public static boolean isDocumentUri(Context context, Uri uri) {
final List<String> paths = uri.getPathSegments();
- if (paths.size() >= 2
- && (PATH_DOCUMENT.equals(paths.get(0)) || PATH_VIA.equals(paths.get(0)))) {
+ if (paths.size() == 2 && PATH_DOCUMENT.equals(paths.get(0))) {
+ return isDocumentsProvider(context, uri.getAuthority());
+ }
+ if (paths.size() == 4 && PATH_TREE.equals(paths.get(0))
+ && PATH_DOCUMENT.equals(paths.get(2))) {
return isDocumentsProvider(context, uri.getAuthority());
}
return false;
}
/** {@hide} */
- public static boolean isViaUri(Uri uri) {
+ public static boolean isTreeUri(Uri uri) {
final List<String> paths = uri.getPathSegments();
- return (paths.size() >= 2 && PATH_VIA.equals(paths.get(0)));
+ return (paths.size() >= 2 && PATH_TREE.equals(paths.get(0)));
}
private static boolean isDocumentsProvider(Context context, String authority) {
@@ -733,7 +747,7 @@ public final class DocumentsContract {
if (paths.size() >= 2 && PATH_DOCUMENT.equals(paths.get(0))) {
return paths.get(1);
}
- if (paths.size() >= 4 && PATH_VIA.equals(paths.get(0))
+ if (paths.size() >= 4 && PATH_TREE.equals(paths.get(0))
&& PATH_DOCUMENT.equals(paths.get(2))) {
return paths.get(3);
}
@@ -742,12 +756,10 @@ public final class DocumentsContract {
/**
* Extract the via {@link Document#COLUMN_DOCUMENT_ID} from the given URI.
- *
- * @see #isViaUri(Uri)
*/
- public static String getViaDocumentId(Uri documentUri) {
+ public static String getTreeDocumentId(Uri documentUri) {
final List<String> paths = documentUri.getPathSegments();
- if (paths.size() >= 2 && PATH_VIA.equals(paths.get(0))) {
+ if (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))) {
return paths.get(1);
}
throw new IllegalArgumentException("Invalid URI: " + documentUri);
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 066b4aa..021fff4 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -20,10 +20,14 @@ import static android.provider.DocumentsContract.EXTRA_THUMBNAIL_SIZE;
import static android.provider.DocumentsContract.METHOD_CREATE_DOCUMENT;
import static android.provider.DocumentsContract.METHOD_DELETE_DOCUMENT;
import static android.provider.DocumentsContract.METHOD_RENAME_DOCUMENT;
+import static android.provider.DocumentsContract.buildDocumentUri;
+import static android.provider.DocumentsContract.buildDocumentUriMaybeUsingTree;
+import static android.provider.DocumentsContract.buildTreeDocumentUri;
import static android.provider.DocumentsContract.getDocumentId;
import static android.provider.DocumentsContract.getRootId;
import static android.provider.DocumentsContract.getSearchDocumentsQuery;
-import static android.provider.DocumentsContract.isViaUri;
+import static android.provider.DocumentsContract.getTreeDocumentId;
+import static android.provider.DocumentsContract.isTreeUri;
import android.content.ContentProvider;
import android.content.ContentResolver;
@@ -117,6 +121,7 @@ import java.util.Objects;
* </p>
*
* @see Intent#ACTION_OPEN_DOCUMENT
+ * @see Intent#ACTION_OPEN_DOCUMENT_TREE
* @see Intent#ACTION_CREATE_DOCUMENT
*/
public abstract class DocumentsProvider extends ContentProvider {
@@ -128,8 +133,8 @@ public abstract class DocumentsProvider extends ContentProvider {
private static final int MATCH_SEARCH = 4;
private static final int MATCH_DOCUMENT = 5;
private static final int MATCH_CHILDREN = 6;
- private static final int MATCH_DOCUMENT_VIA = 7;
- private static final int MATCH_CHILDREN_VIA = 8;
+ private static final int MATCH_DOCUMENT_TREE = 7;
+ private static final int MATCH_CHILDREN_TREE = 8;
private String mAuthority;
@@ -149,8 +154,8 @@ public abstract class DocumentsProvider extends ContentProvider {
mMatcher.addURI(mAuthority, "root/*/search", MATCH_SEARCH);
mMatcher.addURI(mAuthority, "document/*", MATCH_DOCUMENT);
mMatcher.addURI(mAuthority, "document/*/children", MATCH_CHILDREN);
- mMatcher.addURI(mAuthority, "via/*/document/*", MATCH_DOCUMENT_VIA);
- mMatcher.addURI(mAuthority, "via/*/document/*/children", MATCH_CHILDREN_VIA);
+ mMatcher.addURI(mAuthority, "tree/*/document/*", MATCH_DOCUMENT_TREE);
+ mMatcher.addURI(mAuthority, "tree/*/document/*/children", MATCH_CHILDREN_TREE);
// Sanity check our setup
if (!info.exported) {
@@ -169,23 +174,24 @@ public abstract class DocumentsProvider extends ContentProvider {
/**
* Test if a document is descendant (child, grandchild, etc) from the given
- * parent. Providers must override this to support directory selection. You
- * should avoid making network requests to keep this request fast.
+ * parent. For example, providers must implement this to support
+ * {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. You should avoid making network
+ * requests to keep this request fast.
*
* @param parentDocumentId parent to verify against.
* @param documentId child to verify.
* @return if given document is a descendant of the given parent.
- * @see DocumentsContract.Root#FLAG_SUPPORTS_DIR_SELECTION
+ * @see DocumentsContract.Root#FLAG_SUPPORTS_IS_CHILD
*/
public boolean isChildDocument(String parentDocumentId, String documentId) {
return false;
}
/** {@hide} */
- private void enforceVia(Uri documentUri) {
- if (DocumentsContract.isViaUri(documentUri)) {
- final String parent = DocumentsContract.getViaDocumentId(documentUri);
- final String child = DocumentsContract.getDocumentId(documentUri);
+ private void enforceTree(Uri documentUri) {
+ if (isTreeUri(documentUri)) {
+ final String parent = getTreeDocumentId(documentUri);
+ final String child = getDocumentId(documentUri);
if (Objects.equals(parent, child)) {
return;
}
@@ -479,12 +485,12 @@ public abstract class DocumentsProvider extends ContentProvider {
return querySearchDocuments(
getRootId(uri), getSearchDocumentsQuery(uri), projection);
case MATCH_DOCUMENT:
- case MATCH_DOCUMENT_VIA:
- enforceVia(uri);
+ case MATCH_DOCUMENT_TREE:
+ enforceTree(uri);
return queryDocument(getDocumentId(uri), projection);
case MATCH_CHILDREN:
- case MATCH_CHILDREN_VIA:
- enforceVia(uri);
+ case MATCH_CHILDREN_TREE:
+ enforceTree(uri);
if (DocumentsContract.isManageMode(uri)) {
return queryChildDocumentsForManage(
getDocumentId(uri), projection, sortOrder);
@@ -512,8 +518,8 @@ public abstract class DocumentsProvider extends ContentProvider {
case MATCH_ROOT:
return DocumentsContract.Root.MIME_TYPE_ITEM;
case MATCH_DOCUMENT:
- case MATCH_DOCUMENT_VIA:
- enforceVia(uri);
+ case MATCH_DOCUMENT_TREE:
+ enforceTree(uri);
return getDocumentType(getDocumentId(uri));
default:
return null;
@@ -530,21 +536,20 @@ public abstract class DocumentsProvider extends ContentProvider {
* call the superclass. If the superclass returns {@code null}, the subclass
* may implement custom behavior.
* <p>
- * This is typically used to resolve a "via" URI into a concrete document
+ * This is typically used to resolve a subtree URI into a concrete document
* reference, issuing a narrower single-document URI permission grant along
* the way.
*
- * @see DocumentsContract#buildDocumentViaUri(Uri, String)
+ * @see DocumentsContract#buildDocumentUriUsingTree(Uri, String)
*/
@Override
public Uri canonicalize(Uri uri) {
final Context context = getContext();
switch (mMatcher.match(uri)) {
- case MATCH_DOCUMENT_VIA:
- enforceVia(uri);
+ case MATCH_DOCUMENT_TREE:
+ enforceTree(uri);
- final Uri narrowUri = DocumentsContract.buildDocumentUri(uri.getAuthority(),
- DocumentsContract.getDocumentId(uri));
+ final Uri narrowUri = buildDocumentUri(uri.getAuthority(), getDocumentId(uri));
// Caller may only have prefix grant, so extend them a grant to
// the narrow URI.
@@ -628,7 +633,7 @@ public abstract class DocumentsProvider extends ContentProvider {
throw new SecurityException(
"Requested authority " + authority + " doesn't match provider " + mAuthority);
}
- enforceVia(documentUri);
+ enforceTree(documentUri);
final Bundle out = new Bundle();
try {
@@ -641,8 +646,8 @@ public abstract class DocumentsProvider extends ContentProvider {
// No need to issue new grants here, since caller either has
// manage permission or a prefix grant. We might generate a
- // "via" style URI if that's how they called us.
- final Uri newDocumentUri = DocumentsContract.buildDocumentMaybeViaUri(documentUri,
+ // tree style URI if that's how they called us.
+ final Uri newDocumentUri = buildDocumentUriMaybeUsingTree(documentUri,
newDocumentId);
out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
@@ -653,12 +658,12 @@ public abstract class DocumentsProvider extends ContentProvider {
final String newDocumentId = renameDocument(documentId, displayName);
if (newDocumentId != null) {
- final Uri newDocumentUri = DocumentsContract.buildDocumentMaybeViaUri(
- documentUri, newDocumentId);
+ final Uri newDocumentUri = buildDocumentUriMaybeUsingTree(documentUri,
+ newDocumentId);
// If caller came in with a narrow grant, issue them a
// narrow grant for the newly renamed document.
- if (!isViaUri(newDocumentUri)) {
+ if (!isTreeUri(newDocumentUri)) {
final int modeFlags = getCallingOrSelfUriPermissionModeFlags(context,
documentUri);
context.grantUriPermission(getCallingPackage(), newDocumentUri, modeFlags);
@@ -694,8 +699,8 @@ public abstract class DocumentsProvider extends ContentProvider {
*/
public final void revokeDocumentPermission(String documentId) {
final Context context = getContext();
- context.revokeUriPermission(DocumentsContract.buildDocumentUri(mAuthority, documentId), ~0);
- context.revokeUriPermission(DocumentsContract.buildViaUri(mAuthority, documentId), ~0);
+ context.revokeUriPermission(buildDocumentUri(mAuthority, documentId), ~0);
+ context.revokeUriPermission(buildTreeDocumentUri(mAuthority, documentId), ~0);
}
/**
@@ -705,7 +710,7 @@ public abstract class DocumentsProvider extends ContentProvider {
*/
@Override
public final ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- enforceVia(uri);
+ enforceTree(uri);
return openDocument(getDocumentId(uri), mode, null);
}
@@ -717,7 +722,7 @@ public abstract class DocumentsProvider extends ContentProvider {
@Override
public final ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal)
throws FileNotFoundException {
- enforceVia(uri);
+ enforceTree(uri);
return openDocument(getDocumentId(uri), mode, signal);
}
@@ -730,7 +735,7 @@ public abstract class DocumentsProvider extends ContentProvider {
@SuppressWarnings("resource")
public final AssetFileDescriptor openAssetFile(Uri uri, String mode)
throws FileNotFoundException {
- enforceVia(uri);
+ enforceTree(uri);
final ParcelFileDescriptor fd = openDocument(getDocumentId(uri), mode, null);
return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
}
@@ -744,7 +749,7 @@ public abstract class DocumentsProvider extends ContentProvider {
@SuppressWarnings("resource")
public final AssetFileDescriptor openAssetFile(Uri uri, String mode, CancellationSignal signal)
throws FileNotFoundException {
- enforceVia(uri);
+ enforceTree(uri);
final ParcelFileDescriptor fd = openDocument(getDocumentId(uri), mode, signal);
return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
}
@@ -757,7 +762,7 @@ public abstract class DocumentsProvider extends ContentProvider {
@Override
public final AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
throws FileNotFoundException {
- enforceVia(uri);
+ enforceTree(uri);
if (opts != null && opts.containsKey(EXTRA_THUMBNAIL_SIZE)) {
final Point sizeHint = opts.getParcelable(EXTRA_THUMBNAIL_SIZE);
return openDocumentThumbnail(getDocumentId(uri), sizeHint, null);
@@ -775,7 +780,7 @@ public abstract class DocumentsProvider extends ContentProvider {
public final AssetFileDescriptor openTypedAssetFile(
Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
throws FileNotFoundException {
- enforceVia(uri);
+ enforceTree(uri);
if (opts != null && opts.containsKey(EXTRA_THUMBNAIL_SIZE)) {
final Point sizeHint = opts.getParcelable(EXTRA_THUMBNAIL_SIZE);
return openDocumentThumbnail(getDocumentId(uri), sizeHint, signal);
diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java
index d7e8cf0..3907e77 100644
--- a/core/java/android/util/Range.java
+++ b/core/java/android/util/Range.java
@@ -97,6 +97,27 @@ public final class Range<T extends Comparable<? super T>> {
}
/**
+ * Checks if the {@code value} is within the bounds of this range.
+ *
+ * <p>A value is considered to be within this range if it's {@code >=} then
+ * the lower endpoint <i>and</i> {@code <=} to the upper endpoint (using the {@link Comparable}
+ * interface.</p>
+ *
+ * @param value a non-{@code null} {@code T} reference
+ * @return {@code true} if the value is within this inclusive range, {@code false} otherwise
+ *
+ * @throws NullPointerException if {@code value} was {@code null}
+ */
+ public boolean inRange(T value) {
+ checkNotNull(value, "value must not be null");
+
+ boolean gteLower = value.compareTo(mLower) >= 0;
+ boolean lteUpper = value.compareTo(mUpper) <= 0;
+
+ return gteLower && lteUpper;
+ }
+
+ /**
* Compare two ranges for equality.
*
* <p>A range is considered equal if and only if both the lower and upper endpoints
@@ -105,16 +126,13 @@ public final class Range<T extends Comparable<? super T>> {
* @return {@code true} if the ranges are equal, {@code false} otherwise
*/
@Override
- public boolean equals(final Object obj) {
+ public boolean equals(Object obj) {
if (obj == null) {
return false;
- }
- if (this == obj) {
+ } else if (this == obj) {
return true;
- }
- if (obj instanceof Range) {
+ } else if (obj instanceof Range) {
@SuppressWarnings("rawtypes")
- final
Range other = (Range) obj;
return mLower.equals(other.mLower) && mUpper.equals(other.mUpper);
}
diff --git a/core/java/android/util/Rational.java b/core/java/android/util/Rational.java
index 8d4c67f..9952859 100644
--- a/core/java/android/util/Rational.java
+++ b/core/java/android/util/Rational.java
@@ -15,29 +15,88 @@
*/
package android.util;
+import static com.android.internal.util.Preconditions.*;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+
/**
* <p>An immutable data type representation a rational number.</p>
*
* <p>Contains a pair of {@code int}s representing the numerator and denominator of a
* Rational number. </p>
*/
-public final class Rational {
+public final class Rational extends Number implements Comparable<Rational> {
+ /**
+ * Constant for the <em>Not-a-Number (NaN)</em> value of the {@code Rational} type.
+ *
+ * <p>A {@code NaN} value is considered to be equal to itself (that is {@code NaN.equals(NaN)}
+ * will return {@code true}; it is always greater than any non-{@code NaN} value (that is
+ * {@code NaN.compareTo(notNaN)} will return a number greater than {@code 0}).</p>
+ *
+ * <p>Equivalent to constructing a new rational with both the numerator and denominator
+ * equal to {@code 0}.</p>
+ */
+ public static final Rational NaN = new Rational(0, 0);
+
+ /**
+ * Constant for the positive infinity value of the {@code Rational} type.
+ *
+ * <p>Equivalent to constructing a new rational with a positive numerator and a denominator
+ * equal to {@code 0}.</p>
+ */
+ public static final Rational POSITIVE_INFINITY = new Rational(1, 0);
+
+ /**
+ * Constant for the negative infinity value of the {@code Rational} type.
+ *
+ * <p>Equivalent to constructing a new rational with a negative numerator and a denominator
+ * equal to {@code 0}.</p>
+ */
+ public static final Rational NEGATIVE_INFINITY = new Rational(-1, 0);
+
+ /**
+ * Constant for the zero value of the {@code Rational} type.
+ *
+ * <p>Equivalent to constructing a new rational with a numerator equal to {@code 0} and
+ * any non-zero denominator.</p>
+ */
+ public static final Rational ZERO = new Rational(0, 1);
+
+ /**
+ * Unique version number per class to be compliant with {@link java.io.Serializable}.
+ *
+ * <p>Increment each time the fields change in any way.</p>
+ */
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * Do not change the order of these fields or add new instance fields to maintain the
+ * Serializable compatibility across API revisions.
+ */
private final int mNumerator;
private final int mDenominator;
/**
- * <p>Create a Rational with a given numerator and denominator.</p>
+ * <p>Create a {@code Rational} with a given numerator and denominator.</p>
*
* <p>The signs of the numerator and the denominator may be flipped such that the denominator
- * is always positive.</p>
+ * is always positive. Both the numerator and denominator will be converted to their reduced
+ * forms (see {@link #equals} for more details).</p>
*
- * <p>A rational value with a 0-denominator may be constructed, but will have similar semantics
- * as float {@code NaN} and {@code INF} values. For {@code NaN},
- * both {@link #getNumerator} and {@link #getDenominator} functions will return 0. For
- * positive or negative {@code INF}, only the {@link #getDenominator} will return 0.</p>
+ * <p>For example,
+ * <ul>
+ * <li>a rational of {@code 2/4} will be reduced to {@code 1/2}.
+ * <li>a rational of {@code 1/-1} will be flipped to {@code -1/1}
+ * <li>a rational of {@code 5/0} will be reduced to {@code 1/0}
+ * <li>a rational of {@code 0/5} will be reduced to {@code 0/1}
+ * </ul>
+ * </p>
*
* @param numerator the numerator of the rational
* @param denominator the denominator of the rational
+ *
+ * @see #equals
*/
public Rational(int numerator, int denominator) {
@@ -46,32 +105,100 @@ public final class Rational {
denominator = -denominator;
}
- mNumerator = numerator;
- mDenominator = denominator;
+ // Convert to reduced form
+ if (denominator == 0 && numerator > 0) {
+ mNumerator = 1; // +Inf
+ mDenominator = 0;
+ } else if (denominator == 0 && numerator < 0) {
+ mNumerator = -1; // -Inf
+ mDenominator = 0;
+ } else if (denominator == 0 && numerator == 0) {
+ mNumerator = 0; // NaN
+ mDenominator = 0;
+ } else if (numerator == 0) {
+ mNumerator = 0;
+ mDenominator = 1;
+ } else {
+ int gcd = gcd(numerator, denominator);
+
+ mNumerator = numerator / gcd;
+ mDenominator = denominator / gcd;
+ }
}
/**
* Gets the numerator of the rational.
+ *
+ * <p>The numerator will always return {@code 1} if this rational represents
+ * infinity (that is, the denominator is {@code 0}).</p>
*/
public int getNumerator() {
- if (mDenominator == 0) {
- return 0;
- }
return mNumerator;
}
/**
* Gets the denominator of the rational
+ *
+ * <p>The denominator may return {@code 0}, in which case the rational may represent
+ * positive infinity (if the numerator was positive), negative infinity (if the numerator
+ * was negative), or {@code NaN} (if the numerator was {@code 0}).</p>
+ *
+ * <p>The denominator will always return {@code 1} if the numerator is {@code 0}.
*/
public int getDenominator() {
return mDenominator;
}
- private boolean isNaN() {
+ /**
+ * Indicates whether this rational is a <em>Not-a-Number (NaN)</em> value.
+ *
+ * <p>A {@code NaN} value occurs when both the numerator and the denominator are {@code 0}.</p>
+ *
+ * @return {@code true} if this rational is a <em>Not-a-Number (NaN)</em> value;
+ * {@code false} if this is a (potentially infinite) number value
+ */
+ public boolean isNaN() {
return mDenominator == 0 && mNumerator == 0;
}
- private boolean isInf() {
+ /**
+ * Indicates whether this rational represents an infinite value.
+ *
+ * <p>An infinite value occurs when the denominator is {@code 0} (but the numerator is not).</p>
+ *
+ * @return {@code true} if this rational is a (positive or negative) infinite value;
+ * {@code false} if this is a finite number value (or {@code NaN})
+ */
+ public boolean isInfinite() {
+ return mNumerator != 0 && mDenominator == 0;
+ }
+
+ /**
+ * Indicates whether this rational represents a finite value.
+ *
+ * <p>A finite value occurs when the denominator is not {@code 0}; in other words
+ * the rational is neither infinity or {@code NaN}.</p>
+ *
+ * @return {@code true} if this rational is a (positive or negative) infinite value;
+ * {@code false} if this is a finite number value (or {@code NaN})
+ */
+ public boolean isFinite() {
+ return mDenominator != 0;
+ }
+
+ /**
+ * Indicates whether this rational represents a zero value.
+ *
+ * <p>A zero value is a {@link #isFinite finite} rational with a numerator of {@code 0}.</p>
+ *
+ * @return {@code true} if this rational is finite zero value;
+ * {@code false} otherwise
+ */
+ public boolean isZero() {
+ return isFinite() && mNumerator == 0;
+ }
+
+ private boolean isPosInf() {
return mDenominator == 0 && mNumerator > 0;
}
@@ -82,12 +209,12 @@ public final class Rational {
/**
* <p>Compare this Rational to another object and see if they are equal.</p>
*
- * <p>A Rational object can only be equal to another Rational object (comparing against any other
- * type will return false).</p>
+ * <p>A Rational object can only be equal to another Rational object (comparing against any
+ * other type will return {@code false}).</p>
*
* <p>A Rational object is considered equal to another Rational object if and only if one of
- * the following holds</p>:
- * <ul><li>Both are NaN</li>
+ * the following holds:</p>
+ * <ul><li>Both are {@code NaN}</li>
* <li>Both are infinities of the same sign</li>
* <li>Both have the same numerator and denominator in their reduced form</li>
* </ul>
@@ -96,12 +223,12 @@ public final class Rational {
* denominator by their greatest common divisor.</p>
*
* <pre>{@code
- * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true
- * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
- * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction
- * (new Rational(0, 0)).equals(new Rational(0, 0)) == true // NaN.equals(NaN)
- * (new Rational(1, 0)).equals(new Rational(5, 0)) == true // both are +infinity
- * (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
+ * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true
+ * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
+ * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction
+ * (new Rational(0, 0)).equals(new Rational(0, 0)) == true // NaN.equals(NaN)
+ * (new Rational(1, 0)).equals(new Rational(5, 0)) == true // both are +infinity
+ * (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
* }</pre>
*
* @param obj a reference to another object
@@ -110,41 +237,31 @@ public final class Rational {
*/
@Override
public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- } else if (obj instanceof Rational) {
- Rational other = (Rational) obj;
- if (mDenominator == 0 || other.mDenominator == 0) {
- if (isNaN() && other.isNaN()) {
- return true;
- } else if (isInf() && other.isInf() || isNegInf() && other.isNegInf()) {
- return true;
- } else {
- return false;
- }
- } else if (mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
- return true;
- } else {
- int thisGcd = gcd();
- int otherGcd = other.gcd();
-
- int thisNumerator = mNumerator / thisGcd;
- int thisDenominator = mDenominator / thisGcd;
-
- int otherNumerator = other.mNumerator / otherGcd;
- int otherDenominator = other.mDenominator / otherGcd;
-
- return (thisNumerator == otherNumerator && thisDenominator == otherDenominator);
- }
- }
- return false;
+ return obj instanceof Rational && equals((Rational) obj);
+ }
+
+ private boolean equals(Rational other) {
+ return (mNumerator == other.mNumerator && mDenominator == other.mDenominator);
}
+ /**
+ * Return a string representation of this rational, e.g. {@code "1/2"}.
+ *
+ * <p>The following rules of conversion apply:
+ * <ul>
+ * <li>{@code NaN} values will return {@code "NaN"}
+ * <li>Positive infinity values will return {@code "Infinity"}
+ * <li>Negative infinity values will return {@code "-Infinity"}
+ * <li>All other values will return {@code "numerator/denominator"} where {@code numerator}
+ * and {@code denominator} are substituted with the appropriate numerator and denominator
+ * values.
+ * </ul></p>
+ */
@Override
public String toString() {
if (isNaN()) {
return "NaN";
- } else if (isInf()) {
+ } else if (isPosInf()) {
return "Infinity";
} else if (isNegInf()) {
return "-Infinity";
@@ -160,7 +277,8 @@ public final class Rational {
* @hide
*/
public float toFloat() {
- return (float) mNumerator / (float) mDenominator;
+ // TODO: remove this duplicate function (used in CTS and the shim)
+ return floatValue();
}
/**
@@ -177,20 +295,24 @@ public final class Rational {
/**
* Calculates the greatest common divisor using Euclid's algorithm.
*
+ * <p><em>Visible for testing only.</em></p>
+ *
+ * @param numerator the numerator in a fraction
+ * @param denominator the denominator in a fraction
+ *
* @return An int value representing the gcd. Always positive.
* @hide
*/
- public int gcd() {
- /**
+ public static int gcd(int numerator, int denominator) {
+ /*
* Non-recursive implementation of Euclid's algorithm:
*
* gcd(a, 0) := a
* gcd(a, b) := gcd(b, a mod b)
*
*/
-
- int a = mNumerator;
- int b = mDenominator;
+ int a = numerator;
+ int b = denominator;
while (b != 0) {
int oldB = b;
@@ -201,4 +323,221 @@ public final class Rational {
return Math.abs(a);
}
+
+ /**
+ * Returns the value of the specified number as a {@code double}.
+ *
+ * <p>The {@code double} is calculated by converting both the numerator and denominator
+ * to a {@code double}; then returning the result of dividing the numerator by the
+ * denominator.</p>
+ *
+ * @return the divided value of the numerator and denominator as a {@code double}.
+ */
+ @Override
+ public double doubleValue() {
+ double num = mNumerator;
+ double den = mDenominator;
+
+ return num / den;
+ }
+
+ /**
+ * Returns the value of the specified number as a {@code float}.
+ *
+ * <p>The {@code float} is calculated by converting both the numerator and denominator
+ * to a {@code float}; then returning the result of dividing the numerator by the
+ * denominator.</p>
+ *
+ * @return the divided value of the numerator and denominator as a {@code float}.
+ */
+ @Override
+ public float floatValue() {
+ float num = mNumerator;
+ float den = mDenominator;
+
+ return num / den;
+ }
+
+ /**
+ * Returns the value of the specified number as a {@code int}.
+ *
+ * <p>{@link #isInfinite Finite} rationals are converted to an {@code int} value
+ * by dividing the numerator by the denominator; conversion for non-finite values happens
+ * identically to casting a floating point value to an {@code int}, in particular:
+ *
+ * <p>
+ * <ul>
+ * <li>Positive infinity saturates to the largest maximum integer
+ * {@link Integer#MAX_VALUE}</li>
+ * <li>Negative infinity saturates to the smallest maximum integer
+ * {@link Integer#MIN_VALUE}</li>
+ * <li><em>Not-A-Number (NaN)</em> returns {@code 0}.</li>
+ * </ul>
+ * </p>
+ *
+ * @return the divided value of the numerator and denominator as a {@code int}.
+ */
+ @Override
+ public int intValue() {
+ // Mimic float to int conversion rules from JLS 5.1.3
+
+ if (isPosInf()) {
+ return Integer.MAX_VALUE;
+ } else if (isNegInf()) {
+ return Integer.MIN_VALUE;
+ } else if (isNaN()) {
+ return 0;
+ } else { // finite
+ return mNumerator / mDenominator;
+ }
+ }
+
+ /**
+ * Returns the value of the specified number as a {@code long}.
+ *
+ * <p>{@link #isInfinite Finite} rationals are converted to an {@code long} value
+ * by dividing the numerator by the denominator; conversion for non-finite values happens
+ * identically to casting a floating point value to a {@code long}, in particular:
+ *
+ * <p>
+ * <ul>
+ * <li>Positive infinity saturates to the largest maximum long
+ * {@link Long#MAX_VALUE}</li>
+ * <li>Negative infinity saturates to the smallest maximum long
+ * {@link Long#MIN_VALUE}</li>
+ * <li><em>Not-A-Number (NaN)</em> returns {@code 0}.</li>
+ * </ul>
+ * </p>
+ *
+ * @return the divided value of the numerator and denominator as a {@code long}.
+ */
+ @Override
+ public long longValue() {
+ // Mimic float to long conversion rules from JLS 5.1.3
+
+ if (isPosInf()) {
+ return Long.MAX_VALUE;
+ } else if (isNegInf()) {
+ return Long.MIN_VALUE;
+ } else if (isNaN()) {
+ return 0;
+ } else { // finite
+ return mNumerator / mDenominator;
+ }
+ }
+
+ /**
+ * Returns the value of the specified number as a {@code short}.
+ *
+ * <p>{@link #isInfinite Finite} rationals are converted to a {@code short} value
+ * identically to {@link #intValue}; the {@code int} result is then truncated to a
+ * {@code short} before returning the value.</p>
+ *
+ * @return the divided value of the numerator and denominator as a {@code short}.
+ */
+ @Override
+ public short shortValue() {
+ return (short) intValue();
+ }
+
+ /**
+ * Compare this rational to the specified rational to determine their natural order.
+ *
+ * <p>{@link #NaN} is considered to be equal to itself and greater than all other
+ * {@code Rational} values. Otherwise, if the objects are not {@link #equals equal}, then
+ * the following rules apply:</p>
+ *
+ * <ul>
+ * <li>Positive infinity is greater than any other finite number (or negative infinity)
+ * <li>Negative infinity is less than any other finite number (or positive infinity)
+ * <li>The finite number represented by this rational is checked numerically
+ * against the other finite number by converting both rationals to a common denominator multiple
+ * and comparing their numerators.
+ * </ul>
+ *
+ * @param another the rational to be compared
+ *
+ * @return a negative integer, zero, or a positive integer as this object is less than,
+ * equal to, or greater than the specified rational.
+ *
+ * @throws NullPointerException if {@code another} was {@code null}
+ */
+ @Override
+ public int compareTo(Rational another) {
+ checkNotNull(another, "another must not be null");
+
+ if (equals(another)) {
+ return 0;
+ } else if (isNaN()) { // NaN is greater than the other non-NaN value
+ return 1;
+ } else if (another.isNaN()) { // the other NaN is greater than this non-NaN value
+ return -1;
+ } else if (isPosInf() || another.isNegInf()) {
+ return 1; // positive infinity is greater than any non-NaN/non-posInf value
+ } else if (isNegInf() || another.isPosInf()) {
+ return -1; // negative infinity is less than any non-NaN/non-negInf value
+ }
+
+ // else both this and another are finite numbers
+
+ // make the denominators the same, then compare numerators
+ long thisNumerator = ((long)mNumerator) * another.mDenominator; // long to avoid overflow
+ long otherNumerator = ((long)another.mNumerator) * mDenominator; // long to avoid overflow
+
+ // avoid underflow from subtraction by doing comparisons
+ if (thisNumerator < otherNumerator) {
+ return -1;
+ } else if (thisNumerator > otherNumerator) {
+ return 1;
+ } else {
+ // This should be covered by #equals, but have this code path just in case
+ return 0;
+ }
+ }
+
+ /*
+ * Serializable implementation.
+ *
+ * The following methods are omitted:
+ * >> writeObject - the default is sufficient (field by field serialization)
+ * >> readObjectNoData - the default is sufficient (0s for both fields is a NaN)
+ */
+
+ /**
+ * writeObject with default serialized form - guards against
+ * deserializing non-reduced forms of the rational.
+ *
+ * @throws InvalidObjectException if the invariants were violated
+ */
+ private void readObject(java.io.ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+
+ /*
+ * Guard against trying to deserialize illegal values (in this case, ones
+ * that don't have a standard reduced form).
+ *
+ * - Non-finite values must be one of [0, 1], [0, 0], [0, 1], [0, -1]
+ * - Finite values must always have their greatest common divisor as 1
+ */
+
+ if (mNumerator == 0) { // either zero or NaN
+ if (mDenominator == 1 || mDenominator == 0) {
+ return;
+ }
+ throw new InvalidObjectException(
+ "Rational must be deserialized from a reduced form for zero values");
+ } else if (mDenominator == 0) { // either positive or negative infinity
+ if (mNumerator == 1 || mNumerator == -1) {
+ return;
+ }
+ throw new InvalidObjectException(
+ "Rational must be deserialized from a reduced form for infinity values");
+ } else { // finite value
+ if (gcd(mNumerator, mDenominator) > 1) {
+ throw new InvalidObjectException(
+ "Rational must be deserialized from a reduced form for finite values");
+ }
+ }
+ }
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c681919..65b1f8c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -431,7 +431,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* child. The child must use this size, and guarantee that all of its
* descendants will fit within this size.
* <li>AT_MOST: This is used by the parent to impose a maximum size on the
- * child. The child must gurantee that it and all of its descendants will fit
+ * child. The child must guarantee that it and all of its descendants will fit
* within this size.
* </ul>
* </p>
@@ -5377,8 +5377,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Gets the location of this view in screen coordintates.
*
* @param outRect The output location
+ * @hide
*/
- void getBoundsOnScreen(Rect outRect) {
+ public void getBoundsOnScreen(Rect outRect) {
if (mAttachInfo == null) {
return;
}
@@ -9670,7 +9671,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* The transform matrix of this view, which is calculated based on the current
- * roation, scale, and pivot properties.
+ * rotation, scale, and pivot properties.
*
* @see #getRotation()
* @see #getScaleX()
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 02011e0..2905851 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -6939,13 +6939,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (getClass() != another.getClass()) {
return 1;
}
- // First is above second.
- if (mLocation.bottom - another.mLocation.top <= 0) {
- return -1;
- }
- // First is below second.
- if (mLocation.top - another.mLocation.bottom >= 0) {
- return 1;
+ final int topDiference = mLocation.top - another.mLocation.top;
+ if (topDiference != 0) {
+ return topDiference;
}
// LTR
if (mLayoutDirection == LAYOUT_DIRECTION_LTR) {
@@ -6961,11 +6957,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return -rightDifference;
}
}
- // Break tie by top.
- final int topDiference = mLocation.top - another.mLocation.top;
- if (topDiference != 0) {
- return topDiference;
- }
// Break tie by height.
final int heightDiference = mLocation.height() - another.mLocation.height();
if (heightDiference != 0) {
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 294f472..57e774e 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -87,7 +87,12 @@ public final class WindowInsets {
if (mTempRect == null) {
mTempRect = new Rect();
}
- mTempRect.set(mSystemWindowInsets);
+ if (mSystemWindowInsets != null) {
+ mTempRect.set(mSystemWindowInsets);
+ } else {
+ // If there were no system window insets, this is just empty.
+ mTempRect.setEmpty();
+ }
return mTempRect;
}
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index a74e3a0..e1f40b7 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -195,6 +195,7 @@ public class BaseInputConnection implements InputConnection {
public boolean commitText(CharSequence text, int newCursorPosition) {
if (DEBUG) Log.v(TAG, "commitText " + text);
replaceText(text, newCursorPosition, false);
+ mIMM.notifyUserAction();
sendCurrentText();
return true;
}
@@ -435,6 +436,7 @@ public class BaseInputConnection implements InputConnection {
public boolean setComposingText(CharSequence text, int newCursorPosition) {
if (DEBUG) Log.v(TAG, "setComposingText " + text);
replaceText(text, newCursorPosition, true);
+ mIMM.notifyUserAction();
return true;
}
@@ -518,6 +520,7 @@ public class BaseInputConnection implements InputConnection {
viewRootImpl.dispatchKeyFromIme(event);
}
}
+ mIMM.notifyUserAction();
return false;
}
@@ -601,9 +604,6 @@ public class BaseInputConnection implements InputConnection {
}
beginBatchEdit();
- if (!composing && !TextUtils.isEmpty(text)) {
- mIMM.notifyUserAction();
- }
// delete composing text set previously.
int a = getComposingSpanStart(content);
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 0693617..ace8808 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -320,6 +320,25 @@ public final class InputMethodManager {
int mCursorCandEnd;
/**
+ * Represents an invalid action notification sequence number. {@link InputMethodManagerService}
+ * always issues a positive integer for action notification sequence numbers. Thus -1 is
+ * guaranteed to be different from any valid sequence number.
+ */
+ private static final int NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER = -1;
+ /**
+ * The next sequence number that is to be sent to {@link InputMethodManagerService} via
+ * {@link IInputMethodManager#notifyUserAction(int)} at once when a user action is observed.
+ */
+ private int mNextUserActionNotificationSequenceNumber =
+ NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER;
+
+ /**
+ * The last sequence number that is already sent to {@link InputMethodManagerService}.
+ */
+ private int mLastSentUserActionNotificationSequenceNumber =
+ NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER;
+
+ /**
* The instance that has previously been sent to the input method.
*/
private CursorAnchorInfo mCursorAnchorInfo = null;
@@ -364,6 +383,7 @@ public final class InputMethodManager {
static final int MSG_TIMEOUT_INPUT_EVENT = 6;
static final int MSG_FLUSH_INPUT_EVENT = 7;
static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 8;
+ static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 9;
class H extends Handler {
H(Looper looper) {
@@ -503,6 +523,11 @@ public final class InputMethodManager {
}
return;
}
+ case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: {
+ synchronized (mH) {
+ mNextUserActionNotificationSequenceNumber = msg.arg1;
+ }
+ }
}
}
}
@@ -572,6 +597,12 @@ public final class InputMethodManager {
public void setCursorAnchorMonitorMode(int monitorMode) {
mH.sendMessage(mH.obtainMessage(MSG_SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, 0));
}
+
+ @Override
+ public void setUserActionNotificationSequenceNumber(int sequenceNumber) {
+ mH.sendMessage(mH.obtainMessage(MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER,
+ sequenceNumber, 0));
+ }
};
final InputConnection mDummyInputConnection = new BaseInputConnection(this, false);
@@ -1214,6 +1245,8 @@ public final class InputMethodManager {
mBindSequence = res.sequence;
mCurMethod = res.method;
mCurId = res.id;
+ mNextUserActionNotificationSequenceNumber =
+ res.userActionNotificationSequenceNumber;
} else {
if (res.channel != null && res.channel != mCurChannel) {
res.channel.dispose();
@@ -1918,8 +1951,28 @@ public final class InputMethodManager {
*/
public void notifyUserAction() {
synchronized (mH) {
+ if (mLastSentUserActionNotificationSequenceNumber ==
+ mNextUserActionNotificationSequenceNumber) {
+ if (DEBUG) {
+ Log.w(TAG, "Ignoring notifyUserAction as it has already been sent."
+ + " mLastSentUserActionNotificationSequenceNumber: "
+ + mLastSentUserActionNotificationSequenceNumber
+ + " mNextUserActionNotificationSequenceNumber: "
+ + mNextUserActionNotificationSequenceNumber);
+ }
+ return;
+ }
try {
- mService.notifyUserAction();
+ if (DEBUG) {
+ Log.w(TAG, "notifyUserAction: "
+ + " mLastSentUserActionNotificationSequenceNumber: "
+ + mLastSentUserActionNotificationSequenceNumber
+ + " mNextUserActionNotificationSequenceNumber: "
+ + mNextUserActionNotificationSequenceNumber);
+ }
+ mService.notifyUserAction(mNextUserActionNotificationSequenceNumber);
+ mLastSentUserActionNotificationSequenceNumber =
+ mNextUserActionNotificationSequenceNumber;
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
}
@@ -2103,6 +2156,10 @@ public final class InputMethodManager {
+ " mCursorSelEnd=" + mCursorSelEnd
+ " mCursorCandStart=" + mCursorCandStart
+ " mCursorCandEnd=" + mCursorCandEnd);
+ p.println(" mNextUserActionNotificationSequenceNumber="
+ + mNextUserActionNotificationSequenceNumber
+ + " mLastSentUserActionNotificationSequenceNumber="
+ + mLastSentUserActionNotificationSequenceNumber);
}
/**
diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl
index 9e8d12b..b100d27 100644
--- a/core/java/com/android/internal/view/IInputMethodClient.aidl
+++ b/core/java/com/android/internal/view/IInputMethodClient.aidl
@@ -28,4 +28,5 @@ oneway interface IInputMethodClient {
void onUnbindMethod(int sequence);
void setActive(boolean active);
void setCursorAnchorMonitorMode(int monitorMode);
+ void setUserActionNotificationSequenceNumber(int sequenceNumber);
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 4590520..b84c359 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -77,6 +77,6 @@ interface IInputMethodManager {
boolean setInputMethodEnabled(String id, boolean enabled);
void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
int getInputMethodWindowVisibleHeight();
- oneway void notifyUserAction();
+ oneway void notifyUserAction(int sequenceNumber);
void setCursorAnchorMonitorMode(in IBinder token, int monitorMode);
}
diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java
index 14afe21..3a3e56d 100644
--- a/core/java/com/android/internal/view/InputBindResult.java
+++ b/core/java/com/android/internal/view/InputBindResult.java
@@ -47,13 +47,19 @@ public final class InputBindResult implements Parcelable {
* Sequence number of this binding.
*/
public final int sequence;
-
+
+ /**
+ * Sequence number of user action notification.
+ */
+ public final int userActionNotificationSequenceNumber;
+
public InputBindResult(IInputMethodSession _method, InputChannel _channel,
- String _id, int _sequence) {
+ String _id, int _sequence, int _userActionNotificationSequenceNumber) {
method = _method;
channel = _channel;
id = _id;
sequence = _sequence;
+ userActionNotificationSequenceNumber = _userActionNotificationSequenceNumber;
}
InputBindResult(Parcel source) {
@@ -65,12 +71,15 @@ public final class InputBindResult implements Parcelable {
}
id = source.readString();
sequence = source.readInt();
+ userActionNotificationSequenceNumber = source.readInt();
}
@Override
public String toString() {
return "InputBindResult{" + method + " " + id
- + " #" + sequence + "}";
+ + " sequence:" + sequence
+ + " userActionNotificationSequenceNumber:" + userActionNotificationSequenceNumber
+ + "}";
}
/**
@@ -90,6 +99,7 @@ public final class InputBindResult implements Parcelable {
}
dest.writeString(id);
dest.writeInt(sequence);
+ dest.writeInt(userActionNotificationSequenceNumber);
}
/**
diff --git a/core/java/com/android/server/SystemService.java b/core/java/com/android/server/SystemService.java
index bf36bb1..43a05d0 100644
--- a/core/java/com/android/server/SystemService.java
+++ b/core/java/com/android/server/SystemService.java
@@ -193,58 +193,4 @@ public abstract class SystemService {
private SystemServiceManager getManager() {
return LocalServices.getService(SystemServiceManager.class);
}
-
-// /**
-// * Called when a new user has been created. If your service deals with multiple users, this
-// * method should be overridden.
-// *
-// * @param userHandle The user that was created.
-// */
-// public void onUserCreated(int userHandle) {
-// }
-//
-// /**
-// * Called when an existing user has started a new session. If your service deals with multiple
-// * users, this method should be overridden.
-// *
-// * @param userHandle The user who started a new session.
-// */
-// public void onUserStarted(int userHandle) {
-// }
-//
-// /**
-// * Called when a background user session has entered the foreground. If your service deals with
-// * multiple users, this method should be overridden.
-// *
-// * @param userHandle The user who's session entered the foreground.
-// */
-// public void onUserForeground(int userHandle) {
-// }
-//
-// /**
-// * Called when a foreground user session has entered the background. If your service deals with
-// * multiple users, this method should be overridden;
-// *
-// * @param userHandle The user who's session entered the background.
-// */
-// public void onUserBackground(int userHandle) {
-// }
-//
-// /**
-// * Called when a user's active session has stopped. If your service deals with multiple users,
-// * this method should be overridden.
-// *
-// * @param userHandle The user who's session has stopped.
-// */
-// public void onUserStopped(int userHandle) {
-// }
-//
-// /**
-// * Called when a user has been removed from the system. If your service deals with multiple
-// * users, this method should be overridden.
-// *
-// * @param userHandle The user who has been removed.
-// */
-// public void onUserRemoved(int userHandle) {
-// }
}