diff options
Diffstat (limited to 'core')
51 files changed, 2182 insertions, 322 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 3258585..138eea2 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -71,6 +71,7 @@ import android.os.Trace; 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.io.PrintWriter; 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; @@ -750,8 +752,42 @@ public final class ActivityThread { setCoreSettings(coreSettings); - // Tell the VMRuntime about the application. - VMRuntime.registerAppInfo(appInfo.dataDir, appInfo.processName); + /* + * Two possible indications that this package could be + * sharing its runtime with other packages: + * + * 1.) the sharedUserId attribute is set in the manifest, + * indicating a request to share a VM with other + * packages with the same sharedUserId. + * + * 2.) the application element of the manifest has an + * attribute specifying a non-default process name, + * indicating the desire to run in another packages VM. + * + * If sharing is enabled we do not have a unique application + * in a process and therefore cannot rely on the package + * name inside the runtime. + */ + IPackageManager pm = getPackageManager(); + android.content.pm.PackageInfo pi = null; + try { + pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId()); + } catch (RemoteException e) { + } + if (pi != null) { + boolean sharedUserIdSet = (pi.sharedUserId != null); + boolean processNameNotDefault = + (pi.applicationInfo != null && + !appInfo.packageName.equals(pi.applicationInfo.processName)); + boolean sharable = (sharedUserIdSet || processNameNotDefault); + + // Tell the VMRuntime about the application, unless it is shared + // inside a process. + if (!sharable) { + VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir, + appInfo.processName); + } + } AppBindData data = new AppBindData(); data.processName = processName; @@ -1103,6 +1139,11 @@ public final class ActivityThread { 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 +1193,7 @@ public final class ActivityThread { 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 +4257,11 @@ public final class ActivityThread { 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 @@ public abstract class ApplicationThreadNative extends Binder 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 @@ class ApplicationThreadProxy implements IApplicationThread { 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 @@ public interface IApplicationThread extends IInterface { 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 @@ public interface IApplicationThread extends IInterface { 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 cd1fbf6..12a8ff6 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -612,6 +612,13 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable } 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public final class BluetoothInputDevice implements BluetoothProfile { * @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 @@ public final class BluetoothInputDevice implements BluetoothProfile { /** * @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 @@ public final class BluetoothInputDevice implements BluetoothProfile { * @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 class Intent implements Parcelable, Cloneable { 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 @@ public class ColorStateList implements Parcelable { 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 @@ public class Resources { 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 @@ public class Resources { } /** + * {@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/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java index 5b6f154..89c17c7 100644 --- a/core/java/android/net/CaptivePortalTracker.java +++ b/core/java/android/net/CaptivePortalTracker.java @@ -421,6 +421,13 @@ public class CaptivePortalTracker extends StateMachine { case ConnectivityManager.TYPE_WIFI: WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo(); if (currentWifiInfo != null) { + // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not + // surrounded by double quotation marks (thus violating the Javadoc), but this + // was changed to match the Javadoc in API 17. Since clients may have started + // sanitizing the output of this method since API 17 was released, we should + // not change it here as it would become impossible to tell whether the SSID is + // simply being surrounded by quotes due to the API, or whether those quotes + // are actually part of the SSID. latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID()); latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID()); } else { diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index cc4bb51..0da77ea 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -578,6 +578,9 @@ public abstract class BatteryStats implements Parcelable { // The wake lock that was acquired at this point. public HistoryTag wakelockTag; + // Kernel wakeup reason at this point. + public HistoryTag wakeReasonTag; + public static final int EVENT_FLAG_START = 0x8000; public static final int EVENT_FLAG_FINISH = 0x4000; @@ -612,6 +615,7 @@ public abstract class BatteryStats implements Parcelable { // Pre-allocated objects. public final HistoryTag localWakelockTag = new HistoryTag(); + public final HistoryTag localWakeReasonTag = new HistoryTag(); public final HistoryTag localEventTag = new HistoryTag(); public HistoryItem() { @@ -645,6 +649,12 @@ public abstract class BatteryStats implements Parcelable { } else { dest.writeInt(0); } + if (wakeReasonTag != null) { + dest.writeInt(1); + wakeReasonTag.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } dest.writeInt(eventCode); if (eventCode != EVENT_NONE) { dest.writeInt(eventCode); @@ -670,6 +680,12 @@ public abstract class BatteryStats implements Parcelable { } else { wakelockTag = null; } + if (src.readInt() != 0) { + wakeReasonTag = localWakeReasonTag; + wakeReasonTag.readFromParcel(src); + } else { + wakeReasonTag = null; + } eventCode = src.readInt(); if (eventCode != EVENT_NONE) { eventTag = localEventTag; @@ -689,6 +705,7 @@ public abstract class BatteryStats implements Parcelable { batteryVoltage = 0; states = 0; wakelockTag = null; + wakeReasonTag = null; eventCode = EVENT_NONE; eventTag = null; } @@ -719,6 +736,12 @@ public abstract class BatteryStats implements Parcelable { } else { wakelockTag = null; } + if (o.wakeReasonTag != null) { + wakeReasonTag = localWakeReasonTag; + wakeReasonTag.setTo(o.wakeReasonTag); + } else { + wakeReasonTag = null; + } eventCode = o.eventCode; if (o.eventTag != null) { eventTag = localEventTag; @@ -750,6 +773,14 @@ public abstract class BatteryStats implements Parcelable { return false; } } + if (wakeReasonTag != o.wakeReasonTag) { + if (wakeReasonTag == null || o.wakeReasonTag == null) { + return false; + } + if (!wakeReasonTag.equals(o.wakeReasonTag)) { + return false; + } + } if (eventTag != o.eventTag) { if (eventTag == null || o.eventTag == null) { return false; @@ -1916,51 +1947,6 @@ public abstract class BatteryStats implements Parcelable { long fullWakeLockTimeTotalMicros = 0; long partialWakeLockTimeTotalMicros = 0; - final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() { - @Override - public int compare(TimerEntry lhs, TimerEntry rhs) { - long lhsTime = lhs.mTime; - long rhsTime = rhs.mTime; - if (lhsTime < rhsTime) { - return 1; - } - if (lhsTime > rhsTime) { - return -1; - } - return 0; - } - }; - - if (reqUid < 0) { - Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); - if (kernelWakelocks.size() > 0) { - final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>(); - for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { - BatteryStats.Timer timer = ent.getValue(); - long totalTimeMillis = computeWakeLock(timer, rawRealtime, which); - if (totalTimeMillis > 0) { - timers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis)); - } - } - Collections.sort(timers, timerComparator); - for (int i=0; i<timers.size(); i++) { - TimerEntry timer = timers.get(i); - String linePrefix = ": "; - sb.setLength(0); - sb.append(prefix); - sb.append(" Kernel Wake lock "); - sb.append(timer.mName); - linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null, - which, linePrefix); - if (!linePrefix.equals(": ")) { - sb.append(" realtime"); - // Only print out wake locks that were held - pw.println(sb.toString()); - } - } - } - } - final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>(); for (int iu = 0; iu < NU; iu++) { @@ -2292,6 +2278,55 @@ public abstract class BatteryStats implements Parcelable { pw.println(); } + final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() { + @Override + public int compare(TimerEntry lhs, TimerEntry rhs) { + long lhsTime = lhs.mTime; + long rhsTime = rhs.mTime; + if (lhsTime < rhsTime) { + return 1; + } + if (lhsTime > rhsTime) { + return -1; + } + return 0; + } + }; + + if (reqUid < 0) { + Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); + if (kernelWakelocks.size() > 0) { + final ArrayList<TimerEntry> ktimers = new ArrayList<TimerEntry>(); + for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { + BatteryStats.Timer timer = ent.getValue(); + long totalTimeMillis = computeWakeLock(timer, rawRealtime, which); + if (totalTimeMillis > 0) { + ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis)); + } + } + if (ktimers.size() > 0) { + Collections.sort(ktimers, timerComparator); + pw.print(prefix); pw.println(" All kernel wake locks:"); + for (int i=0; i<ktimers.size(); i++) { + TimerEntry timer = ktimers.get(i); + String linePrefix = ": "; + sb.setLength(0); + sb.append(prefix); + sb.append(" Kernel Wake lock "); + sb.append(timer.mName); + linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null, + which, linePrefix); + if (!linePrefix.equals(": ")) { + sb.append(" realtime"); + // Only print out wake locks that were held + pw.println(sb.toString()); + } + } + pw.println(); + } + } + } + if (timers.size() > 0) { Collections.sort(timers, timerComparator); pw.print(prefix); pw.println(" All partial wake locks:"); @@ -2727,14 +2762,22 @@ public abstract class BatteryStats implements Parcelable { public void printNextItem(PrintWriter pw, HistoryItem rec, long now, boolean checkin) { if (!checkin) { pw.print(" "); - TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); + if (now >= 0) { + TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); + } else { + TimeUtils.formatDuration(rec.time, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); + } pw.print(" ("); pw.print(rec.numReadInts); pw.print(") "); } else { if (lastTime < 0) { - pw.print("@"); - pw.print(rec.time-now); + if (now >= 0) { + pw.print("@"); + pw.print(rec.time-now); + } else { + pw.print(rec.time); + } } else { pw.print(rec.time-lastTime); } @@ -2858,6 +2901,18 @@ public abstract class BatteryStats implements Parcelable { } printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag, HISTORY_STATE_DESCRIPTIONS, !checkin); + if (rec.wakeReasonTag != null) { + if (checkin) { + pw.print(",Wr="); + pw.print(rec.wakeReasonTag.poolIdx); + } else { + pw.print(" wake_reason="); + pw.print(rec.wakeReasonTag.uid); + pw.print(":\""); + pw.print(rec.wakeReasonTag.string); + pw.print("\""); + } + } if (rec.eventCode != HistoryItem.EVENT_NONE) { pw.print(checkin ? "," : " "); if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) { @@ -2918,108 +2973,130 @@ public abstract class BatteryStats implements Parcelable { pw.print(suffix); } + public static final int DUMP_UNPLUGGED_ONLY = 1<<0; + public static final int DUMP_CHARGED_ONLY = 1<<1; + public static final int DUMP_HISTORY_ONLY = 1<<2; + public static final int DUMP_INCLUDE_HISTORY = 1<<3; + /** * Dumps a human-readable summary of the battery statistics to the given PrintWriter. * * @param pw a Printer to receive the dump output. */ @SuppressWarnings("unused") - public void dumpLocked(Context context, PrintWriter pw, boolean isUnpluggedOnly, int reqUid, - boolean historyOnly) { + public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { prepareForDumpLocked(); - long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); + final boolean filtering = + (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0; - final HistoryItem rec = new HistoryItem(); - final long historyTotalSize = getHistoryTotalSize(); - final long historyUsedSize = getHistoryUsedSize(); - if (startIteratingHistoryLocked()) { - try { - pw.print("Battery History ("); - pw.print((100*historyUsedSize)/historyTotalSize); - pw.print("% used, "); - printSizeValue(pw, historyUsedSize); - pw.print(" used of "); - printSizeValue(pw, historyTotalSize); - pw.print(", "); - pw.print(getHistoryStringPoolSize()); - pw.print(" strings using "); - printSizeValue(pw, getHistoryStringPoolBytes()); - pw.println("):"); - HistoryPrinter hprinter = new HistoryPrinter(); - while (getNextHistoryLocked(rec)) { - hprinter.printNextItem(pw, rec, now, false); + if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) { + long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); + + final HistoryItem rec = new HistoryItem(); + final long historyTotalSize = getHistoryTotalSize(); + final long historyUsedSize = getHistoryUsedSize(); + if (startIteratingHistoryLocked()) { + try { + pw.print("Battery History ("); + pw.print((100*historyUsedSize)/historyTotalSize); + pw.print("% used, "); + printSizeValue(pw, historyUsedSize); + pw.print(" used of "); + printSizeValue(pw, historyTotalSize); + pw.print(", "); + pw.print(getHistoryStringPoolSize()); + pw.print(" strings using "); + printSizeValue(pw, getHistoryStringPoolBytes()); + pw.println("):"); + HistoryPrinter hprinter = new HistoryPrinter(); + long lastTime = -1; + while (getNextHistoryLocked(rec)) { + lastTime = rec.time; + if (rec.time >= histStart) { + hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, false); + } + } + if (histStart >= 0) { + pw.print(" NEXT: "); pw.println(lastTime+1); + } + pw.println(); + } finally { + finishIteratingHistoryLocked(); } - pw.println(); - } finally { - finishIteratingHistoryLocked(); } - } - if (startIteratingOldHistoryLocked()) { - try { - pw.println("Old battery History:"); - HistoryPrinter hprinter = new HistoryPrinter(); - while (getNextOldHistoryLocked(rec)) { - hprinter.printNextItem(pw, rec, now, false); + if (startIteratingOldHistoryLocked()) { + try { + pw.println("Old battery History:"); + HistoryPrinter hprinter = new HistoryPrinter(); + while (getNextOldHistoryLocked(rec)) { + hprinter.printNextItem(pw, rec, now, false); + } + pw.println(); + } finally { + finishIteratingOldHistoryLocked(); } - pw.println(); - } finally { - finishIteratingOldHistoryLocked(); } } - if (historyOnly) { + if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) { return; } - SparseArray<? extends Uid> uidStats = getUidStats(); - final int NU = uidStats.size(); - boolean didPid = false; - long nowRealtime = SystemClock.elapsedRealtime(); - for (int i=0; i<NU; i++) { - Uid uid = uidStats.valueAt(i); - SparseArray<? extends Uid.Pid> pids = uid.getPidStats(); - if (pids != null) { - for (int j=0; j<pids.size(); j++) { - Uid.Pid pid = pids.valueAt(j); - if (!didPid) { - pw.println("Per-PID Stats:"); - didPid = true; + if (!filtering) { + SparseArray<? extends Uid> uidStats = getUidStats(); + final int NU = uidStats.size(); + boolean didPid = false; + long nowRealtime = SystemClock.elapsedRealtime(); + for (int i=0; i<NU; i++) { + Uid uid = uidStats.valueAt(i); + SparseArray<? extends Uid.Pid> pids = uid.getPidStats(); + if (pids != null) { + for (int j=0; j<pids.size(); j++) { + Uid.Pid pid = pids.valueAt(j); + if (!didPid) { + pw.println("Per-PID Stats:"); + didPid = true; + } + long time = pid.mWakeSum + (pid.mWakeStart != 0 + ? (nowRealtime - pid.mWakeStart) : 0); + pw.print(" PID "); pw.print(pids.keyAt(j)); + pw.print(" wake time: "); + TimeUtils.formatDuration(time, pw); + pw.println(""); } - long time = pid.mWakeSum + (pid.mWakeStart != 0 - ? (nowRealtime - pid.mWakeStart) : 0); - pw.print(" PID "); pw.print(pids.keyAt(j)); - pw.print(" wake time: "); - TimeUtils.formatDuration(time, pw); - pw.println(""); } } - } - if (didPid) { - pw.println(""); + if (didPid) { + pw.println(""); + } } - if (!isUnpluggedOnly) { + if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) { pw.println("Statistics since last charge:"); pw.println(" System starts: " + getStartCount() + ", currently on battery: " + getIsOnBattery()); dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid); pw.println(""); } - pw.println("Statistics since last unplugged:"); - dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid); + if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) { + pw.println("Statistics since last unplugged:"); + dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid); + } } @SuppressWarnings("unused") - public void dumpCheckinLocked(Context context, - PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly, - boolean includeHistory, boolean historyOnly) { + public void dumpCheckinLocked(Context context, PrintWriter pw, + List<ApplicationInfo> apps, int flags, long histStart) { prepareForDumpLocked(); long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); - if (includeHistory || historyOnly) { + final boolean filtering = + (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0; + + if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) { final HistoryItem rec = new HistoryItem(); if (startIteratingHistoryLocked()) { try { @@ -3034,10 +3111,17 @@ public abstract class BatteryStats implements Parcelable { pw.println(); } HistoryPrinter hprinter = new HistoryPrinter(); + long lastTime = -1; while (getNextHistoryLocked(rec)) { - pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); - pw.print(HISTORY_DATA); pw.print(','); - hprinter.printNextItem(pw, rec, now, true); + lastTime = rec.time; + if (rec.time >= histStart) { + pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); + pw.print(HISTORY_DATA); pw.print(','); + hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, true); + } + } + if (histStart >= 0) { + pw.print("NEXT: "); pw.println(lastTime+1); } } finally { finishIteratingHistoryLocked(); @@ -3045,7 +3129,7 @@ public abstract class BatteryStats implements Parcelable { } } - if (historyOnly) { + if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) { return; } @@ -3076,11 +3160,10 @@ public abstract class BatteryStats implements Parcelable { } } } - if (isUnpluggedOnly) { - dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1); - } - else { + if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) { dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1); + } + if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) { dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1); } } 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.TextureView; 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 @@ public abstract class Transition implements Cloneable { 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 @@ public abstract class Transition implements Cloneable { * * @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 @@ public abstract class Transition implements Cloneable { * * @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 abstract class Transition implements Cloneable { 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 @@ public class TransitionManager { 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 @@ public class TransitionManager { mTransition.captureValues(mSceneRoot, false); if (previousRunningTransitions != null) { for (Transition runningTransition : previousRunningTransitions) { - runningTransition.resume(); + runningTransition.resume(mSceneRoot); } } mTransition.playTransition(mSceneRoot); @@ -351,7 +351,7 @@ public class TransitionManager { 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 @@ public class TransitionSet extends Transition { /** @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/KeyEvent.java b/core/java/android/view/KeyEvent.java index 7e745d8..c183f08 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -628,11 +628,19 @@ public class KeyEvent extends InputEvent implements Parcelable { /** Key code constant: Brightness Up key. * Adjusts the screen brightness up. */ public static final int KEYCODE_BRIGHTNESS_UP = 221; - /** Key code constant: Audio Track key + /** Key code constant: Audio Track key. * Switches the audio tracks. */ public static final int KEYCODE_MEDIA_AUDIO_TRACK = 222; + /** Key code constant: Sleep key. + * Puts the device to sleep. Behaves somewhat like {@link #KEYCODE_POWER} but it + * has no effect if the device is already asleep. */ + public static final int KEYCODE_SLEEP = 223; + /** Key code constant: Wakeup key. + * Wakes up the device. Behaves somewhat like {@link #KEYCODE_POWER} but it + * has no effect if the device is already awake. */ + public static final int KEYCODE_WAKEUP = 224; - private static final int LAST_KEYCODE = KEYCODE_MEDIA_AUDIO_TRACK; + private static final int LAST_KEYCODE = KEYCODE_WAKEUP; // NOTE: If you add a new keycode here you must also add it to: // isSystem() @@ -877,6 +885,8 @@ public class KeyEvent extends InputEvent implements Parcelable { names.append(KEYCODE_BRIGHTNESS_DOWN, "KEYCODE_BRIGHTNESS_DOWN"); names.append(KEYCODE_BRIGHTNESS_UP, "KEYCODE_BRIGHTNESS_UP"); names.append(KEYCODE_MEDIA_AUDIO_TRACK, "KEYCODE_MEDIA_AUDIO_TRACK"); + names.append(KEYCODE_SLEEP, "KEYCODE_SLEEP"); + names.append(KEYCODE_WAKEUP, "KEYCODE_WAKEUP"); }; // Symbolic names of all metakeys in bit order from least significant to most significant. 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 @@ public class SurfaceView extends View { updateWindow(false, false); } + /** @hide */ @Override - protected void onDetachedFromWindow() { + protected void onDetachedFromWindowInternal() { if (mGlobalListenersAdded) { ViewTreeObserver observer = getViewTreeObserver(); observer.removeOnScrollChangedListener(mScrollChangedListener); @@ -278,7 +279,7 @@ public class SurfaceView extends View { 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 @@ public class TextureView extends View { } } + /** @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 a57b311..9b45f97 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -8705,7 +8705,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * <p>When implementing this, you probably also want to implement * {@link #onCheckIsTextEditor()} to indicate you will return a - * non-null InputConnection. + * non-null InputConnection.</p> + * + * <p>Also, take good care to fill in the {@link android.view.inputmethod.EditorInfo} + * object correctly and in its entirety, so that the connected IME can rely + * on its values. For example, {@link android.view.inputmethod.EditorInfo#initialSelStart} + * and {@link android.view.inputmethod.EditorInfo#initialSelEnd} members + * must be filled in with the correct cursor position for IMEs to work correctly + * with your application.</p> * * @param outAttrs Fill in with attribute information about the connection. */ @@ -10838,11 +10845,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Sets the outline of the view, which defines the shape of the shadow it * casts, and can used for clipping. * <p> + * The outline path of a View must be {@link android.graphics.Path#isConvex() convex}. + * <p> * If the outline is not set, or {@link Path#isEmpty()}, shadows will be * cast from the bounds of the View, and clipToOutline will be ignored. * - * @param outline The new outline of the view. Must be non-null. + * @param outline The new outline of the view. Must be non-null, and convex. * + * @see #setCastsShadow(boolean) * @see #getOutline(Path) * @see #getClipToOutline() * @see #setClipToOutline(boolean) @@ -10851,6 +10861,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (outline == null) { throw new IllegalArgumentException("Path must be non-null"); } + if (!outline.isConvex()) { + throw new IllegalArgumentException("Path must be convex"); + } // always copy the path since caller may reuse if (mOutline == null) { mOutline = new Path(outline); @@ -10921,9 +10934,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Set to true to enable this View to cast shadows. * <p> * If enabled, and the View has a z translation greater than 0, or is - * rotated in 3D, the shadow will be cast onto the current - * {@link ViewGroup#setIsolatedZVolume(boolean) isolated Z volume}, - * at the z = 0 plane. + * rotated in 3D, the shadow will be cast onto its parent at the z = 0 + * plane. * <p> * The shape of the shadow being cast is defined by the * {@link #setOutline(Path) outline} of the view, or the rectangular bounds @@ -13110,6 +13122,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @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; @@ -13297,6 +13322,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * 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/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java index d4e005b..c0395cf 100644 --- a/core/java/android/view/inputmethod/EditorInfo.java +++ b/core/java/android/view/inputmethod/EditorInfo.java @@ -26,13 +26,13 @@ import android.util.Printer; /** * An EditorInfo describes several attributes of a text editing object * that an input method is communicating with (typically an EditText), most - * importantly the type of text content it contains. + * importantly the type of text content it contains and the current cursor position. */ public class EditorInfo implements InputType, Parcelable { /** * The content type of the text box, whose bits are defined by * {@link InputType}. - * + * * @see InputType * @see #TYPE_MASK_CLASS * @see #TYPE_MASK_VARIATION @@ -47,55 +47,55 @@ public class EditorInfo implements InputType, Parcelable { * to provide alternative mechanisms for providing that command. */ public static final int IME_MASK_ACTION = 0x000000ff; - + /** * Bits of {@link #IME_MASK_ACTION}: no specific action has been * associated with this editor, let the editor come up with its own if * it can. */ public static final int IME_ACTION_UNSPECIFIED = 0x00000000; - + /** * Bits of {@link #IME_MASK_ACTION}: there is no available action. */ public static final int IME_ACTION_NONE = 0x00000001; - + /** * Bits of {@link #IME_MASK_ACTION}: the action key performs a "go" * operation to take the user to the target of the text they typed. * Typically used, for example, when entering a URL. */ public static final int IME_ACTION_GO = 0x00000002; - + /** * Bits of {@link #IME_MASK_ACTION}: the action key performs a "search" * operation, taking the user to the results of searching for the text * they have typed (in whatever context is appropriate). */ public static final int IME_ACTION_SEARCH = 0x00000003; - + /** * Bits of {@link #IME_MASK_ACTION}: the action key performs a "send" * operation, delivering the text to its target. This is typically used * when composing a message in IM or SMS where sending is immediate. */ public static final int IME_ACTION_SEND = 0x00000004; - + /** * Bits of {@link #IME_MASK_ACTION}: the action key performs a "next" * operation, taking the user to the next field that will accept text. */ public static final int IME_ACTION_NEXT = 0x00000005; - + /** * Bits of {@link #IME_MASK_ACTION}: the action key performs a "done" * operation, typically meaning there is nothing more to input and the * IME will be closed. */ public static final int IME_ACTION_DONE = 0x00000006; - + /** - * Bits of {@link #IME_MASK_ACTION}: Like {@link #IME_ACTION_NEXT}, but + * Bits of {@link #IME_MASK_ACTION}: like {@link #IME_ACTION_NEXT}, but * for moving to the previous field. This will normally not be used to * specify an action (since it precludes {@link #IME_ACTION_NEXT}), but * can be returned to the app if it sets {@link #IME_FLAG_NAVIGATE_PREVIOUS}. @@ -154,7 +154,7 @@ public class EditorInfo implements InputType, Parcelable { * on older versions of the platform. */ public static final int IME_FLAG_NO_EXTRACT_UI = 0x10000000; - + /** * Flag of {@link #imeOptions}: used in conjunction with one of the actions * masked by {@link #IME_MASK_ACTION}, this indicates that the action @@ -167,7 +167,7 @@ public class EditorInfo implements InputType, Parcelable { * to show more text. */ public static final int IME_FLAG_NO_ACCESSORY_ACTION = 0x20000000; - + /** * Flag of {@link #imeOptions}: used in conjunction with one of the actions * masked by {@link #IME_MASK_ACTION}. If this flag is not set, IMEs will @@ -202,13 +202,13 @@ public class EditorInfo implements InputType, Parcelable { * Generic unspecified type for {@link #imeOptions}. */ public static final int IME_NULL = 0x00000000; - + /** * Extended type information for the editor, to help the IME better * integrate with it. */ public int imeOptions = IME_NULL; - + /** * A string supplying additional information options that are * private to a particular IME implementation. The string must be @@ -221,7 +221,7 @@ public class EditorInfo implements InputType, Parcelable { * attribute of a TextView. */ public String privateImeOptions = null; - + /** * In some cases an IME may be able to display an arbitrary label for * a command the user can perform, which you can specify here. This is @@ -233,7 +233,7 @@ public class EditorInfo implements InputType, Parcelable { * ignore this. */ public CharSequence actionLabel = null; - + /** * If {@link #actionLabel} has been given, this is the id for that command * when the user presses its button that is delivered back with @@ -241,50 +241,66 @@ public class EditorInfo implements InputType, Parcelable { * InputConnection.performEditorAction()}. */ public int actionId = 0; - + /** * The text offset of the start of the selection at the time editing - * began; -1 if not known. Keep in mind some IMEs may not be able - * to give their full feature set without knowing the cursor position; - * avoid passing -1 here if you can. + * begins; -1 if not known. Keep in mind that, without knowing the cursor + * position, many IMEs will not be able to offer their full feature set and + * may even behave in unpredictable ways: pass the actual cursor position + * here if possible at all. + * + * <p>Also, this needs to be the cursor position <strong>right now</strong>, + * not at some point in the past, even if input is starting in the same text field + * as before. When the app is filling this object, input is about to start by + * definition, and this value will override any value the app may have passed to + * {@link InputMethodManager#updateSelection(android.view.View, int, int, int, int)} + * before.</p> */ public int initialSelStart = -1; - + /** - * The text offset of the end of the selection at the time editing - * began; -1 if not known. Keep in mind some IMEs may not be able - * to give their full feature set without knowing the cursor position; - * avoid passing -1 here if you can. + * <p>The text offset of the end of the selection at the time editing + * begins; -1 if not known. Keep in mind that, without knowing the cursor + * position, many IMEs will not be able to offer their full feature set and + * may behave in unpredictable ways: pass the actual cursor position + * here if possible at all.</p> + * + * <p>Also, this needs to be the cursor position <strong>right now</strong>, + * not at some point in the past, even if input is starting in the same text field + * as before. When the app is filling this object, input is about to start by + * definition, and this value will override any value the app may have passed to + * {@link InputMethodManager#updateSelection(android.view.View, int, int, int, int)} + * before.</p> */ public int initialSelEnd = -1; - + /** * The capitalization mode of the first character being edited in the * text. Values may be any combination of * {@link TextUtils#CAP_MODE_CHARACTERS TextUtils.CAP_MODE_CHARACTERS}, * {@link TextUtils#CAP_MODE_WORDS TextUtils.CAP_MODE_WORDS}, and * {@link TextUtils#CAP_MODE_SENTENCES TextUtils.CAP_MODE_SENTENCES}, though - * you should generally just take a non-zero value to mean start out in - * caps mode. + * you should generally just take a non-zero value to mean "start out in + * caps mode". */ public int initialCapsMode = 0; - + /** * The "hint" text of the text view, typically shown in-line when the * text is empty to tell the user what to enter. */ public CharSequence hintText; - + /** * A label to show to the user describing the text they are writing. */ public CharSequence label; - + /** * Name of the package that owns this editor. */ public String packageName; - + /** * Identifier for the editor's field. This is optional, and may be * 0. By default it is filled in with the result of @@ -292,14 +308,14 @@ public class EditorInfo implements InputType, Parcelable { * is being edited. */ public int fieldId; - + /** * Additional name for the editor's field. This can supply additional * name information for the field. By default it is null. The actual * contents have no meaning. */ public String fieldName; - + /** * Any extra data to supply to the input method. This is for extended * communication with specific input methods; the name fields in the @@ -309,7 +325,7 @@ public class EditorInfo implements InputType, Parcelable { * attribute of a TextView. */ public Bundle extras; - + /** * Ensure that the data in this EditorInfo is compatible with an application * that was developed against the given target API version. This can @@ -365,10 +381,10 @@ public class EditorInfo implements InputType, Parcelable { + " fieldName=" + fieldName); pw.println(prefix + "extras=" + extras); } - + /** * Used to package this object into a {@link Parcel}. - * + * * @param dest The {@link Parcel} to be written. * @param flags The flags used for parceling. */ @@ -392,30 +408,31 @@ public class EditorInfo implements InputType, Parcelable { /** * Used to make this class parcelable. */ - public static final Parcelable.Creator<EditorInfo> CREATOR = new Parcelable.Creator<EditorInfo>() { - public EditorInfo createFromParcel(Parcel source) { - EditorInfo res = new EditorInfo(); - res.inputType = source.readInt(); - res.imeOptions = source.readInt(); - res.privateImeOptions = source.readString(); - res.actionLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); - res.actionId = source.readInt(); - res.initialSelStart = source.readInt(); - res.initialSelEnd = source.readInt(); - res.initialCapsMode = source.readInt(); - res.hintText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); - res.label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); - res.packageName = source.readString(); - res.fieldId = source.readInt(); - res.fieldName = source.readString(); - res.extras = source.readBundle(); - return res; - } + public static final Parcelable.Creator<EditorInfo> CREATOR = + new Parcelable.Creator<EditorInfo>() { + public EditorInfo createFromParcel(Parcel source) { + EditorInfo res = new EditorInfo(); + res.inputType = source.readInt(); + res.imeOptions = source.readInt(); + res.privateImeOptions = source.readString(); + res.actionLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); + res.actionId = source.readInt(); + res.initialSelStart = source.readInt(); + res.initialSelEnd = source.readInt(); + res.initialCapsMode = source.readInt(); + res.hintText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); + res.label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); + res.packageName = source.readString(); + res.fieldId = source.readInt(); + res.fieldName = source.readString(); + res.extras = source.readBundle(); + return res; + } - public EditorInfo[] newArray(int size) { - return new EditorInfo[size]; - } - }; + public EditorInfo[] newArray(int size) { + return new EditorInfo[size]; + } + }; public int describeContents() { return 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.Printer; 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 @@ public final class InputMethodInfo implements Parcelable { 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 @@ public final class InputMethodInfo implements Parcelable { 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 @@ public final class InputMethodInfo implements Parcelable { if (!subtype.isAuxiliary()) { isAuxIme = false; } - mSubtypes.add(subtype); + subtypes.add(subtype); } } } catch (NameNotFoundException e) { @@ -216,7 +218,7 @@ public final class InputMethodInfo implements Parcelable { if (parser != null) parser.close(); } - if (mSubtypes.size() == 0) { + if (subtypes.size() == 0) { isAuxIme = false; } @@ -225,14 +227,15 @@ public final class InputMethodInfo implements Parcelable { 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 @@ public final class InputMethodInfo implements Parcelable { 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 @@ public final class InputMethodInfo implements Parcelable { mSettingsActivityName = settingsActivity; mIsDefaultResId = isDefaultResId; mIsAuxIme = isAuxIme; - if (subtypes != null) { - mSubtypes.addAll(subtypes); - } + mSubtypes = new InputMethodSubtypeArray(subtypes); mForceDefault = forceDefault; mSupportsSwitchingToNextInputMethod = true; } @@ -364,7 +365,7 @@ public final class InputMethodInfo implements Parcelable { * 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 @@ public final class InputMethodInfo implements Parcelable { * Return the count of the subtypes of Input Method. */ public int getSubtypeCount() { - return mSubtypes.size(); + return mSubtypes.getCount(); } /** @@ -479,7 +480,7 @@ public final class InputMethodInfo implements Parcelable { 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/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 70c53d2..e812edd 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1394,6 +1394,14 @@ public final class InputMethodManager { /** * Report the current selection range. + * + * <p><strong>Editor authors</strong>, you need to call this method whenever + * the cursor moves in your editor. Remember that in addition to doing this, your + * editor needs to always supply current cursor values in + * {@link EditorInfo#initialSelStart} and {@link EditorInfo#initialSelEnd} every + * time {@link android.view.View#onCreateInputConnection(EditorInfo)} is + * called, which happens whenever the keyboard shows up or the focus changes + * to a text field, among other cases.</p> */ public void updateSelection(View view, int selStart, int selEnd, int candidatesStart, int candidatesEnd) { 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 @@ public class WebView extends AbsoluteLayout 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/AbsListView.java b/core/java/android/widget/AbsListView.java index 47d42dc..96a2ab5 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2135,15 +2135,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mRecycler.markChildrenDirty(); } - // TODO: Move somewhere sane. This doesn't belong in onLayout(). - if (mFastScroll != null) { - mFastScroll.onItemCountChanged(childCount, mItemCount); - } - layoutChildren(); mInLayout = false; mOverscrollMax = (b - t) / OVERSCROLL_LIMIT_DIVISOR; + + // TODO: Move somewhere sane. This doesn't belong in onLayout(). + if (mFastScroll != null) { + mFastScroll.onItemCountChanged(getChildCount(), mItemCount); + } } /** 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener resetResolvedDrawables(); if (mEditor != null) mEditor.onDetachedFromWindow(); + + super.onDetachedFromWindowInternal(); } @Override diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index fd93604..db21906 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -87,7 +87,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 97 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 98 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -1712,7 +1712,7 @@ public final class BatteryStatsImpl extends BatteryStats { static final int DELTA_STATE_FLAG = 0x00100000; // Flag in delta int: a new full state2 int follows. static final int DELTA_STATE2_FLAG = 0x00200000; - // Flag in delta int: contains a wakelock tag. + // Flag in delta int: contains a wakelock or wakeReason tag. static final int DELTA_WAKELOCK_FLAG = 0x00400000; // Flag in delta int: contains an event description. static final int DELTA_EVENT_FLAG = 0x00800000; @@ -1759,7 +1759,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (stateIntChanged) { firstToken |= DELTA_STATE_FLAG; } - if (cur.wakelockTag != null) { + if (cur.wakelockTag != null || cur.wakeReasonTag != null) { firstToken |= DELTA_WAKELOCK_FLAG; } if (cur.eventCode != HistoryItem.EVENT_NONE) { @@ -1795,11 +1795,24 @@ public final class BatteryStatsImpl extends BatteryStats { + " batteryPlugType=" + cur.batteryPlugType + " states=0x" + Integer.toHexString(cur.states)); } - if (cur.wakelockTag != null) { - int index = writeHistoryTag(cur.wakelockTag); - dest.writeInt(index); - if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx - + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); + if (cur.wakelockTag != null || cur.wakeReasonTag != null) { + int wakeLockIndex; + int wakeReasonIndex; + if (cur.wakelockTag != null) { + wakeLockIndex = writeHistoryTag(cur.wakelockTag); + if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx + + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); + } else { + wakeLockIndex = 0xffff; + } + if (cur.wakeReasonTag != null) { + wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); + if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx + + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); + } else { + wakeReasonIndex = 0xffff; + } + dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); } if (cur.eventCode != HistoryItem.EVENT_NONE) { int index = writeHistoryTag(cur.eventTag); @@ -1905,14 +1918,29 @@ public final class BatteryStatsImpl extends BatteryStats { } if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { - cur.wakelockTag = cur.localWakelockTag; - int index = src.readInt(); - readHistoryTag(index, cur.wakelockTag); + int indexes = src.readInt(); + int wakeLockIndex = indexes&0xffff; + int wakeReasonIndex = (indexes>>16)&0xffff; + if (wakeLockIndex != 0xffff) { + cur.wakelockTag = cur.localWakelockTag; + readHistoryTag(wakeLockIndex, cur.wakelockTag); + if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx + + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); + } else { + cur.wakelockTag = null; + } + if (wakeReasonIndex != 0xffff) { + cur.wakeReasonTag = cur.localWakeReasonTag; + readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); + if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx + + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); + } else { + cur.wakeReasonTag = null; + } cur.numReadInts += 1; - if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx - + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); } else { cur.wakelockTag = null; + cur.wakeReasonTag = null; } if ((firstToken&DELTA_EVENT_FLAG) != 0) { @@ -1944,6 +1972,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 && (mHistoryLastWritten.wakelockTag == null || mHistoryCur.wakelockTag == null) + && (mHistoryLastWritten.wakeReasonTag == null || mHistoryCur.wakeReasonTag == null) && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE || mHistoryCur.eventCode == HistoryItem.EVENT_NONE) && mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel @@ -1968,6 +1997,13 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; mHistoryCur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); } + // If the last written history had a wake reason tag, we need to retain it. + // Note that the condition above made sure that we aren't in a case where + // both it and the current history item have a wakelock tag. + if (mHistoryLastWritten.wakeReasonTag != null) { + mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; + mHistoryCur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); + } // If the last written history had an event, we need to retain it. // Note that the condition above made sure that we aren't in a case where // both it and the current history item have an event. @@ -2016,6 +2052,7 @@ public final class BatteryStatsImpl extends BatteryStats { writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); mLastHistoryTime = curTime; mHistoryCur.wakelockTag = null; + mHistoryCur.wakeReasonTag = null; mHistoryCur.eventCode = HistoryItem.EVENT_NONE; mHistoryCur.eventTag = null; if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos @@ -2304,6 +2341,16 @@ public final class BatteryStatsImpl extends BatteryStats { } } + public void noteWakeupReasonLocked(int irq, String reason) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason irq #" + irq + "\"" + reason +"\": " + + Integer.toHexString(mHistoryCur.states)); + mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; + mHistoryCur.wakeReasonTag.string = reason; + mHistoryCur.wakeReasonTag.uid = irq; + addHistoryRecordLocked(elapsedRealtime); + } + public int startAddingCpuLocked() { mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); @@ -7219,8 +7266,7 @@ public final class BatteryStatsImpl extends BatteryStats { pullPendingStateUpdatesLocked(); } - public void dumpLocked(Context context, PrintWriter pw, boolean isUnpluggedOnly, int reqUid, - boolean historyOnly) { + public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { if (DEBUG) { pw.println("mOnBatteryTimeBase:"); mOnBatteryTimeBase.dump(pw, " "); @@ -7264,6 +7310,6 @@ public final class BatteryStatsImpl extends BatteryStats { mBluetoothStateTimer[i].logState(pr, " "); } } - super.dumpLocked(context, pw, isUnpluggedOnly, reqUid, historyOnly); + super.dumpLocked(context, pw, flags, reqUid, histStart); } } 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 @@ import com.android.internal.view.IInputMethodClient; * 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 @@ public final class RotationPolicy { 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 final class RotationPolicy { */ 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/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index ee9c18d..06e4717 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -781,6 +781,49 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) mOptions.add(opt); } + /* + * Set profiler options + */ + { + char period[sizeof("-Xprofile-period:") + PROPERTY_VALUE_MAX]; + char duration[sizeof("-Xprofile-duration:") + PROPERTY_VALUE_MAX]; + char interval[sizeof("-Xprofile-interval:") + PROPERTY_VALUE_MAX]; + char backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX]; + + // Number of seconds during profile runs. + strcpy(period, "-Xprofile-period:"); + property_get("dalvik.vm.profile.period_secs", period+17, "10"); + opt.optionString = period; + mOptions.add(opt); + + // Length of each profile run (seconds). + strcpy(duration, "-Xprofile-duration:"); + property_get("dalvik.vm.profile.duration_secs", duration+19, "30"); + opt.optionString = duration; + mOptions.add(opt); + + + // Polling interval during profile run (microseconds). + strcpy(interval, "-Xprofile-interval:"); + property_get("dalvik.vm.profile.interval_us", interval+19, "10000"); + opt.optionString = interval; + mOptions.add(opt); + + // Coefficient for period backoff. The the period is multiplied + // by this value after each profile run. + strcpy(backoff, "-Xprofile-backoff:"); + property_get("dalvik.vm.profile.backoff_coeff", backoff+18, "2.0"); + opt.optionString = backoff; + mOptions.add(opt); + } + + /* + * We don't have /tmp on the device, but we often have an SD card. Apps + * shouldn't use this, but some test suites might want to exercise it. + */ + opt.optionString = "-Djava.io.tmpdir=/sdcard"; + mOptions.add(opt); + initArgs.version = JNI_VERSION_1_4; initArgs.options = mOptions.editArray(); initArgs.nOptions = mOptions.size(); diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp index 429f177..e580d36 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -72,11 +72,16 @@ public: *dst = *src; } + static jboolean isConvex(JNIEnv* env, jobject clazz, jlong objHandle) { + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + return obj->isConvex(); + } + static jint getFillType(JNIEnv* env, jobject clazz, jlong objHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); return obj->getFillType(); } - + static void setFillType(JNIEnv* env, jobject clazz, jlong pathHandle, jint ftHandle) { SkPath* path = reinterpret_cast<SkPath*>(pathHandle); SkPath::FillType ft = static_cast<SkPath::FillType>(ftHandle); @@ -524,6 +529,7 @@ static JNINativeMethod methods[] = { {"native_reset","(J)V", (void*) SkPathGlue::reset}, {"native_rewind","(J)V", (void*) SkPathGlue::rewind}, {"native_set","(JJ)V", (void*) SkPathGlue::assign}, + {"native_isConvex","(J)Z", (void*) SkPathGlue::isConvex}, {"native_getFillType","(J)I", (void*) SkPathGlue::getFillType}, {"native_setFillType","(JI)V", (void*) SkPathGlue::setFillType}, {"native_isEmpty","(J)Z", (void*) SkPathGlue::isEmpty}, 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/attrs.xml b/core/res/res/values/attrs.xml index a78ce02..f85b193 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1596,6 +1596,8 @@ <enum name="KEYCODE_BRIGHTNESS_DOWN" value="220" /> <enum name="KEYCODE_BRIGHTNESS_UP" value="221" /> <enum name="KEYCODE_MEDIA_AUDIO_TRACK" value="222" /> + <enum name="KEYCODE_MEDIA_SLEEP" value="223" /> + <enum name="KEYCODE_MEDIA_WAKEUP" value="224" /> </attr> <!-- ***************************************************************** --> 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,31 +393,34 @@ 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> + <!-- 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 + closed. The default is 0. --> + <integer name="config_lidKeyboardAccessibility">0</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> + <!-- Indicate whether the lid state impacts the accessibility of + the navigation buttons. 0 means it doesn't, 1 means it is accessible + when the lid is open, 2 means it is accessible when the lid is + closed. The default is 0. --> + <integer name="config_lidNavigationAccessibility">0</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> + <!-- Indicate whether closing the lid causes the device to go to sleep and opening + it causes the device to wake up. + The default is false. --> + <bool name="config_lidControlsSleep">false</bool> - <!-- 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> + <!-- 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 @@ -414,12 +428,6 @@ 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 @@ -428,27 +436,39 @@ 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> - <!-- 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 - closed. The default is 0. --> - <integer name="config_lidKeyboardAccessibility">0</integer> + <!-- HDMI behavior --> - <!-- Indicate whether the lid state impacts the accessibility of - the navigation buttons. 0 means it doesn't, 1 means it is accessible - when the lid is open, 2 means it is accessible when the lid is - closed. The default is 0. --> - <integer name="config_lidNavigationAccessibility">0</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> - <!-- Indicate whether closing the lid causes the device to go to sleep and opening - it causes the device to wake up. - The default is false. --> - <bool name="config_lidControlsSleep">false</bool> + <!-- 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 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 @@ please see styles_device_defaults.xml. <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/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java index 5a4a2d0..9d97ac5 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java @@ -101,9 +101,10 @@ public class NetworkState { } /* - * Transition from CONNECTED -> DISCONNECTED: - * CONNECTED->DISCONNECTING->DISCONNECTED - * return false if any state transition is not valid and save a message in mReason + * Verifies state transition from CONNECTED->...-> DISCONNECTED. + * + * returns false if initial state or target state is not correct, or if there is + * any transition from DISCONNECTING/DISCONNECTED -> CONNECTED. */ public boolean transitToDisconnection () { mReason = "states: " + printStates(); @@ -120,13 +121,13 @@ public class NetworkState { for (int i = 1; i < mStateDepository.size() - 1; i++) { State preState = mStateDepository.get(i-1); State curState = mStateDepository.get(i); - if ((preState == State.CONNECTED) && ((curState == State.DISCONNECTING) || + if (preState == curState) { + continue; + } else if ((preState == State.CONNECTED) && ((curState == State.DISCONNECTING) || (curState == State.DISCONNECTED))) { continue; } else if ((preState == State.DISCONNECTING) && (curState == State.DISCONNECTED)) { continue; - } else if ((preState == State.DISCONNECTED) && (curState == State.DISCONNECTED)) { - continue; } else { mReason += " Transition state from " + preState.toString() + " to " + curState.toString() + " is not valid."; @@ -136,7 +137,12 @@ public class NetworkState { return true; } - // DISCONNECTED->CONNECTING->CONNECTED + /* + * Verifies state transition from DISCONNECTED->...-> CONNECTED. + * + * returns false if initial state or target state is not correct, or if there is + * any transition from CONNECED -> DISCONNECTED. + */ public boolean transitToConnection() { mReason = "states: " + printStates(); if (mStateDepository.get(0) != State.DISCONNECTED) { @@ -152,14 +158,15 @@ public class NetworkState { for (int i = 1; i < mStateDepository.size(); i++) { State preState = mStateDepository.get(i-1); State curState = mStateDepository.get(i); - if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) || - (curState == State.CONNECTED) || (curState == State.DISCONNECTED))) { + if (preState == curState) { continue; - } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) { - continue; - } else if ((preState == State.CONNECTED) && (curState == State.CONNECTED)) { + } + if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) || + (curState == State.CONNECTED))) { continue; - } else { + } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) { + continue; + } else { mReason += " Transition state from " + preState.toString() + " to " + curState.toString() + " is not valid."; return false; 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 @@ if [[ $rebuild == true ]]; then $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(); + } +} |