Merge "Variant of sendBroadcast with appOp flag for cross-user."
diff --git a/api/current.txt b/api/current.txt
index 8e2c9f1..d3aaf2c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -29,7 +29,7 @@
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
field public static final java.lang.String BIND_ROUTE_PROVIDER = "android.permission.BIND_ROUTE_PROVIDER";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
- field public static final java.lang.String BIND_TRUST_AGENT_SERVICE = "android.permission.BIND_TRUST_AGENT_SERVICE";
+ field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
@@ -4515,6 +4515,7 @@
ctor public Notification.Action(int, java.lang.CharSequence, android.app.PendingIntent);
method public android.app.Notification.Action clone();
method public int describeContents();
+ method public android.os.Bundle getExtras();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
field public android.app.PendingIntent actionIntent;
@@ -4522,6 +4523,14 @@
field public java.lang.CharSequence title;
}
+ public static class Notification.Action.Builder {
+ ctor public Notification.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent);
+ ctor public Notification.Action.Builder(android.app.Notification.Action);
+ method public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
+ method public android.app.Notification.Action build();
+ method public android.os.Bundle getExtras();
+ }
+
public static class Notification.BigPictureStyle extends android.app.Notification.Style {
ctor public Notification.BigPictureStyle();
ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
@@ -4542,6 +4551,7 @@
public static class Notification.Builder {
ctor public Notification.Builder(android.content.Context);
method public android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent);
+ method public android.app.Notification.Builder addAction(android.app.Notification.Action);
method public android.app.Notification.Builder addExtras(android.os.Bundle);
method public android.app.Notification.Builder addPerson(java.lang.String);
method public android.app.Notification build();
@@ -12298,12 +12308,16 @@
field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE;
}
+}
+
+package android.hardware.camera2.params {
+
public final class ColorSpaceTransform {
- ctor public ColorSpaceTransform(android.hardware.camera2.Rational[]);
+ ctor public ColorSpaceTransform(android.util.Rational[]);
ctor public ColorSpaceTransform(int[]);
- method public void copyElements(android.hardware.camera2.Rational[], int);
+ method public void copyElements(android.util.Rational[], int);
method public void copyElements(int[], int);
- method public android.hardware.camera2.Rational getElement(int, int);
+ method public android.util.Rational getElement(int, int);
}
public final class Face {
@@ -12323,7 +12337,7 @@
method public int getColumnCount();
method public float getGainFactor(int, int, int);
method public int getGainFactorCount();
- method public android.hardware.camera2.RggbChannelVector getGainFactorVector(int, int);
+ method public android.hardware.camera2.params.RggbChannelVector getGainFactorVector(int, int);
method public int getRowCount();
field public static final float MINIMUM_GAIN_FACTOR = 1.0f;
}
@@ -12332,7 +12346,7 @@
ctor public MeteringRectangle(int, int, int, int, int);
ctor public MeteringRectangle(android.graphics.Point, android.util.Size, int);
ctor public MeteringRectangle(android.graphics.Rect, int);
- method public boolean equals(android.hardware.camera2.MeteringRectangle);
+ method public boolean equals(android.hardware.camera2.params.MeteringRectangle);
method public int getHeight();
method public int getMeteringWeight();
method public android.graphics.Rect getRect();
@@ -12343,12 +12357,6 @@
method public int getY();
}
- public final class Rational {
- ctor public Rational(int, int);
- method public int getDenominator();
- method public int getNumerator();
- }
-
public final class RggbChannelVector {
ctor public RggbChannelVector(float, float, float, float);
method public void copyTo(float[], int);
@@ -12364,10 +12372,17 @@
field public static final int RED = 0; // 0x0
}
- public final class Size {
- ctor public Size(int, int);
- method public final int getHeight();
- method public final int getWidth();
+ public final class StreamConfigurationMap {
+ method public final int[] getOutputFormats();
+ method public long getOutputMinFrameDuration(int, android.util.Size);
+ method public long getOutputMinFrameDuration(java.lang.Class<T>, android.util.Size);
+ method public android.util.Size[] getOutputSizes(java.lang.Class<T>);
+ method public android.util.Size[] getOutputSizes(int);
+ method public long getOutputStallDuration(int, android.util.Size);
+ method public long getOutputStallDuration(java.lang.Class<T>, android.util.Size);
+ method public boolean isOutputSupportedFor(int);
+ method public static boolean isOutputSupportedFor(java.lang.Class<T>);
+ method public boolean isOutputSupportedFor(android.view.Surface);
}
public final class TonemapCurve {
@@ -12384,23 +12399,6 @@
}
-package android.hardware.camera2.params {
-
- public final class StreamConfigurationMap {
- method public final int[] getOutputFormats();
- method public long getOutputMinFrameDuration(int, android.util.Size);
- method public long getOutputMinFrameDuration(java.lang.Class<T>, android.util.Size);
- method public android.util.Size[] getOutputSizes(java.lang.Class<T>);
- method public android.util.Size[] getOutputSizes(int);
- method public long getOutputStallDuration(int, android.util.Size);
- method public long getOutputStallDuration(java.lang.Class<T>, android.util.Size);
- method public boolean isOutputSupportedFor(int);
- method public static boolean isOutputSupportedFor(java.lang.Class<T>);
- method public boolean isOutputSupportedFor(android.view.Surface);
- }
-
-}
-
package android.hardware.display {
public final class DisplayManager {
@@ -12476,16 +12474,17 @@
field public static final int MESSAGE_FEATURE_ABORT = 0; // 0x0
field public static final int MESSAGE_GET_CEC_VERSION = 159; // 0x9f
field public static final int MESSAGE_GET_MENU_LANGUAGE = 145; // 0x91
- field public static final int MESSAGE_GET_OSD_NAME = 70; // 0x46
field public static final int MESSAGE_GIVE_AUDIO_STATUS = 113; // 0x71
field public static final int MESSAGE_GIVE_DECK_STATUS = 26; // 0x1a
field public static final int MESSAGE_GIVE_DEVICE_POWER_STATUS = 143; // 0x8f
field public static final int MESSAGE_GIVE_DEVICE_VENDOR_ID = 140; // 0x8c
+ field public static final int MESSAGE_GIVE_OSD_NAME = 70; // 0x46
field public static final int MESSAGE_GIVE_PHYSICAL_ADDRESS = 131; // 0x83
field public static final int MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS = 125; // 0x7d
field public static final int MESSAGE_GIVE_TUNER_DEVICE_STATUS = 8; // 0x8
field public static final int MESSAGE_IMAGE_VIEW_ON = 4; // 0x4
field public static final int MESSAGE_INACTIVE_SOURCE = 157; // 0x9d
+ field public static final int MESSAGE_INITIATE_ARC = 192; // 0xc0
field public static final int MESSAGE_MENU_REQUEST = 141; // 0x8d
field public static final int MESSAGE_MENU_STATUS = 142; // 0x8e
field public static final int MESSAGE_PLAY = 65; // 0x41
@@ -12493,10 +12492,14 @@
field public static final int MESSAGE_RECORD_ON = 9; // 0x9
field public static final int MESSAGE_RECORD_STATUS = 10; // 0xa
field public static final int MESSAGE_RECORD_TV_SCREEN = 15; // 0xf
+ field public static final int MESSAGE_REPORT_ARC_INITIATED = 193; // 0xc1
+ field public static final int MESSAGE_REPORT_ARC_TERMINATED = 194; // 0xc2
field public static final int MESSAGE_REPORT_AUDIO_STATUS = 122; // 0x7a
field public static final int MESSAGE_REPORT_PHYSICAL_ADDRESS = 132; // 0x84
field public static final int MESSAGE_REPORT_POWER_STATUS = 144; // 0x90
field public static final int MESSAGE_REQUEST_ACTIVE_SOURCE = 133; // 0x85
+ field public static final int MESSAGE_REQUEST_ARC_INITIATION = 195; // 0xc3
+ field public static final int MESSAGE_REQUEST_ARC_TERMINATION = 196; // 0xc4
field public static final int MESSAGE_ROUTING_CHANGE = 128; // 0x80
field public static final int MESSAGE_ROUTING_INFORMATION = 129; // 0x81
field public static final int MESSAGE_SELECT_ANALOG_SERVICE = 146; // 0x92
@@ -12514,6 +12517,7 @@
field public static final int MESSAGE_STANDBY = 54; // 0x36
field public static final int MESSAGE_SYSTEM_AUDIO_MODE_REQUEST = 112; // 0x70
field public static final int MESSAGE_SYSTEM_AUDIO_MODE_STATUS = 126; // 0x7e
+ field public static final int MESSAGE_TERMINATE_ARC = 197; // 0xc5
field public static final int MESSAGE_TEXT_VIEW_ON = 13; // 0xd
field public static final int MESSAGE_TIMER_CLEARED_STATUS = 67; // 0x43
field public static final int MESSAGE_TIMER_STATUS = 53; // 0x35
@@ -19578,6 +19582,7 @@
public class BatteryProperty implements android.os.Parcelable {
method public int describeContents();
method public int getInt();
+ method public long getLong();
method public void readFromParcel(android.os.Parcel);
method public void writeToParcel(android.os.Parcel, int);
field public static final int CAPACITY = 4; // 0x4
@@ -19585,6 +19590,7 @@
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int CURRENT_AVERAGE = 3; // 0x3
field public static final int CURRENT_NOW = 2; // 0x2
+ field public static final int ENERGY_COUNTER = 4; // 0x4
}
public class Binder implements android.os.IBinder {
@@ -25319,10 +25325,10 @@
public class TrustAgentService extends android.app.Service {
ctor public TrustAgentService();
- method protected final void enableTrust(java.lang.String, long, boolean);
+ method public final void grantTrust(java.lang.CharSequence, long, boolean);
method public final android.os.IBinder onBind(android.content.Intent);
- method protected void onUnlockAttempt(boolean);
- method protected final void revokeTrust();
+ method public void onUnlockAttempt(boolean);
+ method public final void revokeTrust();
field public static final java.lang.String SERVICE_INTERFACE = "android.service.trust.TrustAgentService";
field public static final java.lang.String TRUST_AGENT_META_DATA = "android.service.trust.trustagent";
}
@@ -29978,6 +29984,12 @@
method public T getUpper();
}
+ public final class Rational {
+ ctor public Rational(int, int);
+ method public int getDenominator();
+ method public int getNumerator();
+ }
+
public final class Size {
ctor public Size(int, int);
method public int getHeight();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index d813dab..62c4f0f 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.os.Binder;
import android.os.IBinder;
+import android.os.UserManager;
import android.util.ArrayMap;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IAppOpsCallback;
@@ -412,6 +413,58 @@
};
/**
+ * Specifies whether an Op should be restricted by a user restriction.
+ * Each Op should be filled with a restriction string from UserManager or
+ * null to specify it is not affected by any user restriction.
+ */
+ private static String[] sOpRestrictions = new String[] {
+ null, //COARSE_LOCATION
+ null, //FINE_LOCATION
+ null, //GPS
+ null, //VIBRATE
+ null, //READ_CONTACTS
+ null, //WRITE_CONTACTS
+ null, //READ_CALL_LOG
+ null, //WRITE_CALL_LOG
+ null, //READ_CALENDAR
+ null, //WRITE_CALENDAR
+ null, //WIFI_SCAN
+ null, //POST_NOTIFICATION
+ null, //NEIGHBORING_CELLS
+ null, //CALL_PHONE
+ null, //READ_SMS
+ null, //WRITE_SMS
+ null, //RECEIVE_SMS
+ null, //RECEIVE_EMERGECY_SMS
+ null, //RECEIVE_MMS
+ null, //RECEIVE_WAP_PUSH
+ null, //SEND_SMS
+ null, //READ_ICC_SMS
+ null, //WRITE_ICC_SMS
+ null, //WRITE_SETTINGS
+ null, //SYSTEM_ALERT_WINDOW
+ null, //ACCESS_NOTIFICATIONS
+ null, //CAMERA
+ null, //RECORD_AUDIO
+ null, //PLAY_AUDIO
+ null, //READ_CLIPBOARD
+ null, //WRITE_CLIPBOARD
+ null, //TAKE_MEDIA_BUTTONS
+ null, //TAKE_AUDIO_FOCUS
+ null, //AUDIO_MASTER_VOLUME
+ null, //AUDIO_VOICE_VOLUME
+ null, //AUDIO_RING_VOLUME
+ null, //AUDIO_MEDIA_VOLUME
+ null, //AUDIO_ALARM_VOLUME
+ null, //AUDIO_NOTIFICATION_VOLUME
+ null, //AUDIO_BLUETOOTH_VOLUME
+ null, //WAKE_LOCK
+ null, //MONITOR_LOCATION
+ null, //MONITOR_HIGH_POWER_LOCATION
+ null, //GET_USAGE_STATS
+ };
+
+ /**
* This specifies the default mode for each operation.
*/
private static int[] sOpDefaultMode = new int[] {
@@ -542,6 +595,10 @@
throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
+ " should be " + _NUM_OP);
}
+ if (sOpRestrictions.length != _NUM_OP) {
+ throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
+ + " should be " + _NUM_OP);
+ }
for (int i=0; i<_NUM_OP; i++) {
if (sOpToString[i] != null) {
sOpStrToOp.put(sOpToString[i], i);
@@ -575,6 +632,14 @@
}
/**
+ * Retrieve the user restriction associated with an operation, or null if there is not one.
+ * @hide
+ */
+ public static String opToRestriction(int op) {
+ return sOpRestrictions[op];
+ }
+
+ /**
* Retrieve the default mode for the operation.
* @hide
*/
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 76a6a8e..fd76b9c4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -16,9 +16,6 @@
package android.app;
-import com.android.internal.R;
-import com.android.internal.util.NotificationColorUtil;
-
import android.annotation.IntDef;
import android.content.Context;
import android.content.Intent;
@@ -41,6 +38,9 @@
import android.widget.ProgressBar;
import android.widget.RemoteViews;
+import com.android.internal.R;
+import com.android.internal.util.NotificationColorUtil;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.NumberFormat;
@@ -134,7 +134,7 @@
* leave it at its default value of 0.
*
* @see android.widget.ImageView#setImageLevel
- * @see android.graphics.drawable#setLevel
+ * @see android.graphics.drawable.Drawable#setLevel
*/
public int iconLevel;
@@ -700,10 +700,13 @@
* It must include an icon, a label, and a {@link PendingIntent} to be fired when the action is
* selected by the user.
* <p>
- * Apps should use {@link Builder#addAction(int, CharSequence, PendingIntent)} to create and
- * attach actions.
+ * Apps should use {@link Notification.Builder#addAction(int, CharSequence, PendingIntent)}
+ * or {@link Notification.Builder#addAction(Notification.Action)}
+ * to attach actions.
*/
public static class Action implements Parcelable {
+ private final Bundle mExtras;
+
/**
* Small icon representing the action.
*/
@@ -717,22 +720,102 @@
* may be rendered in a disabled presentation by the system UI.
*/
public PendingIntent actionIntent;
-
- private Action() { }
+
private Action(Parcel in) {
icon = in.readInt();
title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
if (in.readInt() == 1) {
actionIntent = PendingIntent.CREATOR.createFromParcel(in);
}
+ mExtras = in.readBundle();
}
/**
- * Use {@link Builder#addAction(int, CharSequence, PendingIntent)}.
+ * Use {@link Notification.Builder#addAction(int, CharSequence, PendingIntent)}.
*/
public Action(int icon, CharSequence title, PendingIntent intent) {
+ this(icon, title, intent, new Bundle());
+ }
+
+ private Action(int icon, CharSequence title, PendingIntent intent, Bundle extras) {
this.icon = icon;
this.title = title;
this.actionIntent = intent;
+ this.mExtras = extras != null ? extras : new Bundle();
+ }
+
+ /**
+ * Get additional metadata carried around with this Action.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Builder class for {@link Action} objects.
+ */
+ public static class Builder {
+ private final int mIcon;
+ private final CharSequence mTitle;
+ private final PendingIntent mIntent;
+ private final Bundle mExtras;
+
+ /**
+ * Construct a new builder for {@link Action} object.
+ * @param icon icon to show for this action
+ * @param title the title of the action
+ * @param intent the {@link PendingIntent} to fire when users trigger this action
+ */
+ public Builder(int icon, CharSequence title, PendingIntent intent) {
+ this(icon, title, intent, new Bundle());
+ }
+
+ /**
+ * Construct a new builder for {@link Action} object using the fields from an
+ * {@link Action}.
+ * @param action the action to read fields from.
+ */
+ public Builder(Action action) {
+ this(action.icon, action.title, action.actionIntent, new Bundle(action.mExtras));
+ }
+
+ private Builder(int icon, CharSequence title, PendingIntent intent, Bundle extras) {
+ mIcon = icon;
+ mTitle = title;
+ mIntent = intent;
+ mExtras = extras;
+ }
+
+ /**
+ * Merge additional metadata into this builder.
+ *
+ * <p>Values within the Bundle will replace existing extras values in this Builder.
+ *
+ * @see Notification.Action#extras
+ */
+ public Builder addExtras(Bundle extras) {
+ if (extras != null) {
+ mExtras.putAll(extras);
+ }
+ return this;
+ }
+
+ /**
+ * Get the metadata Bundle used by this Builder.
+ *
+ * <p>The returned Bundle is shared with this Builder.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Combine all of the options that have been set and return a new {@link Action}
+ * object.
+ * @return the built action
+ */
+ public Action build() {
+ return new Action(mIcon, mTitle, mIntent, mExtras);
+ }
}
@Override
@@ -740,8 +823,8 @@
return new Action(
this.icon,
this.title,
- this.actionIntent // safe to alias
- );
+ this.actionIntent, // safe to alias
+ new Bundle(this.mExtras));
}
@Override
public int describeContents() {
@@ -757,9 +840,10 @@
} else {
out.writeInt(0);
}
+ out.writeBundle(mExtras);
}
- public static final Parcelable.Creator<Action> CREATOR
- = new Parcelable.Creator<Action>() {
+ public static final Parcelable.Creator<Action> CREATOR =
+ new Parcelable.Creator<Action>() {
public Action createFromParcel(Parcel in) {
return new Action(in);
}
@@ -1372,7 +1456,7 @@
/**
* Add a timestamp pertaining to the notification (usually the time the event occurred).
* It will be shown in the notification content view by default; use
- * {@link Builder#setShowWhen(boolean) setShowWhen} to control this.
+ * {@link #setShowWhen(boolean) setShowWhen} to control this.
*
* @see Notification#when
*/
@@ -1382,7 +1466,7 @@
}
/**
- * Control whether the timestamp set with {@link Builder#setWhen(long) setWhen} is shown
+ * Control whether the timestamp set with {@link #setWhen(long) setWhen} is shown
* in the content view.
*/
public Builder setShowWhen(boolean show) {
@@ -1761,11 +1845,13 @@
*
* @see Notification#extras
*/
- public Builder addExtras(Bundle bag) {
- if (mExtras == null) {
- mExtras = new Bundle(bag);
- } else {
- mExtras.putAll(bag);
+ public Builder addExtras(Bundle extras) {
+ if (extras != null) {
+ if (mExtras == null) {
+ mExtras = new Bundle(extras);
+ } else {
+ mExtras.putAll(extras);
+ }
}
return this;
}
@@ -1782,8 +1868,8 @@
*
* @see Notification#extras
*/
- public Builder setExtras(Bundle bag) {
- mExtras = bag;
+ public Builder setExtras(Bundle extras) {
+ mExtras = extras;
return this;
}
@@ -1827,6 +1913,26 @@
}
/**
+ * Add an action to this notification. Actions are typically displayed by
+ * the system as a button adjacent to the notification content.
+ * <p>
+ * Every action must have an icon (32dp square and matching the
+ * <a href="{@docRoot}design/style/iconography.html#action-bar">Holo
+ * Dark action bar</a> visual style), a textual label, and a {@link PendingIntent}.
+ * <p>
+ * A notification in its expanded form can display up to 3 actions, from left to right in
+ * the order they were added. Actions will not be displayed when the notification is
+ * collapsed, however, so be sure that any essential functions may be accessed by the user
+ * in some other way (for example, in the Activity pointed to by {@link #contentIntent}).
+ *
+ * @param action The action to add.
+ */
+ public Builder addAction(Action action) {
+ mActions.add(action);
+ return this;
+ }
+
+ /**
* Add a rich notification style to be applied at build time.
*
* @param style Object responsible for modifying the notification style.
@@ -1889,26 +1995,20 @@
RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
boolean showLine3 = false;
boolean showLine2 = false;
- int smallIconImageViewId = R.id.icon;
+
if (mPriority < PRIORITY_LOW) {
// TODO: Low priority presentation
}
if (mLargeIcon != null) {
contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
processLargeIcon(mLargeIcon, contentView);
- smallIconImageViewId = R.id.right_icon;
- }
- if (mSmallIcon != 0) {
- contentView.setImageViewResource(smallIconImageViewId, mSmallIcon);
- contentView.setViewVisibility(smallIconImageViewId, View.VISIBLE);
- if (mLargeIcon != null) {
- processSmallRightIcon(mSmallIcon, smallIconImageViewId, contentView);
- } else {
- processSmallIconAsLarge(mSmallIcon, contentView);
- }
-
- } else {
- contentView.setViewVisibility(smallIconImageViewId, View.GONE);
+ contentView.setImageViewResource(R.id.right_icon, mSmallIcon);
+ contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
+ processSmallRightIcon(mSmallIcon, contentView);
+ } else { // small icon at left
+ contentView.setImageViewResource(R.id.icon, mSmallIcon);
+ contentView.setViewVisibility(R.id.icon, View.VISIBLE);
+ processSmallIconAsLarge(mSmallIcon, contentView);
}
if (mContentTitle != null) {
contentView.setTextViewText(R.id.title, processLegacyText(mContentTitle));
@@ -2103,6 +2203,8 @@
private void processLargeIcon(Bitmap largeIcon, RemoteViews contentView) {
if (!isLegacy() || mColorUtil.isGrayscale(largeIcon)) {
applyLargeIconBackground(contentView);
+ } else {
+ removeLargeIconBackground(contentView);
}
}
@@ -2122,16 +2224,31 @@
-1);
}
+ private void removeLargeIconBackground(RemoteViews contentView) {
+ contentView.setInt(R.id.icon, "setBackgroundResource", 0);
+ }
+
/**
* Recolor small icons when used in the R.id.right_icon slot.
*/
- private void processSmallRightIcon(int smallIconDrawableId, int smallIconImageViewId,
+ private void processSmallRightIcon(int smallIconDrawableId,
RemoteViews contentView) {
if (!isLegacy() || mColorUtil.isGrayscale(mContext, smallIconDrawableId)) {
- contentView.setDrawableParameters(smallIconImageViewId, false, -1,
- mContext.getResources().getColor(
- R.color.notification_action_legacy_color_filter),
- PorterDuff.Mode.MULTIPLY, -1);
+ contentView.setDrawableParameters(R.id.right_icon, false, -1,
+ 0xFFFFFFFF,
+ PorterDuff.Mode.SRC_ATOP, -1);
+
+ contentView.setInt(R.id.right_icon,
+ "setBackgroundResource",
+ R.drawable.notification_icon_legacy_bg);
+
+ contentView.setDrawableParameters(
+ R.id.right_icon,
+ true,
+ -1,
+ mColor,
+ PorterDuff.Mode.SRC_ATOP,
+ -1);
}
}
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index 197e3ff..a75372f 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -42,12 +42,8 @@
public class CursorWindow extends SQLiteClosable implements Parcelable {
private static final String STATS_TAG = "CursorWindowStats";
- /** The cursor window size. resource xml file specifies the value in kB.
- * convert it to bytes here by multiplying with 1024.
- */
- private static final int sCursorWindowSize =
- Resources.getSystem().getInteger(
- com.android.internal.R.integer.config_cursorWindowSize) * 1024;
+ // This static member will be evaluated when first used.
+ private static int sCursorWindowSize = -1;
/**
* The native CursorWindow object pointer. (FOR INTERNAL USE ONLY)
@@ -100,6 +96,13 @@
public CursorWindow(String name) {
mStartPos = 0;
mName = name != null && name.length() != 0 ? name : "<unnamed>";
+ if (sCursorWindowSize < 0) {
+ /** The cursor window size. resource xml file specifies the value in kB.
+ * convert it to bytes here by multiplying with 1024.
+ */
+ sCursorWindowSize = Resources.getSystem().getInteger(
+ com.android.internal.R.integer.config_cursorWindowSize) * 1024;
+ }
mWindowPtr = nativeCreate(mName, sCursorWindowSize);
if (mWindowPtr == 0) {
throw new CursorWindowAllocationException("Cursor window allocation of " +
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index b1c1005..1127fe5 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -17,6 +17,7 @@
package android.hardware.camera2;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.util.Rational;
import java.util.Collections;
import java.util.List;
@@ -316,8 +317,8 @@
* <li>All non (0, 0) sizes will have non-zero widths and heights.</li>
* </ul>
*/
- public static final Key<android.hardware.camera2.Size[]> JPEG_AVAILABLE_THUMBNAIL_SIZES =
- new Key<android.hardware.camera2.Size[]>("android.jpeg.availableThumbnailSizes", android.hardware.camera2.Size[].class);
+ public static final Key<android.util.Size[]> JPEG_AVAILABLE_THUMBNAIL_SIZES =
+ new Key<android.util.Size[]>("android.jpeg.availableThumbnailSizes", android.util.Size[].class);
/**
* <p>List of supported aperture
@@ -393,8 +394,8 @@
* <p>The map should be on the order of 30-40 rows and columns, and
* must be smaller than 64x64.</p>
*/
- public static final Key<android.hardware.camera2.Size> LENS_INFO_SHADING_MAP_SIZE =
- new Key<android.hardware.camera2.Size>("android.lens.info.shadingMapSize", android.hardware.camera2.Size.class);
+ public static final Key<android.util.Size> LENS_INFO_SHADING_MAP_SIZE =
+ new Key<android.util.Size>("android.lens.info.shadingMapSize", android.util.Size.class);
/**
* <p>The lens focus distance calibration quality.</p>
@@ -658,8 +659,8 @@
* @hide
*/
@Deprecated
- public static final Key<android.hardware.camera2.Size[]> SCALER_AVAILABLE_JPEG_SIZES =
- new Key<android.hardware.camera2.Size[]>("android.scaler.availableJpegSizes", android.hardware.camera2.Size[].class);
+ public static final Key<android.util.Size[]> SCALER_AVAILABLE_JPEG_SIZES =
+ new Key<android.util.Size[]>("android.scaler.availableJpegSizes", android.util.Size[].class);
/**
* <p>The maximum ratio between active area width
@@ -704,8 +705,8 @@
* @hide
*/
@Deprecated
- public static final Key<android.hardware.camera2.Size[]> SCALER_AVAILABLE_PROCESSED_SIZES =
- new Key<android.hardware.camera2.Size[]>("android.scaler.availableProcessedSizes", android.hardware.camera2.Size[].class);
+ public static final Key<android.util.Size[]> SCALER_AVAILABLE_PROCESSED_SIZES =
+ new Key<android.util.Size[]>("android.scaler.availableProcessedSizes", android.util.Size[].class);
/**
* <p>The mapping of image formats that are supported by this
@@ -961,9 +962,6 @@
* can provide.</p>
* <p>Please reference the documentation for the image data destination to
* check if it limits the maximum size for image data.</p>
- * <p>Not all output formats may be supported in a configuration with
- * an input stream of a particular format. For more details, see
- * android.scaler.availableInputOutputFormatsMap.</p>
* <p>The following table describes the minimum required output stream
* configurations based on the hardware level
* ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}):</p>
@@ -1106,8 +1104,8 @@
* match this in
* android.scaler.availableStreamConfigurations.</p>
*/
- public static final Key<android.hardware.camera2.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE =
- new Key<android.hardware.camera2.Size>("android.sensor.info.pixelArraySize", android.hardware.camera2.Size.class);
+ public static final Key<android.util.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE =
+ new Key<android.util.Size>("android.sensor.info.pixelArraySize", android.util.Size.class);
/**
* <p>Maximum raw value output by sensor.</p>
@@ -1515,13 +1513,4 @@
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
-
-
-
-
-
-
-
-
-
}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 8ae21f3..a70aa3b 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -19,6 +19,7 @@
import android.hardware.camera2.impl.CameraMetadataNative;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Rational;
import android.view.Surface;
import java.util.HashSet;
@@ -169,7 +170,7 @@
* @param in The parcel from which the object should be read
* @hide
*/
- public void readFromParcel(Parcel in) {
+ private void readFromParcel(Parcel in) {
mSettings.readFromParcel(in);
mSurfaceSet.clear();
@@ -965,8 +966,8 @@
* <p>When a jpeg image capture is issued, the thumbnail size selected should have
* the same aspect ratio as the jpeg image.</p>
*/
- public static final Key<android.hardware.camera2.Size> JPEG_THUMBNAIL_SIZE =
- new Key<android.hardware.camera2.Size>("android.jpeg.thumbnailSize", android.hardware.camera2.Size.class);
+ public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
+ new Key<android.util.Size>("android.jpeg.thumbnailSize", android.util.Size.class);
/**
* <p>The ratio of lens focal length to the effective
@@ -1518,12 +1519,4 @@
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
-
-
-
-
-
-
-
-
}
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 0160622..d79f4b0 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -17,6 +17,8 @@
package android.hardware.camera2;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.params.Face;
+import android.util.Rational;
/**
* <p>The results of a single image capture from the image sensor.</p>
@@ -1512,8 +1514,8 @@
* <p>When a jpeg image capture is issued, the thumbnail size selected should have
* the same aspect ratio as the jpeg image.</p>
*/
- public static final Key<android.hardware.camera2.Size> JPEG_THUMBNAIL_SIZE =
- new Key<android.hardware.camera2.Size>("android.jpeg.thumbnailSize", android.hardware.camera2.Size.class);
+ public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
+ new Key<android.util.Size>("android.jpeg.thumbnailSize", android.util.Size.class);
/**
* <p>The ratio of lens focal length to the effective
@@ -2060,6 +2062,16 @@
new Key<byte[]>("android.statistics.faceScores", byte[].class);
/**
+ * <p>List of the faces detected through camera face detection
+ * in this result.</p>
+ * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} <code>!=</code> OFF.</p>
+ *
+ * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
+ */
+ public static final Key<android.hardware.camera2.params.Face[]> STATISTICS_FACES =
+ new Key<android.hardware.camera2.params.Face[]>("android.statistics.faces", android.hardware.camera2.params.Face[].class);
+
+ /**
* <p>The shading map is a low-resolution floating-point map
* that lists the coefficients used to correct for vignetting, for each
* Bayer color channel.</p>
@@ -2425,27 +2437,4 @@
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
-
-
-
-
-
-
-
-
-
- /**
- * <p>
- * List of the {@link Face Faces} detected through camera face detection
- * in this result.
- * </p>
- * <p>
- * Only available if {@link #STATISTICS_FACE_DETECT_MODE} {@code !=}
- * {@link CameraMetadata#STATISTICS_FACE_DETECT_MODE_OFF OFF}.
- * </p>
- *
- * @see Face
- */
- public static final Key<Face[]> STATISTICS_FACES =
- new Key<Face[]>("android.statistics.faces", Face[].class);
}
diff --git a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
index a14d38b..caabed3 100644
--- a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
@@ -17,7 +17,7 @@
package android.hardware.camera2;
import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.CaptureResultExtras;
+import android.hardware.camera2.impl.CaptureResultExtras;
/** @hide */
interface ICameraDeviceCallbacks
diff --git a/core/java/android/hardware/camera2/Size.java b/core/java/android/hardware/camera2/Size.java
deleted file mode 100644
index 9328a003..0000000
--- a/core/java/android/hardware/camera2/Size.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2;
-
-// TODO: Delete this class, since it was moved to android.util as public API
-
-/**
- * Immutable class for describing width and height dimensions in pixels.
- *
- * @hide
- */
-public final class Size {
- /**
- * Create a new immutable Size instance.
- *
- * @param width The width of the size, in pixels
- * @param height The height of the size, in pixels
- */
- public Size(final int width, final int height) {
- mWidth = width;
- mHeight = height;
- }
-
- /**
- * Get the width of the size (in pixels).
- * @return width
- */
- public final int getWidth() {
- return mWidth;
- }
-
- /**
- * Get the height of the size (in pixels).
- * @return height
- */
- public final int getHeight() {
- return mHeight;
- }
-
- /**
- * Check if this size is equal to another size.
- * <p>
- * Two sizes are equal if and only if both their widths and heights are
- * equal.
- * </p>
- * <p>
- * A size object is never equal to any other type of object.
- * </p>
- *
- * @return {@code true} if the objects were equal, {@code false} otherwise
- */
- @Override
- public boolean equals(final Object obj) {
- if (obj == null) {
- return false;
- }
- if (this == obj) {
- return true;
- }
- if (obj instanceof Size) {
- final Size other = (Size) obj;
- return mWidth == other.mWidth && mHeight == other.mHeight;
- }
- return false;
- }
-
- /**
- * Return the size represented as a string with the format {@code "WxH"}
- *
- * @return string representation of the size
- */
- @Override
- public String toString() {
- return mWidth + "x" + mHeight;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
- // assuming most sizes are <2^16, doing a rotate will give us perfect hashing
- return mHeight ^ ((mWidth << (Integer.SIZE / 2)) | (mWidth >>> (Integer.SIZE / 2)));
- }
-
- private final int mWidth;
- private final int mHeight;
-};
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
index 628d1c3..dba24a1 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -21,7 +21,6 @@
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.CaptureResultExtras;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.utils.CameraBinderDecorator;
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index d28f7bd..db7486d 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -22,7 +22,6 @@
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.Face;
import android.hardware.camera2.marshal.Marshaler;
import android.hardware.camera2.marshal.MarshalQueryable;
import android.hardware.camera2.marshal.MarshalRegistry;
@@ -43,6 +42,7 @@
import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration;
import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration;
import android.hardware.camera2.marshal.impl.MarshalQueryableString;
+import android.hardware.camera2.params.Face;
import android.hardware.camera2.params.StreamConfiguration;
import android.hardware.camera2.params.StreamConfigurationDuration;
import android.hardware.camera2.params.StreamConfigurationMap;
diff --git a/core/java/android/hardware/camera2/CaptureResultExtras.aidl b/core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl
similarity index 94%
rename from core/java/android/hardware/camera2/CaptureResultExtras.aidl
rename to core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl
index 6587f02..ebc812a 100644
--- a/core/java/android/hardware/camera2/CaptureResultExtras.aidl
+++ b/core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.camera2;
+package android.hardware.camera2.impl;
/** @hide */
parcelable CaptureResultExtras;
diff --git a/core/java/android/hardware/camera2/CaptureResultExtras.java b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
similarity index 98%
rename from core/java/android/hardware/camera2/CaptureResultExtras.java
rename to core/java/android/hardware/camera2/impl/CaptureResultExtras.java
index e5c2c1c..b3a9559 100644
--- a/core/java/android/hardware/camera2/CaptureResultExtras.java
+++ b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.hardware.camera2;
+package android.hardware.camera2.impl;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/core/java/android/hardware/camera2/marshal/MarshalHelpers.java b/core/java/android/hardware/camera2/marshal/MarshalHelpers.java
index fd72ee2..35ecc2a 100644
--- a/core/java/android/hardware/camera2/marshal/MarshalHelpers.java
+++ b/core/java/android/hardware/camera2/marshal/MarshalHelpers.java
@@ -18,8 +18,8 @@
import static android.hardware.camera2.impl.CameraMetadataNative.*;
import static com.android.internal.util.Preconditions.*;
-import android.hardware.camera2.Rational;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.util.Rational;
/**
* Static functions in order to help implementing various marshaler functionality.
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableColorSpaceTransform.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableColorSpaceTransform.java
index d3796db..47f79bf 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableColorSpaceTransform.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableColorSpaceTransform.java
@@ -15,9 +15,9 @@
*/
package android.hardware.camera2.marshal.impl;
-import android.hardware.camera2.ColorSpaceTransform;
import android.hardware.camera2.marshal.Marshaler;
import android.hardware.camera2.marshal.MarshalQueryable;
+import android.hardware.camera2.params.ColorSpaceTransform;
import android.hardware.camera2.utils.TypeReference;
import java.nio.ByteBuffer;
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableMeteringRectangle.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableMeteringRectangle.java
index c8b9bd8..01780db 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableMeteringRectangle.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableMeteringRectangle.java
@@ -15,9 +15,9 @@
*/
package android.hardware.camera2.marshal.impl;
-import android.hardware.camera2.MeteringRectangle;
import android.hardware.camera2.marshal.Marshaler;
import android.hardware.camera2.marshal.MarshalQueryable;
+import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.utils.TypeReference;
import java.nio.ByteBuffer;
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryablePrimitive.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryablePrimitive.java
index 708da70..189b597 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryablePrimitive.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryablePrimitive.java
@@ -15,11 +15,11 @@
*/
package android.hardware.camera2.marshal.impl;
-import android.hardware.camera2.Rational;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.marshal.Marshaler;
import android.hardware.camera2.marshal.MarshalQueryable;
import android.hardware.camera2.utils.TypeReference;
+import android.util.Rational;
import static android.hardware.camera2.impl.CameraMetadataNative.*;
import static android.hardware.camera2.marshal.MarshalHelpers.*;
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableRggbChannelVector.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableRggbChannelVector.java
index 93c0e92..4253a0a 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableRggbChannelVector.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableRggbChannelVector.java
@@ -15,9 +15,9 @@
*/
package android.hardware.camera2.marshal.impl;
-import android.hardware.camera2.RggbChannelVector;
import android.hardware.camera2.marshal.Marshaler;
import android.hardware.camera2.marshal.MarshalQueryable;
+import android.hardware.camera2.params.RggbChannelVector;
import android.hardware.camera2.utils.TypeReference;
import java.nio.ByteBuffer;
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableSize.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableSize.java
index 6a73bee..721644e 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableSize.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableSize.java
@@ -15,7 +15,7 @@
*/
package android.hardware.camera2.marshal.impl;
-import android.hardware.camera2.Size;
+import android.util.Size;
import android.hardware.camera2.marshal.Marshaler;
import android.hardware.camera2.marshal.MarshalQueryable;
import android.hardware.camera2.utils.TypeReference;
diff --git a/core/java/android/hardware/camera2/ColorSpaceTransform.java b/core/java/android/hardware/camera2/params/ColorSpaceTransform.java
similarity index 98%
rename from core/java/android/hardware/camera2/ColorSpaceTransform.java
rename to core/java/android/hardware/camera2/params/ColorSpaceTransform.java
index 5e4c0a2..fa8c8ea 100644
--- a/core/java/android/hardware/camera2/ColorSpaceTransform.java
+++ b/core/java/android/hardware/camera2/params/ColorSpaceTransform.java
@@ -14,11 +14,13 @@
* limitations under the License.
*/
-package android.hardware.camera2;
+package android.hardware.camera2.params;
import static com.android.internal.util.Preconditions.*;
+import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.utils.HashCodeHelpers;
+import android.util.Rational;
import java.util.Arrays;
diff --git a/core/java/android/hardware/camera2/Face.java b/core/java/android/hardware/camera2/params/Face.java
similarity index 97%
rename from core/java/android/hardware/camera2/Face.java
rename to core/java/android/hardware/camera2/params/Face.java
index ded8839d..2cd83a3 100644
--- a/core/java/android/hardware/camera2/Face.java
+++ b/core/java/android/hardware/camera2/params/Face.java
@@ -15,10 +15,13 @@
*/
-package android.hardware.camera2;
+package android.hardware.camera2.params;
import android.graphics.Point;
import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureResult;
/**
* Describes a face detected in an image.
diff --git a/core/java/android/hardware/camera2/LensShadingMap.java b/core/java/android/hardware/camera2/params/LensShadingMap.java
similarity index 97%
rename from core/java/android/hardware/camera2/LensShadingMap.java
rename to core/java/android/hardware/camera2/params/LensShadingMap.java
index 2b0108c..b328f578 100644
--- a/core/java/android/hardware/camera2/LensShadingMap.java
+++ b/core/java/android/hardware/camera2/params/LensShadingMap.java
@@ -14,11 +14,13 @@
* limitations under the License.
*/
-package android.hardware.camera2;
+package android.hardware.camera2.params;
import static com.android.internal.util.Preconditions.*;
-import static android.hardware.camera2.RggbChannelVector.*;
+import static android.hardware.camera2.params.RggbChannelVector.*;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.utils.HashCodeHelpers;
import java.util.Arrays;
diff --git a/core/java/android/hardware/camera2/MeteringRectangle.java b/core/java/android/hardware/camera2/params/MeteringRectangle.java
similarity index 97%
rename from core/java/android/hardware/camera2/MeteringRectangle.java
rename to core/java/android/hardware/camera2/params/MeteringRectangle.java
index bb8e5b1..a26c57d 100644
--- a/core/java/android/hardware/camera2/MeteringRectangle.java
+++ b/core/java/android/hardware/camera2/params/MeteringRectangle.java
@@ -13,13 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.hardware.camera2;
+package android.hardware.camera2.params;
import android.util.Size;
import static com.android.internal.util.Preconditions.*;
import android.graphics.Point;
import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.utils.HashCodeHelpers;
/**
diff --git a/core/java/android/hardware/camera2/RggbChannelVector.java b/core/java/android/hardware/camera2/params/RggbChannelVector.java
similarity index 99%
rename from core/java/android/hardware/camera2/RggbChannelVector.java
rename to core/java/android/hardware/camera2/params/RggbChannelVector.java
index 80167c6..30591f6 100644
--- a/core/java/android/hardware/camera2/RggbChannelVector.java
+++ b/core/java/android/hardware/camera2/params/RggbChannelVector.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.camera2;
+package android.hardware.camera2.params;
import static com.android.internal.util.Preconditions.*;
diff --git a/core/java/android/hardware/camera2/TonemapCurve.java b/core/java/android/hardware/camera2/params/TonemapCurve.java
similarity index 97%
rename from core/java/android/hardware/camera2/TonemapCurve.java
rename to core/java/android/hardware/camera2/params/TonemapCurve.java
index 2958ebf..0fcffac 100644
--- a/core/java/android/hardware/camera2/TonemapCurve.java
+++ b/core/java/android/hardware/camera2/params/TonemapCurve.java
@@ -14,11 +14,15 @@
* limitations under the License.
*/
-package android.hardware.camera2;
+package android.hardware.camera2.params;
import static com.android.internal.util.Preconditions.*;
import android.graphics.PointF;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.utils.HashCodeHelpers;
import java.util.Arrays;
diff --git a/core/java/android/hardware/hdmi/HdmiCec.java b/core/java/android/hardware/hdmi/HdmiCec.java
index 7213c78..9193f89 100644
--- a/core/java/android/hardware/hdmi/HdmiCec.java
+++ b/core/java/android/hardware/hdmi/HdmiCec.java
@@ -120,7 +120,7 @@
public static final int MESSAGE_TIMER_CLEARED_STATUS = 0x043;
public static final int MESSAGE_USER_CONTROL_PRESSED = 0x44;
public static final int MESSAGE_USER_CONTROL_RELEASED = 0x45;
- public static final int MESSAGE_GET_OSD_NAME = 0x46;
+ public static final int MESSAGE_GIVE_OSD_NAME = 0x46;
public static final int MESSAGE_SET_OSD_NAME = 0x47;
public static final int MESSAGE_SET_OSD_STRING = 0x64;
public static final int MESSAGE_SET_TIMER_PROGRAM_TITLE = 0x67;
@@ -158,6 +158,12 @@
public static final int MESSAGE_VENDOR_COMMAND_WITH_ID = 0xA0;
public static final int MESSAGE_CLEAR_EXTERNAL_TIMER = 0xA1;
public static final int MESSAGE_SET_EXTERNAL_TIMER = 0xA2;
+ public static final int MESSAGE_INITIATE_ARC = 0xC0;
+ public static final int MESSAGE_REPORT_ARC_INITIATED = 0xC1;
+ public static final int MESSAGE_REPORT_ARC_TERMINATED = 0xC2;
+ public static final int MESSAGE_REQUEST_ARC_INITIATION = 0xC3;
+ public static final int MESSAGE_REQUEST_ARC_TERMINATION = 0xC4;
+ public static final int MESSAGE_TERMINATE_ARC = 0xC5;
public static final int MESSAGE_ABORT = 0xFF;
public static final int UNKNOWN_VENDOR_ID = 0xFFFFFF;
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 4b85398..c2b06a2 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -66,6 +66,7 @@
private AsyncChannel mAsyncChannel;
private final String LOG_TAG;
private static final boolean DBG = true;
+ private static final boolean VDBG = true;
// TODO - this class shouldn't cache data or it runs the risk of getting out of sync
// Make the API require each of these when any is updated so we have the data we need,
// without caching.
@@ -266,11 +267,14 @@
*/
private void evalScores() {
if (mConnectionRequested) {
+ if (VDBG) log("evalScores - already trying - size=" + mNetworkRequests.size());
// already trying
return;
}
+ if (VDBG) log("evalScores!");
for (int i=0; i < mNetworkRequests.size(); i++) {
int score = mNetworkRequests.valueAt(i).score;
+ if (VDBG) log(" checking request Min " + score + " vs my score " + mNetworkScore);
if (score < mNetworkScore) {
// have a request that has a lower scored network servicing it
// (or no network) than we could provide, so lets connect!
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index f339e52..32050dc 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -146,9 +146,9 @@
return null;
}
- BatteryProperty prop = new BatteryProperty(Integer.MIN_VALUE);
+ BatteryProperty prop = new BatteryProperty();
if ((mBatteryPropertiesRegistrar.getProperty(id, prop) == 0) &&
- (prop.getInt() != Integer.MIN_VALUE))
+ (prop.getLong() != Long.MIN_VALUE))
return prop;
else
return null;
diff --git a/core/java/android/os/BatteryProperty.java b/core/java/android/os/BatteryProperty.java
index ec73952..0ed856e 100644
--- a/core/java/android/os/BatteryProperty.java
+++ b/core/java/android/os/BatteryProperty.java
@@ -53,20 +53,18 @@
*/
public static final int CAPACITY = 4;
- private int mValueInt;
-
/**
- * @hide
+ * Battery remaining energy in nanowatt-hours, as a long integer.
*/
- public BatteryProperty(int value) {
- mValueInt = value;
- }
+ public static final int ENERGY_COUNTER = 4;
+
+ private long mValueLong;
/**
* @hide
*/
public BatteryProperty() {
- mValueInt = Integer.MIN_VALUE;
+ mValueLong = Long.MIN_VALUE;
}
/**
@@ -79,9 +77,21 @@
* @return The queried property value, or Integer.MIN_VALUE if not supported.
*/
public int getInt() {
- return mValueInt;
+ 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.
+ */
+ public long getLong() {
+ return mValueLong;
+ }
/*
* Parcel read/write code must be kept in sync with
* frameworks/native/services/batteryservice/BatteryProperty.cpp
@@ -92,11 +102,11 @@
}
public void readFromParcel(Parcel p) {
- mValueInt = p.readInt();
+ mValueLong = p.readLong();
}
public void writeToParcel(Parcel p, int flags) {
- p.writeInt(mValueInt);
+ p.writeLong(mValueLong);
}
public static final Parcelable.Creator<BatteryProperty> CREATOR
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 89f4388..d063168 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -769,6 +769,17 @@
public static final String
ACTION_SHOW_REGULATORY_INFO = "android.settings.SHOW_REGULATORY_INFO";
+ /**
+ * Activity Action: Show Device Name Settings.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you safeguard
+ * against ithis.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String DEVICE_NAME_SETTINGS = "android.settings.DEVICE_NAME";
+
// End of Intent actions for Settings
/**
@@ -2889,6 +2900,7 @@
MOVED_TO_GLOBAL.add(Settings.Global.SET_GLOBAL_HTTP_PROXY);
MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_DNS_SERVER);
MOVED_TO_GLOBAL.add(Settings.Global.PREFERRED_NETWORK_MODE);
+ MOVED_TO_GLOBAL.add(Settings.Global.WEBVIEW_DATA_REDUCTION_PROXY_KEY);
}
/** @hide */
@@ -5319,6 +5331,13 @@
*/
public static final String USE_GOOGLE_MAIL = "use_google_mail";
+ /**
+ * Webview Data reduction proxy key.
+ * @hide
+ */
+ public static final String WEBVIEW_DATA_REDUCTION_PROXY_KEY =
+ "webview_data_reduction_proxy_key";
+
/**
* Whether Wifi display is enabled/disabled
* 0=disabled. 1=enabled.
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index a94f45a..e2e9ff4 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -16,9 +16,11 @@
package android.service.notification;
+import android.annotation.PrivateApi;
import android.annotation.SdkConstant;
import android.app.INotificationManager;
import android.app.Service;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
@@ -26,9 +28,6 @@
import android.os.ServiceManager;
import android.util.Log;
-import java.util.Comparator;
-import java.util.HashMap;
-
/**
* A service that receives calls from the system when new notifications are posted or removed.
* <p>To extend this class, you must declare the service in your manifest file with
@@ -53,6 +52,9 @@
private INotificationManager mNoMan;
+ /** Only valid after a successful call to (@link registerAsService}. */
+ private int mCurrentUser;
+
/**
* The {@link Intent} that must be declared as handled by the service.
*/
@@ -267,6 +269,42 @@
return true;
}
+ /**
+ * Directly register this service with the Notification Manager.
+ *
+ * <p>Only system services may use this call. It will fail for non-system callers.
+ * Apps should ask the user to add their listener in Settings.
+ *
+ * @param componentName the component that will consume the notification information
+ * @param currentUser the user to use as the stream filter
+ * @hide
+ */
+ @PrivateApi
+ public void registerAsSystemService(ComponentName componentName, int currentUser)
+ throws RemoteException {
+ if (mWrapper == null) {
+ mWrapper = new INotificationListenerWrapper();
+ }
+ INotificationManager noMan = getNotificationInterface();
+ noMan.registerListener(mWrapper, componentName, currentUser);
+ mCurrentUser = currentUser;
+ }
+
+ /**
+ * Directly unregister this service from the Notification Manager.
+ *
+ * <P>This method will fail for listeners that were not registered
+ * with (@link registerAsService).
+ * @hide
+ */
+ @PrivateApi
+ public void unregisterAsSystemService() throws RemoteException {
+ if (mWrapper != null) {
+ INotificationManager noMan = getNotificationInterface();
+ noMan.unregisterListener(mWrapper, mCurrentUser);
+ }
+ }
+
private class INotificationListenerWrapper extends INotificationListener.Stub {
@Override
public void onNotificationPosted(StatusBarNotification sbn,
diff --git a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
index c346771..9e4c2bf 100644
--- a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
+++ b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
@@ -23,6 +23,6 @@
* @hide
*/
oneway interface ITrustAgentServiceCallback {
- void enableTrust(String message, long durationMs, boolean initiatedByUser);
+ void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser);
void revokeTrust();
}
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index d5ce429..bb40eec 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -29,12 +29,12 @@
* to be trusted.
*
* <p>To extend this class, you must declare the service in your manifest file with
- * the {@link android.Manifest.permission#BIND_TRUST_AGENT_SERVICE} permission
+ * the {@link android.Manifest.permission#BIND_TRUST_AGENT} permission
* and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
* <pre>
* <service android:name=".TrustAgent"
* android:label="@string/service_name"
- * android:permission="android.permission.BIND_TRUST_AGENT_SERVICE">
+ * android:permission="android.permission.BIND_TRUST_AGENT">
* <intent-filter>
* <action android:name="android.service.trust.TrustAgentService" />
* </intent-filter>
@@ -47,7 +47,7 @@
* {@link android.R.styleable#TrustAgent}. For example:</p>
*
* <pre>
- * <trust_agent xmlns:android="http://schemas.android.com/apk/res/android"
+ * <trust-agent xmlns:android="http://schemas.android.com/apk/res/android"
* android:settingsActivity=".TrustAgentSettings" /></pre>
*/
public class TrustAgentService extends Service {
@@ -88,7 +88,7 @@
*
* @param successful true if the attempt succeeded
*/
- protected void onUnlockAttempt(boolean successful) {
+ public void onUnlockAttempt(boolean successful) {
}
private void onError(String msg) {
@@ -96,7 +96,7 @@
}
/**
- * Call to enable trust on the device.
+ * Call to grant trust on the device.
*
* @param message describes why the device is trusted, e.g. "Trusted by location".
* @param durationMs amount of time in milliseconds to keep the device in a trusted state. Trust
@@ -104,10 +104,10 @@
* @param initiatedByUser indicates that the user has explicitly initiated an action that proves
* the user is about to use the device.
*/
- protected final void enableTrust(String message, long durationMs, boolean initiatedByUser) {
+ public final void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser) {
if (mCallback != null) {
try {
- mCallback.enableTrust(message, durationMs, initiatedByUser);
+ mCallback.grantTrust(message.toString(), durationMs, initiatedByUser);
} catch (RemoteException e) {
onError("calling enableTrust()");
}
@@ -117,7 +117,7 @@
/**
* Call to revoke trust on the device.
*/
- protected final void revokeTrust() {
+ public final void revokeTrust() {
if (mCallback != null) {
try {
mCallback.revokeTrust();
diff --git a/core/java/android/hardware/camera2/Rational.java b/core/java/android/util/Rational.java
similarity index 92%
rename from core/java/android/hardware/camera2/Rational.java
rename to core/java/android/util/Rational.java
index 693ee2b..8d4c67f 100644
--- a/core/java/android/hardware/camera2/Rational.java
+++ b/core/java/android/util/Rational.java
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.hardware.camera2;
+package android.util;
/**
- * The rational data type used by CameraMetadata keys. Contains a pair of ints representing the
- * numerator and denominator of a Rational number. This type is immutable.
+ * <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 {
private final int mNumerator;
@@ -30,7 +32,9 @@
* is always positive.</p>
*
* <p>A rational value with a 0-denominator may be constructed, but will have similar semantics
- * as float NaN and INF values. The int getter functions return 0 in this case.</p>
+ * 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>
*
* @param numerator the numerator of the rational
* @param denominator the denominator of the rational
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index 7b49006..9601a8d 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -1220,10 +1220,6 @@
}
private RenderNode buildDisplayList(View view, HardwareCanvas canvas) {
- if (mDrawDelta <= 0) {
- return view.mRenderNode;
- }
-
view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
== View.PFLAG_INVALIDATED;
view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index f23c64f..2b62552 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -30,6 +30,7 @@
import android.media.Metadata;
import android.media.SubtitleController;
import android.media.SubtitleTrack.RenderingWidget;
+import android.media.TtmlRenderer;
import android.media.WebVttRenderer;
import android.net.Uri;
import android.os.Looper;
@@ -314,6 +315,7 @@
final SubtitleController controller = new SubtitleController(
context, mMediaPlayer.getMediaTimeProvider(), mMediaPlayer);
controller.registerRenderer(new WebVttRenderer(context));
+ controller.registerRenderer(new TtmlRenderer(context));
mMediaPlayer.setSubtitleAnchor(controller, this);
if (mAudioSession != 0) {
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index cd75010..8e6fa58 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -17,6 +17,7 @@
package com.android.internal.app;
import android.app.AppOpsManager;
+import android.os.Bundle;
import com.android.internal.app.IAppOpsCallback;
interface IAppOpsService {
@@ -38,4 +39,10 @@
void resetAllModes();
int checkAudioOperation(int code, int stream, int uid, String packageName);
void setAudioRestriction(int code, int stream, int uid, int mode, in String[] exceptionPackages);
+
+ void setDeviceOwner(String packageName);
+ void setProfileOwner(String packageName, int userHandle);
+ void setUserRestrictions(in Bundle restrictions, int userHandle);
+ void removeUser(int userHandle);
+
}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index bf58918..9279758 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -367,7 +367,6 @@
bool forceLTR = false;
bool forceRTL = false;
- ALOGD("computeValues dirFlags=%d", dirFlags);
switch (dirFlags & kBidi_Mask) {
case kBidi_LTR: bidiReq = 0; break; // no ICU constant, canonical LTR level
case kBidi_RTL: bidiReq = 1; break; // no ICU constant, canonical RTL level
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 463a0a8..5fcb5f3 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -201,22 +201,6 @@
{
ALOGV("sampleRate=%d, audioFormat(from Java)=%d, channel mask=%x, buffSize=%d",
sampleRateInHertz, audioFormat, javaChannelMask, buffSizeInBytes);
- uint32_t afSampleRate;
- size_t afFrameCount;
-
- status_t status = AudioSystem::getOutputFrameCount(&afFrameCount,
- (audio_stream_type_t) streamType);
- if (status != NO_ERROR) {
- ALOGE("Error %d creating AudioTrack: Could not get AudioSystem frame count "
- "for stream type %d.", status, streamType);
- return (jint) AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM;
- }
- status = AudioSystem::getOutputSamplingRate(&afSampleRate, (audio_stream_type_t) streamType);
- if (status != NO_ERROR) {
- ALOGE("Error %d creating AudioTrack: Could not get AudioSystem sampling rate "
- "for stream type %d.", status, streamType);
- return (jint) AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM;
- }
// Java channel masks don't map directly to the native definition, but it's a simple shift
// to skip the two deprecated channel configurations "default" and "mono".
@@ -229,23 +213,8 @@
uint32_t channelCount = popcount(nativeChannelMask);
- // check the stream type
- audio_stream_type_t atStreamType;
- switch (streamType) {
- case AUDIO_STREAM_VOICE_CALL:
- case AUDIO_STREAM_SYSTEM:
- case AUDIO_STREAM_RING:
- case AUDIO_STREAM_MUSIC:
- case AUDIO_STREAM_ALARM:
- case AUDIO_STREAM_NOTIFICATION:
- case AUDIO_STREAM_BLUETOOTH_SCO:
- case AUDIO_STREAM_DTMF:
- atStreamType = (audio_stream_type_t) streamType;
- break;
- default:
- ALOGE("Error creating AudioTrack: unknown stream type %d.", streamType);
- return (jint) AUDIOTRACK_ERROR_SETUP_INVALIDSTREAMTYPE;
- }
+ // stream type already checked in Java
+ audio_stream_type_t atStreamType = (audio_stream_type_t) streamType;
// check the format.
// This function was called from Java, so we compare the format against the Java constants
@@ -305,6 +274,7 @@
lpJniStorage->mCallbackData.busy = false;
// initialize the native AudioTrack object
+ status_t status = NO_ERROR;
switch (memoryMode) {
case MODE_STREAM:
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cdb77f1..4eac802 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2613,7 +2613,7 @@
<!-- Must be required by an {@link
android.service.trust.TrustAgentService},
to ensure that only the system can bind to it. -->
- <permission android:name="android.permission.BIND_TRUST_AGENT_SERVICE"
+ <permission android:name="android.permission.BIND_TRUST_AGENT"
android:protectionLevel="signature"
android:label="@string/permlab_bind_trust_agent_service"
android:description="@string/permdesc_bind_trust_agent_service" />
diff --git a/core/res/res/layout/notification_action.xml b/core/res/res/layout/notification_action.xml
deleted file mode 100644
index 4e7c74c..0000000
--- a/core/res/res/layout/notification_action.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<Button xmlns:android="http://schemas.android.com/apk/res/android"
- style="?android:attr/borderlessButtonStyle"
- android:id="@+id/action0"
- android:layout_width="0dp"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:gravity="start|center_vertical"
- android:drawablePadding="8dp"
- android:paddingStart="8dp"
- android:textColor="#ccc"
- android:textSize="14dp"
- android:singleLine="true"
- android:ellipsize="end"
- />
diff --git a/core/res/res/layout/notification_action_tombstone.xml b/core/res/res/layout/notification_action_tombstone.xml
deleted file mode 100644
index 9977cfe..0000000
--- a/core/res/res/layout/notification_action_tombstone.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<Button xmlns:android="http://schemas.android.com/apk/res/android"
- style="?android:attr/borderlessButtonStyle"
- android:id="@+id/action0"
- android:layout_width="0dp"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:gravity="start|center_vertical"
- android:drawablePadding="8dp"
- android:paddingStart="8dp"
- android:textColor="#ccc"
- android:textSize="14dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:alpha="0.5"
- android:enabled="false"
- />
diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml
deleted file mode 100644
index d2e25c1..0000000
--- a/core/res/res/layout/notification_template_base.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:internal="http://schemas.android.com/apk/prv/res/android"
- android:background="@android:drawable/notification_bg"
- android:id="@+id/status_bar_latest_event_content"
- android:layout_width="match_parent"
- android:layout_height="64dp"
- internal:layout_minHeight="64dp"
- internal:layout_maxHeight="64dp"
- >
- <ImageView android:id="@+id/icon"
- android:layout_width="@dimen/notification_large_icon_width"
- android:layout_height="@dimen/notification_large_icon_height"
- android:background="@android:drawable/notification_template_icon_bg"
- android:scaleType="center"
- />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="fill_vertical"
- android:layout_marginStart="@dimen/notification_large_icon_width"
- android:minHeight="@dimen/notification_large_icon_height"
- android:orientation="vertical"
- android:paddingEnd="8dp"
- android:paddingTop="2dp"
- android:paddingBottom="2dp"
- android:gravity="top"
- >
- <LinearLayout
- android:id="@+id/line1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="6dp"
- android:layout_marginStart="8dp"
- android:orientation="horizontal"
- >
- <TextView android:id="@+id/title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:layout_weight="1"
- />
- <ViewStub android:id="@+id/time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:visibility="gone"
- android:layout="@layout/notification_template_part_time"
- />
- <ViewStub android:id="@+id/chronometer"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:visibility="gone"
- android:layout="@layout/notification_template_part_chronometer"
- />
- </LinearLayout>
- <TextView android:id="@+id/text2"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="-2dp"
- android:layout_marginBottom="-2dp"
- android:layout_marginStart="8dp"
- android:singleLine="true"
- android:fadingEdge="horizontal"
- android:ellipsize="marquee"
- android:visibility="gone"
- />
- <ProgressBar
- android:id="@android:id/progress"
- android:layout_width="match_parent"
- android:layout_height="12dp"
- android:layout_marginStart="8dp"
- android:visibility="gone"
- style="?android:attr/progressBarStyleHorizontal"
- />
- <LinearLayout
- android:id="@+id/line3"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:layout_marginStart="8dp"
- >
- <TextView android:id="@+id/text"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_gravity="center"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- />
- <TextView android:id="@+id/info"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:singleLine="true"
- android:gravity="center"
- android:paddingStart="8dp"
- />
- <ImageView android:id="@+id/right_icon"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:visibility="gone"
- android:drawableAlpha="153"
- />
- </LinearLayout>
- </LinearLayout>
-</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_base.xml b/core/res/res/layout/notification_template_big_base.xml
deleted file mode 100644
index 7cc6650..0000000
--- a/core/res/res/layout/notification_template_big_base.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:internal="http://schemas.android.com/apk/prv/res/android"
- android:background="@android:drawable/notification_bg"
- android:id="@+id/status_bar_latest_event_content"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- internal:layout_minHeight="65dp"
- internal:layout_maxHeight="unbounded"
- >
- <ImageView android:id="@+id/icon"
- android:layout_width="@dimen/notification_large_icon_width"
- android:layout_height="@dimen/notification_large_icon_height"
- android:background="@android:drawable/notification_template_icon_bg"
- android:scaleType="center"
- />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="fill_vertical"
- android:minHeight="@dimen/notification_large_icon_height"
- android:orientation="vertical"
- android:gravity="top"
- >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/notification_large_icon_width"
- android:minHeight="@dimen/notification_large_icon_height"
- android:paddingTop="2dp"
- android:orientation="vertical"
- >
- <LinearLayout
- android:id="@+id/line1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="6dp"
- android:layout_marginEnd="8dp"
- android:layout_marginStart="8dp"
- android:orientation="horizontal"
- >
- <TextView android:id="@+id/title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:layout_weight="1"
- />
- <ViewStub android:id="@+id/time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:visibility="gone"
- android:layout="@layout/notification_template_part_time"
- />
- <ViewStub android:id="@+id/chronometer"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:visibility="gone"
- android:layout="@layout/notification_template_part_chronometer"
- />
- </LinearLayout>
- <TextView android:id="@+id/text2"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="-2dp"
- android:layout_marginBottom="-2dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:fadingEdge="horizontal"
- android:ellipsize="marquee"
- android:visibility="gone"
- />
- <TextView android:id="@+id/big_text"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="false"
- android:visibility="gone"
- />
- <LinearLayout
- android:id="@+id/line3"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- >
- <TextView android:id="@+id/text"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_gravity="center"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- />
- <TextView android:id="@+id/info"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:singleLine="true"
- android:gravity="center"
- android:paddingStart="8dp"
- />
- <ImageView android:id="@+id/right_icon"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:visibility="gone"
- android:drawableAlpha="153"
- />
- </LinearLayout>
- <ProgressBar
- android:id="@android:id/progress"
- android:layout_width="match_parent"
- android:layout_height="12dp"
- android:layout_marginBottom="8dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:visibility="gone"
- style="?android:attr/progressBarStyleHorizontal"
- />
- </LinearLayout>
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="1px"
- android:id="@+id/action_divider"
- android:visibility="gone"
- android:background="?android:attr/dividerHorizontal" />
- <include
- layout="@layout/notification_action_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/notification_large_icon_width"
- />
- </LinearLayout>
-</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_picture.xml b/core/res/res/layout/notification_template_big_picture.xml
deleted file mode 100644
index f3f3951..0000000
--- a/core/res/res/layout/notification_template_big_picture.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:internal="http://schemas.android.com/apk/prv/res/android"
- android:background="@android:drawable/notification_bg"
- android:id="@+id/status_bar_latest_event_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- internal:layout_minHeight="65dp"
- internal:layout_maxHeight="unbounded"
- >
- <ImageView
- android:id="@+id/big_picture"
- android:layout_width="match_parent"
- android:layout_height="192dp"
- android:layout_marginTop="64dp"
- android:layout_gravity="bottom"
- android:scaleType="centerCrop"
- />
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="6dp"
- android:layout_marginTop="64dp"
- android:scaleType="fitXY"
- android:src="@drawable/title_bar_shadow"
- />
- <include layout="@layout/notification_template_base"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- />
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="208dp"
- android:paddingStart="64dp"
- android:layout_gravity="bottom"
- android:background="#CC111111"
- >
- <include
- layout="@layout/notification_action_list"
- android:id="@+id/actions"
- android:layout_gravity="bottom"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- />
- </FrameLayout>
-</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml
deleted file mode 100644
index 7e6da22..0000000
--- a/core/res/res/layout/notification_template_big_text.xml
+++ /dev/null
@@ -1,183 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:internal="http://schemas.android.com/apk/prv/res/android"
- android:background="@android:drawable/notification_bg"
- android:id="@+id/status_bar_latest_event_content"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- internal:layout_minHeight="65dp"
- internal:layout_maxHeight="unbounded"
- >
- <ImageView android:id="@+id/icon"
- android:layout_width="@dimen/notification_large_icon_width"
- android:layout_height="@dimen/notification_large_icon_height"
- android:background="@android:drawable/notification_template_icon_bg"
- android:scaleType="center"
- />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="fill_vertical"
- android:layout_marginStart="@dimen/notification_large_icon_width"
- android:orientation="vertical"
- android:paddingTop="0dp"
- android:paddingBottom="2dp"
- android:gravity="top"
- >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/notification_large_icon_height"
- android:orientation="vertical"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:layout_weight="1"
- >
- <LinearLayout
- android:id="@+id/line1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="8dp"
- android:orientation="horizontal"
- android:layout_gravity="top"
- android:layout_weight="0"
- >
- <TextView android:id="@+id/title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:layout_weight="1"
- />
- <ViewStub android:id="@+id/time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:visibility="gone"
- android:layout="@layout/notification_template_part_time"
- />
- <ViewStub android:id="@+id/chronometer"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:visibility="gone"
- android:layout="@layout/notification_template_part_chronometer"
- />
- </LinearLayout>
- <TextView android:id="@+id/text2"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="-2dp"
- android:layout_marginBottom="-2dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:fadingEdge="horizontal"
- android:ellipsize="marquee"
- android:layout_weight="0"
- android:visibility="gone"
- />
- <ProgressBar
- android:id="@android:id/progress"
- android:layout_width="match_parent"
- android:layout_height="12dp"
- android:layout_marginBottom="8dp"
- android:layout_marginEnd="8dp"
- android:visibility="gone"
- android:layout_weight="0"
- style="?android:attr/progressBarStyleHorizontal"
- />
- <TextView android:id="@+id/big_text"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginBottom="10dp"
- android:layout_marginEnd="8dp"
- android:singleLine="false"
- android:visibility="gone"
- android:maxLines="8"
- android:ellipsize="end"
- android:layout_weight="1"
- />
- </LinearLayout>
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:layout_marginTop="-1px"
- android:id="@+id/action_divider"
- android:visibility="gone"
- android:background="?android:attr/dividerHorizontal" />
- <include
- layout="@layout/notification_action_list"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="1px"
- android:id="@+id/overflow_divider"
- android:layout_marginBottom="8dp"
- android:visibility="visible"
- android:background="?android:attr/dividerHorizontal" />
- <LinearLayout
- android:id="@+id/line3"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:layout_marginBottom="8dp"
- android:layout_marginEnd="8dp"
- android:orientation="horizontal"
- android:layout_weight="0"
- android:gravity="center_vertical"
- >
- <TextView android:id="@+id/text"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_gravity="center"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- />
- <TextView android:id="@+id/info"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:singleLine="true"
- android:gravity="center"
- android:paddingStart="8dp"
- />
- <ImageView android:id="@+id/right_icon"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:visibility="gone"
- android:drawableAlpha="153"
- />
- </LinearLayout>
- </LinearLayout>
-</FrameLayout>
diff --git a/core/res/res/layout/notification_template_icon_group.xml b/core/res/res/layout/notification_template_icon_group.xml
new file mode 100644
index 0000000..2ad6f9e
--- /dev/null
+++ b/core/res/res/layout/notification_template_icon_group.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2014 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:id="@+id/icon_group"
+ >
+ <ImageView android:id="@+id/icon"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:padding="8dp"
+ android:scaleType="centerInside"
+ />
+ <ImageView android:id="@+id/right_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:padding="4dp"
+ android:layout_gravity="end|bottom"
+ android:scaleType="centerInside"
+ android:visibility="gone"
+ android:layout_marginEnd="3dp"
+ android:layout_marginBottom="3dp"
+ />
+</FrameLayout>
+
diff --git a/core/res/res/layout/notification_template_inbox.xml b/core/res/res/layout/notification_template_inbox.xml
deleted file mode 100644
index 1eec871..0000000
--- a/core/res/res/layout/notification_template_inbox.xml
+++ /dev/null
@@ -1,267 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:internal="http://schemas.android.com/apk/prv/res/android"
- android:id="@+id/status_bar_latest_event_content"
- android:background="@android:drawable/notification_bg"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- internal:layout_minHeight="65dp"
- internal:layout_maxHeight="unbounded"
- >
- <ImageView android:id="@+id/icon"
- android:layout_width="@dimen/notification_large_icon_width"
- android:layout_height="@dimen/notification_large_icon_height"
- android:background="@android:drawable/notification_template_icon_bg"
- android:scaleType="center"
- />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="fill_vertical"
- android:layout_marginStart="@dimen/notification_large_icon_width"
- android:minHeight="@dimen/notification_large_icon_height"
- android:orientation="vertical"
- android:paddingTop="0dp"
- android:paddingBottom="2dp"
- android:gravity="top"
- >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/notification_large_icon_height"
- android:paddingTop="2dp"
- android:orientation="vertical"
- >
- <LinearLayout
- android:id="@+id/line1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:paddingTop="6dp"
- android:orientation="horizontal"
- android:layout_weight="0"
- >
- <TextView android:id="@+id/title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:layout_weight="1"
- />
- <ViewStub android:id="@+id/time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:visibility="gone"
- android:layout="@layout/notification_template_part_time"
- />
- <ViewStub android:id="@+id/chronometer"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:visibility="gone"
- android:layout="@layout/notification_template_part_chronometer"
- />
- </LinearLayout>
- <TextView android:id="@+id/text2"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="-2dp"
- android:layout_marginBottom="-2dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:fadingEdge="horizontal"
- android:ellipsize="marquee"
- android:visibility="gone"
- android:layout_weight="0"
- />
- <ProgressBar
- android:id="@android:id/progress"
- android:layout_width="match_parent"
- android:layout_height="12dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:visibility="gone"
- android:layout_weight="0"
- style="?android:attr/progressBarStyleHorizontal"
- />
- <TextView android:id="@+id/inbox_text0"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text1"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text2"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text3"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text4"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text5"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_text6"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- />
- <TextView android:id="@+id/inbox_more"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:visibility="gone"
- android:layout_weight="1"
- android:text="@android:string/ellipsis"
- />
- <FrameLayout
- android:id="@+id/inbox_end_pad"
- android:layout_width="match_parent"
- android:layout_height="8dip"
- android:visibility="gone"
- android:layout_weight="0"
- />
- </LinearLayout>
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:layout_marginTop="-1px"
- android:id="@+id/action_divider"
- android:background="?android:attr/dividerHorizontal" />
- <include
- layout="@layout/notification_action_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- />
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:layout_marginTop="-1px"
- android:id="@+id/overflow_divider"
- android:visibility="visible"
- android:background="?android:attr/dividerHorizontal" />
- <LinearLayout
- android:id="@+id/line3"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginStart="8dp"
- android:layout_marginBottom="8dp"
- android:layout_marginEnd="8dp"
- android:orientation="horizontal"
- android:layout_weight="0"
- android:gravity="center_vertical"
- >
- <TextView android:id="@+id/text"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_gravity="center"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- />
- <TextView android:id="@+id/info"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:singleLine="true"
- android:gravity="center"
- android:paddingStart="8dp"
- />
- <ImageView android:id="@+id/right_icon"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:visibility="gone"
- android:drawableAlpha="153"
- />
- </LinearLayout>
- </LinearLayout>
-</FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_base.xml b/core/res/res/layout/notification_template_quantum_base.xml
index 8f3019d..789bf32 100644
--- a/core/res/res/layout/notification_template_quantum_base.xml
+++ b/core/res/res/layout/notification_template_quantum_base.xml
@@ -23,10 +23,9 @@
internal:layout_minHeight="64dp"
internal:layout_maxHeight="64dp"
>
- <ImageView android:id="@+id/icon"
+ <include layout="@layout/notification_template_icon_group"
android:layout_width="@dimen/notification_large_icon_width"
android:layout_height="@dimen/notification_large_icon_height"
- android:scaleType="center"
/>
<LinearLayout
android:layout_width="match_parent"
@@ -91,7 +90,7 @@
android:layout_height="12dp"
android:layout_marginStart="8dp"
android:visibility="gone"
- style="@style/Widget.Quantum.Light.ProgressBar.Horizontal"
+ style="@style/Widget.StatusBar.Quantum.ProgressBar"
/>
<LinearLayout
android:id="@+id/line3"
@@ -121,16 +120,6 @@
android:gravity="center"
android:paddingStart="8dp"
/>
- <ImageView android:id="@+id/right_icon"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:visibility="gone"
- android:drawableAlpha="153"
- />
</LinearLayout>
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_big_base.xml b/core/res/res/layout/notification_template_quantum_big_base.xml
index 45e69b1..8cb5549 100644
--- a/core/res/res/layout/notification_template_quantum_big_base.xml
+++ b/core/res/res/layout/notification_template_quantum_big_base.xml
@@ -23,10 +23,9 @@
internal:layout_minHeight="65dp"
internal:layout_maxHeight="unbounded"
>
- <ImageView android:id="@+id/icon"
+ <include layout="@layout/notification_template_icon_group"
android:layout_width="@dimen/notification_large_icon_width"
android:layout_height="@dimen/notification_large_icon_height"
- android:scaleType="center"
/>
<LinearLayout
android:layout_width="match_parent"
@@ -128,16 +127,6 @@
android:gravity="center"
android:paddingStart="8dp"
/>
- <ImageView android:id="@+id/right_icon"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:visibility="gone"
- android:drawableAlpha="153"
- />
</LinearLayout>
<ProgressBar
android:id="@android:id/progress"
diff --git a/core/res/res/layout/notification_template_quantum_big_text.xml b/core/res/res/layout/notification_template_quantum_big_text.xml
index f7769d7..bbd1071 100644
--- a/core/res/res/layout/notification_template_quantum_big_text.xml
+++ b/core/res/res/layout/notification_template_quantum_big_text.xml
@@ -22,10 +22,9 @@
internal:layout_minHeight="65dp"
internal:layout_maxHeight="unbounded"
>
- <ImageView android:id="@+id/icon"
+ <include layout="@layout/notification_template_icon_group"
android:layout_width="@dimen/notification_large_icon_width"
android:layout_height="@dimen/notification_large_icon_height"
- android:scaleType="center"
/>
<LinearLayout
android:layout_width="match_parent"
@@ -166,16 +165,6 @@
android:gravity="center"
android:paddingStart="8dp"
/>
- <ImageView android:id="@+id/right_icon"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:visibility="gone"
- android:drawableAlpha="153"
- />
</LinearLayout>
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_inbox.xml b/core/res/res/layout/notification_template_quantum_inbox.xml
index 04974c4..a071d59 100644
--- a/core/res/res/layout/notification_template_quantum_inbox.xml
+++ b/core/res/res/layout/notification_template_quantum_inbox.xml
@@ -23,10 +23,9 @@
internal:layout_minHeight="65dp"
internal:layout_maxHeight="unbounded"
>
- <ImageView android:id="@+id/icon"
+ <include layout="@layout/notification_template_icon_group"
android:layout_width="@dimen/notification_large_icon_width"
android:layout_height="@dimen/notification_large_icon_height"
- android:scaleType="center"
/>
<LinearLayout
android:layout_width="match_parent"
@@ -250,16 +249,6 @@
android:gravity="center"
android:paddingStart="8dp"
/>
- <ImageView android:id="@+id/right_icon"
- android:layout_width="16dp"
- android:layout_height="16dp"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:visibility="gone"
- android:drawableAlpha="153"
- />
</LinearLayout>
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/layout/status_bar_latest_event_content.xml b/core/res/res/layout/status_bar_latest_event_content.xml
index b3db01a..dc78174 100644
--- a/core/res/res/layout/status_bar_latest_event_content.xml
+++ b/core/res/res/layout/status_bar_latest_event_content.xml
@@ -22,7 +22,7 @@
android:layout_height="wrap_content"
android:background="#FFFF00FF"
>
- <include layout="@layout/notification_template_base"
+ <include layout="@layout/notification_template_quantum_base"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index ac75b38..1d35c84 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -6115,13 +6115,13 @@
<attr name="settingsActivity" />
</declare-styleable>
- <!-- Use <code>trust_agent</code> as the root tag of the XML resource that
+ <!-- Use <code>trust-agent</code> as the root tag of the XML resource that
describes an {@link android.service.trust.TrustAgentService}, which is
referenced from its {@link android.service.trust.TrustAgentService#TRUST_AGENT_META_DATA}
meta-data entry. Described here are the attributes that can be included in that tag. -->
<declare-styleable name="TrustAgent">
<!-- Component name of an activity that allows the user to modify
- the settings for this TrustAgent. -->
+ the settings for this trust agent. -->
<attr name="settingsActivity" />
</declare-styleable>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 69b11cd..52b021f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -227,9 +227,9 @@
<dimen name="action_bar_stacked_tab_max_width">180dp</dimen>
<!-- Size of notification text (see TextAppearance.StatusBar.EventContent) -->
- <dimen name="notification_text_size">14dp</dimen>
+ <dimen name="notification_text_size">13dp</dimen>
<!-- Size of notification text titles (see TextAppearance.StatusBar.EventContent.Title) -->
- <dimen name="notification_title_text_size">18dp</dimen>
+ <dimen name="notification_title_text_size">16dp</dimen>
<!-- Size of smaller notification text (see TextAppearance.StatusBar.EventContent.Line2, Info, Time) -->
<dimen name="notification_subtext_size">12dp</dimen>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 891265f..fd57c5e 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -280,28 +280,28 @@
<style name="TextAppearance.StatusBar.Quantum">
</style>
<style name="TextAppearance.StatusBar.Quantum.EventContent">
- <item name="android:textColor">#888888</item>
+ <item name="android:textColor">#90000000</item>
<item name="android:textSize">@dimen/notification_text_size</item>
</style>
<style name="TextAppearance.StatusBar.Quantum.EventContent.Title">
- <item name="android:textColor">#000000</item>
- <item name="android:fontFamily">sans-serif-light</item>
+ <item name="android:textColor">#DD000000</item>
<item name="android:textSize">@dimen/notification_title_text_size</item>
- <item name="android:textStyle">bold</item>
</style>
<style name="TextAppearance.StatusBar.Quantum.EventContent.Line2">
<item name="android:textSize">@dimen/notification_subtext_size</item>
</style>
<style name="TextAppearance.StatusBar.Quantum.EventContent.Info">
<item name="android:textSize">@dimen/notification_subtext_size</item>
- <item name="android:textColor">#888888</item>
</style>
<style name="TextAppearance.StatusBar.Quantum.EventContent.Time">
<item name="android:textSize">@dimen/notification_subtext_size</item>
- <item name="android:textColor">#888888</item>
</style>
<style name="TextAppearance.StatusBar.Quantum.EventContent.Emphasis">
- <item name="android:textColor">#555555</item>
+ <item name="android:textColor">#66000000</item>
+ </style>
+
+ <style name="Widget.StatusBar.Quantum.ProgressBar"
+ parent="Widget.Quantum.Light.ProgressBar.Horizontal">
</style>
<style name="TextAppearance.Small.CalendarViewWeekDayView">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 84c9023..2f0ac49 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1209,16 +1209,7 @@
<java-symbol type="layout" name="zoom_container" />
<java-symbol type="layout" name="zoom_controls" />
<java-symbol type="layout" name="zoom_magnify" />
- <java-symbol type="layout" name="notification_action" />
- <java-symbol type="layout" name="notification_action_tombstone" />
<java-symbol type="layout" name="notification_intruder_content" />
- <java-symbol type="layout" name="notification_template_base" />
- <java-symbol type="layout" name="notification_template_big_base" />
- <java-symbol type="layout" name="notification_template_big_picture" />
- <java-symbol type="layout" name="notification_template_big_text" />
- <java-symbol type="layout" name="notification_template_part_time" />
- <java-symbol type="layout" name="notification_template_part_chronometer" />
- <java-symbol type="layout" name="notification_template_inbox" />
<java-symbol type="layout" name="sms_short_code_confirmation_dialog" />
<java-symbol type="layout" name="action_bar_up_container" />
<java-symbol type="layout" name="app_not_authorized" />
@@ -1667,8 +1658,10 @@
<java-symbol type="layout" name="notification_template_quantum_big_picture" />
<java-symbol type="layout" name="notification_template_quantum_big_text" />
<java-symbol type="layout" name="notification_template_quantum_inbox" />
+ <java-symbol type="layout" name="notification_template_icon_group" />
<java-symbol type="color" name="notification_action_legacy_color_filter" />
<java-symbol type="color" name="notification_icon_bg_color" />
+ <java-symbol type="drawable" name="notification_icon_legacy_bg" />
<java-symbol type="drawable" name="notification_icon_legacy_bg_inset" />
<java-symbol type="drawable" name="notification_quantum_bg_dim" />
<java-symbol type="drawable" name="notification_quantum_bg" />
diff --git a/media/java/android/media/TtmlRenderer.java b/media/java/android/media/TtmlRenderer.java
new file mode 100644
index 0000000..0309334
--- /dev/null
+++ b/media/java/android/media/TtmlRenderer.java
@@ -0,0 +1,751 @@
+/*
+ * 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.media;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.media.SubtitleTrack.RenderingWidget.OnChangedListener;
+import android.text.Layout.Alignment;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.MeasureSpec;
+import android.view.ViewGroup.LayoutParams;
+import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.widget.SubtitleView;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+/** @hide */
+public class TtmlRenderer extends SubtitleController.Renderer {
+ private final Context mContext;
+
+ private static final String MEDIA_MIMETYPE_TEXT_TTML = "application/ttml+xml";
+
+ private TtmlRenderingWidget mRenderingWidget;
+
+ public TtmlRenderer(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public boolean supports(MediaFormat format) {
+ if (format.containsKey(MediaFormat.KEY_MIME)) {
+ return format.getString(MediaFormat.KEY_MIME).equals(MEDIA_MIMETYPE_TEXT_TTML);
+ }
+ return false;
+ }
+
+ @Override
+ public SubtitleTrack createTrack(MediaFormat format) {
+ if (mRenderingWidget == null) {
+ mRenderingWidget = new TtmlRenderingWidget(mContext);
+ }
+ return new TtmlTrack(mRenderingWidget, format);
+ }
+}
+
+/**
+ * A class which provides utillity methods for TTML parsing.
+ *
+ * @hide
+ */
+final class TtmlUtils {
+ public static final String TAG_TT = "tt";
+ public static final String TAG_HEAD = "head";
+ public static final String TAG_BODY = "body";
+ public static final String TAG_DIV = "div";
+ public static final String TAG_P = "p";
+ public static final String TAG_SPAN = "span";
+ public static final String TAG_BR = "br";
+ public static final String TAG_STYLE = "style";
+ public static final String TAG_STYLING = "styling";
+ public static final String TAG_LAYOUT = "layout";
+ public static final String TAG_REGION = "region";
+ public static final String TAG_METADATA = "metadata";
+ public static final String TAG_SMPTE_IMAGE = "smpte:image";
+ public static final String TAG_SMPTE_DATA = "smpte:data";
+ public static final String TAG_SMPTE_INFORMATION = "smpte:information";
+ public static final String PCDATA = "#pcdata";
+ public static final String ATTR_BEGIN = "begin";
+ public static final String ATTR_DURATION = "dur";
+ public static final String ATTR_END = "end";
+ public static final long INVALID_TIMESTAMP = Long.MAX_VALUE;
+
+ /**
+ * Time expression RE according to the spec:
+ * http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression
+ */
+ private static final Pattern CLOCK_TIME = Pattern.compile(
+ "^([0-9][0-9]+):([0-9][0-9]):([0-9][0-9])"
+ + "(?:(\\.[0-9]+)|:([0-9][0-9])(?:\\.([0-9]+))?)?$");
+
+ private static final Pattern OFFSET_TIME = Pattern.compile(
+ "^([0-9]+(?:\\.[0-9]+)?)(h|m|s|ms|f|t)$");
+
+ private TtmlUtils() {
+ }
+
+ /**
+ * Parses the given time expression and returns a timestamp in millisecond.
+ * <p>
+ * For the format of the time expression, please refer <a href=
+ * "http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression">timeExpression</a>
+ *
+ * @param time A string which includes time expression.
+ * @param frameRate the framerate of the stream.
+ * @param subframeRate the sub-framerate of the stream
+ * @param tickRate the tick rate of the stream.
+ * @return the parsed timestamp in micro-second.
+ * @throws NumberFormatException if the given string does not match to the
+ * format.
+ */
+ public static long parseTimeExpression(String time, int frameRate, int subframeRate,
+ int tickRate) throws NumberFormatException {
+ Matcher matcher = CLOCK_TIME.matcher(time);
+ if (matcher.matches()) {
+ String hours = matcher.group(1);
+ double durationSeconds = Long.parseLong(hours) * 3600;
+ String minutes = matcher.group(2);
+ durationSeconds += Long.parseLong(minutes) * 60;
+ String seconds = matcher.group(3);
+ durationSeconds += Long.parseLong(seconds);
+ String fraction = matcher.group(4);
+ durationSeconds += (fraction != null) ? Double.parseDouble(fraction) : 0;
+ String frames = matcher.group(5);
+ durationSeconds += (frames != null) ? ((double)Long.parseLong(frames)) / frameRate : 0;
+ String subframes = matcher.group(6);
+ durationSeconds += (subframes != null) ? ((double)Long.parseLong(subframes))
+ / subframeRate / frameRate
+ : 0;
+ return (long)(durationSeconds * 1000);
+ }
+ matcher = OFFSET_TIME.matcher(time);
+ if (matcher.matches()) {
+ String timeValue = matcher.group(1);
+ double value = Double.parseDouble(timeValue);
+ String unit = matcher.group(2);
+ if (unit.equals("h")) {
+ value *= 3600L * 1000000L;
+ } else if (unit.equals("m")) {
+ value *= 60 * 1000000;
+ } else if (unit.equals("s")) {
+ value *= 1000000;
+ } else if (unit.equals("ms")) {
+ value *= 1000;
+ } else if (unit.equals("f")) {
+ value = value / frameRate * 1000000;
+ } else if (unit.equals("t")) {
+ value = value / tickRate * 1000000;
+ }
+ return (long)value;
+ }
+ throw new NumberFormatException("Malformed time expression : " + time);
+ }
+
+ /**
+ * Applies <a href
+ * src="http://www.w3.org/TR/ttaf1-dfxp/#content-attribute-space">the
+ * default space policy</a> to the given string.
+ *
+ * @param in A string to apply the policy.
+ */
+ public static String applyDefaultSpacePolicy(String in) {
+ return applySpacePolicy(in, true);
+ }
+
+ /**
+ * Applies the space policy to the given string. This applies <a href
+ * src="http://www.w3.org/TR/ttaf1-dfxp/#content-attribute-space">the
+ * default space policy</a> with linefeed-treatment as treat-as-space
+ * or preserve.
+ *
+ * @param in A string to apply the policy.
+ * @param treatLfAsSpace Whether convert line feeds to spaces or not.
+ */
+ public static String applySpacePolicy(String in, boolean treatLfAsSpace) {
+ // Removes CR followed by LF. ref:
+ // http://www.w3.org/TR/xml/#sec-line-ends
+ String crRemoved = in.replaceAll("\r\n", "\n");
+ // Apply suppress-at-line-break="auto" and
+ // white-space-treatment="ignore-if-surrounding-linefeed"
+ String spacesNeighboringLfRemoved = crRemoved.replaceAll(" *\n *", "\n");
+ // Apply linefeed-treatment="treat-as-space"
+ String lfToSpace = treatLfAsSpace ? spacesNeighboringLfRemoved.replaceAll("\n", " ")
+ : spacesNeighboringLfRemoved;
+ // Apply white-space-collapse="true"
+ String spacesCollapsed = lfToSpace.replaceAll("[ \t\\x0B\f\r]+", " ");
+ return spacesCollapsed;
+ }
+
+ /**
+ * Returns the timed text for the given time period.
+ *
+ * @param root The root node of the TTML document.
+ * @param startUs The start time of the time period in microsecond.
+ * @param endUs The end time of the time period in microsecond.
+ */
+ public static String extractText(TtmlNode root, long startUs, long endUs) {
+ StringBuilder text = new StringBuilder();
+ extractText(root, startUs, endUs, text, false);
+ return text.toString().replaceAll("\n$", "");
+ }
+
+ private static void extractText(TtmlNode node, long startUs, long endUs, StringBuilder out,
+ boolean inPTag) {
+ if (node.mName.equals(TtmlUtils.PCDATA) && inPTag) {
+ out.append(node.mText);
+ } else if (node.mName.equals(TtmlUtils.TAG_BR) && inPTag) {
+ out.append("\n");
+ } else if (node.mName.equals(TtmlUtils.TAG_METADATA)) {
+ // do nothing.
+ } else if (node.isActive(startUs, endUs)) {
+ boolean pTag = node.mName.equals(TtmlUtils.TAG_P);
+ int length = out.length();
+ for (int i = 0; i < node.mChildren.size(); ++i) {
+ extractText(node.mChildren.get(i), startUs, endUs, out, pTag || inPTag);
+ }
+ if (pTag && length != out.length()) {
+ out.append("\n");
+ }
+ }
+ }
+
+ /**
+ * Returns a TTML fragment string for the given time period.
+ *
+ * @param root The root node of the TTML document.
+ * @param startUs The start time of the time period in microsecond.
+ * @param endUs The end time of the time period in microsecond.
+ */
+ public static String extractTtmlFragment(TtmlNode root, long startUs, long endUs) {
+ StringBuilder fragment = new StringBuilder();
+ extractTtmlFragment(root, startUs, endUs, fragment);
+ return fragment.toString();
+ }
+
+ private static void extractTtmlFragment(TtmlNode node, long startUs, long endUs,
+ StringBuilder out) {
+ if (node.mName.equals(TtmlUtils.PCDATA)) {
+ out.append(node.mText);
+ } else if (node.mName.equals(TtmlUtils.TAG_BR)) {
+ out.append("<br/>");
+ } else if (node.isActive(startUs, endUs)) {
+ out.append("<");
+ out.append(node.mName);
+ out.append(node.mAttributes);
+ out.append(">");
+ for (int i = 0; i < node.mChildren.size(); ++i) {
+ extractTtmlFragment(node.mChildren.get(i), startUs, endUs, out);
+ }
+ out.append("</");
+ out.append(node.mName);
+ out.append(">");
+ }
+ }
+}
+
+/**
+ * A container class which represents a cue in TTML.
+ * @hide
+ */
+class TtmlCue extends SubtitleTrack.Cue {
+ public String mText;
+ public String mTtmlFragment;
+
+ public TtmlCue(long startTimeMs, long endTimeMs, String text, String ttmlFragment) {
+ this.mStartTimeMs = startTimeMs;
+ this.mEndTimeMs = endTimeMs;
+ this.mText = text;
+ this.mTtmlFragment = ttmlFragment;
+ }
+}
+
+/**
+ * A container class which represents a node in TTML.
+ *
+ * @hide
+ */
+class TtmlNode {
+ public final String mName;
+ public final String mAttributes;
+ public final TtmlNode mParent;
+ public final String mText;
+ public final List<TtmlNode> mChildren = new ArrayList<TtmlNode>();
+ public final long mRunId;
+ public final long mStartTimeMs;
+ public final long mEndTimeMs;
+
+ public TtmlNode(String name, String attributes, String text, long startTimeMs, long endTimeMs,
+ TtmlNode parent, long runId) {
+ this.mName = name;
+ this.mAttributes = attributes;
+ this.mText = text;
+ this.mStartTimeMs = startTimeMs;
+ this.mEndTimeMs = endTimeMs;
+ this.mParent = parent;
+ this.mRunId = runId;
+ }
+
+ /**
+ * Check if this node is active in the given time range.
+ *
+ * @param startTimeMs The start time of the range to check in microsecond.
+ * @param endTimeMs The end time of the range to check in microsecond.
+ * @return return true if the given range overlaps the time range of this
+ * node.
+ */
+ public boolean isActive(long startTimeMs, long endTimeMs) {
+ return this.mEndTimeMs > startTimeMs && this.mStartTimeMs < endTimeMs;
+ }
+}
+
+/**
+ * A simple TTML parser (http://www.w3.org/TR/ttaf1-dfxp/) which supports DFXP
+ * presentation profile.
+ * <p>
+ * Supported features in this parser are:
+ * <ul>
+ * <li>content
+ * <li>core
+ * <li>presentation
+ * <li>profile
+ * <li>structure
+ * <li>time-offset
+ * <li>timing
+ * <li>tickRate
+ * <li>time-clock-with-frames
+ * <li>time-clock
+ * <li>time-offset-with-frames
+ * <li>time-offset-with-ticks
+ * </ul>
+ * </p>
+ *
+ * @hide
+ */
+class TtmlParser {
+ static final String TAG = "TtmlParser";
+
+ // TODO: read and apply the following attributes if specified.
+ private static final int DEFAULT_FRAMERATE = 30;
+ private static final int DEFAULT_SUBFRAMERATE = 1;
+ private static final int DEFAULT_TICKRATE = 1;
+
+ private XmlPullParser mParser;
+ private final TtmlNodeListener mListener;
+ private long mCurrentRunId;
+
+ public TtmlParser(TtmlNodeListener listener) {
+ mListener = listener;
+ }
+
+ /**
+ * Parse TTML data. Once this is called, all the previous data are
+ * reset and it starts parsing for the given text.
+ *
+ * @param ttmlText TTML text to parse.
+ * @throws XmlPullParserException
+ * @throws IOException
+ */
+ public void parse(String ttmlText, long runId) throws XmlPullParserException, IOException {
+ mParser = null;
+ mCurrentRunId = runId;
+ loadParser(ttmlText);
+ parseTtml();
+ }
+
+ private void loadParser(String ttmlFragment) throws XmlPullParserException {
+ XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+ factory.setNamespaceAware(false);
+ mParser = factory.newPullParser();
+ StringReader in = new StringReader(ttmlFragment);
+ mParser.setInput(in);
+ }
+
+ private void extractAttribute(XmlPullParser parser, int i, StringBuilder out) {
+ out.append(" ");
+ out.append(parser.getAttributeName(i));
+ out.append("=\"");
+ out.append(parser.getAttributeValue(i));
+ out.append("\"");
+ }
+
+ private void parseTtml() throws XmlPullParserException, IOException {
+ LinkedList<TtmlNode> nodeStack = new LinkedList<TtmlNode>();
+ int depthInUnsupportedTag = 0;
+ boolean active = true;
+ while (!isEndOfDoc()) {
+ int eventType = mParser.getEventType();
+ TtmlNode parent = nodeStack.peekLast();
+ if (active) {
+ if (eventType == XmlPullParser.START_TAG) {
+ if (!isSupportedTag(mParser.getName())) {
+ Log.w(TAG, "Unsupported tag " + mParser.getName() + " is ignored.");
+ depthInUnsupportedTag++;
+ active = false;
+ } else {
+ TtmlNode node = parseNode(parent);
+ nodeStack.addLast(node);
+ if (parent != null) {
+ parent.mChildren.add(node);
+ }
+ }
+ } else if (eventType == XmlPullParser.TEXT) {
+ String text = TtmlUtils.applyDefaultSpacePolicy(mParser.getText());
+ if (!TextUtils.isEmpty(text)) {
+ parent.mChildren.add(new TtmlNode(
+ TtmlUtils.PCDATA, "", text, 0, TtmlUtils.INVALID_TIMESTAMP,
+ parent, mCurrentRunId));
+
+ }
+ } else if (eventType == XmlPullParser.END_TAG) {
+ if (mParser.getName().equals(TtmlUtils.TAG_P)) {
+ mListener.onTtmlNodeParsed(nodeStack.getLast());
+ } else if (mParser.getName().equals(TtmlUtils.TAG_TT)) {
+ mListener.onRootNodeParsed(nodeStack.getLast());
+ }
+ nodeStack.removeLast();
+ }
+ } else {
+ if (eventType == XmlPullParser.START_TAG) {
+ depthInUnsupportedTag++;
+ } else if (eventType == XmlPullParser.END_TAG) {
+ depthInUnsupportedTag--;
+ if (depthInUnsupportedTag == 0) {
+ active = true;
+ }
+ }
+ }
+ mParser.next();
+ }
+ }
+
+ private TtmlNode parseNode(TtmlNode parent) throws XmlPullParserException, IOException {
+ int eventType = mParser.getEventType();
+ if (!(eventType == XmlPullParser.START_TAG)) {
+ return null;
+ }
+ StringBuilder attrStr = new StringBuilder();
+ long start = 0;
+ long end = TtmlUtils.INVALID_TIMESTAMP;
+ long dur = 0;
+ for (int i = 0; i < mParser.getAttributeCount(); ++i) {
+ String attr = mParser.getAttributeName(i);
+ String value = mParser.getAttributeValue(i);
+ // TODO: check if it's safe to ignore the namespace of attributes as follows.
+ attr = attr.replaceFirst("^.*:", "");
+ if (attr.equals(TtmlUtils.ATTR_BEGIN)) {
+ start = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE,
+ DEFAULT_SUBFRAMERATE, DEFAULT_TICKRATE);
+ } else if (attr.equals(TtmlUtils.ATTR_END)) {
+ end = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE,
+ DEFAULT_TICKRATE);
+ } else if (attr.equals(TtmlUtils.ATTR_DURATION)) {
+ dur = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE,
+ DEFAULT_TICKRATE);
+ } else {
+ extractAttribute(mParser, i, attrStr);
+ }
+ }
+ if (parent != null) {
+ start += parent.mStartTimeMs;
+ if (end != TtmlUtils.INVALID_TIMESTAMP) {
+ end += parent.mStartTimeMs;
+ }
+ }
+ if (dur > 0) {
+ if (end != TtmlUtils.INVALID_TIMESTAMP) {
+ Log.e(TAG, "'dur' and 'end' attributes are defined at the same time." +
+ "'end' value is ignored.");
+ }
+ end = start + dur;
+ }
+ if (parent != null) {
+ // If the end time remains unspecified, then the end point is
+ // interpreted as the end point of the external time interval.
+ if (end == TtmlUtils.INVALID_TIMESTAMP &&
+ parent.mEndTimeMs != TtmlUtils.INVALID_TIMESTAMP &&
+ end > parent.mEndTimeMs) {
+ end = parent.mEndTimeMs;
+ }
+ }
+ TtmlNode node = new TtmlNode(mParser.getName(), attrStr.toString(), null, start, end,
+ parent, mCurrentRunId);
+ return node;
+ }
+
+ private boolean isEndOfDoc() throws XmlPullParserException {
+ return (mParser.getEventType() == XmlPullParser.END_DOCUMENT);
+ }
+
+ private static boolean isSupportedTag(String tag) {
+ if (tag.equals(TtmlUtils.TAG_TT) || tag.equals(TtmlUtils.TAG_HEAD) ||
+ tag.equals(TtmlUtils.TAG_BODY) || tag.equals(TtmlUtils.TAG_DIV) ||
+ tag.equals(TtmlUtils.TAG_P) || tag.equals(TtmlUtils.TAG_SPAN) ||
+ tag.equals(TtmlUtils.TAG_BR) || tag.equals(TtmlUtils.TAG_STYLE) ||
+ tag.equals(TtmlUtils.TAG_STYLING) || tag.equals(TtmlUtils.TAG_LAYOUT) ||
+ tag.equals(TtmlUtils.TAG_REGION) || tag.equals(TtmlUtils.TAG_METADATA) ||
+ tag.equals(TtmlUtils.TAG_SMPTE_IMAGE) || tag.equals(TtmlUtils.TAG_SMPTE_DATA) ||
+ tag.equals(TtmlUtils.TAG_SMPTE_INFORMATION)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+/** @hide */
+interface TtmlNodeListener {
+ void onTtmlNodeParsed(TtmlNode node);
+ void onRootNodeParsed(TtmlNode node);
+}
+
+/** @hide */
+class TtmlTrack extends SubtitleTrack implements TtmlNodeListener {
+ private static final String TAG = "TtmlTrack";
+
+ private final TtmlParser mParser = new TtmlParser(this);
+ private final TtmlRenderingWidget mRenderingWidget;
+ private String mParsingData;
+ private Long mCurrentRunID;
+
+ private final LinkedList<TtmlNode> mTtmlNodes;
+ private final TreeSet<Long> mTimeEvents;
+ private TtmlNode mRootNode;
+
+ TtmlTrack(TtmlRenderingWidget renderingWidget, MediaFormat format) {
+ super(format);
+
+ mTtmlNodes = new LinkedList<TtmlNode>();
+ mTimeEvents = new TreeSet<Long>();
+ mRenderingWidget = renderingWidget;
+ mParsingData = "";
+ }
+
+ @Override
+ public TtmlRenderingWidget getRenderingWidget() {
+ return mRenderingWidget;
+ }
+
+ @Override
+ public void onData(String data, boolean eos, long runID) {
+ // implement intermixing restriction for TTML.
+ synchronized(mParser) {
+ if (mCurrentRunID != null && runID != mCurrentRunID) {
+ throw new IllegalStateException(
+ "Run #" + mCurrentRunID +
+ " in progress. Cannot process run #" + runID);
+ }
+ mCurrentRunID = runID;
+ mParsingData += data;
+ if (eos) {
+ try {
+ mParser.parse(mParsingData, mCurrentRunID);
+ } catch (XmlPullParserException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ finishedRun(runID);
+ mParsingData = "";
+ mCurrentRunID = null;
+ }
+ }
+ }
+
+ @Override
+ public void onTtmlNodeParsed(TtmlNode node) {
+ mTtmlNodes.addLast(node);
+ addTimeEvents(node);
+ }
+
+ @Override
+ public void onRootNodeParsed(TtmlNode node) {
+ mRootNode = node;
+ TtmlCue cue = null;
+ while ((cue = getNextResult()) != null) {
+ addCue(cue);
+ }
+ mRootNode = null;
+ mTtmlNodes.clear();
+ mTimeEvents.clear();
+ }
+
+ @Override
+ public void updateView(Vector<SubtitleTrack.Cue> activeCues) {
+ if (!mVisible) {
+ // don't keep the state if we are not visible
+ return;
+ }
+
+ if (DEBUG && mTimeProvider != null) {
+ try {
+ Log.d(TAG, "at " +
+ (mTimeProvider.getCurrentTimeUs(false, true) / 1000) +
+ " ms the active cues are:");
+ } catch (IllegalStateException e) {
+ Log.d(TAG, "at (illegal state) the active cues are:");
+ }
+ }
+
+ mRenderingWidget.setActiveCues(activeCues);
+ }
+
+ /**
+ * Returns a {@link TtmlCue} in the presentation time order.
+ * {@code null} is returned if there is no more timed text to show.
+ */
+ public TtmlCue getNextResult() {
+ while (mTimeEvents.size() >= 2) {
+ long start = mTimeEvents.pollFirst();
+ long end = mTimeEvents.first();
+ List<TtmlNode> activeCues = getActiveNodes(start, end);
+ if (!activeCues.isEmpty()) {
+ return new TtmlCue(start, end,
+ TtmlUtils.applySpacePolicy(TtmlUtils.extractText(
+ mRootNode, start, end), false),
+ TtmlUtils.extractTtmlFragment(mRootNode, start, end));
+ }
+ }
+ return null;
+ }
+
+ private void addTimeEvents(TtmlNode node) {
+ mTimeEvents.add(node.mStartTimeMs);
+ mTimeEvents.add(node.mEndTimeMs);
+ for (int i = 0; i < node.mChildren.size(); ++i) {
+ addTimeEvents(node.mChildren.get(i));
+ }
+ }
+
+ private List<TtmlNode> getActiveNodes(long startTimeUs, long endTimeUs) {
+ List<TtmlNode> activeNodes = new ArrayList<TtmlNode>();
+ for (int i = 0; i < mTtmlNodes.size(); ++i) {
+ TtmlNode node = mTtmlNodes.get(i);
+ if (node.isActive(startTimeUs, endTimeUs)) {
+ activeNodes.add(node);
+ }
+ }
+ return activeNodes;
+ }
+}
+
+/**
+ * Widget capable of rendering TTML captions.
+ *
+ * @hide
+ */
+class TtmlRenderingWidget extends LinearLayout implements SubtitleTrack.RenderingWidget {
+
+ /** Callback for rendering changes. */
+ private OnChangedListener mListener;
+ private final TextView mTextView;
+
+ public TtmlRenderingWidget(Context context) {
+ this(context, null);
+ }
+
+ public TtmlRenderingWidget(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TtmlRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public TtmlRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ // Cannot render text over video when layer type is hardware.
+ setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+
+ CaptioningManager captionManager = (CaptioningManager) context.getSystemService(
+ Context.CAPTIONING_SERVICE);
+ mTextView = new TextView(context);
+ mTextView.setTextColor(captionManager.getUserStyle().foregroundColor);
+ addView(mTextView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ mTextView.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
+ }
+
+ @Override
+ public void setOnChangedListener(OnChangedListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void setSize(int width, int height) {
+ final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+ final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+
+ measure(widthSpec, heightSpec);
+ layout(0, 0, width, height);
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ if (visible) {
+ setVisibility(View.VISIBLE);
+ } else {
+ setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ }
+
+ public void setActiveCues(Vector<SubtitleTrack.Cue> activeCues) {
+ final int count = activeCues.size();
+ String subtitleText = "";
+ for (int i = 0; i < count; i++) {
+ TtmlCue cue = (TtmlCue) activeCues.get(i);
+ subtitleText += cue.mText + "\n";
+ }
+ mTextView.setText(subtitleText);
+
+ if (mListener != null) {
+ mListener.onChanged(this);
+ }
+ }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 89886ef..8a7e642 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -23,10 +23,10 @@
import android.hardware.IProCameraCallbacks;
import android.hardware.IProCameraUser;
import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureResultExtras;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.utils.BinderHolder;
import android.hardware.camera2.utils.CameraBinderDecorator;
import android.os.Binder;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 74ce997..7b2e7dd 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -21,10 +21,10 @@
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResultExtras;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.utils.BinderHolder;
import android.media.Image;
import android.media.ImageReader;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
index 5ab586f..a77b647 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
@@ -18,6 +18,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Range;
+import android.util.Rational;
import android.util.SizeF;
import android.graphics.ImageFormat;
import android.graphics.Point;
@@ -26,15 +27,14 @@
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.ColorSpaceTransform;
-import android.hardware.camera2.Face;
-import android.hardware.camera2.MeteringRectangle;
-import android.hardware.camera2.Rational;
-import android.hardware.camera2.RggbChannelVector;
-import android.hardware.camera2.Size;
+import android.util.Size;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.marshal.impl.MarshalQueryableEnum;
+import android.hardware.camera2.params.ColorSpaceTransform;
+import android.hardware.camera2.params.Face;
+import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.ReprocessFormatsMap;
+import android.hardware.camera2.params.RggbChannelVector;
import android.hardware.camera2.params.StreamConfiguration;
import android.hardware.camera2.params.StreamConfigurationDuration;
import android.hardware.camera2.params.StreamConfigurationMap;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
index 9621f92..18c0d3e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
@@ -17,7 +17,7 @@
package com.android.mediaframeworktest.unit;
import android.test.suitebuilder.annotation.SmallTest;
-import android.hardware.camera2.Rational;
+import android.util.Rational;
/**
* <pre>
diff --git a/packages/Keyguard/test/SampleTrustAgent/res/xml/sample_trust_agent.xml b/packages/Keyguard/test/SampleTrustAgent/res/xml/sample_trust_agent.xml
index b48e011..b363ab4 100644
--- a/packages/Keyguard/test/SampleTrustAgent/res/xml/sample_trust_agent.xml
+++ b/packages/Keyguard/test/SampleTrustAgent/res/xml/sample_trust_agent.xml
@@ -14,5 +14,5 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<trust_agent xmlns:android="http://schemas.android.com/apk/res/android"
+<trust-agent xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity=".SampleTrustAgentSettings" />
diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
index 25406d6..a51ea75 100644
--- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
+++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
@@ -31,7 +31,7 @@
LocalBroadcastManager mLocalBroadcastManager;
- private static final String ACTION_ENABLE_TRUST = "action.sample_trust_agent.enable_trust";
+ private static final String ACTION_GRANT_TRUST = "action.sample_trust_agent.grant_trust";
private static final String ACTION_REVOKE_TRUST = "action.sample_trust_agent.revoke_trust";
private static final String EXTRA_MESSAGE = "extra.message";
@@ -45,14 +45,14 @@
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_ENABLE_TRUST);
+ filter.addAction(ACTION_GRANT_TRUST);
filter.addAction(ACTION_REVOKE_TRUST);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
mLocalBroadcastManager.registerReceiver(mReceiver, filter);
}
@Override
- protected void onUnlockAttempt(boolean successful) {
+ public void onUnlockAttempt(boolean successful) {
if (getReportUnlockAttempts(this)) {
Toast.makeText(this, "onUnlockAttempt(successful=" + successful + ")",
Toast.LENGTH_SHORT).show();
@@ -69,8 +69,8 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (ACTION_ENABLE_TRUST.equals(action)) {
- enableTrust(intent.getStringExtra(EXTRA_MESSAGE),
+ if (ACTION_GRANT_TRUST.equals(action)) {
+ grantTrust(intent.getStringExtra(EXTRA_MESSAGE),
intent.getLongExtra(EXTRA_DURATION, 0),
false /* initiatedByUser */);
} else if (ACTION_REVOKE_TRUST.equals(action)) {
@@ -79,9 +79,9 @@
}
};
- public static void sendEnableTrust(Context context,
+ public static void sendGrantTrust(Context context,
String message, long durationMs, Bundle extra) {
- Intent intent = new Intent(ACTION_ENABLE_TRUST);
+ Intent intent = new Intent(ACTION_GRANT_TRUST);
intent.putExtra(EXTRA_MESSAGE, message);
intent.putExtra(EXTRA_DURATION, durationMs);
intent.putExtra(EXTRA_EXTRA, extra);
diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
index 0a6f675..8e293fb 100644
--- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
+++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
@@ -19,7 +19,6 @@
import android.annotation.Nullable;
import android.app.Activity;
import android.os.Bundle;
-import android.preference.CheckBoxPreference;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
@@ -53,7 +52,7 @@
public void onClick(View v) {
int id = v.getId();
if (id == R.id.enable_trust) {
- SampleTrustAgent.sendEnableTrust(this, "SampleTrustAgent", TRUST_DURATION_MS,
+ SampleTrustAgent.sendGrantTrust(this, "SampleTrustAgent", TRUST_DURATION_MS,
null /* extra */);
} else if (id == R.id.revoke_trust) {
SampleTrustAgent.sendRevokeTrust(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 91df9ef..5e8c769 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -21,6 +21,7 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -45,6 +46,9 @@
private int mBgResId = R.drawable.notification_quantum_bg;
private int mDimmedBgResId = R.drawable.notification_quantum_bg_dim;
+ private int mBgTint = 0;
+ private int mDimmedBgTint = 0;
+
/**
* Flag to indicate that the notification has been touched once and the second touch will
* click it.
@@ -209,17 +213,23 @@
* @param bgResId The background resource to use in normal state.
* @param dimmedBgResId The background resource to use in dimmed state.
*/
- public void setBackgroundResourceIds(int bgResId, int dimmedBgResId) {
+ public void setBackgroundResourceIds(int bgResId, int bgTint, int dimmedBgResId, int dimmedTint) {
mBgResId = bgResId;
+ mBgTint = bgTint;
mDimmedBgResId = dimmedBgResId;
+ mDimmedBgTint = dimmedTint;
updateBackgroundResource();
}
+ public void setBackgroundResourceIds(int bgResId, int dimmedBgResId) {
+ setBackgroundResourceIds(bgResId, 0, dimmedBgResId, 0);
+ }
+
private void fadeBackgroundResource() {
if (mDimmed) {
- setBackgroundDimmed(mDimmedBgResId);
+ setBackgroundDimmed(mDimmedBgResId, mDimmedBgTint);
} else {
- setBackgroundNormal(mBgResId);
+ setBackgroundNormal(mBgResId, mBgTint);
}
int startAlpha = mDimmed ? 255 : 0;
int endAlpha = mDimmed ? 0 : 255;
@@ -256,12 +266,12 @@
private void updateBackgroundResource() {
if (mDimmed) {
- setBackgroundDimmed(mDimmedBgResId);
+ setBackgroundDimmed(mDimmedBgResId, mDimmedBgTint);
mBackgroundDimmed.setAlpha(255);
setBackgroundNormal(null);
} else {
setBackgroundDimmed(null);
- setBackgroundNormal(mBgResId);
+ setBackgroundNormal(mBgResId, mBgTint);
mBackgroundNormal.setAlpha(255);
}
}
@@ -295,12 +305,20 @@
invalidate();
}
- private void setBackgroundNormal(int drawableResId) {
- setBackgroundNormal(getResources().getDrawable(drawableResId));
+ private void setBackgroundNormal(int drawableResId, int tintColor) {
+ final Drawable d = getResources().getDrawable(drawableResId);
+ if (tintColor != 0) {
+ d.setColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP);
+ }
+ setBackgroundNormal(d);
}
- private void setBackgroundDimmed(int drawableResId) {
- setBackgroundDimmed(getResources().getDrawable(drawableResId));
+ private void setBackgroundDimmed(int drawableResId, int tintColor) {
+ final Drawable d = getResources().getDrawable(drawableResId);
+ if (tintColor != 0) {
+ d.setColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP);
+ }
+ setBackgroundDimmed(d);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 898f06e..6090948 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -428,14 +428,16 @@
protected void applyLegacyRowBackground(StatusBarNotification sbn,
NotificationData.Entry entry) {
+ int version = 0;
+ try {
+ ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(sbn.getPackageName(), 0);
+ version = info.targetSdkVersion;
+ } catch (NameNotFoundException ex) {
+ Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
+ }
+
if (entry.expanded.getId() != com.android.internal.R.id.status_bar_latest_event_content) {
- int version = 0;
- try {
- ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(sbn.getPackageName(), 0);
- version = info.targetSdkVersion;
- } catch (NameNotFoundException ex) {
- Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
- }
+ // Using custom RemoteViews
if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) {
entry.row.setBackgroundResource(R.drawable.notification_row_legacy_bg);
} else if (version < Build.VERSION_CODES.L) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 8c70517..dde2ebb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -20,6 +20,7 @@
import android.animation.TimeAnimator;
import android.animation.TimeAnimator.TimeListener;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.util.Log;
@@ -218,7 +219,7 @@
};
private float mVel, mAccel;
- protected int mMaxPanelHeight = 0;
+ protected int mMaxPanelHeight = -1;
private String mViewName;
private float mInitialTouchY;
private float mInitialTouchX;
@@ -617,7 +618,8 @@
// Did one of our children change size?
int newHeight = getMeasuredHeight();
- if (newHeight != mMaxPanelHeight) {
+ if (newHeight > mMaxPanelHeight) {
+ // we only adapt the max height if it's bigger
mMaxPanelHeight = newHeight;
// If the user isn't actively poking us, let's rubberband to the content
if (!mTracking && !mTimeAnimator.isStarted()
@@ -695,6 +697,12 @@
mExpandedFraction = Math.min(1f, (fh == 0) ? 0 : h / fh);
}
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ mMaxPanelHeight = -1;
+ }
+
protected void onHeightUpdated(float expandedHeight) {
requestLayout();
}
@@ -706,6 +714,7 @@
* @return the default implementation simply returns the maximum height.
*/
protected int getMaxPanelHeight() {
+ mMaxPanelHeight = Math.max(mMaxPanelHeight, getHeight());
return mMaxPanelHeight;
}
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index e26747c..be20616 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -36,12 +36,14 @@
import android.media.AudioService;
import android.os.AsyncTask;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.os.UserManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
@@ -49,6 +51,7 @@
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.Xml;
@@ -56,6 +59,7 @@
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
+import com.google.android.util.AbstractMessageParser.MusicTrack;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -91,6 +95,10 @@
final SparseArray<HashMap<String, Ops>> mUidOps
= new SparseArray<HashMap<String, Ops>>();
+ private int mDeviceOwnerUid;
+ private final SparseIntArray mProfileOwnerUids = new SparseIntArray();
+ private final SparseArray<boolean[]> mOpRestrictions = new SparseArray<boolean[]>();
+
public final static class Ops extends SparseArray<Op> {
public final String packageName;
public final int uid;
@@ -548,6 +556,9 @@
verifyIncomingUid(uid);
verifyIncomingOp(code);
synchronized (this) {
+ if (isOpRestricted(uid, code)) {
+ return AppOpsManager.MODE_IGNORED;
+ }
Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false);
if (op == null) {
return AppOpsManager.opToDefaultMode(code);
@@ -631,6 +642,9 @@
return AppOpsManager.MODE_ERRORED;
}
Op op = getOpLocked(ops, code, true);
+ if (isOpRestricted(uid, code)) {
+ return AppOpsManager.MODE_IGNORED;
+ }
if (op.duration == -1) {
Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
+ " code " + code + " time=" + op.time + " duration=" + op.duration);
@@ -665,6 +679,9 @@
return AppOpsManager.MODE_ERRORED;
}
Op op = getOpLocked(ops, code, true);
+ if (isOpRestricted(uid, code)) {
+ return AppOpsManager.MODE_IGNORED;
+ }
final int switchCode = AppOpsManager.opToSwitch(code);
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
@@ -830,6 +847,23 @@
return op;
}
+ private boolean isOpRestricted(int uid, int code) {
+ int userHandle = UserHandle.getUserId(uid);
+ boolean[] opRestrictions = mOpRestrictions.get(userHandle);
+ if ((opRestrictions != null) && opRestrictions[code]) {
+ if (userHandle == UserHandle.USER_OWNER) {
+ if (uid != mDeviceOwnerUid) {
+ return true;
+ }
+ } else {
+ if (uid != mProfileOwnerUids.get(userHandle, -1)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
void readState() {
synchronized (mFile) {
synchronized (this) {
@@ -1167,4 +1201,66 @@
int mode;
ArraySet<String> exceptionPackages = NO_EXCEPTIONS;
}
+
+ @Override
+ public void setDeviceOwner(String packageName) throws RemoteException {
+ checkSystemUid("setDeviceOwner");
+ try {
+ mDeviceOwnerUid = mContext.getPackageManager().getPackageUid(packageName,
+ UserHandle.USER_OWNER);
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Could not find Device Owner UID");
+ mDeviceOwnerUid = -1;
+ throw new IllegalArgumentException("Could not find device owner package "
+ + packageName);
+ }
+ }
+
+ @Override
+ public void setProfileOwner(String packageName, int userHandle) throws RemoteException {
+ checkSystemUid("setProfileOwner");
+ try {
+ int uid = mContext.getPackageManager().getPackageUid(packageName,
+ userHandle);
+ mProfileOwnerUids.put(userHandle, uid);
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Could not find Profile Owner UID");
+ mProfileOwnerUids.put(userHandle, -1);
+ throw new IllegalArgumentException("Could not find profile owner package "
+ + packageName);
+ }
+ }
+
+ @Override
+ public void setUserRestrictions(Bundle restrictions, int userHandle) throws RemoteException {
+ checkSystemUid("setUserRestrictions");
+ boolean[] opRestrictions = mOpRestrictions.get(userHandle);
+ if (opRestrictions == null) {
+ opRestrictions = new boolean[AppOpsManager._NUM_OP];
+ mOpRestrictions.put(userHandle, opRestrictions);
+ }
+ for (int i = 0; i < opRestrictions.length; ++i) {
+ String restriction = AppOpsManager.opToRestriction(i);
+ if (restriction != null) {
+ opRestrictions[i] = restrictions.getBoolean(restriction, false);
+ } else {
+ opRestrictions[i] = false;
+ }
+ }
+ }
+
+ @Override
+ public void removeUser(int userHandle) throws RemoteException {
+ checkSystemUid("removeUser");
+ mOpRestrictions.remove(userHandle);
+ mProfileOwnerUids.removeAt(mProfileOwnerUids.indexOfKey(userHandle));
+ }
+
+ private void checkSystemUid(String function) {
+ int uid = Binder.getCallingUid();
+ if (uid != Process.SYSTEM_UID) {
+ throw new SecurityException(function + " must by called by the system");
+ }
+ }
+
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 982dce0..2d0f6d1 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3216,6 +3216,7 @@
// tell the network currently servicing this that it's no longer interested
NetworkAgentInfo affectedNetwork = mNetworkForRequestId.get(nri.request.requestId);
if (affectedNetwork != null) {
+ mNetworkForRequestId.remove(nri.request.requestId);
affectedNetwork.networkRequests.remove(nri.request.requestId);
if (VDBG) {
log(" Removing from current network " + affectedNetwork.name() + ", leaving " +
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
index fc6183c..6d2b83b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
@@ -58,14 +58,14 @@
}
/**
- * Build <Get Osd Name> command.
+ * Build <Give Osd Name> command.
*
* @param src source address of command
* @param dest destination address of command
* @return newly created {@link HdmiCecMessage}
*/
- static HdmiCecMessage buildGetOsdNameCommand(int src, int dest) {
- return buildCommand(src, dest, HdmiCec.MESSAGE_GET_OSD_NAME);
+ static HdmiCecMessage buildGiveOsdNameCommand(int src, int dest) {
+ return buildCommand(src, dest, HdmiCec.MESSAGE_GIVE_OSD_NAME);
}
/**
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index c122645..ed48c12 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -127,8 +127,8 @@
case HdmiCec.MESSAGE_GET_MENU_LANGUAGE:
handleGetMenuLanguage(message);
return true;
- case HdmiCec.MESSAGE_GET_OSD_NAME:
- handleGetOsdName(message);
+ case HdmiCec.MESSAGE_GIVE_OSD_NAME:
+ handleGiveOsdName(message);
return true;
case HdmiCec.MESSAGE_GIVE_PHYSICAL_ADDRESS:
handleGivePhysicalAddress(message);
@@ -170,7 +170,7 @@
sendCecCommand(cecMessage);
}
- private void handleGetOsdName(HdmiCecMessage message) {
+ private void handleGiveOsdName(HdmiCecMessage message) {
// TODO: read device name from settings or property.
String name = HdmiCec.getDefaultDeviceName(message.getDestination());
HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildSetOsdNameCommand(
diff --git a/services/core/java/com/android/server/hdmi/NewDeviceAction.java b/services/core/java/com/android/server/hdmi/NewDeviceAction.java
index 98da280..e0bc718 100644
--- a/services/core/java/com/android/server/hdmi/NewDeviceAction.java
+++ b/services/core/java/com/android/server/hdmi/NewDeviceAction.java
@@ -71,7 +71,7 @@
@Override
public boolean start() {
sendCommand(
- HdmiCecMessageBuilder.buildGetOsdNameCommand(mSourceAddress,
+ HdmiCecMessageBuilder.buildGiveOsdNameCommand(mSourceAddress,
mDeviceLogicalAddress));
mState = STATE_WAITING_FOR_SET_OSD_NAME;
addTimer(mState, TIMEOUT_MS);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 60212bf..131d05b 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -40,6 +40,7 @@
import android.os.IUserManager;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AtomicFile;
@@ -50,6 +51,7 @@
import android.util.TimeUtils;
import android.util.Xml;
+import com.android.internal.app.IAppOpsService;
import com.android.internal.content.PackageMonitor;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
@@ -162,6 +164,8 @@
private int mNextSerialNumber;
private int mUserVersion = 0;
+ private IAppOpsService mAppOpsService;
+
private static UserManagerService sInstance;
public static UserManagerService getInstance() {
@@ -236,6 +240,15 @@
void systemReady() {
mUserPackageMonitor.register(mContext, null, UserHandle.ALL, false);
userForeground(UserHandle.USER_OWNER);
+ mAppOpsService = IAppOpsService.Stub.asInterface(
+ ServiceManager.getService(Context.APP_OPS_SERVICE));
+ for (int i = 0; i < mUserIds.length; ++i) {
+ try {
+ mAppOpsService.setUserRestrictions(mUserRestrictions.get(mUserIds[i]), mUserIds[i]);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
+ }
+ }
}
@Override
@@ -482,6 +495,14 @@
synchronized (mPackagesLock) {
mUserRestrictions.get(userId).clear();
mUserRestrictions.get(userId).putAll(restrictions);
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppOpsService.setUserRestrictions(mUserRestrictions.get(userId), userId);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
writeUserLocked(mUsers.get(userId));
}
}
@@ -1116,6 +1137,11 @@
return false;
}
mRemovingUserIds.put(userHandle, true);
+ try {
+ mAppOpsService.removeUser(userHandle);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e);
+ }
// Set this to a partially created user, so that the user will be purged
// on next startup, in case the runtime stops now before stopping and
// removing the user completely.
@@ -1125,6 +1151,14 @@
user.flags |= UserInfo.FLAG_DISABLED;
writeUserLocked(user);
}
+
+ if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
+ && user.isManagedProfile()) {
+ // Send broadcast to notify system that the user removed was a
+ // managed user.
+ sendProfileRemovedBroadcast(user.profileGroupId, user.id);
+ }
+
if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
int res;
try {
@@ -1151,7 +1185,6 @@
// wiping the user's system directory and removing from the user list
long ident = Binder.clearCallingIdentity();
try {
- final boolean isManaged = getUserInfo(userHandle).isManagedProfile();
Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED);
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL,
@@ -1172,11 +1205,6 @@
removeUserStateLocked(userHandle);
}
}
- // Send broadcast to notify system that the user removed was a
- // managed user.
- if (isManaged) {
- sendProfileRemovedBroadcast(userHandle);
- }
}
}.start();
}
@@ -1228,11 +1256,11 @@
parent.delete();
}
- private void sendProfileRemovedBroadcast(int userHandle) {
+ private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) {
Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED);
- managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(userHandle));
- // Note: This makes an assumption that the parent owner is user 0.
- mContext.sendBroadcastAsUser(managedProfileIntent, UserHandle.OWNER, null);
+ managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
+ mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null);
}
@Override
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index a83fa87..d8d3da1 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -52,7 +52,7 @@
// Trust state
private boolean mTrusted;
- private String mMessage;
+ private CharSequence mMessage;
private final Handler mHandler = new Handler() {
@Override
@@ -60,7 +60,7 @@
switch (msg.what) {
case MSG_ENABLE_TRUST:
mTrusted = true;
- mMessage = (String) msg.obj;
+ mMessage = (CharSequence) msg.obj;
boolean initiatedByUser = msg.arg1 != 0;
// TODO: Handle handle user initiated trust changes.
mTrustManagerService.updateTrust(mUserId);
@@ -79,7 +79,8 @@
private ITrustAgentServiceCallback mCallback = new ITrustAgentServiceCallback.Stub() {
- public void enableTrust(String userMessage, long durationMs, boolean initiatedByUser) {
+ @Override
+ public void grantTrust(CharSequence userMessage, long durationMs, boolean initiatedByUser) {
if (DEBUG) Slog.v(TAG, "enableTrust(" + userMessage + ", durationMs = " + durationMs
+ ", initiatedByUser = " + initiatedByUser + ")");
@@ -91,6 +92,7 @@
}
}
+ @Override
public void revokeTrust() {
if (DEBUG) Slog.v(TAG, "revokeTrust()");
mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
@@ -155,7 +157,7 @@
return mTrusted;
}
- public String getMessage() {
+ public CharSequence getMessage() {
return mMessage;
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 9061f96..a39c116 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -221,8 +221,8 @@
// Drain preamble.
}
String nodeName = parser.getName();
- if (!"trust_agent".equals(nodeName)) {
- Slog.w(TAG, "Meta-data does not start with trust_agent tag");
+ if (!"trust-agent".equals(nodeName)) {
+ Slog.w(TAG, "Meta-data does not start with trust-agent tag");
return null;
}
TypedArray sa = res
diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp
index 6e03993..1d111a1 100644
--- a/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp
+++ b/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp
@@ -142,7 +142,7 @@
// Handles incoming <Request Active Source> message. If one of logical
// devices is active, it should reply with <Active Source> message.
void handleRequestActiveSource();
- void handleGetOsdName(const cec_message_t& msg);
+ void handleGiveOsdName(const cec_message_t& msg);
void handleGiveDeviceVendorID(const cec_message_t& msg);
void handleGetCECVersion(const cec_message_t& msg);
void handleGetMenuLanguage(const cec_message_t& msg);
@@ -555,8 +555,8 @@
sendReportPhysicalAddress(msg.destination);
} else if (opcode == CEC_MESSAGE_REQUEST_ACTIVE_SOURCE) {
handleRequestActiveSource();
- } else if (opcode == CEC_MESSAGE_GET_OSD_NAME) {
- handleGetOsdName(msg);
+ } else if (opcode == CEC_MESSAGE_GIVE_OSD_NAME) {
+ handleGiveOsdName(msg);
} else if (opcode == CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID) {
handleGiveDeviceVendorID(msg);
} else if (opcode == CEC_MESSAGE_GET_CEC_VERSION) {
@@ -631,7 +631,7 @@
checkAndClearExceptionFromCallback(env, __FUNCTION__);
}
-void HdmiCecHandler::handleGetOsdName(const cec_message_t& msg) {
+void HdmiCecHandler::handleGiveOsdName(const cec_message_t& msg) {
if (!mOsdName.empty()) {
sendSetOsdName(msg.destination, msg.initiator, mOsdName.c_str(), mOsdName.length());
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
index 1647425..674c6f4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -39,6 +39,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
+import java.util.Set;
/**
* Stores and restores state for the Device and Profile owners. By definition there can be
@@ -137,6 +138,10 @@
return profileOwner != null ? profileOwner.name : null;
}
+ Set<Integer> getProfileOwnerKeys() {
+ return mProfileOwners.keySet();
+ }
+
boolean hasDeviceOwner() {
return mDeviceOwner != null;
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 1980d1e..edbbc9f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
import com.android.internal.R;
+import com.android.internal.app.IAppOpsService;
import com.android.internal.os.storage.ExternalStorageFormatter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
@@ -237,6 +238,8 @@
}
};
+ private IAppOpsService mAppOpsService;
+
static class ActiveAdmin {
private static final String TAG_DISABLE_KEYGUARD_FEATURES = "disable-keyguard-features";
private static final String TAG_DISABLE_CAMERA = "disable-camera";
@@ -1209,6 +1212,24 @@
loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER);
loadDeviceOwner();
}
+ mAppOpsService = IAppOpsService.Stub.asInterface(
+ ServiceManager.getService(Context.APP_OPS_SERVICE));
+ if (mDeviceOwner != null) {
+ if (mDeviceOwner.hasDeviceOwner()) {
+ try {
+ mAppOpsService.setDeviceOwner(mDeviceOwner.getDeviceOwnerPackageName());
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Unable to notify AppOpsService of DeviceOwner", e);
+ }
+ }
+ for (Integer i : mDeviceOwner.getProfileOwnerKeys()) {
+ try {
+ mAppOpsService.setProfileOwner(mDeviceOwner.getProfileOwnerName(i), i);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Unable to notify AppOpsService of ProfileOwner", e);
+ }
+ }
+ }
}
private void handlePasswordExpirationNotification(int userHandle) {
@@ -2953,6 +2974,14 @@
"Trying to set device owner but device owner is already set.");
}
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppOpsService.setDeviceOwner(packageName);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Unable to notify AppOpsService of DeviceOwner", e);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
if (mDeviceOwner == null) {
// Device owner is not set and does not exist, set it.
mDeviceOwner = DeviceOwner.createWithDeviceOwner(packageName, ownerName);
@@ -3029,6 +3058,14 @@
throw new IllegalStateException(
"Trying to set profile owner but user is already set-up.");
}
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppOpsService.setProfileOwner(packageName, userHandle);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Unable to notify AppOpsService of ProfileOwner", e);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
if (mDeviceOwner == null) {
// Device owner state does not exist, create it.
mDeviceOwner = DeviceOwner.createWithProfileOwner(packageName, ownerName,
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index bdf5561..d31239b 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -567,7 +567,7 @@
StyleResourceValue customStyleValues = null;
if (customStyle != null) {
ResourceValue item = mRenderResources.findResValue(customStyle,
- false /*forceFrameworkOnly*/);
+ isPlatformFile /*forceFrameworkOnly*/);
// resolve it in case it links to something else
item = mRenderResources.resolveResValue(item);