Merge "Fix build, removing hidden attr"
diff --git a/api/current.txt b/api/current.txt
index e15c1d7..c0f44dc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -345,7 +345,7 @@
field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
- field public static final int castsShadow = 16843775; // 0x10103ff
+ field public static final int castsShadow = 16843774; // 0x10103fe
field public static final int category = 16843752; // 0x10103e8
field public static final int centerBright = 16842956; // 0x10100cc
field public static final int centerColor = 16843275; // 0x101020b
@@ -399,10 +399,10 @@
field public static final int content = 16843355; // 0x101025b
field public static final int contentAuthority = 16843408; // 0x1010290
field public static final int contentDescription = 16843379; // 0x1010273
- field public static final int controlX1 = 16843769; // 0x10103f9
- field public static final int controlX2 = 16843771; // 0x10103fb
- field public static final int controlY1 = 16843770; // 0x10103fa
- field public static final int controlY2 = 16843772; // 0x10103fc
+ field public static final int controlX1 = 16843768; // 0x10103f8
+ field public static final int controlX2 = 16843770; // 0x10103fa
+ field public static final int controlY1 = 16843769; // 0x10103f9
+ field public static final int controlY2 = 16843771; // 0x10103fb
field public static final int cropToPadding = 16843043; // 0x1010123
field public static final int cursorVisible = 16843090; // 0x1010152
field public static final int customNavigationLayout = 16843474; // 0x10102d2
@@ -636,7 +636,6 @@
field public static final int isScrollContainer = 16843342; // 0x101024e
field public static final int isSticky = 16843335; // 0x1010247
field public static final int isolatedProcess = 16843689; // 0x10103a9
- field public static final int isolatedZVolume = 16843768; // 0x10103f8
field public static final int itemBackground = 16843056; // 0x1010130
field public static final int itemIconDisabledAlpha = 16843057; // 0x1010131
field public static final int itemPadding = 16843565; // 0x101032d
@@ -889,7 +888,7 @@
field public static final int required = 16843406; // 0x101028e
field public static final int requiredAccountType = 16843734; // 0x10103d6
field public static final int requiredForAllUsers = 16843728; // 0x10103d0
- field public static final int requiredForProfile = 16843776; // 0x1010400
+ field public static final int requiredForProfile = 16843775; // 0x10103ff
field public static final int requiresFadingEdge = 16843685; // 0x10103a5
field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
field public static final int resizeMode = 16843619; // 0x1010363
@@ -960,7 +959,7 @@
field public static final int shadowRadius = 16843108; // 0x1010164
field public static final int shape = 16843162; // 0x101019a
field public static final int shareInterpolator = 16843195; // 0x10101bb
- field public static final int sharedElementName = 16843773; // 0x10103fd
+ field public static final int sharedElementName = 16843772; // 0x10103fc
field public static final int sharedUserId = 16842763; // 0x101000b
field public static final int sharedUserLabel = 16843361; // 0x1010261
field public static final int shouldDisableView = 16843246; // 0x10101ee
@@ -1159,7 +1158,7 @@
field public static final int transformPivotX = 16843552; // 0x1010320
field public static final int transformPivotY = 16843553; // 0x1010321
field public static final int transition = 16843743; // 0x10103df
- field public static final int transitionGroup = 16843774; // 0x10103fe
+ field public static final int transitionGroup = 16843773; // 0x10103fd
field public static final int transitionOrdering = 16843744; // 0x10103e0
field public static final int translationX = 16843554; // 0x1010322
field public static final int translationY = 16843555; // 0x1010323
@@ -29530,7 +29529,6 @@
method public int getLayoutMode();
method public android.animation.LayoutTransition getLayoutTransition();
method public int getPersistentDrawingCache();
- method public boolean hasIsolatedZVolume();
method public int indexOfChild(android.view.View);
method public final void invalidateChild(android.view.View, android.graphics.Rect);
method public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
@@ -29576,7 +29574,6 @@
method public void setClipChildren(boolean);
method public void setClipToPadding(boolean);
method public void setDescendantFocusability(int);
- method public void setIsolatedZVolume(boolean);
method public void setLayoutAnimation(android.view.animation.LayoutAnimationController);
method public void setLayoutAnimationListener(android.view.animation.Animation.AnimationListener);
method public void setLayoutMode(int);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 3258585..ce2d806 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -71,6 +71,7 @@
import android.os.UserHandle;
import android.transition.Scene;
import android.transition.TransitionManager;
+import android.provider.Settings;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
@@ -110,6 +111,7 @@
import java.lang.ref.WeakReference;
import java.net.InetAddress;
import java.security.Security;
+import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -1103,6 +1105,11 @@
public void scheduleInstallProvider(ProviderInfo provider) {
sendMessage(H.INSTALL_PROVIDER, provider);
}
+
+ @Override
+ public final void updateTimePrefs(boolean is24Hour) {
+ DateFormat.set24HourTimePref(is24Hour);
+ }
}
private class H extends Handler {
@@ -1152,6 +1159,7 @@
public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
public static final int INSTALL_PROVIDER = 145;
+
String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
@@ -4215,6 +4223,11 @@
Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
}
}
+
+
+ final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
+ DateFormat.set24HourTimePref(is24Hr);
+
/**
* For system applications on userdebug/eng builds, log stack
* traces of disk and network access to dropbox for analysis.
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 20198f9..f1c632e 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -630,6 +630,15 @@
reply.writeNoException();
return true;
}
+
+ case UPDATE_TIME_PREFS_TRANSACTION:
+ {
+ data.enforceInterface(IApplicationThread.descriptor);
+ byte is24Hour = data.readByte();
+ updateTimePrefs(is24Hour == (byte) 1);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -1273,4 +1282,13 @@
mRemote.transact(SCHEDULE_INSTALL_PROVIDER_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();
}
+
+ @Override
+ public void updateTimePrefs(boolean is24Hour) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(IApplicationThread.descriptor);
+ data.writeByte(is24Hour ? (byte) 1 : (byte) 0);
+ mRemote.transact(UPDATE_TIME_PREFS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+ data.recycle();
+ }
}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 1ea9d87..ac8ac8f 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -139,6 +139,7 @@
throws RemoteException;
void setProcessState(int state) throws RemoteException;
void scheduleInstallProvider(ProviderInfo provider) throws RemoteException;
+ void updateTimePrefs(boolean is24Hour) throws RemoteException;
String descriptor = "android.app.IApplicationThread";
@@ -192,4 +193,5 @@
int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
int SCHEDULE_INSTALL_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50;
+ int UPDATE_TIME_PREFS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+51;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index cd1fbf6f..12a8ff6 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -612,6 +612,13 @@
public static final String EXTRA_AS_HEADS_UP = "headsup";
/**
+ * Extra added from {@link Notification.Builder} to indicate that the remote views were inflated
+ * from the builder, as opposed to being created directly from the application.
+ * @hide
+ */
+ public static final String EXTRA_BUILDER_REMOTE_VIEWS = "android.builderRemoteViews";
+
+ /**
* Value for {@link #EXTRA_AS_HEADS_UP}.
* @hide
*/
@@ -1273,6 +1280,7 @@
private boolean mShowWhen = true;
private int mVisibility = VISIBILITY_PRIVATE;
private Notification mPublicVersion = null;
+ private boolean mQuantumTheme;
/**
* Constructs a new Builder with the defaults:
@@ -1300,6 +1308,9 @@
mWhen = System.currentTimeMillis();
mAudioStreamType = STREAM_DEFAULT;
mPriority = PRIORITY_DEFAULT;
+
+ // TODO: Decide on targetSdk from calling app whether to use quantum theme.
+ mQuantumTheme = true;
}
/**
@@ -1807,7 +1818,7 @@
contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
smallIconImageViewId = R.id.right_icon;
}
- if (mPriority < PRIORITY_LOW) {
+ if (!mQuantumTheme && mPriority < PRIORITY_LOW) {
contentView.setInt(R.id.icon,
"setBackgroundResource", R.drawable.notification_template_icon_low_bg);
contentView.setInt(R.id.status_bar_latest_event_content,
@@ -1921,7 +1932,7 @@
if (mContentView != null) {
return mContentView;
} else {
- return applyStandardTemplate(R.layout.notification_template_base, true); // no more special large_icon flavor
+ return applyStandardTemplate(getBaseLayoutResource(), true); // no more special large_icon flavor
}
}
@@ -1942,21 +1953,21 @@
private RemoteViews makeBigContentView() {
if (mActions.size() == 0) return null;
- return applyStandardTemplateWithActions(R.layout.notification_template_big_base);
+ return applyStandardTemplateWithActions(getBigBaseLayoutResource());
}
- private RemoteViews makeHEadsUpContentView() {
+ private RemoteViews makeHeadsUpContentView() {
if (mActions.size() == 0) return null;
- return applyStandardTemplateWithActions(R.layout.notification_template_big_base);
+ return applyStandardTemplateWithActions(getBigBaseLayoutResource());
}
private RemoteViews generateActionButton(Action action) {
final boolean tombstone = (action.actionIntent == null);
RemoteViews button = new RemoteViews(mContext.getPackageName(),
- tombstone ? R.layout.notification_action_tombstone
- : R.layout.notification_action);
+ tombstone ? getActionTombstoneLayoutResource()
+ : getActionLayoutResource());
button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
button.setTextViewText(R.id.action0, action.title);
if (!tombstone) {
@@ -1992,7 +2003,7 @@
n.defaults = mDefaults;
n.flags = mFlags;
n.bigContentView = makeBigContentView();
- n.headsUpContentView = makeHEadsUpContentView();
+ n.headsUpContentView = makeHeadsUpContentView();
if (mLedOnMs != 0 || mLedOffMs != 0) {
n.flags |= FLAG_SHOW_LIGHTS;
}
@@ -2037,6 +2048,7 @@
extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate);
extras.putBoolean(EXTRA_SHOW_CHRONOMETER, mUseChronometer);
extras.putBoolean(EXTRA_SHOW_WHEN, mShowWhen);
+ extras.putBoolean(EXTRA_BUILDER_REMOTE_VIEWS, mContentView == null);
if (mLargeIcon != null) {
extras.putParcelable(EXTRA_LARGE_ICON, mLargeIcon);
}
@@ -2080,6 +2092,49 @@
build().cloneInto(n, true);
return n;
}
+
+
+ private int getBaseLayoutResource() {
+ return mQuantumTheme
+ ? R.layout.notification_template_quantum_base
+ : R.layout.notification_template_base;
+ }
+
+ private int getBigBaseLayoutResource() {
+ return mQuantumTheme
+ ? R.layout.notification_template_quantum_big_base
+ : R.layout.notification_template_big_base;
+ }
+
+ private int getBigPictureLayoutResource() {
+ return mQuantumTheme
+ ? R.layout.notification_template_quantum_big_picture
+ : R.layout.notification_template_big_picture;
+ }
+
+ private int getBigTextLayoutResource() {
+ return mQuantumTheme
+ ? R.layout.notification_template_quantum_big_text
+ : R.layout.notification_template_big_text;
+ }
+
+ private int getInboxLayoutResource() {
+ return mQuantumTheme
+ ? R.layout.notification_template_quantum_inbox
+ : R.layout.notification_template_inbox;
+ }
+
+ private int getActionLayoutResource() {
+ return mQuantumTheme
+ ? R.layout.notification_quantum_action
+ : R.layout.notification_action;
+ }
+
+ private int getActionTombstoneLayoutResource() {
+ return mQuantumTheme
+ ? R.layout.notification_quantum_action_tombstone
+ : R.layout.notification_action_tombstone;
+ }
}
/**
@@ -2249,7 +2304,7 @@
}
private RemoteViews makeBigContentView() {
- RemoteViews contentView = getStandardView(R.layout.notification_template_big_picture);
+ RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource());
contentView.setImageViewBitmap(R.id.big_picture, mPicture);
@@ -2348,7 +2403,7 @@
final boolean hadThreeLines = (mBuilder.mContentText != null && mBuilder.mSubText != null);
mBuilder.mContentText = null;
- RemoteViews contentView = getStandardView(R.layout.notification_template_big_text);
+ RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource());
if (hadThreeLines) {
// vertical centering
@@ -2442,7 +2497,7 @@
private RemoteViews makeBigContentView() {
// Remove the content text so line3 disappears unless you have a summary
mBuilder.mContentText = null;
- RemoteViews contentView = getStandardView(R.layout.notification_template_inbox);
+ RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource());
contentView.setViewVisibility(R.id.text2, View.GONE);
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index b8b8f5f..333f825 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -79,6 +79,13 @@
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_HANDSHAKE =
+ "android.bluetooth.input.profile.action.HANDSHAKE";
+
+ /**
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_REPORT =
"android.bluetooth.input.profile.action.REPORT";
@@ -185,6 +192,11 @@
/**
* @hide
*/
+ public static final String EXTRA_STATUS = "android.bluetooth.BluetoothInputDevice.extra.STATUS";
+
+ /**
+ * @hide
+ */
public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS";
private Context mContext;
@@ -608,7 +620,7 @@
* @hide
*/
public boolean setReport(BluetoothDevice device, byte reportType, String report) {
- if (DBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
+ if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.setReport(device, reportType, report);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3fdb6e7..f0b7ca8 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3334,6 +3334,15 @@
public static final String EXTRA_SHUTDOWN_USERSPACE_ONLY
= "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
+ /**
+ * Optional boolean extra for {@link #ACTION_TIME_CHANGED} that indicates the
+ * user has set their time format preferences to the 24 hour format.
+ *
+ * @hide for internal use only.
+ */
+ public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT =
+ "android.intent.extra.TIME_PREF_24_HOUR_FORMAT";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 2893522..419abf2 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -315,6 +315,24 @@
return mDefaultColor;
}
+ /**
+ * Return the states in this {@link ColorStateList}.
+ * @return the states in this {@link ColorStateList}
+ * @hide
+ */
+ public int[][] getStates() {
+ return mStateSpecs;
+ }
+
+ /**
+ * Return the colors in this {@link ColorStateList}.
+ * @return the colors in this {@link ColorStateList}
+ * @hide
+ */
+ public int[] getColors() {
+ return mColors;
+ }
+
@Override
public String toString() {
return "ColorStateList{" +
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index da6ae56..5c27072 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1625,7 +1625,7 @@
String locale = null;
if (mConfiguration.locale != null) {
- locale = localeToLanguageTag(mConfiguration.locale);
+ locale = adjustLanguageTag(localeToLanguageTag(mConfiguration.locale));
}
int width, height;
if (mMetrics.widthPixels >= mMetrics.heightPixels) {
@@ -1713,6 +1713,41 @@
}
/**
+ * {@code Locale.toLanguageTag} will transform the obsolete (and deprecated)
+ * language codes "in", "ji" and "iw" to "id", "yi" and "he" respectively.
+ *
+ * All released versions of android prior to "L" used the deprecated language
+ * tags, so we will need to support them for backwards compatibility.
+ *
+ * Note that this conversion needs to take place *after* the call to
+ * {@code toLanguageTag} because that will convert all the deprecated codes to
+ * the new ones, even if they're set manually.
+ */
+ private static String adjustLanguageTag(String languageTag) {
+ final int separator = languageTag.indexOf('-');
+ final String language;
+ final String remainder;
+
+ if (separator == -1) {
+ language = languageTag;
+ remainder = "";
+ } else {
+ language = languageTag.substring(0, separator);
+ remainder = languageTag.substring(separator);
+ }
+
+ if ("id".equals(language)) {
+ return "in" + remainder;
+ } else if ("yi".equals(language)) {
+ return "ji" + remainder;
+ } else if ("he".equals(language)) {
+ return "iw" + remainder;
+ } else {
+ return languageTag;
+ }
+ }
+
+ /**
* Update the system resources configuration if they have previously
* been initialized.
*
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 9f1e72d..c88b4c0 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -28,6 +28,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOverlay;
+import android.view.WindowId;
import android.widget.ListView;
import android.widget.Spinner;
@@ -496,7 +497,8 @@
view = (start != null) ? start.view : null;
}
if (animator != null) {
- AnimationInfo info = new AnimationInfo(view, getName(), infoValues);
+ AnimationInfo info = new AnimationInfo(view, getName(),
+ sceneRoot.getWindowId(), infoValues);
runningAnimators.put(animator, info);
mAnimators.add(animator);
}
@@ -1199,13 +1201,17 @@
*
* @hide
*/
- public void pause() {
+ public void pause(View sceneRoot) {
if (!mEnded) {
ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
int numOldAnims = runningAnimators.size();
+ WindowId windowId = sceneRoot.getWindowId();
for (int i = numOldAnims - 1; i >= 0; i--) {
- Animator anim = runningAnimators.keyAt(i);
- anim.pause();
+ AnimationInfo info = runningAnimators.valueAt(i);
+ if (info.view != null && windowId.equals(info.windowId)) {
+ Animator anim = runningAnimators.keyAt(i);
+ anim.pause();
+ }
}
if (mListeners != null && mListeners.size() > 0) {
ArrayList<TransitionListener> tmpListeners =
@@ -1226,14 +1232,18 @@
*
* @hide
*/
- public void resume() {
+ public void resume(View sceneRoot) {
if (mPaused) {
if (!mEnded) {
ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
int numOldAnims = runningAnimators.size();
+ WindowId windowId = sceneRoot.getWindowId();
for (int i = numOldAnims - 1; i >= 0; i--) {
- Animator anim = runningAnimators.keyAt(i);
- anim.resume();
+ AnimationInfo info = runningAnimators.valueAt(i);
+ if (info.view != null && windowId.equals(info.windowId)) {
+ Animator anim = runningAnimators.keyAt(i);
+ anim.resume();
+ }
}
if (mListeners != null && mListeners.size() > 0) {
ArrayList<TransitionListener> tmpListeners =
@@ -1644,11 +1654,13 @@
public View view;
String name;
TransitionValues values;
+ WindowId windowId;
- AnimationInfo(View view, String name, TransitionValues values) {
+ AnimationInfo(View view, String name, WindowId windowId, TransitionValues values) {
this.view = view;
this.name = name;
this.values = values;
+ this.windowId = windowId;
}
}
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index f3abfb0..1614d34 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -302,7 +302,7 @@
ArrayList<Transition> runningTransitions = getRunningTransitions().get(mSceneRoot);
if (runningTransitions != null && runningTransitions.size() > 0) {
for (Transition runningTransition : runningTransitions) {
- runningTransition.resume();
+ runningTransition.resume(mSceneRoot);
}
}
mTransition.clearValues(true);
@@ -335,7 +335,7 @@
mTransition.captureValues(mSceneRoot, false);
if (previousRunningTransitions != null) {
for (Transition runningTransition : previousRunningTransitions) {
- runningTransition.resume();
+ runningTransition.resume(mSceneRoot);
}
}
mTransition.playTransition(mSceneRoot);
@@ -351,7 +351,7 @@
if (runningTransitions != null && runningTransitions.size() > 0) {
for (Transition runningTransition : runningTransitions) {
- runningTransition.pause();
+ runningTransition.pause(sceneRoot);
}
}
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 4545e3b..19d6b3d 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -317,21 +317,21 @@
/** @hide */
@Override
- public void pause() {
- super.pause();
+ public void pause(View sceneRoot) {
+ super.pause(sceneRoot);
int numTransitions = mTransitions.size();
for (int i = 0; i < numTransitions; ++i) {
- mTransitions.get(i).pause();
+ mTransitions.get(i).pause(sceneRoot);
}
}
/** @hide */
@Override
- public void resume() {
- super.resume();
+ public void resume(View sceneRoot) {
+ super.resume(sceneRoot);
int numTransitions = mTransitions.size();
for (int i = 0; i < numTransitions; ++i) {
- mTransitions.get(i).resume();
+ mTransitions.get(i).resume(sceneRoot);
}
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 9b23b35..1f211c2 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -255,8 +255,9 @@
updateWindow(false, false);
}
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
+ protected void onDetachedFromWindowInternal() {
if (mGlobalListenersAdded) {
ViewTreeObserver observer = getViewTreeObserver();
observer.removeOnScrollChangedListener(mScrollChangedListener);
@@ -278,7 +279,7 @@
mSession = null;
mLayout.token = null;
- super.onDetachedFromWindow();
+ super.onDetachedFromWindowInternal();
}
@Override
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index ef0d80d..3cfe5e9 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -228,10 +228,11 @@
}
}
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
+ protected void onDetachedFromWindowInternal() {
destroySurface();
+ super.onDetachedFromWindowInternal();
}
private void destroySurface() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index afa63a2..827c4cc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13116,6 +13116,19 @@
* @see #onAttachedToWindow()
*/
protected void onDetachedFromWindow() {
+ }
+
+ /**
+ * This is a framework-internal mirror of onDetachedFromWindow() that's called
+ * after onDetachedFromWindow().
+ *
+ * If you override this you *MUST* call super.onDetachedFromWindowInternal()!
+ * The super method should be called at the end of the overriden method to ensure
+ * subclasses are destroyed first
+ *
+ * @hide
+ */
+ protected void onDetachedFromWindowInternal() {
mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
@@ -13303,6 +13316,7 @@
}
onDetachedFromWindow();
+ onDetachedFromWindowInternal();
ListenerInfo li = mListenerInfo;
final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9c50323..f9b9401 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3166,6 +3166,8 @@
* @see #setIsolatedZVolume(boolean)
*
* @return True if the ViewGroup has an isolated Z volume.
+ *
+ * @hide
*/
public boolean hasIsolatedZVolume() {
return ((mGroupFlags & FLAG_ISOLATED_Z_VOLUME) != 0);
@@ -3180,6 +3182,8 @@
* ordering space, false if its decendents should inhabit the
* inherited Z ordering volume.
* @attr ref android.R.styleable#ViewGroup_isolatedZVolume
+ *
+ * @hide
*/
public void setIsolatedZVolume(boolean isolateZVolume) {
boolean previousValue = (mGroupFlags & FLAG_ISOLATED_Z_VOLUME) != 0;
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 9f2bf33..f8160c8 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -37,6 +37,7 @@
import android.util.Slog;
import android.util.Xml;
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
+import android.view.inputmethod.InputMethodSubtypeArray;
import java.io.IOException;
import java.util.ArrayList;
@@ -86,9 +87,9 @@
final int mIsDefaultResId;
/**
- * The array of the subtypes.
+ * An array-like container of the subtypes.
*/
- private final ArrayList<InputMethodSubtype> mSubtypes = new ArrayList<InputMethodSubtype>();
+ private final InputMethodSubtypeArray mSubtypes;
private final boolean mIsAuxIme;
@@ -138,6 +139,7 @@
int isDefaultResId = 0;
XmlResourceParser parser = null;
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
try {
parser = si.loadXmlMetaData(pm, InputMethod.SERVICE_META_DATA);
if (parser == null) {
@@ -206,7 +208,7 @@
if (!subtype.isAuxiliary()) {
isAuxIme = false;
}
- mSubtypes.add(subtype);
+ subtypes.add(subtype);
}
}
} catch (NameNotFoundException e) {
@@ -216,7 +218,7 @@
if (parser != null) parser.close();
}
- if (mSubtypes.size() == 0) {
+ if (subtypes.size() == 0) {
isAuxIme = false;
}
@@ -225,14 +227,15 @@
final int N = additionalSubtypes.size();
for (int i = 0; i < N; ++i) {
final InputMethodSubtype subtype = additionalSubtypes.get(i);
- if (!mSubtypes.contains(subtype)) {
- mSubtypes.add(subtype);
+ if (!subtypes.contains(subtype)) {
+ subtypes.add(subtype);
} else {
Slog.w(TAG, "Duplicated subtype definition found: "
+ subtype.getLocale() + ", " + subtype.getMode());
}
}
}
+ mSubtypes = new InputMethodSubtypeArray(subtypes);
mSettingsActivityName = settingsActivityComponent;
mIsDefaultResId = isDefaultResId;
mIsAuxIme = isAuxIme;
@@ -246,7 +249,7 @@
mIsAuxIme = source.readInt() == 1;
mSupportsSwitchingToNextInputMethod = source.readInt() == 1;
mService = ResolveInfo.CREATOR.createFromParcel(source);
- source.readTypedList(mSubtypes, InputMethodSubtype.CREATOR);
+ mSubtypes = new InputMethodSubtypeArray(source);
mForceDefault = false;
}
@@ -272,9 +275,7 @@
mSettingsActivityName = settingsActivity;
mIsDefaultResId = isDefaultResId;
mIsAuxIme = isAuxIme;
- if (subtypes != null) {
- mSubtypes.addAll(subtypes);
- }
+ mSubtypes = new InputMethodSubtypeArray(subtypes);
mForceDefault = forceDefault;
mSupportsSwitchingToNextInputMethod = true;
}
@@ -364,7 +365,7 @@
* composed of {@link #getPackageName} and the class name returned here.
*
* <p>A null will be returned if there is no settings activity associated
- * with the input method.
+ * with the input method.</p>
*/
public String getSettingsActivity() {
return mSettingsActivityName;
@@ -374,7 +375,7 @@
* Return the count of the subtypes of Input Method.
*/
public int getSubtypeCount() {
- return mSubtypes.size();
+ return mSubtypes.getCount();
}
/**
@@ -479,7 +480,7 @@
dest.writeInt(mIsAuxIme ? 1 : 0);
dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0);
mService.writeToParcel(dest, flags);
- dest.writeTypedList(mSubtypes);
+ mSubtypes.writeToParcel(dest);
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
new file mode 100644
index 0000000..5bef71f
--- /dev/null
+++ b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2007-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.view.inputmethod;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AndroidRuntimeException;
+import android.util.Slog;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * An array-like container that stores multiple instances of {@link InputMethodSubtype}.
+ *
+ * <p>This container is designed to reduce the risk of {@link TransactionTooLargeException}
+ * when one or more instancess of {@link InputMethodInfo} are transferred through IPC.
+ * Basically this class does following three tasks.</p>
+ * <ul>
+ * <li>Applying compression for the marshalled data</li>
+ * <li>Lazily unmarshalling objects</li>
+ * <li>Caching the marshalled data when appropriate</li>
+ * </ul>
+ *
+ * @hide
+ */
+public class InputMethodSubtypeArray {
+ private final static String TAG = "InputMethodSubtypeArray";
+
+ /**
+ * Create a new instance of {@link InputMethodSubtypeArray} from an existing list of
+ * {@link InputMethodSubtype}.
+ *
+ * @param subtypes A list of {@link InputMethodSubtype} from which
+ * {@link InputMethodSubtypeArray} will be created.
+ */
+ public InputMethodSubtypeArray(final List<InputMethodSubtype> subtypes) {
+ if (subtypes == null) {
+ mCount = 0;
+ return;
+ }
+ mCount = subtypes.size();
+ mInstance = subtypes.toArray(new InputMethodSubtype[mCount]);
+ }
+
+ /**
+ * Unmarshall an instance of {@link InputMethodSubtypeArray} from a given {@link Parcel}
+ * object.
+ *
+ * @param source A {@link Parcel} object from which {@link InputMethodSubtypeArray} will be
+ * unmarshalled.
+ */
+ public InputMethodSubtypeArray(final Parcel source) {
+ mCount = source.readInt();
+ if (mCount > 0) {
+ mDecompressedSize = source.readInt();
+ mCompressedData = source.createByteArray();
+ }
+ }
+
+ /**
+ * Marshall the instance into a given {@link Parcel} object.
+ *
+ * <p>This methods may take a bit additional time to compress data lazily when called
+ * first time.</p>
+ *
+ * @param source A {@link Parcel} object to which {@link InputMethodSubtypeArray} will be
+ * marshalled.
+ */
+ public void writeToParcel(final Parcel dest) {
+ if (mCount == 0) {
+ dest.writeInt(mCount);
+ return;
+ }
+
+ byte[] compressedData = mCompressedData;
+ int decompressedSize = mDecompressedSize;
+ if (compressedData == null && decompressedSize == 0) {
+ synchronized (mLockObject) {
+ compressedData = mCompressedData;
+ decompressedSize = mDecompressedSize;
+ if (compressedData == null && decompressedSize == 0) {
+ final byte[] decompressedData = marshall(mInstance);
+ compressedData = compress(decompressedData);
+ if (compressedData == null) {
+ decompressedSize = -1;
+ Slog.i(TAG, "Failed to compress data.");
+ } else {
+ decompressedSize = decompressedData.length;
+ }
+ mDecompressedSize = decompressedSize;
+ mCompressedData = compressedData;
+ }
+ }
+ }
+
+ if (compressedData != null && decompressedSize > 0) {
+ dest.writeInt(mCount);
+ dest.writeInt(decompressedSize);
+ dest.writeByteArray(compressedData);
+ } else {
+ Slog.i(TAG, "Unexpected state. Behaving as an empty array.");
+ dest.writeInt(0);
+ }
+ }
+
+ /**
+ * Return {@link InputMethodSubtype} specified with the given index.
+ *
+ * <p>This methods may take a bit additional time to decompress data lazily when called
+ * first time.</p>
+ *
+ * @param index The index of {@link InputMethodSubtype}.
+ */
+ public InputMethodSubtype get(final int index) {
+ if (index < 0 || mCount <= index) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ InputMethodSubtype[] instance = mInstance;
+ if (instance == null) {
+ synchronized (mLockObject) {
+ instance = mInstance;
+ if (instance == null) {
+ final byte[] decompressedData =
+ decompress(mCompressedData, mDecompressedSize);
+ // Clear the compressed data until {@link #getMarshalled()} is called.
+ mCompressedData = null;
+ mDecompressedSize = 0;
+ if (decompressedData != null) {
+ instance = unmarshall(decompressedData);
+ } else {
+ Slog.e(TAG, "Failed to decompress data. Returns null as fallback.");
+ instance = new InputMethodSubtype[mCount];
+ }
+ mInstance = instance;
+ }
+ }
+ }
+ return instance[index];
+ }
+
+ /**
+ * Return the number of {@link InputMethodSubtype} objects.
+ */
+ public int getCount() {
+ return mCount;
+ }
+
+ private final Object mLockObject = new Object();
+ private final int mCount;
+
+ private volatile InputMethodSubtype[] mInstance;
+ private volatile byte[] mCompressedData;
+ private volatile int mDecompressedSize;
+
+ private static byte[] marshall(final InputMethodSubtype[] array) {
+ Parcel parcel = null;
+ try {
+ parcel = Parcel.obtain();
+ parcel.writeTypedArray(array, 0);
+ return parcel.marshall();
+ } finally {
+ if (parcel != null) {
+ parcel.recycle();
+ parcel = null;
+ }
+ }
+ }
+
+ private static InputMethodSubtype[] unmarshall(final byte[] data) {
+ Parcel parcel = null;
+ try {
+ parcel = Parcel.obtain();
+ parcel.unmarshall(data, 0, data.length);
+ parcel.setDataPosition(0);
+ return parcel.createTypedArray(InputMethodSubtype.CREATOR);
+ } finally {
+ if (parcel != null) {
+ parcel.recycle();
+ parcel = null;
+ }
+ }
+ }
+
+ private static byte[] compress(final byte[] data) {
+ ByteArrayOutputStream resultStream = null;
+ GZIPOutputStream zipper = null;
+ try {
+ resultStream = new ByteArrayOutputStream();
+ zipper = new GZIPOutputStream(resultStream);
+ zipper.write(data);
+ } catch(IOException e) {
+ return null;
+ } finally {
+ try {
+ if (zipper != null) {
+ zipper.close();
+ }
+ } catch (IOException e) {
+ zipper = null;
+ Slog.e(TAG, "Failed to close the stream.", e);
+ // swallowed, not propagated back to the caller
+ }
+ try {
+ if (resultStream != null) {
+ resultStream.close();
+ }
+ } catch (IOException e) {
+ resultStream = null;
+ Slog.e(TAG, "Failed to close the stream.", e);
+ // swallowed, not propagated back to the caller
+ }
+ }
+ return resultStream != null ? resultStream.toByteArray() : null;
+ }
+
+ private static byte[] decompress(final byte[] data, final int expectedSize) {
+ ByteArrayInputStream inputStream = null;
+ GZIPInputStream unzipper = null;
+ try {
+ inputStream = new ByteArrayInputStream(data);
+ unzipper = new GZIPInputStream(inputStream);
+ final byte [] result = new byte[expectedSize];
+ int totalReadBytes = 0;
+ while (totalReadBytes < result.length) {
+ final int restBytes = result.length - totalReadBytes;
+ final int readBytes = unzipper.read(result, totalReadBytes, restBytes);
+ if (readBytes < 0) {
+ break;
+ }
+ totalReadBytes += readBytes;
+ }
+ if (expectedSize != totalReadBytes) {
+ return null;
+ }
+ return result;
+ } catch(IOException e) {
+ return null;
+ } finally {
+ try {
+ if (unzipper != null) {
+ unzipper.close();
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close the stream.", e);
+ // swallowed, not propagated back to the caller
+ }
+ try {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close the stream.", e);
+ // swallowed, not propagated back to the caller
+ }
+ }
+ }
+}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 826bcec..81d36a4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2139,10 +2139,11 @@
mProvider.getViewDelegate().onAttachedToWindow();
}
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
+ protected void onDetachedFromWindowInternal() {
mProvider.getViewDelegate().onDetachedFromWindow();
- super.onDetachedFromWindow();
+ super.onDetachedFromWindowInternal();
}
@Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index e5cb16f..687036c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4729,10 +4729,9 @@
if (mEditor != null) mEditor.onAttachedToWindow();
}
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
+ protected void onDetachedFromWindowInternal() {
if (mPreDrawRegistered) {
getViewTreeObserver().removeOnPreDrawListener(this);
mPreDrawRegistered = false;
@@ -4741,6 +4740,8 @@
resetResolvedDrawables();
if (mEditor != null) mEditor.onDetachedFromWindow();
+
+ super.onDetachedFromWindowInternal();
}
@Override
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 325a27d..e51345c 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -32,7 +32,9 @@
* this file.
*/
interface IInputMethodManager {
+ // TODO: Use ParceledListSlice instead
List<InputMethodInfo> getInputMethodList();
+ // TODO: Use ParceledListSlice instead
List<InputMethodInfo> getEnabledInputMethodList();
List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,
boolean allowsImplicitlySelectedSubtypes);
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 9fefd00..b479cb1 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -58,7 +58,9 @@
PackageManager pm = context.getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER)
&& pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT)
- && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);
+ && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
+ && context.getResources().getBoolean(
+ com.android.internal.R.bool.config_supportAutoRotation);
}
/**
@@ -184,6 +186,7 @@
*/
public static abstract class RotationPolicyListener {
final ContentObserver mObserver = new ContentObserver(new Handler()) {
+ @Override
public void onChange(boolean selfChange, Uri uri) {
RotationPolicyListener.this.onChange();
}
diff --git a/core/res/res/drawable/notification_quantum_background.xml b/core/res/res/drawable/notification_quantum_background.xml
new file mode 100644
index 0000000..f33e2e3
--- /dev/null
+++ b/core/res/res/drawable/notification_quantum_background.xml
@@ -0,0 +1,21 @@
+<?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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#ffffffff" />
+ <corners android:radius="2dp" />
+</shape>
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_quantum_bg.xml b/core/res/res/drawable/notification_quantum_bg.xml
new file mode 100644
index 0000000..608115e
--- /dev/null
+++ b/core/res/res/drawable/notification_quantum_bg.xml
@@ -0,0 +1,21 @@
+<?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
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/notification_quantum_press" />
+ <item android:state_pressed="false" android:drawable="@drawable/notification_quantum_background" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_quantum_press.xml b/core/res/res/drawable/notification_quantum_press.xml
new file mode 100644
index 0000000..4999f55
--- /dev/null
+++ b/core/res/res/drawable/notification_quantum_press.xml
@@ -0,0 +1,21 @@
+<?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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#ffcccccc" />
+ <corners android:radius="2dp" />
+</shape>
\ No newline at end of file
diff --git a/core/res/res/layout/notification_quantum_action.xml b/core/res/res/layout/notification_quantum_action.xml
new file mode 100644
index 0000000..775182f
--- /dev/null
+++ b/core/res/res/layout/notification_quantum_action.xml
@@ -0,0 +1,31 @@
+<?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
+ -->
+
+<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="#555555"
+ android:textSize="14dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ />
diff --git a/core/res/res/layout/notification_quantum_action_list.xml b/core/res/res/layout/notification_quantum_action_list.xml
new file mode 100644
index 0000000..a8aef97
--- /dev/null
+++ b/core/res/res/layout/notification_quantum_action_list.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/actions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="gone"
+ android:layout_marginBottom="8dp"
+ android:showDividers="middle"
+ android:divider="?android:attr/listDivider"
+ android:dividerPadding="12dp"
+ >
+ <!-- actions will be added here -->
+</LinearLayout>
diff --git a/core/res/res/layout/notification_quantum_action_tombstone.xml b/core/res/res/layout/notification_quantum_action_tombstone.xml
new file mode 100644
index 0000000..9104991
--- /dev/null
+++ b/core/res/res/layout/notification_quantum_action_tombstone.xml
@@ -0,0 +1,33 @@
+<?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
+ -->
+
+<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="#555555"
+ 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_quantum_base.xml b/core/res/res/layout/notification_template_quantum_base.xml
new file mode 100644
index 0000000..3e97b2a
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_base.xml
@@ -0,0 +1,137 @@
+<?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:background="@android:drawable/notification_quantum_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: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.Quantum.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.Quantum.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.Quantum.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.Quantum.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_big_base.xml b/core/res/res/layout/notification_template_quantum_big_base.xml
new file mode 100644
index 0000000..d860045
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_big_base.xml
@@ -0,0 +1,167 @@
+<?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:background="@android:drawable/notification_quantum_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: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.Quantum.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.Quantum.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.Quantum.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.Quantum.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.Quantum.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="1dp"
+ android:id="@+id/action_divider"
+ android:visibility="gone"
+ android:background="?android:attr/dividerHorizontal" />
+ <include
+ layout="@layout/notification_quantum_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_quantum_big_picture.xml b/core/res/res/layout/notification_template_quantum_big_picture.xml
new file mode 100644
index 0000000..e49c3bd
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_big_picture.xml
@@ -0,0 +1,62 @@
+<?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:background="@android:drawable/notification_quantum_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_quantum_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="#CCEEEEEE"
+ >
+ <include
+ layout="@layout/notification_quantum_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_quantum_big_text.xml b/core/res/res/layout/notification_template_quantum_big_text.xml
new file mode 100644
index 0000000..585be80
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_big_text.xml
@@ -0,0 +1,182 @@
+<?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:background="@android:drawable/notification_quantum_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: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.Quantum.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.Quantum.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.Quantum.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:id="@+id/action_divider"
+ android:visibility="gone"
+ android:background="?android:attr/dividerHorizontal" />
+ <include
+ layout="@layout/notification_quantum_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="1dp"
+ 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.Quantum.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.Quantum.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_inbox.xml b/core/res/res/layout/notification_template_quantum_inbox.xml
new file mode 100644
index 0000000..31ed508
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_inbox.xml
@@ -0,0 +1,266 @@
+<?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:id="@+id/status_bar_latest_event_content"
+ android:background="@android:drawable/notification_quantum_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: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.Quantum.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.Quantum.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.Quantum.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.Quantum.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.Quantum.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.Quantum.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.Quantum.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.Quantum.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.Quantum.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.Quantum.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:id="@+id/action_divider"
+ android:visibility="gone"
+ android:background="?android:attr/dividerHorizontal" />
+ <include
+ layout="@layout/notification_quantum_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: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.Quantum.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.Quantum.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/values/config.xml b/core/res/res/values/config.xml
index 8d68277..cfd4a63 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -370,6 +370,17 @@
<!-- If this is true, key chords can be used to take a screenshot on the device. -->
<bool name="config_enableScreenshotChord">true</bool>
+ <!-- Auto-rotation behavior -->
+
+ <!-- If true, enables auto-rotation features using the accelerometer.
+ Otherwise, auto-rotation is disabled. Applications may still request
+ to use specific orientations but the sensor is ignored and sensor-based
+ orientations are not available. Furthermore, all auto-rotation related
+ settings are omitted from the system UI. In certain situations we may
+ still use the accelerometer to determine the orientation, such as when
+ docked if the dock is configured to enable the accelerometer. -->
+ <bool name="config_supportAutoRotation">true</bool>
+
<!-- If true, the screen can be rotated via the accelerometer in all 4
rotations as the default behavior. -->
<bool name="config_allowAllRotations">false</bool>
@@ -382,57 +393,12 @@
true here reverses that logic. -->
<bool name="config_reverseDefaultRotation">false</bool>
+ <!-- Lid switch behavior -->
+
<!-- The number of degrees to rotate the display when the keyboard is open.
A value of -1 means no change in orientation by default. -->
<integer name="config_lidOpenRotation">-1</integer>
- <!-- The number of degrees to rotate the display when the device is in a desk dock.
- A value of -1 means no change in orientation by default. -->
- <integer name="config_deskDockRotation">-1</integer>
-
- <!-- The number of degrees to rotate the display when the device is in a car dock.
- A value of -1 means no change in orientation by default. -->
- <integer name="config_carDockRotation">-1</integer>
-
- <!-- The number of degrees to rotate the display when the device has HDMI connected
- but is not in a dock. A value of -1 means no change in orientation by default.
- Use -1 except on older devices whose Hardware Composer HAL does not
- provide full support for multiple displays. -->
- <integer name="config_undockedHdmiRotation">-1</integer>
-
- <!-- Control the default UI mode type to use when there is no other type override
- happening. One of the following values (See Configuration.java):
- 1 UI_MODE_TYPE_NORMAL
- 4 UI_MODE_TYPE_TELEVISION
- 5 UI_MODE_TYPE_APPLIANCE
- Any other values will have surprising consequences. -->
- <integer name="config_defaultUiModeType">1</integer>
-
- <!-- Control whether being in the desk dock (and powered) always
- keeps the screen on. By default it stays on when plugged in to
- AC. 0 will not keep it on; or together 1 to stay on when plugged
- in to AC and 2 to stay on when plugged in to USB. (So 3 for both.) -->
- <integer name="config_deskDockKeepsScreenOn">1</integer>
-
- <!-- Control whether being in the car dock (and powered) always
- keeps the screen on. By default it stays on when plugged in to
- AC. 0 will not keep it on; or together 1 to stay on when plugged
- in to AC and 2 to stay on when plugged in to USB. (So 3 for both.) -->
- <integer name="config_carDockKeepsScreenOn">1</integer>
-
- <!-- Control whether being in the desk dock should enable accelerometer
- based screen orientation. This defaults to true because it is
- common for desk docks to be sold in a variety of form factors
- with different orientations. Since we cannot always tell these docks
- apart and the docks cannot report their true orientation on their own,
- we rely on gravity to determine the effective orientation. -->
- <bool name="config_deskDockEnablesAccelerometer">true</bool>
-
- <!-- Control whether being in the car dock should enable accelerometer based
- screen orientation. This defaults to true because putting a device in
- a car dock make the accelerometer more a physical input (like a lid). -->
- <bool name="config_carDockEnablesAccelerometer">true</bool>
-
<!-- Indicate whether the lid state impacts the accessibility of
the physical keyboard. 0 means it doesn't, 1 means it is accessible
when the lid is open, 2 means it is accessible when the lid is
@@ -450,6 +416,60 @@
The default is false. -->
<bool name="config_lidControlsSleep">false</bool>
+ <!-- Desk dock behavior -->
+
+ <!-- The number of degrees to rotate the display when the device is in a desk dock.
+ A value of -1 means no change in orientation by default. -->
+ <integer name="config_deskDockRotation">-1</integer>
+
+ <!-- Control whether being in the desk dock (and powered) always
+ keeps the screen on. By default it stays on when plugged in to
+ AC. 0 will not keep it on; or together 1 to stay on when plugged
+ in to AC and 2 to stay on when plugged in to USB. (So 3 for both.) -->
+ <integer name="config_deskDockKeepsScreenOn">1</integer>
+
+ <!-- Control whether being in the desk dock should enable accelerometer
+ based screen orientation. This defaults to true because it is
+ common for desk docks to be sold in a variety of form factors
+ with different orientations. Since we cannot always tell these docks
+ apart and the docks cannot report their true orientation on their own,
+ we rely on gravity to determine the effective orientation. -->
+ <bool name="config_deskDockEnablesAccelerometer">true</bool>
+
+ <!-- Car dock behavior -->
+
+ <!-- The number of degrees to rotate the display when the device is in a car dock.
+ A value of -1 means no change in orientation by default. -->
+ <integer name="config_carDockRotation">-1</integer>
+
+ <!-- Control whether being in the car dock (and powered) always
+ keeps the screen on. By default it stays on when plugged in to
+ AC. 0 will not keep it on; or together 1 to stay on when plugged
+ in to AC and 2 to stay on when plugged in to USB. (So 3 for both.) -->
+ <integer name="config_carDockKeepsScreenOn">1</integer>
+
+ <!-- Control whether being in the car dock should enable accelerometer based
+ screen orientation. This defaults to true because putting a device in
+ a car dock make the accelerometer more a physical input (like a lid). -->
+
+ <bool name="config_carDockEnablesAccelerometer">true</bool>
+
+ <!-- HDMI behavior -->
+
+ <!-- The number of degrees to rotate the display when the device has HDMI connected
+ but is not in a dock. A value of -1 means no change in orientation by default.
+ Use -1 except on older devices whose Hardware Composer HAL does not
+ provide full support for multiple displays. -->
+ <integer name="config_undockedHdmiRotation">-1</integer>
+
+ <!-- Control the default UI mode type to use when there is no other type override
+ happening. One of the following values (See Configuration.java):
+ 1 UI_MODE_TYPE_NORMAL
+ 4 UI_MODE_TYPE_TELEVISION
+ 5 UI_MODE_TYPE_APPLIANCE
+ Any other values will have surprising consequences. -->
+ <integer name="config_defaultUiModeType">1</integer>
+
<!-- Indicate whether to allow the device to suspend when the screen is off
due to the proximity sensor. This resource should only be set to true
if the sensor HAL correctly handles the proximity sensor as a wake-up source.
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3106daa..3ab3e5d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2098,7 +2098,6 @@
<public type="attr" name="windowContentTransitionManager" />
<public type="attr" name="translationZ" />
<public type="attr" name="tintMode" />
- <public type="attr" name="isolatedZVolume" />
<public type="attr" name="controlX1" />
<public type="attr" name="controlY1" />
<public type="attr" name="controlX2" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index e525ef7..be875ff 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -271,6 +271,33 @@
<item name="android:textColor">#CCCCCC</item>
</style>
+ <style name="TextAppearance.StatusBar.Quantum">
+ </style>
+ <style name="TextAppearance.StatusBar.Quantum.EventContent">
+ <item name="android:textColor">#888888</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: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>
+ </style>
+
<style name="TextAppearance.Small.CalendarViewWeekDayView">
<item name="android:textStyle">bold</item>
</style>
diff --git a/core/res/res/values/styles_micro.xml b/core/res/res/values/styles_micro.xml
index c35bd48..52d90bc 100644
--- a/core/res/res/values/styles_micro.xml
+++ b/core/res/res/values/styles_micro.xml
@@ -25,7 +25,7 @@
<item name="android:solidColor">@android:color/transparent</item>
<item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
<item name="android:selectionDividerHeight">0dip</item>
- <item name="android:selectionDividersDistance">0dip</item>
+ <item name="android:selectionDividersDistance">104dip</item>
<item name="android:internalMinWidth">64dip</item>
<item name="android:internalMaxHeight">180dip</item>
<item name="virtualButtonPressedDrawable">?android:attr/selectableItemBackground</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a4f9762..6624da4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1303,6 +1303,7 @@
<java-symbol type="bool" name="config_lidControlsSleep" />
<java-symbol type="bool" name="config_reverseDefaultRotation" />
<java-symbol type="bool" name="config_showNavigationBar" />
+ <java-symbol type="bool" name="config_supportAutoRotation" />
<java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
<java-symbol type="dimen" name="navigation_bar_height" />
<java-symbol type="dimen" name="navigation_bar_height_landscape" />
@@ -1627,7 +1628,16 @@
<java-symbol type="integer" name="config_maxResolverActivityColumns" />
<java-symbol type="array" name="config_notificationScorers" />
- <!-- From SystemUI -->
+ <java-symbol type="layout" name="notification_quantum_action" />
+ <java-symbol type="layout" name="notification_quantum_action_list" />
+ <java-symbol type="layout" name="notification_quantum_action_tombstone" />
+ <java-symbol type="layout" name="notification_template_quantum_base" />
+ <java-symbol type="layout" name="notification_template_quantum_big_base" />
+ <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" />
+
+ <!-- From SystemUI -->
<java-symbol type="anim" name="push_down_in" />
<java-symbol type="anim" name="push_down_out" />
<java-symbol type="anim" name="push_up_in" />
diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml
index e429f96..7c0b7bc 100644
--- a/core/res/res/values/themes_micro.xml
+++ b/core/res/res/values/themes_micro.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
<resources>
- <style name="Theme.Micro" parent="Theme.Holo">
+ <style name="Theme.Micro" parent="Theme.Holo.NoActionBar">
+ <item name="textViewStyle">@android:style/Widget.Micro.TextView</item>
<item name="numberPickerStyle">@android:style/Widget.Micro.NumberPicker</item>
<item name="windowAnimationStyle">@android:style/Animation.SwipeDismiss</item>
<item name="windowIsFloating">false</item>
diff --git a/core/tests/inputmethodtests/run_core_inputmethod_test.sh b/core/tests/inputmethodtests/run_core_inputmethod_test.sh
index 5e123ec..b0b119b 100755
--- a/core/tests/inputmethodtests/run_core_inputmethod_test.sh
+++ b/core/tests/inputmethodtests/run_core_inputmethod_test.sh
@@ -21,4 +21,4 @@
$COMMAND
fi
-adb shell am instrument -w -e class android.os.InputMethodTest com.android.frameworks.coretests.inputmethod/android.test.InstrumentationTestRunner
+adb shell am instrument -w -e class android.os.InputMethodTest,android.os.InputMethodSubtypeArrayTest com.android.frameworks.coretests.inputmethod/android.test.InstrumentationTestRunner
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java
new file mode 100644
index 0000000..1e0a919
--- /dev/null
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.os;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.inputmethod.InputMethodSubtype;
+import android.view.inputmethod.InputMethodSubtypeArray;
+import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
+
+import java.util.ArrayList;
+
+public class InputMethodSubtypeArrayTest extends InstrumentationTestCase {
+ @SmallTest
+ public void testInstanciate() throws Exception {
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+ subtypes.add(createDummySubtype(0, "en_US"));
+ subtypes.add(createDummySubtype(1, "en_US"));
+ subtypes.add(createDummySubtype(2, "ja_JP"));
+
+ final InputMethodSubtypeArray array = new InputMethodSubtypeArray(subtypes);
+ assertEquals(subtypes.size(), array.getCount());
+ assertEquals(subtypes.get(0), array.get(0));
+ assertEquals(subtypes.get(1), array.get(1));
+ assertEquals(subtypes.get(2), array.get(2));
+
+ final InputMethodSubtypeArray clonedArray = cloneViaParcel(array);
+ assertEquals(subtypes.size(), clonedArray.getCount());
+ assertEquals(subtypes.get(0), clonedArray.get(0));
+ assertEquals(subtypes.get(1), clonedArray.get(1));
+ assertEquals(subtypes.get(2), clonedArray.get(2));
+
+ final InputMethodSubtypeArray clonedClonedArray = cloneViaParcel(clonedArray);
+ assertEquals(clonedArray.getCount(), clonedClonedArray.getCount());
+ assertEquals(clonedArray.get(0), clonedClonedArray.get(0));
+ assertEquals(clonedArray.get(1), clonedClonedArray.get(1));
+ assertEquals(clonedArray.get(2), clonedClonedArray.get(2));
+ }
+
+ InputMethodSubtypeArray cloneViaParcel(final InputMethodSubtypeArray original) {
+ Parcel parcel = null;
+ try {
+ parcel = Parcel.obtain();
+ original.writeToParcel(parcel);
+ parcel.setDataPosition(0);
+ return new InputMethodSubtypeArray(parcel);
+ } finally {
+ if (parcel != null) {
+ parcel.recycle();
+ }
+ }
+ }
+
+ private static InputMethodSubtype createDummySubtype(final int id, final String locale) {
+ final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder();
+ return builder.setSubtypeNameResId(0)
+ .setSubtypeIconResId(0)
+ .setSubtypeId(id)
+ .setSubtypeLocale(locale)
+ .setIsAsciiCapable(true)
+ .build();
+ }
+}
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index c3aa733..0f76486 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -109,6 +109,9 @@
void DisplayList::setData(DisplayListData* data) {
delete mDisplayListData;
mDisplayListData = data;
+ if (mDisplayListData) {
+ Caches::getInstance().registerFunctors(mDisplayListData->functorCount);
+ }
}
/**
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 35327c0..ed98b96 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -38,6 +38,7 @@
libcamera_client \
libmtp \
libusbhost \
+ libjhead \
libexif \
libstagefright_amrnb_common \
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index d3a8b22..a78f16d 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -561,7 +561,7 @@
return JNI_FALSE;
}
- size_t numSubSamples = size / sizeof(size_t);
+ size_t numSubSamples = size / sizeof(int32_t);
if (numSubSamples == 0) {
return JNI_FALSE;
@@ -571,7 +571,7 @@
jboolean isCopy;
jint *dst = env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);
for (size_t i = 0; i < numSubSamples; ++i) {
- dst[i] = ((const size_t *)data)[i];
+ dst[i] = ((const int32_t *)data)[i];
}
env->ReleaseIntArrayElements(numBytesOfEncryptedDataObj, dst, 0);
dst = NULL;
@@ -588,7 +588,7 @@
jboolean isCopy;
jint *dst = env->GetIntArrayElements(numBytesOfPlainDataObj, &isCopy);
for (size_t i = 0; i < numSubSamples; ++i) {
- dst[i] = ((const size_t *)data)[i];
+ dst[i] = ((const int32_t *)data)[i];
}
env->ReleaseIntArrayElements(numBytesOfPlainDataObj, dst, 0);
dst = NULL;
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index f3a7ff7..4e42ae3 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -256,7 +256,7 @@
fields.createConfigMethod,
SkBitmap::kRGB_565_Config);
- size_t width, height;
+ uint32_t width, height;
bool swapWidthAndHeight = false;
if (videoFrame->mRotationAngle == 90 || videoFrame->mRotationAngle == 270) {
width = videoFrame->mHeight;
@@ -287,8 +287,8 @@
if (videoFrame->mDisplayWidth != videoFrame->mWidth ||
videoFrame->mDisplayHeight != videoFrame->mHeight) {
- size_t displayWidth = videoFrame->mDisplayWidth;
- size_t displayHeight = videoFrame->mDisplayHeight;
+ uint32_t displayWidth = videoFrame->mDisplayWidth;
+ uint32_t displayHeight = videoFrame->mDisplayHeight;
if (swapWidthAndHeight) {
displayWidth = videoFrame->mDisplayHeight;
displayHeight = videoFrame->mDisplayWidth;
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 5a2e261..a9322b9 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -595,13 +595,9 @@
mDetached = false;
}
- /**
- * This method is used as part of the View class and is not normally
- * called or subclassed by clients of GLSurfaceView.
- * Must not be called before a renderer has been set.
- */
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
+ protected void onDetachedFromWindowInternal() {
if (LOG_ATTACH_DETACH) {
Log.d(TAG, "onDetachedFromWindow");
}
@@ -609,7 +605,7 @@
mGLThread.requestExitAndWait();
}
mDetached = true;
- super.onDetachedFromWindow();
+ super.onDetachedFromWindowInternal();
}
// ----------------------------------------------------------------------
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..fe6dc52
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..0f9dfc7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..aea75c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..46d2a16
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..704b4ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..d56efb5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..18b6029
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..a4dd087
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..b6ea14e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..95cf67f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..9331e52
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..efd8b9e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..7f441c8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..82c3842
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..ce9bae2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml b/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml
new file mode 100644
index 0000000..cf34ba6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_color_space_alpha"
+ android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml b/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml
new file mode 100644
index 0000000..1806688
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_color_space_alpha"
+ android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml b/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml
new file mode 100644
index 0000000..5f65d8a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_contrast_alpha"
+ android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml b/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml
new file mode 100644
index 0000000..a018929
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_contrast_alpha"
+ android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
new file mode 100644
index 0000000..9018a90
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_inversion_alpha"
+ android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
new file mode 100644
index 0000000..9110201
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_inversion_alpha"
+ android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml b/packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml
new file mode 100644
index 0000000..4ac67c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml
@@ -0,0 +1,22 @@
+<?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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid
+ android:color="@color/notification_icon_legacy_bg_color"/>
+</shape>
diff --git a/packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml b/packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml
new file mode 100644
index 0000000..96c5573
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml
@@ -0,0 +1,21 @@
+<?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
+ -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/notification_icon_legacy_bg" android:insetBottom="8dp"
+ android:insetLeft="8dp" android:insetRight="8dp" android:insetTop="8dp"
+ android:visible="true"/>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index e525fbb..a59dc75 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -39,4 +39,12 @@
<color name="status_bar_clock_color">#FFFFFFFF</color>
<drawable name="notification_item_background_color">#ff111111</drawable>
<drawable name="notification_item_background_color_pressed">#ff454545</drawable>
+ <color name="notification_icon_legacy_bg_color">#ff4285F4</color>
+ <color name="notification_action_legacy_color_filter">#ff555555</color>
+
+ <!-- Tint color for inactive Quick Settings icons. -->
+ <color name="ic_qs_off">#ff404040</color>
+
+ <!-- Tint color for active Quick Settings icons. -->
+ <color name="ic_qs_on">#ffffffff</color>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ImageUtils.java b/packages/SystemUI/src/com/android/systemui/ImageUtils.java
new file mode 100644
index 0000000..540ba20
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ImageUtils.java
@@ -0,0 +1,82 @@
+/*
+ * 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 com.android.systemui;
+
+import android.graphics.Bitmap;
+
+/**
+ * Utility class for image analysis and processing.
+ */
+public class ImageUtils {
+
+ // Amount (max is 255) that two channels can differ before the color is no longer "gray".
+ private static final int TOLERANCE = 20;
+
+ // Alpha amount for which values below are considered transparent.
+ private static final int ALPHA_TOLERANCE = 50;
+
+ private int[] mTempBuffer;
+
+ /**
+ * Checks whether a bitmap is grayscale. Grayscale here means "very close to a perfect
+ * gray".
+ */
+ public boolean isGrayscale(Bitmap bitmap) {
+ final int height = bitmap.getHeight();
+ final int width = bitmap.getWidth();
+ int size = height*width;
+
+ ensureBufferSize(size);
+ bitmap.getPixels(mTempBuffer, 0, width, 0, 0, width, height);
+ for (int i = 0; i < size; i++) {
+ if (!isGrayscale(mTempBuffer[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Makes sure that {@code mTempBuffer} has at least length {@code size}.
+ */
+ private void ensureBufferSize(int size) {
+ if (mTempBuffer == null || mTempBuffer.length < size) {
+ mTempBuffer = new int[size];
+ }
+ }
+
+ /**
+ * Classifies a color as grayscale or not. Grayscale here means "very close to a perfect
+ * gray"; if all three channels are approximately equal, this will return true.
+ *
+ * Note that really transparent colors are always grayscale.
+ */
+ public boolean isGrayscale(int color) {
+ int alpha = 0xFF & (color >> 24);
+ if (alpha < ALPHA_TOLERANCE) {
+ return true;
+ }
+
+ int r = 0xFF & (color >> 16);
+ int g = 0xFF & (color >> 8);
+ int b = 0xFF & color;
+
+ return Math.abs(r - g) < TOLERANCE
+ && Math.abs(r - b) < TOLERANCE
+ && Math.abs(g - b) < TOLERANCE;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
new file mode 100644
index 0000000..feec87c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
@@ -0,0 +1,218 @@
+/*
+ * 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 com.android.systemui.power;
+
+import android.app.AlertDialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+import java.io.PrintWriter;
+
+public class PowerDialogWarnings implements PowerUI.WarningsUI {
+ private static final String TAG = PowerUI.TAG + ".Dialog";
+ private static final boolean DEBUG = PowerUI.DEBUG;
+
+ private final Context mContext;
+
+ private int mBatteryLevel;
+ private int mBucket;
+ private long mScreenOffTime;
+
+ private AlertDialog mInvalidChargerDialog;
+ private AlertDialog mLowBatteryDialog;
+ private TextView mBatteryLevelTextView;
+
+ public PowerDialogWarnings(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void dump(PrintWriter pw) {
+ pw.print("mInvalidChargerDialog=");
+ pw.println(mInvalidChargerDialog == null ? "null" : mInvalidChargerDialog.toString());
+ pw.print("mLowBatteryDialog=");
+ pw.println(mLowBatteryDialog == null ? "null" : mLowBatteryDialog.toString());
+ }
+
+ @Override
+ public void update(int batteryLevel, int bucket, long screenOffTime) {
+ mBatteryLevel = batteryLevel;
+ mBucket = bucket;
+ mScreenOffTime = screenOffTime;
+ }
+
+ @Override
+ public boolean isInvalidChargerWarningShowing() {
+ return mInvalidChargerDialog != null;
+ }
+
+ @Override
+ public void updateLowBatteryWarning() {
+ if (mBatteryLevelTextView != null) {
+ showLowBatteryWarning(false /*playSound*/);
+ }
+ }
+
+ @Override
+ public void dismissLowBatteryWarning() {
+ if (mLowBatteryDialog != null) {
+ Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
+ mLowBatteryDialog.dismiss();
+ }
+ }
+
+ @Override
+ public void showLowBatteryWarning(boolean playSound) {
+ Slog.i(TAG,
+ ((mBatteryLevelTextView == null) ? "showing" : "updating")
+ + " low battery warning: level=" + mBatteryLevel
+ + " [" + mBucket + "]");
+
+ CharSequence levelText = mContext.getString(
+ R.string.battery_low_percent_format, mBatteryLevel);
+
+ if (mBatteryLevelTextView != null) {
+ mBatteryLevelTextView.setText(levelText);
+ } else {
+ View v = View.inflate(mContext, R.layout.battery_low, null);
+ mBatteryLevelTextView = (TextView)v.findViewById(R.id.level_percent);
+
+ mBatteryLevelTextView.setText(levelText);
+
+ AlertDialog.Builder b = new AlertDialog.Builder(mContext);
+ b.setCancelable(true);
+ b.setTitle(R.string.battery_low_title);
+ b.setView(v);
+ b.setIconAttribute(android.R.attr.alertDialogIcon);
+ b.setPositiveButton(android.R.string.ok, null);
+
+ final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_NO_HISTORY);
+ if (intent.resolveActivity(mContext.getPackageManager()) != null) {
+ b.setNegativeButton(R.string.battery_low_why,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ dismissLowBatteryWarning();
+ }
+ });
+ }
+
+ AlertDialog d = b.create();
+ d.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mLowBatteryDialog = null;
+ mBatteryLevelTextView = null;
+ }
+ });
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ d.getWindow().getAttributes().privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ d.show();
+ mLowBatteryDialog = d;
+ if (playSound) {
+ playLowBatterySound();
+ }
+ }
+ }
+
+ private void playLowBatterySound() {
+ final ContentResolver cr = mContext.getContentResolver();
+
+ final int silenceAfter = Settings.Global.getInt(cr,
+ Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
+ final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
+ if (silenceAfter > 0
+ && mScreenOffTime > 0
+ && offTime > silenceAfter) {
+ Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
+ + "ms): not waking up the user with low battery sound");
+ return;
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
+ }
+
+ if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
+ final String soundPath = Settings.Global.getString(cr,
+ Settings.Global.LOW_BATTERY_SOUND);
+ if (soundPath != null) {
+ final Uri soundUri = Uri.parse("file://" + soundPath);
+ if (soundUri != null) {
+ final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+ if (sfx != null) {
+ sfx.setStreamType(AudioManager.STREAM_SYSTEM);
+ sfx.play();
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void dismissInvalidChargerWarning() {
+ if (mInvalidChargerDialog != null) {
+ mInvalidChargerDialog.dismiss();
+ }
+ }
+
+ @Override
+ public void showInvalidChargerWarning() {
+ Slog.d(TAG, "showing invalid charger dialog");
+
+ dismissLowBatteryWarning();
+
+ AlertDialog.Builder b = new AlertDialog.Builder(mContext);
+ b.setCancelable(true);
+ b.setMessage(R.string.invalid_charger);
+ b.setIconAttribute(android.R.attr.alertDialogIcon);
+ b.setPositiveButton(android.R.string.ok, null);
+
+ AlertDialog d = b.create();
+ d.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ public void onDismiss(DialogInterface dialog) {
+ mInvalidChargerDialog = null;
+ mBatteryLevelTextView = null;
+ }
+ });
+
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ d.show();
+ mInvalidChargerDialog = d;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 28c2772..0fb0f8b 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -16,29 +16,17 @@
package com.android.systemui.power;
-import android.app.AlertDialog;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.media.Ringtone;
-import android.media.RingtoneManager;
-import android.net.Uri;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.TextView;
-import com.android.systemui.R;
import com.android.systemui.SystemUI;
import java.io.FileDescriptor;
@@ -50,19 +38,17 @@
static final boolean DEBUG = false;
- Handler mHandler = new Handler();
+ private WarningsUI mWarnings;
- int mBatteryLevel = 100;
- int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
- int mPlugType = 0;
- int mInvalidCharger = 0;
+ private final Handler mHandler = new Handler();
- int mLowBatteryAlertCloseLevel;
- int[] mLowBatteryReminderLevels = new int[2];
+ private int mBatteryLevel = 100;
+ private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ private int mPlugType = 0;
+ private int mInvalidCharger = 0;
- AlertDialog mInvalidChargerDialog;
- AlertDialog mLowBatteryDialog;
- TextView mBatteryLevelTextView;
+ private int mLowBatteryAlertCloseLevel;
+ private final int[] mLowBatteryReminderLevels = new int[2];
private long mScreenOffTime = -1;
@@ -77,6 +63,7 @@
final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
+ mWarnings = new PowerDialogWarnings(mContext);
// Register for Intent broadcasts for...
IntentFilter filter = new IntentFilter();
@@ -145,13 +132,14 @@
Slog.d(TAG, "plugged " + oldPlugged + " --> " + plugged);
}
+ mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);
if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
Slog.d(TAG, "showing invalid charger warning");
- showInvalidChargerDialog();
+ mWarnings.showInvalidChargerWarning();
return;
} else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
- dismissInvalidChargerDialog();
- } else if (mInvalidChargerDialog != null) {
+ mWarnings.dismissInvalidChargerWarning();
+ } else if (mWarnings.isInvalidChargerWarningShowing()) {
// if invalid charger is showing, don't show low battery
return;
}
@@ -160,16 +148,13 @@
&& (bucket < oldBucket || oldPlugged)
&& mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
&& bucket < 0) {
- showLowBatteryWarning();
-
// only play SFX when the dialog comes up or the bucket changes
- if (bucket != oldBucket || oldPlugged) {
- playLowBatterySound();
- }
+ final boolean playSound = bucket != oldBucket || oldPlugged;
+ mWarnings.showLowBatteryWarning(playSound);
} else if (plugged || (bucket > oldBucket && bucket > 0)) {
- dismissLowBatteryWarning();
- } else if (mBatteryLevelTextView != null) {
- showLowBatteryWarning();
+ mWarnings.dismissLowBatteryWarning();
+ } else {
+ mWarnings.updateLowBatteryWarning();
}
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
mScreenOffTime = SystemClock.elapsedRealtime();
@@ -181,142 +166,11 @@
}
};
- void dismissLowBatteryWarning() {
- if (mLowBatteryDialog != null) {
- Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
- mLowBatteryDialog.dismiss();
- }
- }
-
- void showLowBatteryWarning() {
- Slog.i(TAG,
- ((mBatteryLevelTextView == null) ? "showing" : "updating")
- + " low battery warning: level=" + mBatteryLevel
- + " [" + findBatteryLevelBucket(mBatteryLevel) + "]");
-
- CharSequence levelText = mContext.getString(
- R.string.battery_low_percent_format, mBatteryLevel);
-
- if (mBatteryLevelTextView != null) {
- mBatteryLevelTextView.setText(levelText);
- } else {
- View v = View.inflate(mContext, R.layout.battery_low, null);
- mBatteryLevelTextView = (TextView)v.findViewById(R.id.level_percent);
-
- mBatteryLevelTextView.setText(levelText);
-
- AlertDialog.Builder b = new AlertDialog.Builder(mContext);
- b.setCancelable(true);
- b.setTitle(R.string.battery_low_title);
- b.setView(v);
- b.setIconAttribute(android.R.attr.alertDialogIcon);
- b.setPositiveButton(android.R.string.ok, null);
-
- final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- | Intent.FLAG_ACTIVITY_NO_HISTORY);
- if (intent.resolveActivity(mContext.getPackageManager()) != null) {
- b.setNegativeButton(R.string.battery_low_why,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
- dismissLowBatteryWarning();
- }
- });
- }
-
- AlertDialog d = b.create();
- d.setOnDismissListener(new DialogInterface.OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- mLowBatteryDialog = null;
- mBatteryLevelTextView = null;
- }
- });
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- d.getWindow().getAttributes().privateFlags |=
- WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- d.show();
- mLowBatteryDialog = d;
- }
- }
-
- void playLowBatterySound() {
- final ContentResolver cr = mContext.getContentResolver();
-
- final int silenceAfter = Settings.Global.getInt(cr,
- Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
- final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
- if (silenceAfter > 0
- && mScreenOffTime > 0
- && offTime > silenceAfter) {
- Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
- + "ms): not waking up the user with low battery sound");
- return;
- }
-
- if (DEBUG) {
- Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
- }
-
- if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
- final String soundPath = Settings.Global.getString(cr,
- Settings.Global.LOW_BATTERY_SOUND);
- if (soundPath != null) {
- final Uri soundUri = Uri.parse("file://" + soundPath);
- if (soundUri != null) {
- final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
- if (sfx != null) {
- sfx.setStreamType(AudioManager.STREAM_SYSTEM);
- sfx.play();
- }
- }
- }
- }
- }
-
- void dismissInvalidChargerDialog() {
- if (mInvalidChargerDialog != null) {
- mInvalidChargerDialog.dismiss();
- }
- }
-
- void showInvalidChargerDialog() {
- Slog.d(TAG, "showing invalid charger dialog");
-
- dismissLowBatteryWarning();
-
- AlertDialog.Builder b = new AlertDialog.Builder(mContext);
- b.setCancelable(true);
- b.setMessage(R.string.invalid_charger);
- b.setIconAttribute(android.R.attr.alertDialogIcon);
- b.setPositiveButton(android.R.string.ok, null);
-
- AlertDialog d = b.create();
- d.setOnDismissListener(new DialogInterface.OnDismissListener() {
- public void onDismiss(DialogInterface dialog) {
- mInvalidChargerDialog = null;
- mBatteryLevelTextView = null;
- }
- });
-
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- d.show();
- mInvalidChargerDialog = d;
- }
-
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.print("mLowBatteryAlertCloseLevel=");
pw.println(mLowBatteryAlertCloseLevel);
pw.print("mLowBatteryReminderLevels=");
pw.println(Arrays.toString(mLowBatteryReminderLevels));
- pw.print("mInvalidChargerDialog=");
- pw.println(mInvalidChargerDialog == null ? "null" : mInvalidChargerDialog.toString());
- pw.print("mLowBatteryDialog=");
- pw.println(mLowBatteryDialog == null ? "null" : mLowBatteryDialog.toString());
pw.print("mBatteryLevel=");
pw.println(Integer.toString(mBatteryLevel));
pw.print("mBatteryStatus=");
@@ -338,6 +192,18 @@
Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0));
pw.print("bucket: ");
pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
+ mWarnings.dump(pw);
+ }
+
+ public interface WarningsUI {
+ void update(int batteryLevel, int bucket, long screenOffTime);
+ void dismissLowBatteryWarning();
+ void showLowBatteryWarning(boolean playSound);
+ void dismissInvalidChargerWarning();
+ void showInvalidChargerWarning();
+ void updateLowBatteryWarning();
+ boolean isInvalidChargerWarningShowing();
+ void dump(PrintWriter pw);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index fb11743..eb07d88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -28,9 +28,15 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.database.ContentObserver;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
@@ -44,9 +50,13 @@
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
import android.text.TextUtils;
+import android.text.style.TextAppearanceSpan;
import android.util.Log;
import android.util.SparseBooleanArray;
+import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.IWindowManager;
import android.view.LayoutInflater;
@@ -57,6 +67,7 @@
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
@@ -67,6 +78,7 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.widget.SizeAdaptiveLayout;
+import com.android.systemui.ImageUtils;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SearchPanelView;
@@ -76,6 +88,7 @@
import java.util.ArrayList;
import java.util.Locale;
+import java.util.Stack;
public abstract class BaseStatusBar extends SystemUI implements
CommandQueue.Callbacks {
@@ -140,6 +153,8 @@
// public mode, private notifications, etc
private boolean mLockscreenPublicMode = false;
private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
+ private Context mLightThemeContext;
+ private ImageUtils mImageUtils = new ImageUtils();
// UI-specific methods
@@ -261,6 +276,8 @@
true,
mLockscreenSettingsObserver,
UserHandle.USER_ALL);
+ mLightThemeContext = new RemoteViewsThemeContextWrapper(mContext,
+ android.R.style.Theme_Holo_Light);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -412,6 +429,158 @@
}
}
+ private void processLegacyHoloNotification(StatusBarNotification sbn, View content) {
+
+ // TODO: Also skip processing if it is a holo-style notification.
+ // If the notification is custom, we can't process it.
+ if (!sbn.getNotification().extras.getBoolean(Notification.EXTRA_BUILDER_REMOTE_VIEWS)) {
+ return;
+ }
+
+ processLegacyHoloLargeIcon(content);
+ processLegacyHoloActions(content);
+ processLegacyNotificationIcon(content);
+ processLegacyTextViews(content);
+ }
+
+ /**
+ * @return the context to be used for the inflation of the specified {@code sbn}; this is
+ * dependent whether the notification is quantum-style or holo-style
+ */
+ private Context getInflationContext(StatusBarNotification sbn) {
+
+ // TODO: Adjust this logic when we change the theme of the status bar windows.
+ if (sbn.getNotification().extras.getBoolean(Notification.EXTRA_BUILDER_REMOTE_VIEWS)) {
+ return mLightThemeContext;
+ } else {
+ return mContext;
+ }
+ }
+
+ private void processLegacyNotificationIcon(View content) {
+ View v = content.findViewById(com.android.internal.R.id.right_icon);
+ if (v != null & v instanceof ImageView) {
+ ImageView iv = (ImageView) v;
+ Drawable d = iv.getDrawable();
+ if (isMonochrome(d)) {
+ d.mutate();
+ d.setColorFilter(mLightThemeContext.getResources().getColor(
+ R.color.notification_action_legacy_color_filter), PorterDuff.Mode.MULTIPLY);
+ }
+ }
+ }
+
+ private void processLegacyHoloLargeIcon(View content) {
+ View v = content.findViewById(com.android.internal.R.id.icon);
+ if (v != null & v instanceof ImageView) {
+ ImageView iv = (ImageView) v;
+ if (isMonochrome(iv.getDrawable())) {
+ iv.setBackground(mLightThemeContext.getResources().getDrawable(
+ R.drawable.notification_icon_legacy_bg_inset));
+ }
+ }
+ }
+
+ private boolean isMonochrome(Drawable d) {
+ if (d == null) {
+ return false;
+ } else if (d instanceof BitmapDrawable) {
+ BitmapDrawable bd = (BitmapDrawable) d;
+ return bd.getBitmap() != null && mImageUtils.isGrayscale(bd.getBitmap());
+ } else if (d instanceof AnimationDrawable) {
+ AnimationDrawable ad = (AnimationDrawable) d;
+ int count = ad.getNumberOfFrames();
+ return count > 0 && isMonochrome(ad.getFrame(0));
+ } else {
+ return false;
+ }
+ }
+
+ private void processLegacyHoloActions(View content) {
+ View v = content.findViewById(com.android.internal.R.id.actions);
+ if (v != null & v instanceof ViewGroup) {
+ ViewGroup vg = (ViewGroup) v;
+ int childCount = vg.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = vg.getChildAt(i);
+ if (child instanceof Button) {
+ Button button = (Button) child;
+ Drawable[] compoundDrawables = button.getCompoundDrawablesRelative();
+ if (isMonochrome(compoundDrawables[0])) {
+ Drawable d = compoundDrawables[0];
+ d.mutate();
+ d.setColorFilter(mLightThemeContext.getResources().getColor(
+ R.color.notification_action_legacy_color_filter),
+ PorterDuff.Mode.MULTIPLY);
+ }
+ }
+ }
+ }
+ }
+
+ private void processLegacyTextViews(View content) {
+ Stack<View> viewStack = new Stack<View>();
+ viewStack.push(content);
+ while(!viewStack.isEmpty()) {
+ View current = viewStack.pop();
+ if(current instanceof ViewGroup){
+ ViewGroup currentGroup = (ViewGroup) current;
+ int numChildren = currentGroup.getChildCount();
+ for(int i=0;i<numChildren;i++){
+ viewStack.push(currentGroup.getChildAt(i));
+ }
+ }
+ if (current instanceof TextView) {
+ processLegacyTextView((TextView) current);
+ }
+ }
+ }
+
+ private void processLegacyTextView(TextView textView) {
+ if (textView.getText() instanceof Spanned) {
+ Spanned ss = (Spanned) textView.getText();
+ Object[] spans = ss.getSpans(0, ss.length(), Object.class);
+ SpannableStringBuilder builder = new SpannableStringBuilder(ss.toString());
+ for (Object span : spans) {
+ Object resultSpan = span;
+ if (span instanceof TextAppearanceSpan) {
+ resultSpan = processTextAppearanceSpan((TextAppearanceSpan) span);
+ }
+ builder.setSpan(resultSpan, ss.getSpanStart(span), ss.getSpanEnd(span),
+ ss.getSpanFlags(span));
+ }
+ textView.setText(builder);
+ }
+ }
+
+ private TextAppearanceSpan processTextAppearanceSpan(TextAppearanceSpan span) {
+ ColorStateList colorStateList = span.getTextColor();
+ if (colorStateList != null) {
+ int[] colors = colorStateList.getColors();
+ boolean changed = false;
+ for (int i = 0; i < colors.length; i++) {
+ if (mImageUtils.isGrayscale(colors[i])) {
+ colors[i] = processColor(colors[i]);
+ changed = true;
+ }
+ }
+ if (changed) {
+ return new TextAppearanceSpan(
+ span.getFamily(), span.getTextStyle(), span.getTextSize(),
+ new ColorStateList(colorStateList.getStates(), colors),
+ span.getLinkTextColor());
+ }
+ }
+ return span;
+ }
+
+ private int processColor(int color) {
+ return Color.argb(Color.alpha(color),
+ 255 - Color.red(color),
+ 255 - Color.green(color),
+ 255 - Color.blue(color));
+ }
+
private void startApplicationDetailsActivity(String packageName) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null));
@@ -748,9 +917,11 @@
View contentViewLocal = null;
View bigContentViewLocal = null;
try {
- contentViewLocal = contentView.apply(mContext, expanded, mOnClickHandler);
+ contentViewLocal = contentView.apply(getInflationContext(sbn), expanded,
+ mOnClickHandler);
if (bigContentView != null) {
- bigContentViewLocal = bigContentView.apply(mContext, expanded, mOnClickHandler);
+ bigContentViewLocal = bigContentView.apply(getInflationContext(sbn), expanded,
+ mOnClickHandler);
}
}
catch (RuntimeException e) {
@@ -780,7 +951,7 @@
View publicViewLocal = null;
if (publicNotification != null) {
try {
- publicViewLocal = publicNotification.contentView.apply(mContext,
+ publicViewLocal = publicNotification.contentView.apply(getInflationContext(sbn),
expandedPublic, mOnClickHandler);
if (publicViewLocal != null) {
@@ -831,6 +1002,13 @@
row.setDrawingCacheEnabled(true);
applyLegacyRowBackground(sbn, content);
+ processLegacyHoloNotification(sbn, contentViewLocal);
+ if (bigContentViewLocal != null) {
+ processLegacyHoloNotification(sbn, bigContentViewLocal);
+ }
+ if (publicViewLocal != null) {
+ processLegacyHoloNotification(sbn, publicViewLocal);
+ }
if (MULTIUSER_DEBUG) {
TextView debug = (TextView) row.findViewById(R.id.debug_info);
@@ -1245,12 +1423,17 @@
: null;
// Reapply the RemoteViews
- contentView.reapply(mContext, entry.expanded, mOnClickHandler);
+ contentView.reapply(getInflationContext(notification), entry.expanded, mOnClickHandler);
+ processLegacyHoloNotification(notification, entry.expanded);
if (bigContentView != null && entry.getBigContentView() != null) {
- bigContentView.reapply(mContext, entry.getBigContentView(), mOnClickHandler);
+ bigContentView.reapply(getInflationContext(notification), entry.getBigContentView(),
+ mOnClickHandler);
+ processLegacyHoloNotification(notification, entry.getBigContentView());
}
if (publicContentView != null && entry.getPublicContentView() != null) {
- publicContentView.reapply(mContext, entry.getPublicContentView(), mOnClickHandler);
+ publicContentView.reapply(getInflationContext(notification),
+ entry.getPublicContentView(), mOnClickHandler);
+ processLegacyHoloNotification(notification, entry.getPublicContentView());
}
// update the contentIntent
final PendingIntent contentIntent = notification.getNotification().contentIntent;
@@ -1330,4 +1513,35 @@
}
mContext.unregisterReceiver(mBroadcastReceiver);
}
+
+ /**
+ * A custom context theme wrapper that applies a platform theme to a created package context.
+ * This is useful if you want to inflate {@link RemoteViews} with a custom theme (normally, the
+ * theme used there is the default platform theme).
+ */
+ private static class RemoteViewsThemeContextWrapper extends ContextThemeWrapper {
+
+ private int mThemeRes;
+
+ private RemoteViewsThemeContextWrapper(Context base, int themeres) {
+ super(base, themeres);
+ mThemeRes = themeres;
+ }
+
+ @Override
+ public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
+ throws NameNotFoundException {
+ Context c = super.createPackageContextAsUser(packageName, flags, user);
+ c.setTheme(mThemeRes);
+ return c;
+ }
+
+ @Override
+ public Context createPackageContext(String packageName, int flags)
+ throws NameNotFoundException {
+ Context c = super.createPackageContext(packageName, flags);
+ c.setTheme(mThemeRes);
+ return c;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 48ee1ce..174cad8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -996,8 +996,8 @@
mInversionState.toggled = enabled;
mInversionState.type = type;
// TODO: Add real icon assets.
- mInversionState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
- : R.drawable.ic_qs_bluetooth_off;
+ mInversionState.iconId = enabled ? R.drawable.ic_qs_inversion_on
+ : R.drawable.ic_qs_inversion_off;
mInversionState.label = res.getString(R.string.quick_settings_inversion_label);
mInversionCallback.refreshView(mInversionTile, mInversionState);
}
@@ -1026,8 +1026,8 @@
mContrastState.contrast = contrast;
mContrastState.brightness = brightness;
// TODO: Add real icon assets.
- mContrastState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
- : R.drawable.ic_qs_bluetooth_off;
+ mContrastState.iconId = enabled ? R.drawable.ic_qs_contrast_on
+ : R.drawable.ic_qs_contrast_off;
mContrastState.label = res.getString(R.string.quick_settings_contrast_label);
mContrastCallback.refreshView(mContrastTile, mContrastState);
}
@@ -1053,8 +1053,8 @@
mColorSpaceState.toggled = enabled;
mColorSpaceState.type = type;
// TODO: Add real icon assets.
- mColorSpaceState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
- : R.drawable.ic_qs_bluetooth_off;
+ mColorSpaceState.iconId = enabled ? R.drawable.ic_qs_color_space_on
+ : R.drawable.ic_qs_color_space_off;
mColorSpaceState.label = res.getString(R.string.quick_settings_color_space_label);
mColorSpaceCallback.refreshView(mColorSpaceTile, mColorSpaceState);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
index c4d2cce..fa7f96a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
@@ -28,6 +28,8 @@
import android.graphics.Typeface;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.PathShape;
+import android.os.AsyncTask;
+import android.os.Vibrator;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
@@ -45,7 +47,6 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
-import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
@@ -79,6 +80,7 @@
private final Rect mLayoutRect = new Rect();
private final UntilPager mUntilPager;
private final AlarmWarning mAlarmWarning;
+ private final int mPopDuration;
private float mDownY;
private int mDownBottom;
@@ -87,6 +89,7 @@
private int mBottom;
private int mWidthSpec;
private Adapter mAdapter;
+ private boolean mPopped;
public ZenModeView(Context context) {
this(context, null);
@@ -144,7 +147,6 @@
lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
addView(mModeSpinner, lp);
-
mUntilPager = new UntilPager(mContext, mPathPaint, iconSize);
mUntilPager.setId(android.R.id.tabhost);
mUntilPager.setAlpha(0);
@@ -165,6 +167,8 @@
mHintText.setGravity(Gravity.CENTER);
mHintText.setTextColor(GRAY);
addView(mHintText, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+
+ mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms);
}
private boolean isApplicable() {
@@ -180,9 +184,11 @@
public void onAnimationUpdate(ValueAnimator animation) {
final float f = animation.getAnimatedFraction();
final int hintBottom = mHintText.getBottom();
- setPeeked(hintBottom + (int)((1-f) * (startBottom - hintBottom)), max);
- if (f == 1) {
+ final boolean isDone = f == 1;
+ setPeeked(hintBottom + (int)((1-f) * (startBottom - hintBottom)), max, isDone);
+ if (isDone) {
mPeekable = true;
+ mPopped = false;
mClosing = false;
mModeSpinner.updateState();
if (mAdapter != null) {
@@ -335,11 +341,15 @@
return true;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
final float dy = event.getY() - mDownY;
- setPeeked(mDownBottom + (int)dy, getExpandedBottom());
+ if (!mPopped) {
+ mPopped = true;
+ AsyncTask.execute(mPopVibration);
+ }
+ setPeeked(mDownBottom + (int)dy, getExpandedBottom(), false);
} else if (event.getAction() == MotionEvent.ACTION_UP
|| event.getAction() == MotionEvent.ACTION_CANCEL) {
final float dy = event.getY() - mDownY;
- setPeeked(mDownBottom + (int)dy, getExpandedBottom());
+ setPeeked(mDownBottom + (int)dy, getExpandedBottom(), true);
if (mPeekable) {
close();
}
@@ -347,14 +357,14 @@
return rt;
}
- private void setPeeked(int peeked, int max) {
+ private void setPeeked(int peeked, int max, boolean isDone) {
if (DEBUG) log("setPeeked=" + peeked);
final int min = mHintText.getBottom();
peeked = Math.max(min, Math.min(peeked, max));
- if (mBottom == peeked) {
+ if (!isDone && mBottom == peeked) {
return;
}
- if (peeked == max) {
+ if (peeked == max && isDone) {
mPeekable = false;
mModeSpinner.setEnabled(true);
if (mAdapter != null) {
@@ -419,6 +429,14 @@
}).start();
}
+ private final Runnable mPopVibration = new Runnable() {
+ @Override
+ public void run() {
+ Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+ v.vibrate(mPopDuration);
+ }
+ };
+
private final class UntilPager extends RelativeLayout {
private final ImageView mPrev;
private final ImageView mNext;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index abc3fb1..17a0e60 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -286,6 +286,7 @@
int mUserRotation = Surface.ROTATION_0;
boolean mAccelerometerDefault;
+ boolean mSupportAutoRotation;
int mAllowAllRotations = -1;
boolean mCarDockEnablesAccelerometer;
boolean mDeskDockEnablesAccelerometer;
@@ -372,6 +373,7 @@
static final Rect mTmpNavigationFrame = new Rect();
WindowState mTopFullscreenOpaqueWindowState;
+ boolean mHideWindowBehindKeyguard;
boolean mTopIsFullscreen;
boolean mForceStatusBar;
boolean mForceStatusBarFromKeyguard;
@@ -585,13 +587,15 @@
* screen is switched off.
*/
boolean needSensorRunningLp() {
- if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
- // If the application has explicitly requested to follow the
- // orientation, then we need to turn the sensor or.
- return true;
+ if (mSupportAutoRotation) {
+ if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
+ // If the application has explicitly requested to follow the
+ // orientation, then we need to turn the sensor on.
+ return true;
+ }
}
if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) ||
(mDeskDockEnablesAccelerometer && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
@@ -612,7 +616,7 @@
// still be turned off when the screen is off.)
return false;
}
- return true;
+ return mSupportAutoRotation;
}
/*
@@ -877,6 +881,8 @@
mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"PhoneWindowManager.mBroadcastWakeLock");
mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
+ mSupportAutoRotation = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_supportAutoRotation);
mLidOpenRotation = readRotation(
com.android.internal.R.integer.config_lidOpenRotation);
mCarDockRotation = readRotation(
@@ -3355,6 +3361,7 @@
@Override
public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
mTopFullscreenOpaqueWindowState = null;
+ mHideWindowBehindKeyguard = false;
mForceStatusBar = false;
mForceStatusBarFromKeyguard = false;
mForcingShowNavBar = false;
@@ -3391,7 +3398,7 @@
if (attrs.type == TYPE_KEYGUARD) {
mShowingLockscreen = true;
}
- boolean applyWindow = attrs.type >= FIRST_APPLICATION_WINDOW
+ boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
&& attrs.type <= LAST_APPLICATION_WINDOW;
if (attrs.type == TYPE_DREAM) {
// If the lockscreen was showing when the dream started then wait
@@ -3399,30 +3406,35 @@
if (!mDreamingLockscreen
|| (win.isVisibleLw() && win.hasDrawnLw())) {
mShowingDream = true;
- applyWindow = true;
+ appWindow = true;
}
}
- if (applyWindow
- && attrs.x == 0 && attrs.y == 0
- && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
- && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
- mTopFullscreenOpaqueWindowState = win;
- if ((fl & FLAG_SHOW_WHEN_LOCKED) != 0) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mHideLockScreen to true by win " + win);
- mHideLockScreen = true;
- mForceStatusBarFromKeyguard = false;
- }
- if ((fl & FLAG_DISMISS_KEYGUARD) != 0
- && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mDismissKeyguard true by win " + win);
- mDismissKeyguard = mWinDismissingKeyguard == win ?
- DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
- mWinDismissingKeyguard = win;
- mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
- }
- if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
- mAllowLockscreenWhenOn = true;
+
+ final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
+ if (appWindow) {
+ if (attrs.x == 0 && attrs.y == 0
+ && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
+ && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
+ mTopFullscreenOpaqueWindowState = win;
+ if (showWhenLocked && !mHideWindowBehindKeyguard) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mHideLockScreen to true by win " + win);
+ mHideLockScreen = true;
+ mForceStatusBarFromKeyguard = false;
+ }
+ if ((fl & FLAG_DISMISS_KEYGUARD) != 0
+ && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mDismissKeyguard true by win " + win);
+ mDismissKeyguard = mWinDismissingKeyguard == win ?
+ DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
+ mWinDismissingKeyguard = win;
+ mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
+ }
+ if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
+ mAllowLockscreenWhenOn = true;
+ }
+ } else if (!showWhenLocked) {
+ mHideWindowBehindKeyguard = true;
}
}
}
@@ -3509,7 +3521,7 @@
if (mKeyguard != null) {
if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
+ mHideLockScreen);
- if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardDelegate.isSecure()) {
+ if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !isKeyguardSecure()) {
if (mKeyguard.hideLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
@@ -4481,6 +4493,10 @@
} else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
// Application just wants to remain locked in the last rotation.
preferredRotation = lastRotation;
+ } else if (!mSupportAutoRotation) {
+ // If we don't support auto-rotation then bail out here and ignore
+ // the sensor and any rotation lock settings.
+ preferredRotation = -1;
} else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
&& (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
|| orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
@@ -5297,6 +5313,7 @@
pw.print(prefix); pw.print("mLastFocusNeedsMenu=");
pw.println(mLastFocusNeedsMenu);
}
+ pw.print(prefix); pw.print("mSupportAutoRotation="); pw.println(mSupportAutoRotation);
pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
pw.print(" mDockMode="); pw.print(mDockMode);
pw.print(" mCarDockRotation="); pw.print(mCarDockRotation);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 782868e..d910861 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1074,6 +1074,7 @@
static final int PERSIST_URI_GRANTS_MSG = 38;
static final int REQUEST_ALL_PSS_MSG = 39;
static final int START_RELATED_USERS_MSG = 40;
+ static final int UPDATE_TIME = 41;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1693,6 +1694,21 @@
}
break;
}
+ case UPDATE_TIME: {
+ synchronized (ActivityManagerService.this) {
+ for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
+ ProcessRecord r = mLruProcesses.get(i);
+ if (r.thread != null) {
+ try {
+ r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
+ }
+ }
+ }
+ }
+ break;
+ }
}
}
};
@@ -9212,8 +9228,13 @@
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
if (lastDoneReceivers.contains(comp)) {
+ // We already did the pre boot receiver for this app with the current
+ // platform version, so don't do it again...
ris.remove(i);
i--;
+ // ...however, do keep it as one that has been done, so we don't
+ // forget about it when rewriting the file of last done receivers.
+ doneReceivers.add(comp);
}
}
@@ -13441,11 +13462,20 @@
* of all currently running processes. This message will get queued up before the broadcast
* happens.
*/
- if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
+ if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
}
- if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
+ /*
+ * If the user set the time, let all running processes know.
+ */
+ if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
+ final int is24Hour = intent.getBooleanExtra(
+ Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
+ mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
+ }
+
+ if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
}
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 10ea67c..4c887dd 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -37,11 +37,16 @@
private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();
// mapping form property name to its type
- private static final Map<String, Class<?>> sCoreSettingToTypeMap = new HashMap<
+ private static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<
+ String, Class<?>>();
+ private static final Map<String, Class<?>> sSystemSettingToTypeMap = new HashMap<
String, Class<?>>();
static {
- sCoreSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
- // add other core settings here...
+ sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
+ // add other secure settings here...
+
+ sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class);
+ // add other system settings here...
}
private final Bundle mCoreSettings = new Bundle();
@@ -67,39 +72,62 @@
}
private void sendCoreSettings() {
- populateCoreSettings(mCoreSettings);
+ populateSettings(mCoreSettings, sSecureSettingToTypeMap);
+ populateSettings(mCoreSettings, sSystemSettingToTypeMap);
mActivityManagerService.onCoreSettingsChange(mCoreSettings);
}
private void beginObserveCoreSettings() {
- for (String setting : sCoreSettingToTypeMap.keySet()) {
+ for (String setting : sSecureSettingToTypeMap.keySet()) {
Uri uri = Settings.Secure.getUriFor(setting);
mActivityManagerService.mContext.getContentResolver().registerContentObserver(
uri, false, this);
}
+
+ for (String setting : sSystemSettingToTypeMap.keySet()) {
+ Uri uri = Settings.System.getUriFor(setting);
+ mActivityManagerService.mContext.getContentResolver().registerContentObserver(
+ uri, false, this);
+ }
}
- private void populateCoreSettings(Bundle snapshot) {
+ private void populateSettings(Bundle snapshot, Map<String, Class<?>> map) {
Context context = mActivityManagerService.mContext;
- for (Map.Entry<String, Class<?>> entry : sCoreSettingToTypeMap.entrySet()) {
+ for (Map.Entry<String, Class<?>> entry : map.entrySet()) {
String setting = entry.getKey();
Class<?> type = entry.getValue();
try {
if (type == String.class) {
- String value = Settings.Secure.getString(context.getContentResolver(),
- setting);
+ final String value;
+ if (map == sSecureSettingToTypeMap) {
+ value = Settings.Secure.getString(context.getContentResolver(), setting);
+ } else {
+ value = Settings.System.getString(context.getContentResolver(), setting);
+ }
snapshot.putString(setting, value);
} else if (type == int.class) {
- int value = Settings.Secure.getInt(context.getContentResolver(),
- setting);
+ final int value;
+ if (map == sSecureSettingToTypeMap) {
+ value = Settings.Secure.getInt(context.getContentResolver(), setting);
+ } else {
+ value = Settings.System.getInt(context.getContentResolver(), setting);
+ }
snapshot.putInt(setting, value);
} else if (type == float.class) {
- float value = Settings.Secure.getFloat(context.getContentResolver(),
- setting);
+ final float value;
+ if (map == sSecureSettingToTypeMap) {
+ value = Settings.Secure.getFloat(context.getContentResolver(), setting);
+ } else {
+ value = Settings.System.getFloat(context.getContentResolver(), setting);
+ }
snapshot.putFloat(setting, value);
} else if (type == long.class) {
- long value = Settings.Secure.getLong(context.getContentResolver(),
- setting);
+ final long value;
+ if (map == sSecureSettingToTypeMap) {
+ value = Settings.Secure.getLong(context.getContentResolver(), setting);
+ } else {
+ value = Settings.System.getLong(context.getContentResolver(), setting);
+ }
snapshot.putLong(setting, value);
}
} catch (SettingNotFoundException snfe) {