Merge "media: VideoCapabilities: publish codec performance data"
diff --git a/api/current.txt b/api/current.txt
index dee6874..f25edb1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1723,6 +1723,7 @@
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
field public static final int selectedIcon = 16908302; // 0x102000e
+ field public static final int shareText = 16908343; // 0x1020037
field public static final int startSelectingText = 16908328; // 0x1020028
field public static final int statusBarBackground = 16908335; // 0x102002f
field public static final int stopSelectingText = 16908329; // 0x1020029
@@ -5651,6 +5652,7 @@
method public void onProfileProvisioningComplete(android.content.Context, android.content.Intent);
method public void onReadyForUserInitialization(android.content.Context, android.content.Intent);
method public void onReceive(android.content.Context, android.content.Intent);
+ method public void onSystemUpdatePending(android.content.Context, android.content.Intent, long);
field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
field public static final java.lang.String ACTION_DEVICE_ADMIN_ENABLED = "android.app.action.DEVICE_ADMIN_ENABLED";
@@ -15294,7 +15296,9 @@
method public final void releaseOutputBuffer(int, boolean);
method public final void releaseOutputBuffer(int, long);
method public final void reset();
+ method public void setCallback(android.media.MediaCodec.Callback, android.os.Handler);
method public void setCallback(android.media.MediaCodec.Callback);
+ method public void setOnFrameRenderedListener(android.media.MediaCodec.OnFrameRenderedListener, android.os.Handler);
method public final void setParameters(android.os.Bundle);
method public final void setVideoScalingMode(int);
method public final void signalEndOfInputStream();
@@ -15363,6 +15367,10 @@
field public int numSubSamples;
}
+ public static abstract interface MediaCodec.OnFrameRenderedListener {
+ method public abstract void onFrameRendered(android.media.MediaCodec, long, long);
+ }
+
public final class MediaCodecInfo {
method public final android.media.MediaCodecInfo.CodecCapabilities getCapabilitiesForType(java.lang.String);
method public final java.lang.String getName();
@@ -18269,11 +18277,8 @@
method public void reportNetworkConnectivity(android.net.Network, boolean);
method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
- method public deprecated boolean requestRouteToHost(int, int);
method public deprecated void setNetworkPreference(int);
method public static deprecated boolean setProcessDefaultNetwork(android.net.Network);
- method public deprecated int startUsingNetworkFeature(int, java.lang.String);
- method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
@@ -18292,9 +18297,9 @@
field public static final int TYPE_ETHERNET = 9; // 0x9
field public static final int TYPE_MOBILE = 0; // 0x0
field public static final int TYPE_MOBILE_DUN = 4; // 0x4
- field public static final int TYPE_MOBILE_HIPRI = 5; // 0x5
- field public static final int TYPE_MOBILE_MMS = 2; // 0x2
- field public static final int TYPE_MOBILE_SUPL = 3; // 0x3
+ field public static final deprecated int TYPE_MOBILE_HIPRI = 5; // 0x5
+ field public static final deprecated int TYPE_MOBILE_MMS = 2; // 0x2
+ field public static final deprecated int TYPE_MOBILE_SUPL = 3; // 0x3
field public static final int TYPE_VPN = 17; // 0x11
field public static final int TYPE_WIFI = 1; // 0x1
field public static final int TYPE_WIMAX = 6; // 0x6
diff --git a/api/removed.txt b/api/removed.txt
index 326b05d..a722e17 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -35,6 +35,13 @@
package android.net {
+ public class ConnectivityManager {
+ method public deprecated boolean requestRouteToHost(int, int);
+ method public deprecated boolean requestRouteToHostAddress(int, java.net.InetAddress);
+ method public deprecated int startUsingNetworkFeature(int, java.lang.String);
+ method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
+ }
+
public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index e38d91b..fc85475 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1800,6 +1800,7 @@
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
field public static final int selectedIcon = 16908302; // 0x102000e
+ field public static final int shareText = 16908343; // 0x1020037
field public static final int startSelectingText = 16908328; // 0x1020028
field public static final int statusBarBackground = 16908335; // 0x102002f
field public static final int stopSelectingText = 16908329; // 0x1020029
@@ -5746,6 +5747,7 @@
method public void onProfileProvisioningComplete(android.content.Context, android.content.Intent);
method public void onReadyForUserInitialization(android.content.Context, android.content.Intent);
method public void onReceive(android.content.Context, android.content.Intent);
+ method public void onSystemUpdatePending(android.content.Context, android.content.Intent, long);
field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
field public static final java.lang.String ACTION_DEVICE_ADMIN_ENABLED = "android.app.action.DEVICE_ADMIN_ENABLED";
@@ -5851,6 +5853,7 @@
method public boolean isProfileOwnerApp(java.lang.String);
method public boolean isUninstallBlocked(android.content.ComponentName, java.lang.String);
method public void lockNow();
+ method public void notifyPendingSystemUpdate(long);
method public void removeActiveAdmin(android.content.ComponentName);
method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
@@ -16506,7 +16509,9 @@
method public final void releaseOutputBuffer(int, boolean);
method public final void releaseOutputBuffer(int, long);
method public final void reset();
+ method public void setCallback(android.media.MediaCodec.Callback, android.os.Handler);
method public void setCallback(android.media.MediaCodec.Callback);
+ method public void setOnFrameRenderedListener(android.media.MediaCodec.OnFrameRenderedListener, android.os.Handler);
method public final void setParameters(android.os.Bundle);
method public final void setVideoScalingMode(int);
method public final void signalEndOfInputStream();
@@ -16575,6 +16580,10 @@
field public int numSubSamples;
}
+ public static abstract interface MediaCodec.OnFrameRenderedListener {
+ method public abstract void onFrameRendered(android.media.MediaCodec, long, long);
+ }
+
public final class MediaCodecInfo {
method public final android.media.MediaCodecInfo.CodecCapabilities getCapabilitiesForType(java.lang.String);
method public final java.lang.String getName();
@@ -19727,11 +19736,8 @@
method public void reportNetworkConnectivity(android.net.Network, boolean);
method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
- method public deprecated boolean requestRouteToHost(int, int);
method public deprecated void setNetworkPreference(int);
method public static deprecated boolean setProcessDefaultNetwork(android.net.Network);
- method public deprecated int startUsingNetworkFeature(int, java.lang.String);
- method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
@@ -19750,9 +19756,9 @@
field public static final int TYPE_ETHERNET = 9; // 0x9
field public static final int TYPE_MOBILE = 0; // 0x0
field public static final int TYPE_MOBILE_DUN = 4; // 0x4
- field public static final int TYPE_MOBILE_HIPRI = 5; // 0x5
- field public static final int TYPE_MOBILE_MMS = 2; // 0x2
- field public static final int TYPE_MOBILE_SUPL = 3; // 0x3
+ field public static final deprecated int TYPE_MOBILE_HIPRI = 5; // 0x5
+ field public static final deprecated int TYPE_MOBILE_MMS = 2; // 0x2
+ field public static final deprecated int TYPE_MOBILE_SUPL = 3; // 0x3
field public static final int TYPE_VPN = 17; // 0x11
field public static final int TYPE_WIFI = 1; // 0x1
field public static final int TYPE_WIMAX = 6; // 0x6
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 326b05d..a722e17 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -35,6 +35,13 @@
package android.net {
+ public class ConnectivityManager {
+ method public deprecated boolean requestRouteToHost(int, int);
+ method public deprecated boolean requestRouteToHostAddress(int, java.net.InetAddress);
+ method public deprecated int startUsingNetworkFeature(int, java.lang.String);
+ method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
+ }
+
public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
}
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index fe284ce..aea413d 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -264,6 +264,20 @@
public static final String EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE = "android.app.extra.CHOOSE_PRIVATE_KEY_RESPONSE";
/**
+ * Broadcast action: notify device owner that there is a pending system update.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_NOTIFY_PENDING_SYSTEM_UPDATE = "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE";
+
+ /**
+ * A long type extra for {@link #onSystemUpdatePending} recording the system time as given by
+ * {@link System#currentTimeMillis()} when the current pending system update is first available.
+ * @hide
+ */
+ public static final String EXTRA_SYSTEM_UPDATE_RECEIVED_TIME = "android.app.extra.SYSTEM_UPDATE_RECEIVED_TIME";
+
+ /**
* Name under which a DevicePolicy component publishes information
* about itself. This meta-data must reference an XML resource containing
* a device-admin tag.
@@ -486,6 +500,22 @@
}
/**
+ * Allows the receiver to be notified when information about a pending system update is
+ * available from the system update service. The same pending system update can trigger multiple
+ * calls to this method, so it is necessary to examine the incoming parameters for details about
+ * the update.
+ * <p>
+ * This callback is only applicable to device owners.
+ *
+ * @param context The running context as per {@link #onReceive}.
+ * @param intent The received intent as per {@link #onReceive}.
+ * @param receivedTime The time as given by {@link System#currentTimeMillis()} indicating when
+ * the current pending update was first available. -1 if no pending update is available.
+ */
+ public void onSystemUpdatePending(Context context, Intent intent, long receivedTime) {
+ }
+
+ /**
* Intercept standard device administrator broadcasts. Implementations
* should not override this method; it is better to implement the
* convenience callbacks for each action.
@@ -530,6 +560,9 @@
onLockTaskModeExiting(context, intent);
} else if (ACTION_READY_FOR_USER_INITIALIZATION.equals(action)) {
onReadyForUserInitialization(context, intent);
+ } else if (ACTION_NOTIFY_PENDING_SYSTEM_UPDATE.equals(action)) {
+ long receivedTime = intent.getLongExtra(EXTRA_SYSTEM_UPDATE_RECEIVED_TIME, -1);
+ onSystemUpdatePending(context, intent, receivedTime);
}
}
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9e2da61..a20aa668 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -4301,4 +4301,24 @@
Log.w(TAG, "Failed talking with device policy service", re);
}
}
+
+ /**
+ * Callable by the system update service to notify device owners about pending updates.
+ * The caller must hold {@link android.Manifest.permission#NOTIFY_PENDING_SYSTEM_UPDATE}
+ * permission.
+ *
+ * @param updateReceivedTime The time as given by {@link System#currentTimeMillis()} indicating
+ * when the current pending update was first available. -1 if no update is available.
+ * @hide
+ */
+ @SystemApi
+ public void notifyPendingSystemUpdate(long updateReceivedTime) {
+ if (mService != null) {
+ try {
+ mService.notifyPendingSystemUpdate(updateReceivedTime);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not notify device owner about pending system update", re);
+ }
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 1f7498e..087fc88 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -225,4 +225,6 @@
boolean setKeyguardEnabledState(in ComponentName admin, boolean enabled);
void setStatusBarEnabledState(in ComponentName who, boolean enabled);
boolean getDoNotAskCredentialsOnBoot();
+
+ void notifyPendingSystemUpdate(in long updateReceivedTime);
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a48b324..63f48cf 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -305,6 +305,9 @@
* same network interface as {@link #TYPE_MOBILE} or it may use a different
* one. This is used by applications needing to talk to the carrier's
* Multimedia Messaging Service servers.
+ *
+ * @deprecated Applications should instead use {@link #requestNetwork} to request a network that
+ * provides the {@link NetworkCapabilities#NET_CAPABILITY_MMS} capability.
*/
public static final int TYPE_MOBILE_MMS = 2;
/**
@@ -312,6 +315,9 @@
* same network interface as {@link #TYPE_MOBILE} or it may use a different
* one. This is used by applications needing to talk to the carrier's
* Secure User Plane Location servers for help locating the device.
+ *
+ * @deprecated Applications should instead use {@link #requestNetwork} to request a network that
+ * provides the {@link NetworkCapabilities#NET_CAPABILITY_SUPL} capability.
*/
public static final int TYPE_MOBILE_SUPL = 3;
/**
@@ -324,9 +330,10 @@
/**
* A High Priority Mobile data connection. This network type uses the
* same network interface as {@link #TYPE_MOBILE} but the routing setup
- * is different. Only requesting processes will have access to the
- * Mobile DNS servers and only IP's explicitly requested via {@link #requestRouteToHost}
- * will route over this interface if no default route exists.
+ * is different.
+ *
+ * @deprecated Applications should instead use {@link #requestNetwork} to request a network that
+ * uses the {@link NetworkCapabilities#TRANSPORT_CELLULAR} transport.
*/
public static final int TYPE_MOBILE_HIPRI = 5;
/**
@@ -386,7 +393,7 @@
*/
public static final int TYPE_MOBILE_IA = 14;
-/**
+ /**
* Emergency PDN connection for emergency calls
* {@hide}
*/
@@ -736,7 +743,7 @@
}
/**
- * Returns an array of of {@link NetworkCapabilities} objects, representing
+ * Returns an array of {@link android.net.NetworkCapabilities} objects, representing
* the Networks that applications run by the given user will use by default.
* @hide
*/
@@ -826,11 +833,11 @@
}
/**
- * Get the {@link NetworkCapabilities} for the given {@link Network}. This
+ * Get the {@link android.net.NetworkCapabilities} for the given {@link Network}. This
* will return {@code null} if the network is unknown.
*
* @param network The {@link Network} object identifying the network in question.
- * @return The {@link NetworkCapabilities} for the network, or {@code null}.
+ * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}.
*/
public NetworkCapabilities getNetworkCapabilities(Network network) {
try {
@@ -854,6 +861,7 @@
* always indicates failure.
*
* @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
+ * @removed
*/
public int startUsingNetworkFeature(int networkType, String feature) {
NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
@@ -901,6 +909,7 @@
* always indicates failure.
*
* @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
+ * @removed
*/
public int stopUsingNetworkFeature(int networkType, String feature) {
NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
@@ -1179,6 +1188,7 @@
*
* @deprecated Deprecated in favor of the {@link #requestNetwork},
* {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} api.
+ * @removed
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
@@ -1197,6 +1207,7 @@
* @hide
* @deprecated Deprecated in favor of the {@link #requestNetwork} and
* {@link #bindProcessToNetwork} api.
+ * @removed
*/
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
try {
@@ -2057,7 +2068,7 @@
* changes capabilities but still satisfies the stated need.
*
* @param network The {@link Network} whose capabilities have changed.
- * @param networkCapabilities The new {@link NetworkCapabilities} for this network.
+ * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this network.
*/
public void onCapabilitiesChanged(Network network,
NetworkCapabilities networkCapabilities) {}
@@ -2299,7 +2310,7 @@
}
/**
- * Request a network to satisfy a set of {@link NetworkCapabilities}.
+ * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
*
* This {@link NetworkRequest} will live until released via
* {@link #unregisterNetworkCallback} or the calling application exits.
@@ -2318,7 +2329,7 @@
}
/**
- * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
+ * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
* by a timeout.
*
* This function behaves identically to the non-timedout version, but if a suitable
@@ -2365,7 +2376,7 @@
/**
- * Request a network to satisfy a set of {@link NetworkCapabilities}.
+ * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
*
* This function behaves identically to the version that takes a NetworkCallback, but instead
* of {@link NetworkCallback} a {@link PendingIntent} is used. This means
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 954fc1d..b049e49 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3079,6 +3079,12 @@
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
+ if (mTextView.canShare()) {
+ menu.add(0, TextView.ID_SHARE, 0, com.android.internal.R.string.share).
+ setShowAsAction(
+ MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ }
+
menu.add(0, TextView.ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
setAlphabeticShortcut('a').
setShowAsAction(
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 726b89a..3e8df08 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8955,13 +8955,14 @@
static final int ID_CUT = android.R.id.cut;
static final int ID_COPY = android.R.id.copy;
static final int ID_PASTE = android.R.id.paste;
+ static final int ID_SHARE = android.R.id.shareText;
static final int ID_PASTE_AS_PLAIN_TEXT = android.R.id.pasteAsPlainText;
static final int ID_REPLACE = android.R.id.replaceText;
/**
* Called when a context menu option for the text view is selected. Currently
* this will be one of {@link android.R.id#selectAll}, {@link android.R.id#cut},
- * {@link android.R.id#copy} or {@link android.R.id#paste}.
+ * {@link android.R.id#copy}, {@link android.R.id#paste} or {@link android.R.id#shareText}.
*
* @return true if the context menu item action was performed.
*/
@@ -9014,6 +9015,10 @@
setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
stopSelectionActionMode();
return true;
+
+ case ID_SHARE:
+ shareSelectedText();
+ return true;
}
return false;
}
@@ -9091,15 +9096,15 @@
* If provided, this ActionMode.Callback will be used to create the ActionMode when text
* selection is initiated in this View.
*
- * The standard implementation populates the menu with a subset of Select All, Cut, Copy and
- * Paste actions, depending on what this View supports.
+ * The standard implementation populates the menu with a subset of Select All, Cut, Copy,
+ * Paste and Share actions, depending on what this View supports.
*
* A custom implementation can add new entries in the default menu in its
* {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The
* default actions can also be removed from the menu using
* {@link android.view.Menu#removeItem(int)} and passing {@link android.R.id#selectAll},
- * {@link android.R.id#cut}, {@link android.R.id#copy} or {@link android.R.id#paste} ids as
- * parameters.
+ * {@link android.R.id#cut}, {@link android.R.id#copy}, {@link android.R.id#paste} or
+ * {@link android.R.id#shareText} ids as parameters.
*
* Returning false from
* {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, Menu)} will prevent
@@ -9168,6 +9173,10 @@
return false;
}
+ boolean canShare() {
+ return canCopy();
+ }
+
boolean canPaste() {
return (mText instanceof Editable &&
mEditor != null && mEditor.mKeyListener != null &&
@@ -9241,6 +9250,18 @@
}
}
+ private void shareSelectedText() {
+ String selectedText = getSelectedText();
+ if (selectedText != null && !selectedText.isEmpty()) {
+ Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
+ sharingIntent.setType("text/plain");
+ sharingIntent.removeExtra(android.content.Intent.EXTRA_TEXT);
+ sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, selectedText);
+ getContext().startActivity(Intent.createChooser(sharingIntent, null));
+ stopSelectionActionMode();
+ }
+ }
+
private void setPrimaryClip(ClipData clip) {
ClipboardManager clipboard = (ClipboardManager) getContext().
getSystemService(Context.CLIPBOARD_SERVICE);
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index a14e98d..579cad4 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -346,6 +346,17 @@
};
private final Region mTouchableRegion = new Region();
+ private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer =
+ new ViewTreeObserver.OnComputeInternalInsetsListener() {
+ public void onComputeInternalInsets(
+ ViewTreeObserver.InternalInsetsInfo info) {
+ info.contentInsets.setEmpty();
+ info.visibleInsets.setEmpty();
+ info.touchableRegion.set(mTouchableRegion);
+ info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo
+ .TOUCHABLE_INSETS_REGION);
+ }
+ };
private boolean mDismissed = true; // tracks whether this popup is dismissed or dismissing.
private boolean mHidden; // tracks whether this popup is hidden or hiding.
@@ -382,21 +393,6 @@
mPopupWindow.dismiss();
}
});
- // Make the touchable area of this popup be the area specified by mTouchableRegion.
- mPopupWindow.getContentView()
- .getRootView()
- .getViewTreeObserver()
- .addOnComputeInternalInsetsListener(
- new ViewTreeObserver.OnComputeInternalInsetsListener() {
- public void onComputeInternalInsets(
- ViewTreeObserver.InternalInsetsInfo info) {
- info.contentInsets.setEmpty();
- info.visibleInsets.setEmpty();
- info.touchableRegion.set(mTouchableRegion);
- info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo
- .TOUCHABLE_INSETS_REGION);
- }
- });
mMarginHorizontal = parent.getResources()
.getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
mMarginVertical = parent.getResources()
@@ -447,6 +443,7 @@
// The "show" animation will make this visible.
mContentContainer.setAlpha(0);
mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, x, y);
+ setTouchableSurfaceInsetsComputer();
runShowAnimation();
}
@@ -804,6 +801,19 @@
(int) mContentContainer.getX() + width,
(int) mContentContainer.getY() + height);
}
+
+ /**
+ * Make the touchable area of this popup be the area specified by mTouchableRegion.
+ * This should be called after the popup window has been dismissed (dismiss/hide)
+ * and is probably being re-shown with a new content root view.
+ */
+ private void setTouchableSurfaceInsetsComputer() {
+ ViewTreeObserver viewTreeObserver = mPopupWindow.getContentView()
+ .getRootView()
+ .getViewTreeObserver();
+ viewTreeObserver.removeOnComputeInternalInsetsListener(mInsetsComputer);
+ viewTreeObserver.addOnComputeInternalInsetsListener(mInsetsComputer);
+ }
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index fa5e4ad..62685a1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1116,6 +1116,11 @@
<permission android:name="android.permission.ACCESS_PDB_STATE"
android:protectionLevel="signature" />
+ <!-- @hide Allows system update service to notify device owner about pending updates.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.NOTIFY_PENDING_SYSTEM_UPDATE"
+ android:protectionLevel="signatureOrSystem" />
+
<!-- =========================================== -->
<!-- Permissions associated with camera and image capture -->
<!-- =========================================== -->
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index aaf252a..bdc8d9f 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -93,6 +93,7 @@
<item type="id" name="undo" />
<item type="id" name="redo" />
<item type="id" name="replaceText" />
+ <item type="id" name="shareText" />
<!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SHOW_ON_SCREEN}. -->
<item type="id" name="accessibilityActionShowOnScreen" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7252584..0b4320c 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2650,6 +2650,7 @@
<public type="id" name="replaceText" />
<public type="id" name="accessibilityActionShowOnScreen" />
<public type="id" name="accessibilityActionScrollToPosition" />
+ <public type="id" name="shareText" />
<public type="attr" name="allowUndo" />
<public type="attr" name="colorBackgroundFloating" />
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index a9a8f37..f036b19 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.CheckResult;
import android.os.Parcel;
import android.os.Parcelable;
@@ -389,6 +390,7 @@
* (and this rectangle is then set to that intersection) else
* return false and do not change this rectangle.
*/
+ @CheckResult
public boolean intersect(int left, int top, int right, int bottom) {
if (this.left < right && left < this.right && this.top < bottom && top < this.bottom) {
if (this.left < left) this.left = left;
@@ -411,6 +413,7 @@
* (and this rectangle is then set to that intersection) else
* return false and do not change this rectangle.
*/
+ @CheckResult
public boolean intersect(Rect r) {
return intersect(r.left, r.top, r.right, r.bottom);
}
@@ -427,6 +430,7 @@
* this rectangle to that intersection. If they do not, return
* false and do not change this rectangle.
*/
+ @CheckResult
public boolean setIntersect(Rect a, Rect b) {
if (a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom) {
left = Math.max(a.left, b.left);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index b0cd3e4..bb9b6db 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -300,6 +300,14 @@
*/
@BufferFlag
public int flags;
+
+ /** @hide */
+ @NonNull
+ public BufferInfo dup() {
+ BufferInfo copy = new BufferInfo();
+ copy.set(offset, size, presentationTimeUs, flags);
+ return copy;
+ }
};
// The follow flag constants MUST stay in sync with their equivalents
@@ -343,11 +351,25 @@
@Retention(RetentionPolicy.SOURCE)
public @interface BufferFlag {}
+ private static class FrameRenderedInfo {
+ public long mPresentationTimeUs;
+ public long mNanoTime;
+ public FrameRenderedInfo(long presentationTimeUs, long nanoTime) {
+ mPresentationTimeUs = presentationTimeUs;
+ mNanoTime = nanoTime;
+ }
+ }
+
private EventHandler mEventHandler;
+ private EventHandler mOnFrameRenderedHandler;
+ private EventHandler mCallbackHandler;
private Callback mCallback;
+ private OnFrameRenderedListener mOnFrameRenderedListener;
+ private Object mListenerLock = new Object();
private static final int EVENT_CALLBACK = 1;
private static final int EVENT_SET_CALLBACK = 2;
+ private static final int EVENT_FRAME_RENDERED = 3;
private static final int CB_INPUT_AVAILABLE = 1;
private static final int CB_OUTPUT_AVAILABLE = 2;
@@ -375,6 +397,15 @@
mCallback = (MediaCodec.Callback) msg.obj;
break;
}
+ case EVENT_FRAME_RENDERED:
+ synchronized (mListenerLock) {
+ FrameRenderedInfo info = (FrameRenderedInfo)msg.obj;
+ if (mOnFrameRenderedListener != null) {
+ mOnFrameRenderedListener.onFrameRendered(
+ mCodec, info.mPresentationTimeUs, info.mNanoTime);
+ }
+ break;
+ }
default:
{
break;
@@ -431,6 +462,8 @@
}
}
+ private boolean mHasSurface = false;
+
/**
* Instantiate a decoder supporting input data of the given mime type.
*
@@ -501,6 +534,9 @@
} else {
mEventHandler = null;
}
+ mCallbackHandler = mEventHandler;
+ mOnFrameRenderedHandler = mEventHandler;
+
mBufferLock = new Object();
native_setup(name, nameIsType, encoder);
@@ -607,6 +643,8 @@
}
}
+ mHasSurface = surface != null;
+
native_configure(keys, values, surface, crypto, flags);
}
@@ -662,9 +700,14 @@
native_stop();
freeAllTrackedBuffers();
- if (mEventHandler != null) {
- mEventHandler.removeMessages(EVENT_CALLBACK);
- mEventHandler.removeMessages(EVENT_SET_CALLBACK);
+ synchronized (mListenerLock) {
+ if (mCallbackHandler != null) {
+ mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
+ mCallbackHandler.removeMessages(EVENT_CALLBACK);
+ }
+ if (mOnFrameRenderedHandler != null) {
+ mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
+ }
}
}
@@ -1124,6 +1167,9 @@
cacheBuffers(false /* input */);
} else if (res >= 0) {
validateOutputByteBuffer(mCachedOutputBuffers, res, info);
+ if (mHasSurface) {
+ mDequeuedOutputInfos.put(res, info.dup());
+ }
}
}
return res;
@@ -1150,13 +1196,34 @@
* @throws MediaCodec.CodecException upon codec error.
*/
public final void releaseOutputBuffer(int index, boolean render) {
+ BufferInfo info = null;
synchronized(mBufferLock) {
invalidateByteBuffer(mCachedOutputBuffers, index);
mDequeuedOutputBuffers.remove(index);
+ if (mHasSurface) {
+ info = mDequeuedOutputInfos.remove(index);
+ }
}
+ // TODO
+ // until codec and libgui supports callback, assume frame is rendered within 50 ms
+ postRenderedCallback(render, info, 50 /* delayMs */);
releaseOutputBuffer(index, render, false /* updatePTS */, 0 /* dummy */);
}
+ private void postRenderedCallback(boolean render, @Nullable BufferInfo info, long delayMs) {
+ if (render && info != null) {
+ synchronized (mListenerLock) {
+ if (mOnFrameRenderedListener != null) {
+ FrameRenderedInfo obj = new FrameRenderedInfo(
+ info.presentationTimeUs, System.nanoTime() + delayMs * 1000000);
+ Message msg = mOnFrameRenderedHandler.obtainMessage(
+ EVENT_FRAME_RENDERED, obj);
+ mOnFrameRenderedHandler.sendMessageDelayed(msg, delayMs);
+ }
+ }
+ }
+ }
+
/**
* If you are done with a buffer, use this call to update its surface timestamp
* and return it to the codec to render it on the output surface. If you
@@ -1207,10 +1274,20 @@
* @throws MediaCodec.CodecException upon codec error.
*/
public final void releaseOutputBuffer(int index, long renderTimestampNs) {
+ BufferInfo info = null;
synchronized(mBufferLock) {
invalidateByteBuffer(mCachedOutputBuffers, index);
mDequeuedOutputBuffers.remove(index);
+ if (mHasSurface) {
+ info = mDequeuedOutputInfos.remove(index);
+ }
}
+ // TODO
+ // until codec and libgui supports callback, assume frame is rendered at the
+ // render time or 16 ms from now, whichever is later.
+ postRenderedCallback(
+ true /* render */, info,
+ Math.max(renderTimestampNs - System.nanoTime(), 16666666) / 1000000);
releaseOutputBuffer(
index, true /* render */, true /* updatePTS */, renderTimestampNs);
}
@@ -1350,6 +1427,8 @@
private ByteBuffer[] mCachedOutputBuffers;
private final BufferMap mDequeuedInputBuffers = new BufferMap();
private final BufferMap mDequeuedOutputBuffers = new BufferMap();
+ private final Map<Integer, BufferInfo> mDequeuedOutputInfos =
+ new HashMap<Integer, BufferInfo>();
final private Object mBufferLock;
private final void invalidateByteBuffer(
@@ -1715,21 +1794,121 @@
* @param cb The callback that will run. Use {@code null} to clear a previously
* set callback (before {@link #configure configure} is called and run
* in synchronous mode).
+ * @param handler Callbacks will happen on the handler's thread. If {@code null},
+ * callbacks are done on the default thread (the caller's thread or the
+ * main thread.)
*/
- public void setCallback(@Nullable /* MediaCodec. */ Callback cb) {
- if (mEventHandler != null) {
- // set java callback on handler
- Message msg = mEventHandler.obtainMessage(EVENT_SET_CALLBACK, 0, 0, cb);
- mEventHandler.sendMessage(msg);
+ public void setCallback(@Nullable /* MediaCodec. */ Callback cb, @Nullable Handler handler) {
+ if (cb != null) {
+ synchronized (mListenerLock) {
+ EventHandler newHandler = getEventHandlerOn(handler, mCallbackHandler);
+ // NOTE: there are no callbacks on the handler at this time, but check anyways
+ // even if we were to extend this to be callable dynamically, it must
+ // be called when codec is flushed, so no messages are pending.
+ if (newHandler != mCallbackHandler) {
+ mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
+ mCallbackHandler.removeMessages(EVENT_CALLBACK);
+ mCallbackHandler = newHandler;
+ }
+ }
+ } else if (mCallbackHandler != null) {
+ mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
+ mCallbackHandler.removeMessages(EVENT_CALLBACK);
+ }
+
+ if (mCallbackHandler != null) {
+ // set java callback on main handler
+ Message msg = mCallbackHandler.obtainMessage(EVENT_SET_CALLBACK, 0, 0, cb);
+ mCallbackHandler.sendMessage(msg);
// set native handler here, don't post to handler because
- // it may cause the callback to be delayed and set in a wrong state,
- // and MediaCodec is already doing it on looper.
+ // it may cause the callback to be delayed and set in a wrong state.
+ // Note that native codec may start sending events to the callback
+ // handler after this returns.
native_setCallback(cb);
}
}
/**
+ * Sets an asynchronous callback for actionable MediaCodec events on the default
+ * looper.
+ * <p>
+ * Same as {@link #setCallback(Callback, Handler)} with handler set to null.
+ * @param cb The callback that will run. Use {@code null} to clear a previously
+ * set callback (before {@link #configure configure} is called and run
+ * in synchronous mode).
+ * @see #setCallback(Callback, Handler)
+ */
+ public void setCallback(@Nullable /* MediaCodec. */ Callback cb) {
+ setCallback(cb, null /* handler */);
+ }
+
+ /**
+ * Listener to be called when an output frame has rendered on the output surface
+ *
+ * @see MediaCodec#setOnFrameRenderedListener
+ */
+ public interface OnFrameRenderedListener {
+
+ /**
+ * Called when an output frame has rendered on the output surface.
+ *
+ * @param codec the MediaCodec instance
+ * @param presentationTimeUs the presentation time (media time) of the frame rendered.
+ * This is usually the same as specified in {@link #queueInputBuffer}; however,
+ * some codecs may alter the media time by applying some time-based transformation,
+ * such as frame rate conversion. In that case, presentation time corresponds
+ * to the actual output frame rendered.
+ * @param nanoTime The system time when the frame was rendered.
+ *
+ * @see System#nanoTime
+ */
+ public void onFrameRendered(
+ @NonNull MediaCodec codec, long presentationTimeUs, long nanoTime);
+ }
+
+ /**
+ * Register a callback to be invoked when an output frame is rendered on the output surface.
+ * <p>
+ * This method can be called in any codec state, but will only have an effect in the
+ * Executing state for codecs that render buffers to the output surface.
+ *
+ * @param listener the callback that will be run
+ * @param handler the callback will be run on the handler's thread. If {@code null},
+ * the callback will be run on the default thread, which is the looper
+ * from which the codec was created, or a new thread if there was none.
+ */
+ public void setOnFrameRenderedListener(
+ @Nullable OnFrameRenderedListener listener, @Nullable Handler handler) {
+ synchronized (mListenerLock) {
+ mOnFrameRenderedListener = listener;
+ if (listener != null) {
+ EventHandler newHandler = getEventHandlerOn(handler, mOnFrameRenderedHandler);
+ if (newHandler != mOnFrameRenderedHandler) {
+ mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
+ }
+ mOnFrameRenderedHandler = newHandler;
+ } else if (mOnFrameRenderedHandler != null) {
+ mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
+ }
+ }
+ }
+
+ private EventHandler getEventHandlerOn(
+ @Nullable Handler handler, @NonNull EventHandler lastHandler) {
+ if (handler == null) {
+ return mEventHandler;
+ } else {
+ Looper looper = handler.getLooper();
+ if (lastHandler.getLooper() == looper) {
+ return lastHandler;
+ } else {
+ return new EventHandler(this, looper);
+ }
+ }
+ }
+
+ /**
* MediaCodec callback interface. Used to notify the user asynchronously
* of various MediaCodec events.
*/
@@ -1772,9 +1951,17 @@
private void postEventFromNative(
int what, int arg1, int arg2, @Nullable Object obj) {
- if (mEventHandler != null) {
- Message msg = mEventHandler.obtainMessage(what, arg1, arg2, obj);
- mEventHandler.sendMessage(msg);
+ synchronized (mListenerLock) {
+ EventHandler handler = mEventHandler;
+ if (what == EVENT_CALLBACK) {
+ handler = mCallbackHandler;
+ } else if (what == EVENT_FRAME_RENDERED) {
+ handler = mOnFrameRenderedHandler;
+ }
+ if (handler != null) {
+ Message msg = handler.obtainMessage(what, arg1, arg2, obj);
+ handler.sendMessage(msg);
+ }
}
}
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 9bdeb25..278d627 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -883,6 +883,10 @@
/**
* Called when the application sets playback rate and audio mode.
+ * <p>
+ * Once a playback rate is set, the implementation should honor the value until a new tune
+ * request. Pause/resume/seek request does not reset the playback rate previously set.
+ * </p>
*
* @param rate The ratio between desired playback rate and normal one.
* @param audioMode Audio playback mode. Must be one of the supported audio modes:
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index dc7fad6..80d075d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -22,6 +22,7 @@
import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
+import android.Manifest.permission;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accounts.AccountManager;
import android.app.Activity;
@@ -45,6 +46,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -6088,4 +6090,42 @@
}
return false;
}
+
+ @Override
+ public void notifyPendingSystemUpdate(long updateReceivedTime) {
+ mContext.enforceCallingOrSelfPermission(permission.NOTIFY_PENDING_SYSTEM_UPDATE,
+ "Only the system update service can broadcast update information");
+
+ if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
+ Slog.w(LOG_TAG, "Only the system update service in the primary user" +
+ "can broadcast update information.");
+ return;
+ }
+ Intent intent = new Intent(DeviceAdminReceiver.ACTION_NOTIFY_PENDING_SYSTEM_UPDATE);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_SYSTEM_UPDATE_RECEIVED_TIME,
+ updateReceivedTime);
+
+ synchronized (this) {
+ String deviceOwnerPackage = getDeviceOwner();
+ if (deviceOwnerPackage == null) {
+ return;
+ }
+
+ try {
+ ActivityInfo[] receivers = mContext.getPackageManager().getPackageInfo(
+ deviceOwnerPackage, PackageManager.GET_RECEIVERS).receivers;
+ if (receivers != null) {
+ for (int i = 0; i < receivers.length; i++) {
+ if (permission.BIND_DEVICE_ADMIN.equals(receivers[i].permission)) {
+ intent.setComponent(new ComponentName(deviceOwnerPackage,
+ receivers[i].name));
+ mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
+ }
+ }
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(LOG_TAG, "Cannot find device owner package", e);
+ }
+ }
+ }
}